util.c

Utilities used in rsync [詳細]

ソースコードを見る。


データ構造

struct  bitbag

関数

void set_nonblocking (int fd)
 Set a fd into nonblocking mode
void set_blocking (int fd)
 Set a fd into blocking mode
int fd_pair (int fd[2])
 Create a file descriptor pair - like pipe() but use socketpair if possible (because of blocking issues on pipes).
void print_child_argv (char **cmd)
void out_of_memory (char *str)
void overflow_exit (char *str)
int set_modtime (char *fname, time_t modtime, mode_t mode)
int mkdir_defmode (char *fname)
int create_directory_path (char *fname)
int full_write (int desc, char *ptr, size_t len)
 Write len bytes at ptr to descriptor desc, retrying if interrupted.
static int safe_read (int desc, char *ptr, size_t len)
 Read len bytes at ptr from descriptor desc, retrying if interrupted.
int copy_file (const char *source, const char *dest, mode_t mode)
 Copy a file.
int robust_unlink (const char *fname)
 Robust unlink: some OS'es (HPUX) refuse to unlink busy files, so rename to <path>/.rsyncNNN instead.
int robust_rename (char *from, char *to, char *partialptr, int mode)
pid_t do_fork (void)
 Fork and record the pid of the child.
void kill_all (int sig)
 Kill all children.
int name_to_uid (char *name, uid_t *uid)
 Turn a user name into a uid
int name_to_gid (char *name, gid_t *gid)
 Turn a group name into a gid
int lock_range (int fd, int offset, int len)
 Lock a byte range in a open file
static int filter_server_path (char *arg)
static void glob_expand_one (char *s, char ***argv_ptr, int *argc_ptr, int *maxargs_ptr)
void glob_expand (char *base1, char ***argv_ptr, int *argc_ptr, int *maxargs_ptr)
void strlower (char *s)
 Convert a string to lower case
size_t pathjoin (char *dest, size_t destsize, const char *p1, const char *p2)
size_t stringjoin (char *dest, size_t destsize,...)
int count_dir_elements (const char *p)
unsigned int clean_fname (char *name, BOOL collapse_dot_dot)
char * sanitize_path (char *dest, const char *p, const char *rootdir, int depth)
int push_dir (char *dir)
 Like chdir(), but it keeps track of the current directory (in the global "curr_dir"), and ensures that the path size doesn't overflow.
int pop_dir (char *dir)
 Reverse a push_dir() call.
char * full_fname (const char *fn)
 Return a quoted string with the full pathname of the indicated filename.
char * partial_dir_fname (const char *fname)
int handle_partial_dir (const char *fname, int create)
int unsafe_symlink (const char *dest, const char *src)
 Determine if a symlink points outside the current directory tree.
char * human_num (int64 num)
char * human_dnum (double dnum, int decimal_digits)
char * timestring (time_t t)
 Return the date and time as a string
int msleep (int t)
 Sleep for a specified number of milliseconds.
int cmp_time (time_t file1, time_t file2)
int _Insure_trap_error (int a1, int a2, int a3, int a4, int a5, int a6)
 This routine is a trick to immediately catch errors when debugging with insure.
void * _new_array (unsigned int size, unsigned long num)
void * _realloc_array (void *ptr, unsigned int size, unsigned long num)
const char * find_filename_suffix (const char *fn, int fn_len, int *len_ptr)
uint32 fuzzy_distance (const char *s1, int len1, const char *s2, int len2)
bitbagbitbag_create (int max_ndx)
void bitbag_set_bit (struct bitbag *bb, int ndx)
void bitbag_clear_bit (struct bitbag *bb, int ndx)
int bitbag_check_bit (struct bitbag *bb, int ndx)
int bitbag_next_bit (struct bitbag *bb, int after)

変数

int verbose
int dry_run
int module_id
int modify_window
int relative_paths
int human_readable
mode_t orig_umask
char * partial_dir
filter_list_struct server_filter_list
int sanitize_paths = 0
static pid_t all_pids [10]
static int num_pids
char curr_dir [MAXPATHLEN]
unsigned int curr_dir_len
static char partial_fname [MAXPATHLEN]

説明

Utilities used in rsync

util.c で定義されています。


関数

void set_nonblocking ( int  fd  ) 

Set a fd into nonblocking mode

util.c47 行で定義されています。

00048 {
00049         int val;
00050 
00051         if ((val = fcntl(fd, F_GETFL, 0)) == -1)
00052                 return;
00053         if (!(val & NONBLOCK_FLAG)) {
00054                 val |= NONBLOCK_FLAG;
00055                 fcntl(fd, F_SETFL, val);
00056         }
00057 }

void set_blocking ( int  fd  ) 

Set a fd into blocking mode

util.c62 行で定義されています。

00063 {
00064         int val;
00065 
00066         if ((val = fcntl(fd, F_GETFL, 0)) == -1)
00067                 return;
00068         if (val & NONBLOCK_FLAG) {
00069                 val &= ~NONBLOCK_FLAG;
00070                 fcntl(fd, F_SETFL, val);
00071         }
00072 }

int fd_pair ( int  fd[2]  ) 

Create a file descriptor pair - like pipe() but use socketpair if possible (because of blocking issues on pipes).

Always set non-blocking.

util.c80 行で定義されています。

参照先 set_nonblocking().

参照元 do_cmd()do_recv()local_child()piped_child().

00081 {
00082         int ret;
00083 
00084 #ifdef HAVE_SOCKETPAIR
00085         ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
00086 #else
00087         ret = pipe(fd);
00088 #endif
00089 
00090         if (ret == 0) {
00091                 set_nonblocking(fd[0]);
00092                 set_nonblocking(fd[1]);
00093         }
00094 
00095         return ret;
00096 }

void print_child_argv ( char **  cmd  ) 

util.c98 行で定義されています。

参照先 FINFOrprintf().

参照元 piped_child()start_inband_exchange().

00099 {
00100         rprintf(FINFO, "opening connection using ");
00101         for (; *cmd; cmd++) {
00102                 /* Look for characters that ought to be quoted.  This
00103                 * is not a great quoting algorithm, but it's
00104                 * sufficient for a log message. */
00105                 if (strspn(*cmd, "abcdefghijklmnopqrstuvwxyz"
00106                            "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
00107                            "0123456789"
00108                            ",.-_=+@/") != strlen(*cmd)) {
00109                         rprintf(FINFO, "\"%s\" ", *cmd);
00110                 } else {
00111                         rprintf(FINFO, "%s ", *cmd);
00112                 }
00113         }
00114         rprintf(FINFO, "\n");
00115 }

void out_of_memory ( char *  str  ) 

util.c117 行で定義されています。

参照先 FERRORrprintf().

