changed strlcat() and strlcpy() to have the same semantics as the
authorAndrew Tridgell <tridge@samba.org>
Sat, 14 Nov 1998 23:31:58 +0000 (23:31 +0000)
committerAndrew Tridgell <tridge@samba.org>
Sat, 14 Nov 1998 23:31:58 +0000 (23:31 +0000)
OpenBSD functions of the same name.

changed slprintf() to take buffer length rather than buffer length -1

14 files changed:
authenticate.c
exclude.c
flist.c
generator.c
io.c
lib/compat.c
loadparm.c
log.c
mkproto.awk
receiver.c
rsync.c
sender.c
socket.c
util.c

index 5ecce15..a4835a6 100644 (file)
@@ -55,7 +55,7 @@ static void gen_challenge(char *addr, char *challenge)
 
        memset(input, 0, sizeof(input));
 
-       strlcpy((char *)input, addr, 16);
+       strlcpy((char *)input, addr, 17);
        gettimeofday(&tv, NULL);
        SIVAL(input, 16, tv.tv_sec);
        SIVAL(input, 20, tv.tv_usec);
index 11d5eb0..9b32554 100644 (file)
--- a/exclude.c
+++ b/exclude.c
@@ -321,7 +321,7 @@ void add_cvs_excludes(void)
                add_exclude(cvs_ignore_list[i], 0);
 
        if ((p=getenv("HOME")) && strlen(p) < (MAXPATHLEN-12)) {
-               slprintf(fname,sizeof(fname)-1, "%s/.cvsignore",p);
+               slprintf(fname,sizeof(fname), "%s/.cvsignore",p);
                add_exclude_file(fname,0,0);
        }
 
diff --git a/flist.c b/flist.c
index f614b8b..caca010 100644 (file)
--- a/flist.c
+++ b/flist.c
@@ -230,7 +230,7 @@ static void send_file_entry(struct file_struct *file,int f,unsigned base_flags)
        last_gid = file->gid;
        last_time = file->modtime;
 
-       strlcpy(lastname,fname,MAXPATHLEN-1);
+       strlcpy(lastname,fname,MAXPATHLEN);
        lastname[MAXPATHLEN-1] = 0;
 }
 
@@ -265,11 +265,11 @@ static void receive_file_entry(struct file_struct **fptr,
 
        if (l2 >= MAXPATHLEN-l1) overflow("receive_file_entry");
 
-       strlcpy(thisname,lastname,l1);
+       strlcpy(thisname,lastname,l1+1);
        read_sbuf(f,&thisname[l1],l2);
        thisname[l1+l2] = 0;
 
-       strlcpy(lastname,thisname,MAXPATHLEN-1);
+       strlcpy(lastname,thisname,MAXPATHLEN);
        lastname[MAXPATHLEN-1] = 0;
 
        clean_fname(thisname);
@@ -370,7 +370,7 @@ static struct file_struct *make_file(char *fname)
        char *p;
        char cleaned_name[MAXPATHLEN];
 
-       strlcpy(cleaned_name, fname, MAXPATHLEN-1);
+       strlcpy(cleaned_name, fname, MAXPATHLEN);
        cleaned_name[MAXPATHLEN-1] = 0;
        clean_fname(cleaned_name);
        fname = cleaned_name;
@@ -531,7 +531,7 @@ static void send_directory(int f,struct file_list *flist,char *dir)
                return;
        }
 
-       strlcpy(fname,dir,MAXPATHLEN-1);
+       strlcpy(fname,dir,MAXPATHLEN);
        l = strlen(fname);
        if (fname[l-1] != '/') {
                if (l == MAXPATHLEN-1) {
@@ -540,7 +540,7 @@ static void send_directory(int f,struct file_list *flist,char *dir)
                        closedir(d);
                        return;
                }
-               strlcat(fname,"/", MAXPATHLEN-1);
+               strlcat(fname,"/", MAXPATHLEN);
                l++;
        }
        p = fname + strlen(fname);
@@ -562,7 +562,7 @@ static void send_directory(int f,struct file_list *flist,char *dir)
                if (strcmp(dname,".")==0 ||
                    strcmp(dname,"..")==0)
                        continue;
-               strlcpy(p,dname,MAXPATHLEN-(l+1));
+               strlcpy(p,dname,MAXPATHLEN-l);
                send_file_name(f,flist,fname,recurse,0);
        }
 
@@ -608,11 +608,11 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
                char fname2[MAXPATHLEN];
                char *fname = fname2;
 
-               strlcpy(fname,argv[i],MAXPATHLEN-1);
+               strlcpy(fname,argv[i],MAXPATHLEN);
 
                l = strlen(fname);
                if (l != 1 && fname[l-1] == '/') {
-                       strlcat(fname,".",MAXPATHLEN-1);
+                       strlcat(fname,".",MAXPATHLEN);
                }
 
                if (link_stat(fname,&st) != 0) {
@@ -644,7 +644,7 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
                           thus getting their permissions right */
                        *p = 0;
                        if (strcmp(lastpath,fname)) {
-                               strlcpy(lastpath, fname, sizeof(lastpath)-1);
+                               strlcpy(lastpath, fname, sizeof(lastpath));
                                *p = '/';
                                for (p=fname+1; (p=strchr(p,'/')); p++) {
                                        int copy_links_saved = copy_links;
@@ -956,11 +956,11 @@ char *f_name(struct file_struct *f)
        n = (n+1)%10;
 
        if (f->dirname) {
-               strlcpy(p, f->dirname, MAXPATHLEN-1);
-               strlcat(p, "/", MAXPATHLEN-1);
-               strlcat(p, f->basename, MAXPATHLEN-1);
+               strlcpy(p, f->dirname, MAXPATHLEN);
+               strlcat(p, "/", MAXPATHLEN);
+               strlcat(p, f->basename, MAXPATHLEN);
        } else {
-               strlcpy(p, f->basename, MAXPATHLEN-1);
+               strlcpy(p, f->basename, MAXPATHLEN);
        }
 
        return p;
index 06c1fa4..b772d33 100644 (file)
@@ -273,7 +273,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
        if ((statret == -1) && (compare_dest != NULL)) {
                /* try the file at compare_dest instead */
                int saveerrno = errno;
-               slprintf(fnamecmpbuf,MAXPATHLEN-1,"%s/%s",compare_dest,fname);
+               slprintf(fnamecmpbuf,MAXPATHLEN,"%s/%s",compare_dest,fname);
                statret = link_stat(fnamecmpbuf,&st);
                if (!S_ISREG(st.st_mode))
                        statret = -1;
diff --git a/io.c b/io.c
index 7191140..25d7516 100644 (file)
--- a/io.c
+++ b/io.c
@@ -538,7 +538,7 @@ void io_printf(int fd, const char *format, ...)
        int len;
        
        va_start(ap, format);
-       len = vslprintf(buf, sizeof(buf)-1, format, ap);
+       len = vslprintf(buf, sizeof(buf), format, ap);
        va_end(ap);
 
        if (len < 0) exit_cleanup(RERR_STREAMIO);
index f47275f..922d119 100644 (file)
@@ -83,10 +83,10 @@ char *rep_inet_ntoa(struct in_addr ip)
        unsigned char *p = (unsigned char *)&ip.s_addr;
        static char buf[18];
 #if WORDS_BIGENDIAN
-       slprintf(buf, 17, "%d.%d.%d.%d", 
+       slprintf(buf, 18, "%d.%d.%d.%d", 
                 (int)p[0], (int)p[1], (int)p[2], (int)p[3]);
 #else
-       slprintf(buf, 17, "%d.%d.%d.%d", 
+       slprintf(buf, 18, "%d.%d.%d.%d", 
                 (int)p[3], (int)p[2], (int)p[1], (int)p[0]);
 #endif
        return buf;
index 81c4943..09fdd5a 100644 (file)
@@ -51,7 +51,7 @@
 #define strequal(a,b) (strcasecmp(a,b)==0)
 #define BOOLSTR(b) ((b) ? "Yes" : "No")
 typedef char pstring[1024];
-#define pstrcpy(a,b) strlcpy(a,b,sizeof(pstring)-1)
+#define pstrcpy(a,b) strlcpy(a,b,sizeof(pstring))
 
 /* the following are used by loadparm for option lists */
 typedef enum
@@ -610,7 +610,7 @@ static BOOL lp_do_parameter(int snum, char *parmname, char *parmvalue)
        break;
 
      case P_GSTRING:
-       strlcpy((char *)parm_ptr,parmvalue,sizeof(pstring)-1);
+       strlcpy((char *)parm_ptr,parmvalue,sizeof(pstring));
        break;
 
      case P_ENUM:
diff --git a/log.c b/log.c
index 18e1da0..6594d45 100644 (file)
--- a/log.c
+++ b/log.c
@@ -90,7 +90,7 @@ void log_open(void)
        /* recursion can happen with certain fatal conditions */
 
        va_start(ap, format);
-       len = vslprintf(buf, sizeof(buf)-1, format, ap);
+       len = vslprintf(buf, sizeof(buf), format, ap);
        va_end(ap);
 
        if (len < 0) exit_cleanup(RERR_MESSAGEIO);
@@ -188,7 +188,7 @@ static void log_formatted(int fd,
        extern int am_sender;
        int64 b;
 
-       strlcpy(buf, format, sizeof(buf)-1);
+       strlcpy(buf, format, sizeof(buf));
        
        for (s=&buf[0]; 
             s && (p=strchr(s,'%')); ) {
@@ -199,18 +199,18 @@ static void log_formatted(int fd,
                case 'h': n = client_name(0); break;
                case 'a': n = client_addr(0); break;
                case 'l': 
-                       slprintf(buf2,sizeof(buf2)-1,"%.0f", 
+                       slprintf(buf2,sizeof(buf2),"%.0f", 
                                 (double)file->length); 
                        n = buf2;
                        break;
                case 'p': 
-                       slprintf(buf2,sizeof(buf2)-1,"%d", 
+                       slprintf(buf2,sizeof(buf2),"%d", 
                                 (int)getpid()); 
                        n = buf2;
                        break;
                case 'o': n = op; break;
                case 'f': 
-                       slprintf(buf2, sizeof(buf2)-1, "%s/%s", 
+                       slprintf(buf2, sizeof(buf2), "%s/%s", 
                                 file->basedir?file->basedir:"", 
                                 f_name(file));
                        clean_fname(buf2);
@@ -229,7 +229,7 @@ static void log_formatted(int fd,
                                b = stats.total_read - 
                                        initial_stats->total_read;
                        }
-                       slprintf(buf2,sizeof(buf2)-1,"%.0f", (double)b); 
+                       slprintf(buf2,sizeof(buf2),"%.0f", (double)b); 
                        n = buf2;
                        break;
                case 'c': 
@@ -240,7 +240,7 @@ static void log_formatted(int fd,
                                b = stats.total_read - 
                                        initial_stats->total_read;
                        }
-                       slprintf(buf2,sizeof(buf2)-1,"%.0f", (double)b); 
+                       slprintf(buf2,sizeof(buf2),"%.0f", (double)b); 
                        n = buf2;
                        break;
                }
index a08b1af..6af5dfc 100644 (file)
@@ -58,7 +58,7 @@ BEGIN {
   next;
 }
 
-!/^OFF_T|^off_t|^pid_t|^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^struct|^BOOL|^void|^time/ {
+!/^OFF_T|^size_t|^off_t|^pid_t|^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^struct|^BOOL|^void|^time/ {
   next;
 }
 
index ac9c669..9701303 100644 (file)
@@ -163,7 +163,7 @@ static int get_tmpname(char *fnametmp, char *fname)
                        rprintf(FERROR,"filename too long\n");
                        return 0;
                }
-               slprintf(fnametmp,MAXPATHLEN-1, "%s/.%s.XXXXXX",tmpdir,f);
+               slprintf(fnametmp,MAXPATHLEN, "%s/.%s.XXXXXX",tmpdir,f);
                return 1;
        } 
 
@@ -176,11 +176,11 @@ static int get_tmpname(char *fnametmp, char *fname)
 
        if (f) {
                *f = 0;
-               slprintf(fnametmp,MAXPATHLEN-1,"%s/.%s.XXXXXX",
+               slprintf(fnametmp,MAXPATHLEN,"%s/.%s.XXXXXX",
                         fname,f+1);
                *f = '/';
        } else {
-               slprintf(fnametmp,MAXPATHLEN-1,".%s.XXXXXX",fname);
+               slprintf(fnametmp,MAXPATHLEN,".%s.XXXXXX",fname);
        }
 
        return 1;
@@ -353,7 +353,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
 
                if ((fd1 == -1) && (compare_dest != NULL)) {
                        /* try the file at compare_dest instead */
-                       slprintf(fnamecmpbuf,MAXPATHLEN-1,"%s/%s",
+                       slprintf(fnamecmpbuf,MAXPATHLEN,"%s/%s",
                                                compare_dest,fname);
                        fnamecmp = fnamecmpbuf;
                        fd1 = open(fnamecmp,O_RDONLY);
diff --git a/rsync.c b/rsync.c
index 7021fd1..0f8d33b 100644 (file)
--- a/rsync.c
+++ b/rsync.c
@@ -94,7 +94,7 @@ int delete_file(char *fname)
                if (strcmp(dname,".")==0 ||
                    strcmp(dname,"..")==0)
                        continue;
-               slprintf(buf, sizeof(buf)-1, "%s/%s", fname, dname);
+               slprintf(buf, sizeof(buf), "%s/%s", fname, dname);
                if (verbose > 0)
                        rprintf(FINFO,"deleting %s\n", buf);
                if (delete_file(buf) != 0) {
@@ -202,7 +202,7 @@ void finish_transfer(char *fname, char *fnametmp, struct file_struct *file)
                        rprintf(FERROR,"backup filename too long\n");
                        return;
                }
-               slprintf(fnamebak,sizeof(fnamebak)-1,"%s%s",fname,backup_suffix);
+               slprintf(fnamebak,sizeof(fnamebak),"%s%s",fname,backup_suffix);
                if (do_rename(fname,fnamebak) != 0 && errno != ENOENT) {
                        rprintf(FERROR,"rename %s %s : %s\n",fname,fnamebak,strerror(errno));
                        return;
index 45c0920..4a344ea 100644 (file)
--- a/sender.c
+++ b/sender.c
@@ -128,17 +128,17 @@ void send_files(struct file_list *flist,int f_out,int f_in)
 
                fname[0] = 0;
                if (file->basedir) {
-                       strlcpy(fname,file->basedir,MAXPATHLEN-1);
+                       strlcpy(fname,file->basedir,MAXPATHLEN);
                        if (strlen(fname) == MAXPATHLEN-1) {
                                io_error = 1;
                                rprintf(FERROR, "send_files failed on long-named directory %s\n",
                                        fname);
                                return;
                        }
-                       strlcat(fname,"/",MAXPATHLEN-1);
+                       strlcat(fname,"/",MAXPATHLEN);
                        offset = strlen(file->basedir)+1;
                }
-               strlcat(fname,f_name(file),MAXPATHLEN-strlen(fname));
+               strlcat(fname,f_name(file),MAXPATHLEN);
          
                if (verbose > 2) 
                        rprintf(FINFO,"send_files(%d,%s)\n",i,fname);
index 6fd4e36..b9f01a6 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -330,7 +330,7 @@ char *client_addr(int fd)
                exit_cleanup(RERR_SOCKETIO);
        }
        
-       strlcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr), sizeof(addr_buf)-1);
+       strlcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr), sizeof(addr_buf));
        return addr_buf;
 }
 
@@ -363,7 +363,7 @@ char *client_name(int fd)
        if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
                                sizeof(sockin->sin_addr),
                                AF_INET))) {
-               strlcpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
+               strlcpy(name_buf,(char *)hp->h_name,sizeof(name_buf));
        }
 
 
diff --git a/util.c b/util.c
index 8c352b2..c5bb4a7 100644 (file)
--- a/util.c
+++ b/util.c
@@ -359,28 +359,34 @@ void kill_all(int sig)
 }
 
 /* like strncpy but does not 0 fill the buffer and always null 
-   terminates (thus it can use maxlen+1 space in d) */
-void strlcpy(char *d, char *s, int maxlen)
+   terminates. bufsize is the size of the destination buffer */
+size_t strlcpy(char *d, const char *s, size_t bufsize)
 {
-       int len = strlen(s);
-       if (len > maxlen) len = maxlen;
+       size_t len = strlen(s);
+       size_t ret = len;
+       if (len >= bufsize) len = bufsize-1;
        memcpy(d, s, len);
        d[len] = 0;
+       return ret;
 }
 
 /* like strncat but does not 0 fill the buffer and always null 
-   terminates (thus it can use maxlen+1 space in d) */
-void strlcat(char *d, char *s, int maxlen)
+   terminates. bufsize is the length of the buffer, which should
+   be one more than the maximum resulting string length */
+size_t strlcat(char *d, const char *s, size_t bufsize)
 {
-       int len1 = strlen(d);
-       int len2 = strlen(s);
-       if (len1+len2 > maxlen) {
-               len2 = maxlen-len1;
+       size_t len1 = strlen(d);
+       size_t len2 = strlen(s);
+       size_t ret = len1 + len2;
+
+       if (len1+len2 >= bufsize) {
+               len2 = bufsize - (len1+1);
        }
        if (len2 > 0) {
                memcpy(d+len1, s, len2);
                d[len1+len2] = 0;
        }
+       return ret;
 }
 
 /* turn a user name into a uid */
@@ -502,14 +508,13 @@ void strlower(char *s)
        }
 }
 
-/* this is like vsnprintf but the 'n' limit does not include
-   the terminating null. So if you have a 1024 byte buffer then
-   pass 1023 for n */
+/* this is like vsnprintf but it always null terminates, so you
+   can fit at most n-1 chars in */
 int vslprintf(char *str, int n, const char *format, va_list ap)
 {
        int ret = vsnprintf(str, n, format, ap);
-       if (ret > n || ret < 0) {
-               str[n] = 0;
+       if (ret >= n || ret < 0) {
+               str[n-1] = 0;
                return -1;
        }
        str[ret] = 0;
@@ -670,10 +675,10 @@ char *push_dir(char *dir, int save)
        }
 
        if (*dir == '/') {
-               strlcpy(curr_dir, dir, sizeof(curr_dir)-1);
+               strlcpy(curr_dir, dir, sizeof(curr_dir));
        } else {
-               strlcat(curr_dir,"/", sizeof(curr_dir)-1);
-               strlcat(curr_dir,dir, sizeof(curr_dir)-1);
+               strlcat(curr_dir,"/", sizeof(curr_dir));
+               strlcat(curr_dir,dir, sizeof(curr_dir));
        }
 
        clean_fname(curr_dir);
@@ -692,7 +697,7 @@ int pop_dir(char *dir)
                return ret;
        }
 
-       strlcpy(curr_dir, dir, sizeof(curr_dir)-1);
+       strlcpy(curr_dir, dir, sizeof(curr_dir));
 
        free(dir);
 
@@ -797,7 +802,7 @@ char *timestring(time_t t)
 #ifdef HAVE_STRFTIME
        strftime(TimeBuf,sizeof(TimeBuf)-1,"%Y/%m/%d %T",tm);
 #else
-       strlcpy(TimeBuf, asctime(tm), sizeof(TimeBuf)-1);
+       strlcpy(TimeBuf, asctime(tm), sizeof(TimeBuf));
 #endif
 
        if (TimeBuf[strlen(TimeBuf)-1] == '\n') {