参照元 access_match()add_rule()add_to_list()auth_server()bitbag_create()bitbag_set_bit()build_hash_table()do_cmd()expand_file_acl_index_list()expand_ida_list()expand_rsync_acl_list()expand_smb_acl_list()finish_pre_exec()flist_expand()flist_ndx_push()flist_new()get_checksum2()glob_expand()glob_expand_one()init_hard_links()io_start_buffering_in()io_start_buffering_out()is_in_group()link_idev_data()make_file()map_file()map_ptr()msg_list_add()open_socket_in()parse_size_arg()push_local_filters()readfd_unbuffered()receive_sums()receive_xattr()recv_deflated_token()recv_file_list()recv_uid_list()rsync_module()rsync_xal_get()rsync_xal_store()sanitize_path()send_deflated_token()server_options()set_compression()set_socket_options()simple_recv_token()write_file().

00118 {
00119         rprintf(FERROR, "ERROR: out of memory in %s\n", str);
00120         exit_cleanup(RERR_MALLOC);
00121 }

void overflow_exit ( char *  str  ) 

util.c123 行で定義されています。

参照先 FERRORrprintf().

参照元 receive_file_entry()recv_filter_list()send_file_list().

00124 {
00125         rprintf(FERROR, "ERROR: buffer overflow in %s\n", str);
00126         exit_cleanup(RERR_MALLOC);
00127 }

int set_modtime ( char *  fname,
time_t  modtime,
mode_t  mode 
)

util.c129 行で定義されています。

参照先 dry_runFINFOrprintf()verbose.

参照元 set_file_attrs().

00130 {
00131 #if !defined HAVE_LUTIMES || !defined HAVE_UTIMES
00132         if (S_ISLNK(mode))
00133                 return 1;
00134 #endif
00135 
00136         if (verbose > 2) {
00137                 rprintf(FINFO, "set modtime of %s to (%ld) %s",
00138                         fname, (long)modtime,
00139                         asctime(localtime(&modtime)));
00140         }
00141 
00142         if (dry_run)
00143                 return 0;
00144 
00145         {
00146 #ifdef HAVE_UTIMES
00147                 struct timeval t[2];
00148                 t[0].tv_sec = time(NULL);
00149                 t[0].tv_usec = 0;
00150                 t[1].tv_sec = modtime;
00151                 t[1].tv_usec = 0;
00152 # ifdef HAVE_LUTIMES
00153                 if (S_ISLNK(mode))
00154                         return lutimes(fname, t);
00155 # endif
00156                 return utimes(fname, t);
00157 #elif defined HAVE_UTIMBUF
00158                 struct utimbuf tbuf;
00159                 tbuf.actime = time(NULL);
00160                 tbuf.modtime = modtime;
00161                 return utime(fname,&tbuf);
00162 #elif defined HAVE_UTIME
00163                 time_t t[2];
00164                 t[0] = time(NULL);
00165                 t[1] = modtime;
00166                 return utime(fname,t);
00167 #else
00168 #error No file-time-modification routine found!
00169 #endif
00170         }
00171 }

int mkdir_defmode ( char *  fname  ) 

util.c176 行で定義されています。

参照先 do_mkdir()orig_umask.

参照元 get_local_name()make_bak_dir().

00177 {
00178         int ret;
00179 
00180         umask(orig_umask);
00181         ret = do_mkdir(fname, ACCESSPERMS);
00182         umask(0);
00183 
00184         return ret;
00185 }

int create_directory_path ( char *  fname  ) 

util.c189 行で定義されています。

参照先 do_mkdir()errnoorig_umask.

参照元 recv_files()recv_generator().

00190 {
00191         char *p;
00192         int ret = 0;
00193 
00194         while (*fname == '/')
00195                 fname++;
00196         while (strncmp(fname, "./", 2) == 0)
00197                 fname += 2;
00198 
00199         umask(orig_umask);
00200         p = fname;
00201         while ((p = strchr(p,'/')) != NULL) {
00202                 *p = '\0';
00203                 if (do_mkdir(fname, ACCESSPERMS) < 0 && errno != EEXIST)
00204                     ret = -1;
00205                 *p++ = '/';
00206         }
00207         umask(0);
00208 
00209         return ret;
00210 }

int full_write ( int  desc,
char *  ptr,
size_t  len 
)

Write len bytes at ptr to descriptor desc, retrying if interrupted.

戻り値:
len upon success
<0 write's (negative) error code
Derived from GNU C's cccp.c.

util.c222 行で定義されています。

参照先 errnototal_written.

参照元 copy_file()generate_and_send_sums().

00223 {
00224         int total_written;
00225 
00226         total_written = 0;
00227         while (len > 0) {
00228                 int written = write(desc, ptr, len);
00229                 if (written < 0)  {
00230                         if (errno == EINTR)
00231                                 continue;
00232                         return written;
00233                 }
00234                 total_written += written;
00235                 ptr += written;
00236                 len -= written;
00237         }
00238         return total_written;
00239 }

static int safe_read ( int  desc,
char *  ptr,
size_t  len 
) [static]

Read len bytes at ptr from descriptor desc, retrying if interrupted.

戻り値:
>0 the actual number of bytes read
0 for EOF
<0 for an error.
Derived from GNU C's cccp.c.

util.c252 行で定義されています。

参照先 errno.

参照元 copy_file().

00253 {
00254         int n_chars;
00255 
00256         if (len == 0)
00257                 return len;
00258 
00259         do {
00260                 n_chars = read(desc, ptr, len);
00261         } while (n_chars < 0 && errno == EINTR);
00262 
00263         return n_chars;
00264 }

int copy_file ( const char *  source,
const char *  dest,
mode_t  mode 
)

Copy a file.

This is used in conjunction with the --temp-dir, --backup, and --copy-dest options.

util.c270 行で定義されています。

参照先 bufdo_open()errnoFERRORFINFOfull_fname()full_write()robust_unlink()rsyserr()safe_read().

参照元 robust_rename()try_dests_reg().

00271 {
00272         int ifd;
00273         int ofd;
00274         char buf[1024 * 8];
00275         int len;   /* Number of bytes read into `buf'. */
00276 
00277         ifd = do_open(source, O_RDONLY, 0);
00278         if (ifd == -1) {
00279                 rsyserr(FERROR, errno, "open %s", full_fname(source));
00280                 return -1;
00281         }
00282 
00283         if (robust_unlink(dest) && errno != ENOENT) {
00284                 rsyserr(FERROR, errno, "unlink %s", full_fname(dest));
00285                 return -1;
00286         }
00287 
00288         ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode);
00289         if (ofd == -1) {
00290                 rsyserr(FERROR, errno, "open %s", full_fname(dest));
00291                 close(ifd);
00292                 return -1;
00293         }
00294 
00295         while ((len = safe_read(ifd, buf, sizeof buf)) > 0) {
00296                 if (full_write(ofd, buf, len) < 0) {
00297                         rsyserr(FERROR, errno, "write %s", full_fname(dest));
00298                         close(ifd);
00299                         close(ofd);
00300                         return -1;
00301                 }
00302         }
00303 
00304         if (len < 0) {
00305                 rsyserr(FERROR, errno, "read %s", full_fname(source));
00306                 close(ifd);
00307                 close(ofd);
00308                 return -1;
00309         }
00310 
00311         if (close(ifd) < 0) {
00312                 rsyserr(FINFO, errno, "close failed on %s",
00313                         full_fname(source));
00314         }
00315 
00316         if (close(ofd) < 0) {
00317                 rsyserr(FERROR, errno, "close failed on %s",
00318                         full_fname(dest));
00319                 return -1;
00320         }
00321 
00322         return 0;
00323 }

int robust_unlink ( const char *  fname  ) 

Robust unlink: some OS'es (HPUX) refuse to unlink busy files, so rename to <path>/.rsyncNNN instead.

Note that successive rsync runs will shuffle the filenames around a bit as long as the file is still busy; this is because this function does not know if the unlink call is due to a new file coming in, or --delete trying to remove old .rsyncNNN files, hence it renames it each time.

util.c339 行で定義されています。

参照先 do_rename()do_unlink()errnoFINFOrprintf()sprintf()strlcpy()verbose.

参照元 copy_file()delete_item()keep_backup()maybe_hard_link()recv_generator()robust_rename().

00340 {
00341 #ifndef ETXTBSY
00342         return do_unlink(fname);
00343 #else
00344         static int counter = 1;
00345         int rc, pos, start;
00346         char path[MAXPATHLEN];
00347 
00348         rc = do_unlink(fname);
00349         if (rc == 0 || errno != ETXTBSY)
00350                 return rc;
00351 
00352         if ((pos = strlcpy(path, fname, MAXPATHLEN)) >= MAXPATHLEN)
00353                 pos = MAXPATHLEN - 1;
00354 
00355         while (pos > 0 && path[pos-1] != '/')
00356                 pos--;
00357         pos += strlcpy(path+pos, ".rsync", MAXPATHLEN-pos);
00358 
00359         if (pos > (MAXPATHLEN-MAX_RENAMES_DIGITS-1)) {
00360                 errno = ETXTBSY;
00361                 return -1;
00362         }
00363 
00364         /* start where the last one left off to reduce chance of clashes */
00365         start = counter;
00366         do {
00367                 sprintf(&path[pos], "%03d", counter);
00368                 if (++counter >= MAX_RENAMES)
00369                         counter = 1;
00370         } while ((rc = access(path, 0)) == 0 && counter != start);
00371 
00372         if (verbose > 0) {
00373                 rprintf(FINFO,"renaming %s to %s because of text busy\n",
00374                         fname, path);
00375         }
00376 
00377         /* maybe we should return rename()'s exit status? Nah. */
00378         if (do_rename(fname, path) != 0) {
00379                 errno = ETXTBSY;
00380                 return -1;
00381         }
00382         return 0;
00383 #endif
00384 }

int robust_rename ( char *  from,
char *  to,
char *  partialptr,
int  mode 
)

util.c390 行で定義されています。

参照先 copy_file()do_rename()do_unlink()errnohandle_partial_dir()robust_unlink().

参照元 finish_transfer()robust_move().

00392 {
00393         int tries = 4;
00394 
00395         while (tries--) {
00396                 if (do_rename(from, to) == 0)
00397                         return 0;
00398 
00399                 switch (errno) {
00400 #ifdef ETXTBSY
00401                 case ETXTBSY:
00402                         if (robust_unlink(to) != 0)
00403                                 return -1;
00404                         break;
00405 #endif
00406                 case EXDEV:
00407                         if (partialptr) {
00408                                 if (!handle_partial_dir(partialptr,PDIR_CREATE))
00409                                         return -1;
00410                                 to = partialptr;
00411                         }
00412                         if (copy_file(from, to, mode) != 0)
00413                                 return -2;
00414                         do_unlink(from);
00415                         return 1;
00416                 default:
00417                         return -1;
00418                 }
00419         }
00420         return -1;
00421 }

pid_t do_fork ( void   ) 

Fork and record the pid of the child.

util.c427 行で定義されています。

参照先 all_pidsnum_pids.

参照元 do_recv()local_child()piped_child().

00428 {
00429         pid_t newpid = fork();
00430 
00431         if (newpid != 0  &&  newpid != -1) {
00432                 all_pids[num_pids++] = newpid;
00433         }
00434         return newpid;
00435 }

void kill_all ( int  sig  ) 

Kill all children.

TODO:
It would be kind of nice to make sure that they are actually all our children before we kill them, because their pids may have been recycled by some other process. Perhaps when we wait for a child, we should remove it from this array. Alternatively we could perhaps use process groups, but I think that would not work on ancient Unix versions that don't support them.

util.c447 行で定義されています。

参照先 all_pidsnum_pids.

参照元 _exit_cleanup().

00448 {
00449         int i;
00450 
00451         for (i = 0; i < num_pids; i++) {
00452                 /* Let's just be a little careful where we
00453                  * point that gun, hey?  See kill(2) for the
00454                  * magic caused by negative values. */
00455                 pid_t p = all_pids[i];
00456 
00457                 if (p == getpid())
00458                         continue;
00459                 if (p <= 0)
00460                         continue;
00461 
00462                 kill(p, sig);
00463         }
00464 }

int name_to_uid ( char *  name,
uid_t *  uid 
)

Turn a user name into a uid

util.c467 行で定義されています。

参照元 map_uid()rsync_module().

00468 {
00469         struct passwd *pass;
00470         if (!name || !*name)
00471                 return 0;
00472         pass = getpwnam(name);
00473         if (pass) {
00474                 *uid = pass->pw_uid;
00475                 return 1;
00476         }
00477         return 0;
00478 }

int name_to_gid ( char *  name,
gid_t *  gid 
)

Turn a group name into a gid

util.c481 行で定義されています。

参照元 map_gid()rsync_module().

00482 {
00483         struct group *grp;
00484         if (!name || !*name)
00485                 return 0;
00486         grp = getgrnam(name);
00487         if (grp) {
00488                 *gid = grp->gr_gid;
00489                 return 1;
00490         }
00491         return 0;
00492 }

int lock_range ( int  fd,
int  offset,
int  len 
)

Lock a byte range in a open file

util.c495 行で定義されています。

参照元 claim_connection().

00496 {
00497         struct flock lock;
00498 
00499         lock.l_type = F_WRLCK;
00500         lock.l_whence = SEEK_SET;
00501         lock.l_start = offset;
00502         lock.l_len = len;
00503         lock.l_pid = 0;
00504 
00505         return fcntl(fd,F_SETLK,&lock) == 0;
00506 }

static int filter_server_path ( char *  arg  )  [static]

util.c508 行で定義されています。

参照先 check_filter()filter_list_struct::headserver_filter_list.

参照元 glob_expand_one().

00509 {
00510         char *s;
00511 
00512         if (server_filter_list.head) {
00513                 for (s = arg; (s = strchr(s, '/')) != NULL; ) {
00514                         *s = '\0';
00515                         if (check_filter(&server_filter_list, arg, 1) < 0) {
00516                                 /* We must leave arg truncated! */
00517                                 return 1;
00518                         }
00519                         *s++ = '/';
00520                 }
00521         }
00522         return 0;
00523 }

static void glob_expand_one ( char *  s,
char ***  argv_ptr,
int *  argc_ptr,
int *  maxargs_ptr 
) [static]

util.c525 行で定義されています。

参照先 filter_server_path()out_of_memory()sanitize_path()sanitize_pathsstrdup().

参照元 glob_expand().

00527 {
00528         char **argv = *argv_ptr;
00529         int argc = *argc_ptr;
00530         int maxargs = *maxargs_ptr;
00531 #if !defined HAVE_GLOB || !defined HAVE_GLOB_H
00532         if (argc == maxargs) {
00533                 maxargs += MAX_ARGS;
00534                 if (!(argv = realloc_array(argv, char *, maxargs)))
00535                         out_of_memory("glob_expand_one");
00536                 *argv_ptr = argv;
00537                 *maxargs_ptr = maxargs;
00538         }
00539         if (!*s)
00540                 s = ".";
00541         s = argv[argc++] = strdup(s);
00542         filter_server_path(s);
00543 #else
00544         glob_t globbuf;
00545 
00546         if (maxargs <= argc)
00547                 return;
00548         if (!*s)
00549                 s = ".";
00550 
00551         if (sanitize_paths)
00552                 s = sanitize_path(NULL, s, "", 0);
00553         else
00554                 s = strdup(s);
00555 
00556         memset(&globbuf, 0, sizeof globbuf);
00557         if (!filter_server_path(s))
00558                 glob(s, 0, NULL, &globbuf);
00559         if (MAX((int)globbuf.gl_pathc, 1) > maxargs - argc) {
00560                 maxargs += globbuf.gl_pathc + MAX_ARGS;
00561                 if (!(argv = realloc_array(argv, char *, maxargs)))
00562                         out_of_memory("glob_expand_one");
00563                 *argv_ptr = argv;
00564                 *maxargs_ptr = maxargs;
00565         }
00566         if (globbuf.gl_pathc == 0)
00567                 argv[argc++] = s;
00568         else {
00569                 int i;
00570                 free(s);
00571                 for (i = 0; i < (int)globbuf.gl_pathc; i++) {
00572                         if (!(argv[argc++] = strdup(globbuf.gl_pathv[i])))
00573                                 out_of_memory("glob_expand_one");
00574                 }
00575         }
00576         globfree(&globbuf);
00577 #endif
00578         *argc_ptr = argc;
00579 }

void glob_expand ( char *  base1,
char ***  argv_ptr,
int *  argc_ptr,
int *  maxargs_ptr 
)

util.c582 行で定義されています。

参照先 asprintf()glob_expand_one()out_of_memory()strdup().

参照元 rsync_module().

00583 {
00584         char *s = (*argv_ptr)[*argc_ptr];
00585         char *p, *q;
00586         char *base = base1;
00587         int base_len = strlen(base);
00588 
00589         if (!s || !*s)
00590                 return;
00591 
00592         if (strncmp(s, base, base_len) == 0)
00593                 s += base_len;
00594 
00595         if (!(s = strdup(s)))
00596                 out_of_memory("glob_expand");
00597 
00598         if (asprintf(&base," %s/", base1) <= 0)
00599                 out_of_memory("glob_expand");
00600         base_len++;
00601 
00602         for (q = s; *q; q = p + base_len) {
00603                 if ((p = strstr(q, base)) != NULL)
00604                         *p = '\0'; /* split it at this point */
00605                 glob_expand_one(q, argv_ptr, argc_ptr, maxargs_ptr);
00606                 if (!p)
00607                         break;
00608         }
00609 
00610         free(s);
00611         free(base);
00612 }

void strlower ( char *  s  ) 

Convert a string to lower case

util.c617 行で定義されています。

参照元 access_match().

00618 {
00619         while (*s) {
00620                 if (isupper(*(unsigned char *)s))
00621                         *s = tolower(*(unsigned char *)s);
00622                 s++;
00623         }
00624 }

size_t pathjoin ( char *  dest,
size_t  destsize,
const char *  p1,
const char *  p2 
)

util.c630 行で定義されています。

参照先 strlcpy().

参照元 get_cvs_excludes()hard_link_check()log_formatted()partial_dir_fname()recv_files()setup_merge_file()try_dests_non()try_dests_reg().

00631 {
00632         size_t len = strlcpy(dest, p1, destsize);
00633         if (len < destsize - 1) {
00634                 if (!len || dest[len-1] != '/')
00635                         dest[len++] = '/';
00636                 if (len < destsize - 1)
00637                         len += strlcpy(dest + len, p2, destsize - len);
00638                 else {
00639                         dest[len] = '\0';
00640                         len += strlen(p2);
00641                 }
00642         }
00643         else
00644                 len += strlen(p2) + 1; /* Assume we'd insert a '/'. */
00645         return len;
00646 }

size_t stringjoin ( char *  dest,
size_t  destsize,
  ... 
)

util.c652 行で定義されています。

参照元 establish_proxy_connection()get_backup_name()successful_send()write_batch_shell_file().

00653 {
00654         va_list ap;
00655         size_t len, ret = 0;
00656         const char *src;
00657 
00658         va_start(ap, destsize);
00659         while (1) {
00660                 if (!(src = va_arg(ap, const char *)))
00661                         break;
00662                 len = strlen(src);
00663                 ret += len;
00664                 if (destsize > 1) {
00665                         if (len >= destsize)
00666                                 len = destsize - 1;
00667                         memcpy(dest, src, len);
00668                         destsize -= len;
00669                         dest += len;
00670                 }
00671         }
00672         *dest = '\0';
00673         va_end(ap);
00674 
00675         return ret;
00676 }

int count_dir_elements ( const char *  p  ) 

util.c678 行で定義されています。

参照元 receive_file_entry()set_filter_dir().

00679 {
00680         int cnt = 0, new_component = 1;
00681         while (*p) {
00682                 if (*p++ == '/')
00683                         new_component = 1;
00684                 else if (new_component) {
00685                         new_component = 0;
00686                         cnt++;
00687                 }
00688         }
00689         return cnt;
00690 }

unsigned int clean_fname ( char *  name,
BOOL  collapse_dot_dot 
)

util.c696 行で定義されています。

参照元 log_formatted()make_file()parse_arguments()parse_filter_file()parse_merge_name()push_dir()receive_file_entry()set_filter_dir()setup_merge_file().

00697 {
00698         char *limit = name - 1, *t = name, *f = name;
00699         int anchored;
00700 
00701         if (!name)
00702                 return 0;
00703 
00704         if ((anchored = *f == '/') != 0)
00705                 *t++ = *f++;
00706         while (*f) {
00707                 /* discard extra slashes */
00708                 if (*f == '/') {
00709                         f++;
00710                         continue;
00711                 }
00712                 if (*f == '.') {
00713                         /* discard "." dirs (but NOT a trailing '.'!) */
00714                         if (f[1] == '/') {
00715                                 f += 2;
00716                                 continue;
00717                         }
00718                         /* collapse ".." dirs */
00719                         if (collapse_dot_dot
00720                             && f[1] == '.' && (f[2] == '/' || !f[2])) {
00721                                 char *s = t - 1;
00722                                 if (s == name && anchored) {
00723                                         f += 2;
00724                                         continue;
00725                                 }
00726                                 while (s > limit && *--s != '/') {}
00727                                 if (s != t - 1 && (s < name || *s == '/')) {
00728                                         t = s + 1;
00729                                         f += 2;
00730                                         continue;
00731                                 }
00732                                 limit = t + 2;
00733                         }
00734                 }
00735                 while (*f && (*t++ = *f++) != '/') {}
00736         }
00737 
00738         if (t > name+anchored && t[-1] == '/')
00739                 t--;
00740         if (t == name)
00741                 *t++ = '.';
00742         *t = '\0';
00743 
00744         return t - name;
00745 }

char* sanitize_path ( char *  dest,
const char *  p,
const char *  rootdir,
int  depth 
)

util.c769 行で定義されています。

参照先 lp_path()module_idout_of_memory()relative_paths.

参照元 glob_expand_one()make_file()parse_arguments()parse_merge_name()receive_file_entry()send_file_list().

00770 {
00771         char *start, *sanp;
00772         int rlen = 0, leave_one_dotdir = relative_paths;
00773 
00774         if (dest != p) {
00775                 int plen = strlen(p);
00776                 if (*p == '/') {
00777                         if (!rootdir)
00778                                 rootdir = lp_path(module_id);
00779                         rlen = strlen(rootdir);
00780                         depth = 0;
00781                         p++;
00782                 }
00783                 if (dest) {
00784                         if (rlen + plen + 1 >= MAXPATHLEN)
00785                                 return NULL;
00786                 } else if (!(dest = new_array(char, rlen + plen + 1)))
00787                         out_of_memory("sanitize_path");
00788                 if (rlen) {
00789                         memcpy(dest, rootdir, rlen);
00790                         if (rlen > 1)
00791                                 dest[rlen++] = '/';
00792                 }
00793         }
00794 
00795         start = sanp = dest + rlen;
00796         while (*p != '\0') {
00797                 /* discard leading or extra slashes */
00798                 if (*p == '/') {
00799                         p++;
00800                         continue;
00801                 }
00802                 /* this loop iterates once per filename component in p.
00803                  * both p (and sanp if the original had a slash) should
00804                  * always be left pointing after a slash
00805                  */
00806                 if (*p == '.' && (p[1] == '/' || p[1] == '\0')) {
00807                         if (leave_one_dotdir && p[1])
00808                                 leave_one_dotdir = 0;
00809                         else {
00810                                 /* skip "." component */
00811                                 p++;
00812                                 continue;
00813                         }
00814                 }
00815                 if (*p == '.' && p[1] == '.' && (p[2] == '/' || p[2] == '\0')) {
00816                         /* ".." component followed by slash or end */
00817                         if (depth <= 0 || sanp != start) {
00818                                 p += 2;
00819                                 if (sanp != start) {
00820                                         /* back up sanp one level */
00821                                         --sanp; /* now pointing at slash */
00822                                         while (sanp > start && sanp[-1] != '/') {
00823                                                 /* skip back up to slash */
00824                                                 sanp--;
00825                                         }
00826                                 }
00827                                 continue;
00828                         }
00829                         /* allow depth levels of .. at the beginning */
00830                         depth--;
00831                         /* move the virtual beginning to leave the .. alone */
00832                         start = sanp + 3;
00833                 }
00834                 /* copy one component through next slash */
00835                 while (*p && (*sanp++ = *p++) != '/') {}
00836         }
00837         if (sanp == dest) {
00838                 /* ended up with nothing, so put in "." component */
00839                 *sanp++ = '.';
00840         }
00841         *sanp = '\0';
00842 
00843         return dest;
00844 }

int push_dir ( char *  dir  ) 

Like chdir(), but it keeps track of the current directory (in the global "curr_dir"), and ensures that the path size doesn't overflow.

Also cleans the path using the clean_fname() function.

util.c854 行で定義されています。

参照先 clean_fname()curr_dircurr_dir_lengetcwd().

参照元 do_server_recv()do_server_sender()get_local_name()main()rsync_module()send_file_list().

00855 {
00856         static int initialised;
00857         unsigned int len;
00858 
00859         if (!initialised) {
00860                 initialised = 1;
00861                 getcwd(curr_dir, sizeof curr_dir - 1);
00862                 curr_dir_len = strlen(curr_dir);
00863         }
00864 
00865         if (!dir)       /* this call was probably just to initialize */
00866                 return 0;
00867 
00868         len = strlen(dir);
00869         if (len == 1 && *dir == '.')
00870                 return 1;
00871 
00872         if ((*dir == '/' ? len : curr_dir_len + 1 + len) >= sizeof curr_dir)
00873                 return 0;
00874 
00875         if (chdir(dir))
00876                 return 0;
00877 
00878         if (*dir == '/') {
00879                 memcpy(curr_dir, dir, len + 1);
00880                 curr_dir_len = len;
00881         } else {
00882                 curr_dir[curr_dir_len++] = '/';
00883                 memcpy(curr_dir + curr_dir_len, dir, len + 1);
00884                 curr_dir_len += len;
00885         }
00886 
00887         curr_dir_len = clean_fname(curr_dir, 1);
00888 
00889         return 1;
00890 }

int pop_dir ( char *  dir  ) 

Reverse a push_dir() call.

You must pass in an absolute path that was copied from a prior value of "curr_dir".

util.c896 行で定義されています。

参照先 curr_dircurr_dir_lenstrlcpy().

参照元 send_file_list().

00897 {
00898         if (chdir(dir))
00899                 return 0;
00900 
00901         curr_dir_len = strlcpy(curr_dir, dir, sizeof curr_dir);
00902         if (curr_dir_len >= sizeof curr_dir)
00903                 curr_dir_len = sizeof curr_dir - 1;
00904 
00905         return 1;
00906 }

char* full_fname ( const char *  fn  ) 

Return a quoted string with the full pathname of the indicated filename.

The string " (in MODNAME)" may also be appended. The returned pointer remains valid until the next time full_fname() is called.

util.c913 行で定義されています。

参照先 asprintf()curr_dirlp_name()lp_path()lp_use_chroot()module_id.

参照元 copy_file()delete_item()do_server_recv()do_server_sender()finish_transfer()generate_files()get_local_name()handle_delayed_updates()hard_link_check()hard_link_one()keep_backup()main()make_bak_dir()make_file()maybe_hard_link()receive_data()recv_files()recv_generator()send_directory()send_file_list()send_files()send_if_directory()set_file_attrs()try_dests_reg().

00914 {
00915         static char *result = NULL;
00916         char *m1, *m2, *m3;
00917         char *p1, *p2;
00918 
00919         if (result)
00920                 free(result);
00921 
00922         if (*fn == '/')
00923                 p1 = p2 = "";
00924         else {
00925                 p1 = curr_dir;
00926                 for (p2 = p1; *p2 == '/'; p2++) {}
00927                 if (*p2)
00928                         p2 = "/";
00929         }
00930         if (module_id >= 0) {
00931                 m1 = " (in ";
00932                 m2 = lp_name(module_id);
00933                 m3 = ")";
00934                 if (p1 == curr_dir) {
00935                         if (!lp_use_chroot(module_id)) {
00936                                 char *p = lp_path(module_id);
00937                                 if (*p != '/' || p[1])
00938                                         p1 += strlen(p);
00939                         }
00940                 }
00941         } else
00942                 m1 = m2 = m3 = "";
00943 
00944         asprintf(&result, "\"%s%s%s\"%s%s%s", p1, p2, fn, m1, m2, m3);
00945 
00946         return result;
00947 }

char* partial_dir_fname ( const char *  fname  ) 

util.c951 行で定義されています。

参照先 check_filter()filter_list_struct::headpartial_dirpathjoin()server_filter_list.

参照元 handle_delayed_updates()recv_files()recv_generator().

00952 {
00953         char *t = partial_fname;
00954         int sz = sizeof partial_fname;
00955         const char *fn;
00956 
00957         if ((fn = strrchr(fname, '/')) != NULL) {
00958                 fn++;
00959                 if (*partial_dir != '/') {
00960                         int len = fn - fname;
00961                         strncpy(t, fname, len); /* safe */
00962                         t += len;
00963                         sz -= len;
00964                 }
00965         } else
00966                 fn = fname;
00967         if ((int)pathjoin(t, sz, partial_dir, fn) >= sz)
00968                 return NULL;
00969         if (server_filter_list.head) {
00970                 static int len;
00971                 if (!len)
00972                         len = strlen(partial_dir);
00973                 t[len] = '\0';
00974                 if (check_filter(&server_filter_list, partial_fname, 1) < 0)
00975                         return NULL;
00976                 t[len] = '/';
00977                 if (check_filter(&server_filter_list, partial_fname, 0) < 0)
00978                         return NULL;
00979         }
00980 
00981         return partial_fname;
00982 }

int handle_partial_dir ( const char *  fname,
int  create 
)

util.c986 行で定義されています。

参照先 do_lstat()do_mkdir()do_rmdir()do_unlink()partial_dir.

参照元 _exit_cleanup()finish_transfer()handle_delayed_updates()recv_files()recv_generator()robust_rename().

00987 {
00988         char *fn, *dir;
00989 
00990         if (fname != partial_fname)
00991                 return 1;
00992         if (!create && *partial_dir == '/')
00993                 return 1;
00994         if (!(fn = strrchr(partial_fname, '/')))
00995                 return 1;
00996 
00997         *fn = '\0';
00998         dir = partial_fname;
00999         if (create) {
01000                 STRUCT_STAT st;
01001                 int statret = do_lstat(dir, &st);
01002                 if (statret == 0 && !S_ISDIR(st.st_mode)) {
01003                         if (do_unlink(dir) < 0)
01004                                 return 0;
01005                         statret = -1;
01006                 }
01007                 if (statret < 0 && do_mkdir(dir, 0700) < 0)
01008                         return 0;
01009         } else
01010                 do_rmdir(dir);
01011         *fn = '/';
01012 
01013         return 1;
01014 }

int unsafe_symlink ( const char *  dest,
const char *  src 
)

Determine if a symlink points outside the current directory tree.

This is considered "unsafe" because e.g. when mirroring somebody else's machine it might allow them to establish a symlink to /etc/passwd, and then read it through a web server.

Null symlinks and absolute symlinks are always unsafe.

Basically here we are concerned with symlinks whose target contains "..", because this might cause us to walk back up out of the transferred directory. We are not allowed to go back up and reenter.

引数:
dest Target of the symlink in question.
src Top source directory currently applicable. Basically this is the first parameter to rsync in a simple invocation, but it's modified by flist.c in slightly complex ways.
戻り値:
True if unsafe
False is unsafe
参照:
t_unsafe.c

util.c1040 行で定義されています。

参照先 name.

参照元 keep_backup()main()readlink_stat()recv_generator().

01041 {
01042         const char *name, *slash;
01043         int depth = 0;
01044 
01045         /* all absolute and null symlinks are unsafe */
01046         if (!dest || !*dest || *dest == '/')
01047                 return 1;
01048 
01049         /* find out what our safety margin is */
01050         for (name = src; (slash = strchr(name, '/')) != 0; name = slash+1) {
01051                 if (strncmp(name, "../", 3) == 0) {
01052                         depth = 0;
01053                 } else if (strncmp(name, "./", 2) == 0) {
01054                         /* nothing */
01055                 } else {
01056                         depth++;
01057                 }
01058         }
01059         if (strcmp(name, "..") == 0)
01060                 depth = 0;
01061 
01062         for (name = dest; (slash = strchr(name, '/')) != 0; name = slash+1) {
01063                 if (strncmp(name, "../", 3) == 0) {
01064                         /* if at any point we go outside the current directory
01065                            then stop - it is unsafe */
01066                         if (--depth < 0)
01067                                 return 1;
01068                 } else if (strncmp(name, "./", 2) == 0) {
01069                         /* nothing */
01070                 } else {
01071                         depth++;
01072                 }
01073         }
01074         if (strcmp(name, "..") == 0)
01075                 depth--;
01076 
01077         return (depth < 0);
01078 }

char* human_num ( int64  num  ) 

util.c1083 行で定義されています。

参照先 human_readablesprintf().

参照元 human_dnum()output_summary()rprint_progress().

01084 {
01085         static char bufs[4][128]; /* more than enough room */
01086         static unsigned int n;
01087         char *s;
01088 
01089         n = (n + 1) % (sizeof bufs / sizeof bufs[0]);
01090 
01091         if (human_readable) {
01092                 char units = '\0';
01093                 int mult = human_readable == 1 ? 1000 : 1024;
01094                 double dnum = 0;
01095                 if (num > mult*mult*mult) {
01096                         dnum = (double)num / (mult*mult*mult);
01097                         units = 'G';
01098                 } else if (num > mult*mult) {
01099                         dnum = (double)num / (mult*mult);
01100                         units = 'M';
01101                 } else if (num > mult) {
01102                         dnum = (double)num / mult;
01103                         units = 'K';
01104                 }
01105                 if (units) {
01106                         sprintf(bufs[n], "%.2f%c", dnum, units);
01107                         return bufs[n];
01108                 }
01109         }
01110 
01111         s = bufs[n] + sizeof bufs[0] - 1;
01112         *s = '\0';
01113 
01114         if (!num)
01115                 *--s = '0';
01116         while (num) {
01117                 *--s = (num % 10) + '0';
01118                 num /= 10;
01119         }
01120         return s;
01121 }

char* human_dnum ( double  dnum,
int  decimal_digits 
)

util.c1126 行で定義されています。

参照先 bufhuman_num()snprintf().

参照元 output_summary().

01127 {
01128         char *buf = human_num(dnum);
01129         int len = strlen(buf);
01130         if (isdigit(*(uchar*)(buf+len-1))) {
01131                 /* There's extra room in buf prior to the start of the num. */
01132                 buf -= decimal_digits + 1;
01133                 snprintf(buf, len + decimal_digits + 2, "%.*f", decimal_digits, dnum);
01134         }
01135         return buf;
01136 }

char* timestring ( time_t  t  ) 

Return the date and time as a string

util.c1141 行で定義されています。

参照先 strlcpy().

参照元 list_file_entry()log_formatted()logit().

01142 {
01143         static char TimeBuf[200];
01144         struct tm *tm = localtime(&t);
01145         char *p;
01146 
01147 #ifdef HAVE_STRFTIME
01148         strftime(TimeBuf, sizeof TimeBuf - 1, "%Y/%m/%d %H:%M:%S", tm);
01149 #else
01150         strlcpy(TimeBuf, asctime(tm), sizeof TimeBuf);
01151 #endif
01152 
01153         if ((p = strchr(TimeBuf, '\n')) != NULL)
01154                 *p = '\0';
01155 
01156         return TimeBuf;
01157 }

int msleep ( int  t  ) 

Sleep for a specified number of milliseconds.

Always returns TRUE. (In the future it might return FALSE if interrupted.)

util.c1165 行で定義されています。

参照先 errno.

参照元 do_recv()option_error()rsync_module()sig_int()wait_process_with_flush()whine_about_eof()writefd_unbuffered().

01166 {
01167         int tdiff = 0;
01168         struct timeval tval, t1, t2;
01169 
01170         gettimeofday(&t1, NULL);
01171 
01172         while (tdiff < t) {
01173                 tval.tv_sec = (t-tdiff)/1000;
01174                 tval.tv_usec = 1000*((t-tdiff)%1000);
01175 
01176                 errno = 0;
01177                 select(0,NULL,NULL, NULL, &tval);
01178 
01179                 gettimeofday(&t2, NULL);
01180                 tdiff = (t2.tv_sec - t1.tv_sec)*1000 +
01181                         (t2.tv_usec - t1.tv_usec)/1000;
01182         }
01183 
01184         return True;
01185 }

int cmp_time ( time_t  file1,
time_t  file2 
)

util.c1196 行で定義されています。

参照先 modify_window.

参照元 find_fuzzy()itemize()recv_generator()set_file_attrs()try_dests_reg()unchanged_file().

01197 {
01198         if (file2 > file1) {
01199                 if (file2 - file1 <= modify_window)
01200                         return 0;
01201                 return -1;
01202         }
01203         if (file1 - file2 <= modify_window)
01204                 return 0;
01205         return 1;
01206 }

int _Insure_trap_error ( int  a1,
int  a2,
int  a3,
int  a4,
int  a5,
int  a6 
)

This routine is a trick to immediately catch errors when debugging with insure.

A xterm with a gdb is popped up when insure catches a error. It is Linux specific.

util.c1217 行で定義されています。

参照先 asprintf().

01218 {
01219         static int (*fn)();
01220         int ret;
01221         char *cmd;
01222 
01223         asprintf(&cmd, "/usr/X11R6/bin/xterm -display :0 -T Panic -n Panic -e /bin/sh -c 'cat /tmp/ierrs.*.%d ; gdb /proc/%d/exe %d'",
01224                 getpid(), getpid(), getpid());
01225 
01226         if (!fn) {
01227                 static void *h;
01228                 h = dlopen("/usr/local/parasoft/insure++lite/lib.linux2/libinsure.so", RTLD_LAZY);
01229                 fn = dlsym(h, "_Insure_trap_error");
01230         }
01231 
01232         ret = fn(a1, a2, a3, a4, a5, a6);
01233 
01234         system(cmd);
01235 
01236         free(cmd);
01237 
01238         return ret;
01239 }

void* _new_array ( unsigned int  size,
unsigned long  num 
)

util.c1244 行で定義されています。

01245 {
01246         if (num >= MALLOC_MAX/size)
01247                 return NULL;
01248         return malloc(size * num);
01249 }

void* _realloc_array ( void *  ptr,
unsigned int  size,
unsigned long  num 
)

util.c1251 行で定義されています。

01252 {
01253         if (num >= MALLOC_MAX/size)
01254                 return NULL;
01255         /* No realloc should need this, but just in case... */
01256         if (!ptr)
01257                 return malloc(size * num);
01258         return realloc(ptr, size * num);
01259 }

const char* find_filename_suffix ( const char *  fn,
int  fn_len,
int *  len_ptr 
)

util.c1264 行で定義されています。

参照元 find_fuzzy().

01265 {
01266         const char *suf, *s;
01267         BOOL had_tilde;
01268         int s_len;
01269 
01270         /* One or more dots at the start aren't a suffix. */
01271         while (fn_len && *fn == '.') fn++, fn_len--;
01272 
01273         /* Ignore the ~ in a "foo~" filename. */
01274         if (fn_len > 1 && fn[fn_len-1] == '~')
01275                 fn_len--, had_tilde = True;
01276         else
01277                 had_tilde = False;
01278 
01279         /* Assume we don't find an suffix. */
01280         suf = "";
01281         *len_ptr = 0;
01282 
01283         /* Find the last significant suffix. */
01284         for (s = fn + fn_len; fn_len > 1; ) {
01285                 while (*--s != '.' && s != fn) {}
01286                 if (s == fn)
01287                         break;
01288                 s_len = fn_len - (s - fn);
01289                 fn_len = s - fn;
01290                 if (s_len == 4) {
01291                         if (strcmp(s+1, "bak") == 0
01292                          || strcmp(s+1, "old") == 0)
01293                                 continue;
01294                 } else if (s_len == 5) {
01295                         if (strcmp(s+1, "orig") == 0)
01296                                 continue;
01297                 } else if (s_len > 2 && had_tilde
01298                     && s[1] == '~' && isdigit(*(uchar*)(s+2)))
01299                         continue;
01300                 *len_ptr = s_len;
01301                 suf = s;
01302                 if (s_len == 1)
01303                         break;
01304                 /* Determine if the suffix is all digits. */
01305                 for (s++, s_len--; s_len > 0; s++, s_len--) {
01306                         if (!isdigit(*(uchar*)s))
01307                                 return suf;
01308                 }
01309                 /* An all-digit suffix may not be that signficant. */
01310                 s = suf;
01311         }
01312 
01313         return suf;
01314 }

uint32 fuzzy_distance ( const char *  s1,
int  len1,
const char *  s2,
int  len2 
)

util.c1325 行で定義されています。

参照元 find_fuzzy().

01326 {
01327         uint32 a[MAXPATHLEN], diag, above, left, diag_inc, above_inc, left_inc;
01328         int32 cost;
01329         int i1, i2;
01330 
01331         if (!len1 || !len2) {
01332                 if (!len1) {
01333                         s1 = s2;
01334                         len1 = len2;
01335                 }
01336                 for (i1 = 0, cost = 0; i1 < len1; i1++)
01337                         cost += s1[i1];
01338                 return (int32)len1 * UNIT + cost;
01339         }
01340 
01341         for (i2 = 0; i2 < len2; i2++)
01342                 a[i2] = (i2+1) * UNIT;
01343 
01344         for (i1 = 0; i1 < len1; i1++) {
01345                 diag = i1 * UNIT;
01346                 above = (i1+1) * UNIT;
01347                 for (i2 = 0; i2 < len2; i2++) {
01348                         left = a[i2];
01349                         if ((cost = *((uchar*)s1+i1) - *((uchar*)s2+i2)) != 0) {
01350                                 if (cost < 0)
01351                                         cost = UNIT - cost;
01352                                 else
01353                                         cost = UNIT + cost;
01354                         }
01355                         diag_inc = diag + cost;
01356                         left_inc = left + UNIT + *((uchar*)s1+i1);
01357                         above_inc = above + UNIT + *((uchar*)s2+i2);
01358                         a[i2] = above = left < above
01359                               ? (left_inc < diag_inc ? left_inc : diag_inc)
01360                               : (above_inc < diag_inc ? above_inc : diag_inc);
01361                         diag = left;
01362                 }
01363         }
01364 
01365         return a[len2-1];
01366 }

struct bitbag* bitbag_create ( int  max_ndx  ) 

util.c1377 行で定義されています。

参照先 bitbag::bitsout_of_memory()bitbag::slot_cnt.

参照元 recv_files().

01378 {
01379         struct bitbag *bb = new(struct bitbag);
01380         bb->slot_cnt = (max_ndx + BB_PER_SLOT_BITS - 1) / BB_PER_SLOT_BITS;
01381 
01382         if (!(bb->bits = (uint32**)calloc(bb->slot_cnt, sizeof (uint32*))))
01383                 out_of_memory("bitbag_create");
01384 
01385         return bb;
01386 }

void bitbag_set_bit ( struct bitbag bb,
int  ndx 
)

util.c1388 行で定義されています。

参照先 bitbag::bitsout_of_memory().

参照元 recv_files().

01389 {
01390         int slot = ndx / BB_PER_SLOT_BITS;
01391         ndx %= BB_PER_SLOT_BITS;
01392 
01393         if (!bb->bits[slot]) {
01394                 if (!(bb->bits[slot] = (uint32*)calloc(BB_PER_SLOT_INTS, 4)))
01395                         out_of_memory("bitbag_set_bit");
01396         }
01397 
01398         bb->bits[slot][ndx/32] |= 1u << (ndx % 32);
01399 }

void bitbag_clear_bit ( struct bitbag bb,
int  ndx 
)

util.c1402 行で定義されています。

参照先 bitbag::bits.

01403 {
01404         int slot = ndx / BB_PER_SLOT_BITS;
01405         ndx %= BB_PER_SLOT_BITS;
01406 
01407         if (!bb->bits[slot])
01408                 return;
01409 
01410         bb->bits[slot][ndx/32] &= ~(1u << (ndx % 32));
01411 }

int bitbag_check_bit ( struct bitbag bb,
int  ndx 
)

util.c1413 行で定義されています。

参照先 bitbag::bits.

01414 {
01415         int slot = ndx / BB_PER_SLOT_BITS;
01416         ndx %= BB_PER_SLOT_BITS;
01417 
01418         if (!bb->bits[slot])
01419                 return 0;
01420 
01421         return bb->bits[slot][ndx/32] & (1u << (ndx % 32)) ? 1 : 0;
01422 }

int bitbag_next_bit ( struct bitbag bb,
int  after 
)

util.c1426 行で定義されています。

参照先 bitbag::bitsbitbag::slot_cnt.

参照元 handle_delayed_updates().

01427 {
01428         uint32 bits, mask;
01429         int i, ndx = after + 1;
01430         int slot = ndx / BB_PER_SLOT_BITS;
01431         ndx %= BB_PER_SLOT_BITS;
01432 
01433         mask = (1u << (ndx % 32)) - 1;
01434         for (i = ndx / 32; slot < bb->slot_cnt; slot++, i = mask = 0) {
01435                 if (!bb->bits[slot])
01436                         continue;
01437                 for ( ; i < BB_PER_SLOT_INTS; i++, mask = 0) {
01438                         if (!(bits = bb->bits[slot][i] & ~mask))
01439                                 continue;
01440                         /* The xor magic figures out the lowest enabled bit in
01441                          * bits, and the switch quickly computes log2(bit). */
01442                         switch (bits ^ (bits & (bits-1))) {
01443 #define LOG2(n) case 1u << n: return slot*BB_PER_SLOT_BITS + i*32 + n
01444                             LOG2(0);  LOG2(1);  LOG2(2);  LOG2(3);
01445                             LOG2(4);  LOG2(5);  LOG2(6);  LOG2(7);
01446                             LOG2(8);  LOG2(9);  LOG2(10); LOG2(11);
01447                             LOG2(12); LOG2(13); LOG2(14); LOG2(15);
01448                             LOG2(16); LOG2(17); LOG2(18); LOG2(19);
01449                             LOG2(20); LOG2(21); LOG2(22); LOG2(23);
01450                             LOG2(24); LOG2(25); LOG2(26); LOG2(27);
01451                             LOG2(28); LOG2(29); LOG2(30); LOG2(31);
01452                         }
01453                         return -1; /* impossible... */
01454                 }
01455         }
01456 
01457         return -1;
01458 }


変数

int verbose

options.c163 行で定義されています。

int dry_run

options.c60 行で定義されています。

int module_id

clientserver.c60 行で定義されています。

int modify_window

options.c113 行で定義されています。

int relative_paths

options.c79 行で定義されています。

int human_readable

options.c91 行で定義されています。

mode_t orig_umask

main.c65 行で定義されています。

char* partial_dir

options.c146 行で定義されています。

struct filter_list_struct server_filter_list

exclude.c51 行で定義されています。

int sanitize_paths = 0

util.c40 行で定義されています。

pid_t all_pids[10] [static]

util.c423 行で定義されています。

参照元 do_fork()kill_all().

int num_pids [static]

util.c424 行で定義されています。

参照元 do_fork()kill_all().

char curr_dir[MAXPATHLEN]

util.c846 行で定義されています。

unsigned int curr_dir_len

util.c847 行で定義されています。

参照元 pop_dir()push_dir()rule_matches()set_filter_dir().

char partial_fname[MAXPATHLEN] [static]

util.c949 行で定義されています。


rsyncに対してSat Dec 5 19:45:46 2009に生成されました。  doxygen 1.4.7