util.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626
  1. /*
  2. * Utility routines used in rsync.
  3. *
  4. * Copyright (C) 1996-2000 Andrew Tridgell
  5. * Copyright (C) 1996 Paul Mackerras
  6. * Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
  7. * Copyright (C) 2003-2008 Wayne Davison
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 3 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License along
  20. * with this program; if not, visit the http://fsf.org website.
  21. */
  22. #include "rsync.h"
  23. #include "ifuncs.h"
  24. extern int verbose;
  25. extern int dry_run;
  26. extern int module_id;
  27. extern int modify_window;
  28. extern int relative_paths;
  29. extern int human_readable;
  30. extern int preserve_xattrs;
  31. extern char *module_dir;
  32. extern unsigned int module_dirlen;
  33. extern mode_t orig_umask;
  34. extern char *partial_dir;
  35. extern struct filter_list_struct daemon_filter_list;
  36. int sanitize_paths = 0;
  37. char curr_dir[MAXPATHLEN];
  38. unsigned int curr_dir_len;
  39. int curr_dir_depth; /* This is only set for a sanitizing daemon. */
  40. /* Set a fd into nonblocking mode. */
  41. void set_nonblocking(int fd)
  42. {
  43. int val;
  44. if ((val = fcntl(fd, F_GETFL)) == -1)
  45. return;
  46. if (!(val & NONBLOCK_FLAG)) {
  47. val |= NONBLOCK_FLAG;
  48. fcntl(fd, F_SETFL, val);
  49. }
  50. }
  51. /* Set a fd into blocking mode. */
  52. void set_blocking(int fd)
  53. {
  54. int val;
  55. if ((val = fcntl(fd, F_GETFL)) == -1)
  56. return;
  57. if (val & NONBLOCK_FLAG) {
  58. val &= ~NONBLOCK_FLAG;
  59. fcntl(fd, F_SETFL, val);
  60. }
  61. }
  62. /**
  63. * Create a file descriptor pair - like pipe() but use socketpair if
  64. * possible (because of blocking issues on pipes).
  65. *
  66. * Always set non-blocking.
  67. */
  68. int fd_pair(int fd[2])
  69. {
  70. int ret;
  71. #ifdef HAVE_SOCKETPAIR
  72. ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
  73. #else
  74. ret = pipe(fd);
  75. #endif
  76. if (ret == 0) {
  77. set_nonblocking(fd[0]);
  78. set_nonblocking(fd[1]);
  79. }
  80. return ret;
  81. }
  82. void print_child_argv(const char *prefix, char **cmd)
  83. {
  84. rprintf(FCLIENT, "%s ", prefix);
  85. for (; *cmd; cmd++) {
  86. /* Look for characters that ought to be quoted. This
  87. * is not a great quoting algorithm, but it's
  88. * sufficient for a log message. */
  89. if (strspn(*cmd, "abcdefghijklmnopqrstuvwxyz"
  90. "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  91. "0123456789"
  92. ",.-_=+@/") != strlen(*cmd)) {
  93. rprintf(FCLIENT, "\"%s\" ", *cmd);
  94. } else {
  95. rprintf(FCLIENT, "%s ", *cmd);
  96. }
  97. }
  98. rprintf(FCLIENT, "\n");
  99. }
  100. NORETURN void out_of_memory(const char *str)
  101. {
  102. rprintf(FERROR, "ERROR: out of memory in %s [%s]\n", str, who_am_i());
  103. exit_cleanup(RERR_MALLOC);
  104. }
  105. NORETURN void overflow_exit(const char *str)
  106. {
  107. rprintf(FERROR, "ERROR: buffer overflow in %s [%s]\n", str, who_am_i());
  108. exit_cleanup(RERR_MALLOC);
  109. }
  110. int set_modtime(const char *fname, time_t modtime, mode_t mode)
  111. {
  112. #if !defined HAVE_LUTIMES || !defined HAVE_UTIMES
  113. if (S_ISLNK(mode))
  114. return 1;
  115. #endif
  116. if (verbose > 2) {
  117. rprintf(FINFO, "set modtime of %s to (%ld) %s",
  118. fname, (long)modtime,
  119. asctime(localtime(&modtime)));
  120. }
  121. if (dry_run)
  122. return 0;
  123. {
  124. #ifdef HAVE_UTIMES
  125. struct timeval t[2];
  126. t[0].tv_sec = time(NULL);
  127. t[0].tv_usec = 0;
  128. t[1].tv_sec = modtime;
  129. t[1].tv_usec = 0;
  130. # ifdef HAVE_LUTIMES
  131. if (S_ISLNK(mode)) {
  132. if (lutimes(fname, t) < 0)
  133. return errno == ENOSYS ? 1 : -1;
  134. return 0;
  135. }
  136. # endif
  137. return utimes(fname, t);
  138. #elif defined HAVE_STRUCT_UTIMBUF
  139. struct utimbuf tbuf;
  140. tbuf.actime = time(NULL);
  141. tbuf.modtime = modtime;
  142. return utime(fname,&tbuf);
  143. #elif defined HAVE_UTIME
  144. time_t t[2];
  145. t[0] = time(NULL);
  146. t[1] = modtime;
  147. return utime(fname,t);
  148. #else
  149. #error No file-time-modification routine found!
  150. #endif
  151. }
  152. }
  153. /* This creates a new directory with default permissions. Since there
  154. * might be some directory-default permissions affecting this, we can't
  155. * force the permissions directly using the original umask and mkdir(). */
  156. int mkdir_defmode(char *fname)
  157. {
  158. int ret;
  159. umask(orig_umask);
  160. ret = do_mkdir(fname, ACCESSPERMS);
  161. umask(0);
  162. return ret;
  163. }
  164. /* Create any necessary directories in fname. Any missing directories are
  165. * created with default permissions. */
  166. int create_directory_path(char *fname)
  167. {
  168. char *p;
  169. int ret = 0;
  170. while (*fname == '/')
  171. fname++;
  172. while (strncmp(fname, "./", 2) == 0)
  173. fname += 2;
  174. umask(orig_umask);
  175. p = fname;
  176. while ((p = strchr(p,'/')) != NULL) {
  177. *p = '\0';
  178. if (do_mkdir(fname, ACCESSPERMS) < 0 && errno != EEXIST)
  179. ret = -1;
  180. *p++ = '/';
  181. }
  182. umask(0);
  183. return ret;
  184. }
  185. /**
  186. * Write @p len bytes at @p ptr to descriptor @p desc, retrying if
  187. * interrupted.
  188. *
  189. * @retval len upon success
  190. *
  191. * @retval <0 write's (negative) error code
  192. *
  193. * Derived from GNU C's cccp.c.
  194. */
  195. int full_write(int desc, const char *ptr, size_t len)
  196. {
  197. int total_written;
  198. total_written = 0;
  199. while (len > 0) {
  200. int written = write(desc, ptr, len);
  201. if (written < 0) {
  202. if (errno == EINTR)
  203. continue;
  204. return written;
  205. }
  206. total_written += written;
  207. ptr += written;
  208. len -= written;
  209. }
  210. return total_written;
  211. }
  212. /**
  213. * Read @p len bytes at @p ptr from descriptor @p desc, retrying if
  214. * interrupted.
  215. *
  216. * @retval >0 the actual number of bytes read
  217. *
  218. * @retval 0 for EOF
  219. *
  220. * @retval <0 for an error.
  221. *
  222. * Derived from GNU C's cccp.c. */
  223. static int safe_read(int desc, char *ptr, size_t len)
  224. {
  225. int n_chars;
  226. if (len == 0)
  227. return len;
  228. do {
  229. n_chars = read(desc, ptr, len);
  230. } while (n_chars < 0 && errno == EINTR);
  231. return n_chars;
  232. }
  233. /* Copy a file. If ofd < 0, copy_file unlinks and opens the "dest" file.
  234. * Otherwise, it just writes to and closes the provided file descriptor.
  235. * In either case, if --xattrs are being preserved, the dest file will
  236. * have its xattrs set from the source file.
  237. *
  238. * This is used in conjunction with the --temp-dir, --backup, and
  239. * --copy-dest options. */
  240. int copy_file(const char *source, const char *dest, int ofd,
  241. mode_t mode, int create_bak_dir)
  242. {
  243. int ifd;
  244. char buf[1024 * 8];
  245. int len; /* Number of bytes read into `buf'. */
  246. if ((ifd = do_open(source, O_RDONLY, 0)) < 0) {
  247. int save_errno = errno;
  248. rsyserr(FERROR_XFER, errno, "open %s", full_fname(source));
  249. errno = save_errno;
  250. return -1;
  251. }
  252. if (ofd < 0) {
  253. if (robust_unlink(dest) && errno != ENOENT) {
  254. int save_errno = errno;
  255. rsyserr(FERROR_XFER, errno, "unlink %s", full_fname(dest));
  256. errno = save_errno;
  257. return -1;
  258. }
  259. if ((ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode)) < 0) {
  260. int save_errno = errno ? errno : EINVAL; /* 0 paranoia */
  261. if (create_bak_dir && errno == ENOENT && make_bak_dir(dest) == 0) {
  262. if ((ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode)) < 0)
  263. save_errno = errno ? errno : save_errno;
  264. else
  265. save_errno = 0;
  266. }
  267. if (save_errno) {
  268. rsyserr(FERROR_XFER, save_errno, "open %s", full_fname(dest));
  269. close(ifd);
  270. errno = save_errno;
  271. return -1;
  272. }
  273. }
  274. }
  275. while ((len = safe_read(ifd, buf, sizeof buf)) > 0) {
  276. if (full_write(ofd, buf, len) < 0) {
  277. int save_errno = errno;
  278. rsyserr(FERROR_XFER, errno, "write %s", full_fname(dest));
  279. close(ifd);
  280. close(ofd);
  281. errno = save_errno;
  282. return -1;
  283. }
  284. }
  285. if (len < 0) {
  286. int save_errno = errno;
  287. rsyserr(FERROR_XFER, errno, "read %s", full_fname(source));
  288. close(ifd);
  289. close(ofd);
  290. errno = save_errno;
  291. return -1;
  292. }
  293. if (close(ifd) < 0) {
  294. rsyserr(FWARNING, errno, "close failed on %s",
  295. full_fname(source));
  296. }
  297. if (close(ofd) < 0) {
  298. int save_errno = errno;
  299. rsyserr(FERROR_XFER, errno, "close failed on %s",
  300. full_fname(dest));
  301. errno = save_errno;
  302. return -1;
  303. }
  304. #ifdef SUPPORT_XATTRS
  305. if (preserve_xattrs)
  306. copy_xattrs(source, dest);
  307. #endif
  308. return 0;
  309. }
  310. /* MAX_RENAMES should be 10**MAX_RENAMES_DIGITS */
  311. #define MAX_RENAMES_DIGITS 3
  312. #define MAX_RENAMES 1000
  313. /**
  314. * Robust unlink: some OS'es (HPUX) refuse to unlink busy files, so
  315. * rename to <path>/.rsyncNNN instead.
  316. *
  317. * Note that successive rsync runs will shuffle the filenames around a
  318. * bit as long as the file is still busy; this is because this function
  319. * does not know if the unlink call is due to a new file coming in, or
  320. * --delete trying to remove old .rsyncNNN files, hence it renames it
  321. * each time.
  322. **/
  323. int robust_unlink(const char *fname)
  324. {
  325. #ifndef ETXTBSY
  326. return do_unlink(fname);
  327. #else
  328. static int counter = 1;
  329. int rc, pos, start;
  330. char path[MAXPATHLEN];
  331. rc = do_unlink(fname);
  332. if (rc == 0 || errno != ETXTBSY)
  333. return rc;
  334. if ((pos = strlcpy(path, fname, MAXPATHLEN)) >= MAXPATHLEN)
  335. pos = MAXPATHLEN - 1;
  336. while (pos > 0 && path[pos-1] != '/')
  337. pos--;
  338. pos += strlcpy(path+pos, ".rsync", MAXPATHLEN-pos);
  339. if (pos > (MAXPATHLEN-MAX_RENAMES_DIGITS-1)) {
  340. errno = ETXTBSY;
  341. return -1;
  342. }
  343. /* start where the last one left off to reduce chance of clashes */
  344. start = counter;
  345. do {
  346. snprintf(&path[pos], MAX_RENAMES_DIGITS+1, "%03d", counter);
  347. if (++counter >= MAX_RENAMES)
  348. counter = 1;
  349. } while ((rc = access(path, 0)) == 0 && counter != start);
  350. if (verbose > 0) {
  351. rprintf(FWARNING, "renaming %s to %s because of text busy\n",
  352. fname, path);
  353. }
  354. /* maybe we should return rename()'s exit status? Nah. */
  355. if (do_rename(fname, path) != 0) {
  356. errno = ETXTBSY;
  357. return -1;
  358. }
  359. return 0;
  360. #endif
  361. }
  362. /* Returns 0 on successful rename, 1 if we successfully copied the file
  363. * across filesystems, -2 if copy_file() failed, and -1 on other errors.
  364. * If partialptr is not NULL and we need to do a copy, copy the file into
  365. * the active partial-dir instead of over the destination file. */
  366. int robust_rename(const char *from, const char *to, const char *partialptr,
  367. int mode)
  368. {
  369. int tries = 4;
  370. while (tries--) {
  371. if (do_rename(from, to) == 0)
  372. return 0;
  373. switch (errno) {
  374. #ifdef ETXTBSY
  375. case ETXTBSY:
  376. if (robust_unlink(to) != 0) {
  377. errno = ETXTBSY;
  378. return -1;
  379. }
  380. errno = ETXTBSY;
  381. break;
  382. #endif
  383. case EXDEV:
  384. if (partialptr) {
  385. if (!handle_partial_dir(partialptr,PDIR_CREATE))
  386. return -2;
  387. to = partialptr;
  388. }
  389. if (copy_file(from, to, -1, mode, 0) != 0)
  390. return -2;
  391. do_unlink(from);
  392. return 1;
  393. default:
  394. return -1;
  395. }
  396. }
  397. return -1;
  398. }
  399. static pid_t all_pids[10];
  400. static int num_pids;
  401. /** Fork and record the pid of the child. **/
  402. pid_t do_fork(void)
  403. {
  404. pid_t newpid = fork();
  405. if (newpid != 0 && newpid != -1) {
  406. all_pids[num_pids++] = newpid;
  407. }
  408. return newpid;
  409. }
  410. /**
  411. * Kill all children.
  412. *
  413. * @todo It would be kind of nice to make sure that they are actually
  414. * all our children before we kill them, because their pids may have
  415. * been recycled by some other process. Perhaps when we wait for a
  416. * child, we should remove it from this array. Alternatively we could
  417. * perhaps use process groups, but I think that would not work on
  418. * ancient Unix versions that don't support them.
  419. **/
  420. void kill_all(int sig)
  421. {
  422. int i;
  423. for (i = 0; i < num_pids; i++) {
  424. /* Let's just be a little careful where we
  425. * point that gun, hey? See kill(2) for the
  426. * magic caused by negative values. */
  427. pid_t p = all_pids[i];
  428. if (p == getpid())
  429. continue;
  430. if (p <= 0)
  431. continue;
  432. kill(p, sig);
  433. }
  434. }
  435. /** Turn a user name into a uid */
  436. int name_to_uid(const char *name, uid_t *uid_p)
  437. {
  438. struct passwd *pass;
  439. if (!name || !*name)
  440. return 0;
  441. if (!(pass = getpwnam(name)))
  442. return 0;
  443. *uid_p = pass->pw_uid;
  444. return 1;
  445. }
  446. /** Turn a group name into a gid */
  447. int name_to_gid(const char *name, gid_t *gid_p)
  448. {
  449. struct group *grp;
  450. if (!name || !*name)
  451. return 0;
  452. if (!(grp = getgrnam(name)))
  453. return 0;
  454. *gid_p = grp->gr_gid;
  455. return 1;
  456. }
  457. /** Lock a byte range in a open file */
  458. int lock_range(int fd, int offset, int len)
  459. {
  460. struct flock lock;
  461. lock.l_type = F_WRLCK;
  462. lock.l_whence = SEEK_SET;
  463. lock.l_start = offset;
  464. lock.l_len = len;
  465. lock.l_pid = 0;
  466. return fcntl(fd,F_SETLK,&lock) == 0;
  467. }
  468. #define ENSURE_MEMSPACE(buf, type, sz, req) \
  469. if ((req) > sz && !(buf = realloc_array(buf, type, sz = MAX(sz * 2, req)))) \
  470. out_of_memory("glob_expand")
  471. static inline void call_glob_match(const char *name, int len, int from_glob,
  472. char *arg, int abpos, int fbpos);
  473. static struct glob_data {
  474. char *arg_buf, *filt_buf, **argv;
  475. int absize, fbsize, maxargs, argc;
  476. } glob;
  477. static void glob_match(char *arg, int abpos, int fbpos)
  478. {
  479. int len;
  480. char *slash;
  481. while (*arg == '.' && arg[1] == '/') {
  482. if (fbpos < 0) {
  483. ENSURE_MEMSPACE(glob.filt_buf, char, glob.fbsize, glob.absize);
  484. memcpy(glob.filt_buf, glob.arg_buf, abpos + 1);
  485. fbpos = abpos;
  486. }
  487. ENSURE_MEMSPACE(glob.arg_buf, char, glob.absize, abpos + 3);
  488. glob.arg_buf[abpos++] = *arg++;
  489. glob.arg_buf[abpos++] = *arg++;
  490. glob.arg_buf[abpos] = '\0';
  491. }
  492. if ((slash = strchr(arg, '/')) != NULL) {
  493. *slash = '\0';
  494. len = slash - arg;
  495. } else
  496. len = strlen(arg);
  497. if (strpbrk(arg, "*?[")) {
  498. struct dirent *di;
  499. DIR *d;
  500. if (!(d = opendir(abpos ? glob.arg_buf : ".")))
  501. return;
  502. while ((di = readdir(d)) != NULL) {
  503. char *dname = d_name(di);
  504. if (dname[0] == '.' && (dname[1] == '\0'
  505. || (dname[1] == '.' && dname[2] == '\0')))
  506. continue;
  507. if (!wildmatch(arg, dname))
  508. continue;
  509. call_glob_match(dname, strlen(dname), 1,
  510. slash ? arg + len + 1 : NULL,
  511. abpos, fbpos);
  512. }
  513. closedir(d);
  514. } else {
  515. call_glob_match(arg, len, 0,
  516. slash ? arg + len + 1 : NULL,
  517. abpos, fbpos);
  518. }
  519. if (slash)
  520. *slash = '/';
  521. }
  522. static inline void call_glob_match(const char *name, int len, int from_glob,
  523. char *arg, int abpos, int fbpos)
  524. {
  525. char *use_buf;
  526. ENSURE_MEMSPACE(glob.arg_buf, char, glob.absize, abpos + len + 2);
  527. memcpy(glob.arg_buf + abpos, name, len);
  528. abpos += len;
  529. glob.arg_buf[abpos] = '\0';
  530. if (fbpos >= 0) {
  531. ENSURE_MEMSPACE(glob.filt_buf, char, glob.fbsize, fbpos + len + 2);
  532. memcpy(glob.filt_buf + fbpos, name, len);
  533. fbpos += len;
  534. glob.filt_buf[fbpos] = '\0';
  535. use_buf = glob.filt_buf;
  536. } else
  537. use_buf = glob.arg_buf;
  538. if (from_glob || (arg && len)) {
  539. STRUCT_STAT st;
  540. int is_dir;
  541. if (do_stat(glob.arg_buf, &st) != 0)
  542. return;
  543. is_dir = S_ISDIR(st.st_mode) != 0;
  544. if (arg && !is_dir)
  545. return;
  546. if (daemon_filter_list.head
  547. && check_filter(&daemon_filter_list, FLOG, use_buf, is_dir) < 0)
  548. return;
  549. }
  550. if (arg) {
  551. glob.arg_buf[abpos++] = '/';
  552. glob.arg_buf[abpos] = '\0';
  553. if (fbpos >= 0) {
  554. glob.filt_buf[fbpos++] = '/';
  555. glob.filt_buf[fbpos] = '\0';
  556. }
  557. glob_match(arg, abpos, fbpos);
  558. } else {
  559. ENSURE_MEMSPACE(glob.argv, char *, glob.maxargs, glob.argc + 1);
  560. if (!(glob.argv[glob.argc++] = strdup(glob.arg_buf)))
  561. out_of_memory("glob_match");
  562. }
  563. }
  564. /* This routine performs wild-card expansion of the pathname in "arg". Any
  565. * daemon-excluded files/dirs will not be matched by the wildcards. Returns 0
  566. * if a wild-card string is the only returned item (due to matching nothing). */
  567. int glob_expand(const char *arg, char ***argv_p, int *argc_p, int *maxargs_p)
  568. {
  569. int ret, save_argc;
  570. char *s;
  571. if (!arg) {
  572. if (glob.filt_buf)
  573. free(glob.filt_buf);
  574. free(glob.arg_buf);
  575. memset(&glob, 0, sizeof glob);
  576. return -1;
  577. }
  578. if (sanitize_paths)
  579. s = sanitize_path(NULL, arg, "", 0, SP_KEEP_DOT_DIRS);
  580. else {
  581. s = strdup(arg);
  582. if (!s)
  583. out_of_memory("glob_expand");
  584. clean_fname(s, CFN_KEEP_DOT_DIRS
  585. | CFN_KEEP_TRAILING_SLASH
  586. | CFN_COLLAPSE_DOT_DOT_DIRS);
  587. }
  588. ENSURE_MEMSPACE(glob.arg_buf, char, glob.absize, MAXPATHLEN);
  589. *glob.arg_buf = '\0';
  590. glob.argc = save_argc = *argc_p;
  591. glob.argv = *argv_p;
  592. glob.maxargs = *maxargs_p;
  593. ENSURE_MEMSPACE(glob.argv, char *, glob.maxargs, 100);
  594. glob_match(s, 0, -1);
  595. /* The arg didn't match anything, so add the failed arg to the list. */
  596. if (glob.argc == save_argc) {
  597. ENSURE_MEMSPACE(glob.argv, char *, glob.maxargs, glob.argc + 1);
  598. glob.argv[glob.argc++] = s;
  599. ret = 0;
  600. } else {
  601. free(s);
  602. ret = 1;
  603. }
  604. *maxargs_p = glob.maxargs;
  605. *argv_p = glob.argv;
  606. *argc_p = glob.argc;
  607. return ret;
  608. }
  609. /* This routine is only used in daemon mode. */
  610. void glob_expand_module(char *base1, char *arg, char ***argv_p, int *argc_p, int *maxargs_p)
  611. {
  612. char *p, *s;
  613. char *base = base1;
  614. int base_len = strlen(base);
  615. if (!arg || !*arg)
  616. return;
  617. if (strncmp(arg, base, base_len) == 0)
  618. arg += base_len;
  619. if (!(arg = strdup(arg)))
  620. out_of_memory("glob_expand_module");
  621. if (asprintf(&base," %s/", base1) <= 0)
  622. out_of_memory("glob_expand_module");
  623. base_len++;
  624. for (s = arg; *s; s = p + base_len) {
  625. if ((p = strstr(s, base)) != NULL)
  626. *p = '\0'; /* split it at this point */
  627. glob_expand(s, argv_p, argc_p, maxargs_p);
  628. if (!p)
  629. break;
  630. }
  631. free(arg);
  632. free(base);
  633. }
  634. /**
  635. * Convert a string to lower case
  636. **/
  637. void strlower(char *s)
  638. {
  639. while (*s) {
  640. if (isUpper(s))
  641. *s = toLower(s);
  642. s++;
  643. }
  644. }
  645. /* Join strings p1 & p2 into "dest" with a guaranteed '/' between them. (If
  646. * p1 ends with a '/', no extra '/' is inserted.) Returns the length of both
  647. * strings + 1 (if '/' was inserted), regardless of whether the null-terminated
  648. * string fits into destsize. */
  649. size_t pathjoin(char *dest, size_t destsize, const char *p1, const char *p2)
  650. {
  651. size_t len = strlcpy(dest, p1, destsize);
  652. if (len < destsize - 1) {
  653. if (!len || dest[len-1] != '/')
  654. dest[len++] = '/';
  655. if (len < destsize - 1)
  656. len += strlcpy(dest + len, p2, destsize - len);
  657. else {
  658. dest[len] = '\0';
  659. len += strlen(p2);
  660. }
  661. }
  662. else
  663. len += strlen(p2) + 1; /* Assume we'd insert a '/'. */
  664. return len;
  665. }
  666. /* Join any number of strings together, putting them in "dest". The return
  667. * value is the length of all the strings, regardless of whether the null-
  668. * terminated whole fits in destsize. Your list of string pointers must end
  669. * with a NULL to indicate the end of the list. */
  670. size_t stringjoin(char *dest, size_t destsize, ...)
  671. {
  672. va_list ap;
  673. size_t len, ret = 0;
  674. const char *src;
  675. va_start(ap, destsize);
  676. while (1) {
  677. if (!(src = va_arg(ap, const char *)))
  678. break;
  679. len = strlen(src);
  680. ret += len;
  681. if (destsize > 1) {
  682. if (len >= destsize)
  683. len = destsize - 1;
  684. memcpy(dest, src, len);
  685. destsize -= len;
  686. dest += len;
  687. }
  688. }
  689. *dest = '\0';
  690. va_end(ap);
  691. return ret;
  692. }
  693. int count_dir_elements(const char *p)
  694. {
  695. int cnt = 0, new_component = 1;
  696. while (*p) {
  697. if (*p++ == '/')
  698. new_component = (*p != '.' || (p[1] != '/' && p[1] != '\0'));
  699. else if (new_component) {
  700. new_component = 0;
  701. cnt++;
  702. }
  703. }
  704. return cnt;
  705. }
  706. /* Turns multiple adjacent slashes into a single slash, drops all leading or
  707. * interior "." elements unless CFN_KEEP_DOT_DIRS is flagged. Will also drop
  708. * a trailing '.' after a '/' if CFN_DROP_TRAILING_DOT_DIR is flagged, removes
  709. * a trailing slash (perhaps after removing the aforementioned dot) unless
  710. * CFN_KEEP_TRAILING_SLASH is flagged, and will also collapse ".." elements
  711. * (except at the start) if CFN_COLLAPSE_DOT_DOT_DIRS is flagged. If the
  712. * resulting name would be empty, returns ".". */
  713. unsigned int clean_fname(char *name, int flags)
  714. {
  715. char *limit = name - 1, *t = name, *f = name;
  716. int anchored;
  717. if (!name)
  718. return 0;
  719. if ((anchored = *f == '/') != 0)
  720. *t++ = *f++;
  721. else if (flags & CFN_KEEP_DOT_DIRS && *f == '.' && f[1] == '/') {
  722. *t++ = *f++;
  723. *t++ = *f++;
  724. }
  725. while (*f) {
  726. /* discard extra slashes */
  727. if (*f == '/') {
  728. f++;
  729. continue;
  730. }
  731. if (*f == '.') {
  732. /* discard interior "." dirs */
  733. if (f[1] == '/' && !(flags & CFN_KEEP_DOT_DIRS)) {
  734. f += 2;
  735. continue;
  736. }
  737. if (f[1] == '\0' && flags & CFN_DROP_TRAILING_DOT_DIR)
  738. break;
  739. /* collapse ".." dirs */
  740. if (flags & CFN_COLLAPSE_DOT_DOT_DIRS
  741. && f[1] == '.' && (f[2] == '/' || !f[2])) {
  742. char *s = t - 1;
  743. if (s == name && anchored) {
  744. f += 2;
  745. continue;
  746. }
  747. while (s > limit && *--s != '/') {}
  748. if (s != t - 1 && (s < name || *s == '/')) {
  749. t = s + 1;
  750. f += 2;
  751. continue;
  752. }
  753. limit = t + 2;
  754. }
  755. }
  756. while (*f && (*t++ = *f++) != '/') {}
  757. }
  758. if (t > name+anchored && t[-1] == '/' && !(flags & CFN_KEEP_TRAILING_SLASH))
  759. t--;
  760. if (t == name)
  761. *t++ = '.';
  762. *t = '\0';
  763. return t - name;
  764. }
  765. /* Make path appear as if a chroot had occurred. This handles a leading
  766. * "/" (either removing it or expanding it) and any leading or embedded
  767. * ".." components that attempt to escape past the module's top dir.
  768. *
  769. * If dest is NULL, a buffer is allocated to hold the result. It is legal
  770. * to call with the dest and the path (p) pointing to the same buffer, but
  771. * rootdir will be ignored to avoid expansion of the string.
  772. *
  773. * The rootdir string contains a value to use in place of a leading slash.
  774. * Specify NULL to get the default of "module_dir".
  775. *
  776. * The depth var is a count of how many '..'s to allow at the start of the
  777. * path.
  778. *
  779. * We also clean the path in a manner similar to clean_fname() but with a
  780. * few differences:
  781. *
  782. * Turns multiple adjacent slashes into a single slash, gets rid of "." dir
  783. * elements (INCLUDING a trailing dot dir), PRESERVES a trailing slash, and
  784. * ALWAYS collapses ".." elements (except for those at the start of the
  785. * string up to "depth" deep). If the resulting name would be empty,
  786. * change it into a ".". */
  787. char *sanitize_path(char *dest, const char *p, const char *rootdir, int depth,
  788. int flags)
  789. {
  790. char *start, *sanp;
  791. int rlen = 0, drop_dot_dirs = !relative_paths || !(flags & SP_KEEP_DOT_DIRS);
  792. if (dest != p) {
  793. int plen = strlen(p);
  794. if (*p == '/') {
  795. if (!rootdir)
  796. rootdir = module_dir;
  797. rlen = strlen(rootdir);
  798. depth = 0;
  799. p++;
  800. }
  801. if (dest) {
  802. if (rlen + plen + 1 >= MAXPATHLEN)
  803. return NULL;
  804. } else if (!(dest = new_array(char, rlen + plen + 1)))
  805. out_of_memory("sanitize_path");
  806. if (rlen) {
  807. memcpy(dest, rootdir, rlen);
  808. if (rlen > 1)
  809. dest[rlen++] = '/';
  810. }
  811. }
  812. if (drop_dot_dirs) {
  813. while (*p == '.' && p[1] == '/')
  814. p += 2;
  815. }
  816. start = sanp = dest + rlen;
  817. /* This loop iterates once per filename component in p, pointing at
  818. * the start of the name (past any prior slash) for each iteration. */
  819. while (*p) {
  820. /* discard leading or extra slashes */
  821. if (*p == '/') {
  822. p++;
  823. continue;
  824. }
  825. if (drop_dot_dirs) {
  826. if (*p == '.' && (p[1] == '/' || p[1] == '\0')) {
  827. /* skip "." component */
  828. p++;
  829. continue;
  830. }
  831. }
  832. if (*p == '.' && p[1] == '.' && (p[2] == '/' || p[2] == '\0')) {
  833. /* ".." component followed by slash or end */
  834. if (depth <= 0 || sanp != start) {
  835. p += 2;
  836. if (sanp != start) {
  837. /* back up sanp one level */
  838. --sanp; /* now pointing at slash */
  839. while (sanp > start && sanp[-1] != '/')
  840. sanp--;
  841. }
  842. continue;
  843. }
  844. /* allow depth levels of .. at the beginning */
  845. depth--;
  846. /* move the virtual beginning to leave the .. alone */
  847. start = sanp + 3;
  848. }
  849. /* copy one component through next slash */
  850. while (*p && (*sanp++ = *p++) != '/') {}
  851. }
  852. if (sanp == dest) {
  853. /* ended up with nothing, so put in "." component */
  854. *sanp++ = '.';
  855. }
  856. *sanp = '\0';
  857. return dest;
  858. }
  859. /* Like chdir(), but it keeps track of the current directory (in the
  860. * global "curr_dir"), and ensures that the path size doesn't overflow.
  861. * Also cleans the path using the clean_fname() function. */
  862. int change_dir(const char *dir, int set_path_only)
  863. {
  864. static int initialised;
  865. unsigned int len;
  866. if (!initialised) {
  867. initialised = 1;
  868. getcwd(curr_dir, sizeof curr_dir - 1);
  869. curr_dir_len = strlen(curr_dir);
  870. }
  871. if (!dir) /* this call was probably just to initialize */
  872. return 0;
  873. len = strlen(dir);
  874. if (len == 1 && *dir == '.')
  875. return 1;
  876. if (*dir == '/') {
  877. if (len >= sizeof curr_dir) {
  878. errno = ENAMETOOLONG;
  879. return 0;
  880. }
  881. if (!set_path_only && chdir(dir))
  882. return 0;
  883. memcpy(curr_dir, dir, len + 1);
  884. } else {
  885. if (curr_dir_len + 1 + len >= sizeof curr_dir) {
  886. errno = ENAMETOOLONG;
  887. return 0;
  888. }
  889. curr_dir[curr_dir_len] = '/';
  890. memcpy(curr_dir + curr_dir_len + 1, dir, len + 1);
  891. if (!set_path_only && chdir(curr_dir)) {
  892. curr_dir[curr_dir_len] = '\0';
  893. return 0;
  894. }
  895. }
  896. curr_dir_len = clean_fname(curr_dir, CFN_COLLAPSE_DOT_DOT_DIRS);
  897. if (sanitize_paths) {
  898. if (module_dirlen > curr_dir_len)
  899. module_dirlen = curr_dir_len;
  900. curr_dir_depth = count_dir_elements(curr_dir + module_dirlen);
  901. }
  902. if (verbose >= 5 && !set_path_only)
  903. rprintf(FINFO, "[%s] change_dir(%s)\n", who_am_i(), curr_dir);
  904. return 1;
  905. }
  906. /**
  907. * Return a quoted string with the full pathname of the indicated filename.
  908. * The string " (in MODNAME)" may also be appended. The returned pointer
  909. * remains valid until the next time full_fname() is called.
  910. **/
  911. char *full_fname(const char *fn)
  912. {
  913. static char *result = NULL;
  914. char *m1, *m2, *m3;
  915. char *p1, *p2;
  916. if (result)
  917. free(result);
  918. if (*fn == '/')
  919. p1 = p2 = "";
  920. else {
  921. p1 = curr_dir + module_dirlen;
  922. for (p2 = p1; *p2 == '/'; p2++) {}
  923. if (*p2)
  924. p2 = "/";
  925. }
  926. if (module_id >= 0) {
  927. m1 = " (in ";
  928. m2 = lp_name(module_id);
  929. m3 = ")";
  930. } else
  931. m1 = m2 = m3 = "";
  932. if (asprintf(&result, "\"%s%s%s\"%s%s%s", p1, p2, fn, m1, m2, m3) <= 0)
  933. out_of_memory("full_fname");
  934. return result;
  935. }
  936. static char partial_fname[MAXPATHLEN];
  937. char *partial_dir_fname(const char *fname)
  938. {
  939. char *t = partial_fname;
  940. int sz = sizeof partial_fname;
  941. const char *fn;
  942. if ((fn = strrchr(fname, '/')) != NULL) {
  943. fn++;
  944. if (*partial_dir != '/') {
  945. int len = fn - fname;
  946. strncpy(t, fname, len); /* safe */
  947. t += len;
  948. sz -= len;
  949. }
  950. } else
  951. fn = fname;
  952. if ((int)pathjoin(t, sz, partial_dir, fn) >= sz)
  953. return NULL;
  954. if (daemon_filter_list.head) {
  955. t = strrchr(partial_fname, '/');
  956. *t = '\0';
  957. if (check_filter(&daemon_filter_list, FLOG, partial_fname, 1) < 0)
  958. return NULL;
  959. *t = '/';
  960. if (check_filter(&daemon_filter_list, FLOG, partial_fname, 0) < 0)
  961. return NULL;
  962. }
  963. return partial_fname;
  964. }
  965. /* If no --partial-dir option was specified, we don't need to do anything
  966. * (the partial-dir is essentially '.'), so just return success. */
  967. int handle_partial_dir(const char *fname, int create)
  968. {
  969. char *fn, *dir;
  970. if (fname != partial_fname)
  971. return 1;
  972. if (!create && *partial_dir == '/')
  973. return 1;
  974. if (!(fn = strrchr(partial_fname, '/')))
  975. return 1;
  976. *fn = '\0';
  977. dir = partial_fname;
  978. if (create) {
  979. STRUCT_STAT st;
  980. int statret = do_lstat(dir, &st);
  981. if (statret == 0 && !S_ISDIR(st.st_mode)) {
  982. if (do_unlink(dir) < 0) {
  983. *fn = '/';
  984. return 0;
  985. }
  986. statret = -1;
  987. }
  988. if (statret < 0 && do_mkdir(dir, 0700) < 0) {
  989. *fn = '/';
  990. return 0;
  991. }
  992. } else
  993. do_rmdir(dir);
  994. *fn = '/';
  995. return 1;
  996. }
  997. /**
  998. * Determine if a symlink points outside the current directory tree.
  999. * This is considered "unsafe" because e.g. when mirroring somebody
  1000. * else's machine it might allow them to establish a symlink to
  1001. * /etc/passwd, and then read it through a web server.
  1002. *
  1003. * Null symlinks and absolute symlinks are always unsafe.
  1004. *
  1005. * Basically here we are concerned with symlinks whose target contains
  1006. * "..", because this might cause us to walk back up out of the
  1007. * transferred directory. We are not allowed to go back up and
  1008. * reenter.
  1009. *
  1010. * @param dest Target of the symlink in question.
  1011. *
  1012. * @param src Top source directory currently applicable. Basically this
  1013. * is the first parameter to rsync in a simple invocation, but it's
  1014. * modified by flist.c in slightly complex ways.
  1015. *
  1016. * @retval True if unsafe
  1017. * @retval False is unsafe
  1018. *
  1019. * @sa t_unsafe.c
  1020. **/
  1021. int unsafe_symlink(const char *dest, const char *src)
  1022. {
  1023. const char *name, *slash;
  1024. int depth = 0;
  1025. /* all absolute and null symlinks are unsafe */
  1026. if (!dest || !*dest || *dest == '/')
  1027. return 1;
  1028. /* find out what our safety margin is */
  1029. for (name = src; (slash = strchr(name, '/')) != 0; name = slash+1) {
  1030. if (strncmp(name, "../", 3) == 0) {
  1031. depth = 0;
  1032. } else if (strncmp(name, "./", 2) == 0) {
  1033. /* nothing */
  1034. } else {
  1035. depth++;
  1036. }
  1037. }
  1038. if (strcmp(name, "..") == 0)
  1039. depth = 0;
  1040. for (name = dest; (slash = strchr(name, '/')) != 0; name = slash+1) {
  1041. if (strncmp(name, "../", 3) == 0) {
  1042. /* if at any point we go outside the current directory
  1043. then stop - it is unsafe */
  1044. if (--depth < 0)
  1045. return 1;
  1046. } else if (strncmp(name, "./", 2) == 0) {
  1047. /* nothing */
  1048. } else {
  1049. depth++;
  1050. }
  1051. }
  1052. if (strcmp(name, "..") == 0)
  1053. depth--;
  1054. return (depth < 0);
  1055. }
  1056. #define HUMANIFY(mult) \
  1057. do { \
  1058. if (num >= mult || num <= -mult) { \
  1059. double dnum = (double)num / mult; \
  1060. char units; \
  1061. if (num < 0) \
  1062. dnum = -dnum; \
  1063. if (dnum < mult) \
  1064. units = 'K'; \
  1065. else if ((dnum /= mult) < mult) \
  1066. units = 'M'; \
  1067. else { \
  1068. dnum /= mult; \
  1069. units = 'G'; \
  1070. } \
  1071. if (num < 0) \
  1072. dnum = -dnum; \
  1073. snprintf(bufs[n], sizeof bufs[0], "%.2f%c", dnum, units); \
  1074. return bufs[n]; \
  1075. } \
  1076. } while (0)
  1077. /* Return the int64 number as a string. If the --human-readable option was
  1078. * specified, we may output the number in K, M, or G units. We can return
  1079. * up to 4 buffers at a time. */
  1080. char *human_num(int64 num)
  1081. {
  1082. static char bufs[4][128]; /* more than enough room */
  1083. static unsigned int n;
  1084. char *s;
  1085. int negated;
  1086. n = (n + 1) % (sizeof bufs / sizeof bufs[0]);
  1087. if (human_readable) {
  1088. if (human_readable == 1)
  1089. HUMANIFY(1000);
  1090. else
  1091. HUMANIFY(1024);
  1092. }
  1093. s = bufs[n] + sizeof bufs[0] - 1;
  1094. *s = '\0';
  1095. if (!num)
  1096. *--s = '0';
  1097. if (num < 0) {
  1098. /* A maximum-size negated number can't fit as a positive,
  1099. * so do one digit in negated form to start us off. */
  1100. *--s = (char)(-(num % 10)) + '0';
  1101. num = -(num / 10);
  1102. negated = 1;
  1103. } else
  1104. negated = 0;
  1105. while (num) {
  1106. *--s = (char)(num % 10) + '0';
  1107. num /= 10;
  1108. }
  1109. if (negated)
  1110. *--s = '-';
  1111. return s;
  1112. }
  1113. /* Return the double number as a string. If the --human-readable option was
  1114. * specified, we may output the number in K, M, or G units. We use a buffer
  1115. * from human_num() to return our result. */
  1116. char *human_dnum(double dnum, int decimal_digits)
  1117. {
  1118. char *buf = human_num(dnum);
  1119. int len = strlen(buf);
  1120. if (isDigit(buf + len - 1)) {
  1121. /* There's extra room in buf prior to the start of the num. */
  1122. buf -= decimal_digits + 2;
  1123. snprintf(buf, len + decimal_digits + 3, "%.*f", decimal_digits, dnum);
  1124. }
  1125. return buf;
  1126. }
  1127. /* Return the date and time as a string. Some callers tweak returned buf. */
  1128. char *timestring(time_t t)
  1129. {
  1130. static char TimeBuf[200];
  1131. struct tm *tm = localtime(&t);
  1132. char *p;
  1133. #ifdef HAVE_STRFTIME
  1134. strftime(TimeBuf, sizeof TimeBuf - 1, "%Y/%m/%d %H:%M:%S", tm);
  1135. #else
  1136. strlcpy(TimeBuf, asctime(tm), sizeof TimeBuf);
  1137. #endif
  1138. if ((p = strchr(TimeBuf, '\n')) != NULL)
  1139. *p = '\0';
  1140. return TimeBuf;
  1141. }
  1142. /**
  1143. * Sleep for a specified number of milliseconds.
  1144. *
  1145. * Always returns TRUE. (In the future it might return FALSE if
  1146. * interrupted.)
  1147. **/
  1148. int msleep(int t)
  1149. {
  1150. int tdiff = 0;
  1151. struct timeval tval, t1, t2;
  1152. gettimeofday(&t1, NULL);
  1153. while (tdiff < t) {
  1154. tval.tv_sec = (t-tdiff)/1000;
  1155. tval.tv_usec = 1000*((t-tdiff)%1000);
  1156. errno = 0;
  1157. select(0,NULL,NULL, NULL, &tval);
  1158. gettimeofday(&t2, NULL);
  1159. tdiff = (t2.tv_sec - t1.tv_sec)*1000 +
  1160. (t2.tv_usec - t1.tv_usec)/1000;
  1161. }
  1162. return True;
  1163. }
  1164. /* Determine if two time_t values are equivalent (either exact, or in
  1165. * the modification timestamp window established by --modify-window).
  1166. *
  1167. * @retval 0 if the times should be treated as the same
  1168. *
  1169. * @retval +1 if the first is later
  1170. *
  1171. * @retval -1 if the 2nd is later
  1172. **/
  1173. int cmp_time(time_t file1, time_t file2)
  1174. {
  1175. if (file2 > file1) {
  1176. if (file2 - file1 <= modify_window)
  1177. return 0;
  1178. return -1;
  1179. }
  1180. if (file1 - file2 <= modify_window)
  1181. return 0;
  1182. return 1;
  1183. }
  1184. #ifdef __INSURE__XX
  1185. #include <dlfcn.h>
  1186. /**
  1187. This routine is a trick to immediately catch errors when debugging
  1188. with insure. A xterm with a gdb is popped up when insure catches
  1189. a error. It is Linux specific.
  1190. **/
  1191. int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
  1192. {
  1193. static int (*fn)();
  1194. int ret;
  1195. char *cmd;
  1196. 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'",
  1197. getpid(), getpid(), getpid());
  1198. if (!fn) {
  1199. static void *h;
  1200. h = dlopen("/usr/local/parasoft/insure++lite/lib.linux2/libinsure.so", RTLD_LAZY);
  1201. fn = dlsym(h, "_Insure_trap_error");
  1202. }
  1203. ret = fn(a1, a2, a3, a4, a5, a6);
  1204. system(cmd);
  1205. free(cmd);
  1206. return ret;
  1207. }
  1208. #endif
  1209. #define MALLOC_MAX 0x40000000
  1210. void *_new_array(unsigned long num, unsigned int size, int use_calloc)
  1211. {
  1212. if (num >= MALLOC_MAX/size)
  1213. return NULL;
  1214. return use_calloc ? calloc(num, size) : malloc(num * size);
  1215. }
  1216. void *_realloc_array(void *ptr, unsigned int size, size_t num)
  1217. {
  1218. if (num >= MALLOC_MAX/size)
  1219. return NULL;
  1220. if (!ptr)
  1221. return malloc(size * num);
  1222. return realloc(ptr, size * num);
  1223. }
  1224. /* Take a filename and filename length and return the most significant
  1225. * filename suffix we can find. This ignores suffixes such as "~",
  1226. * ".bak", ".orig", ".~1~", etc. */
  1227. const char *find_filename_suffix(const char *fn, int fn_len, int *len_ptr)
  1228. {
  1229. const char *suf, *s;
  1230. BOOL had_tilde;
  1231. int s_len;
  1232. /* One or more dots at the start aren't a suffix. */
  1233. while (fn_len && *fn == '.') fn++, fn_len--;
  1234. /* Ignore the ~ in a "foo~" filename. */
  1235. if (fn_len > 1 && fn[fn_len-1] == '~')
  1236. fn_len--, had_tilde = True;
  1237. else
  1238. had_tilde = False;
  1239. /* Assume we don't find an suffix. */
  1240. suf = "";
  1241. *len_ptr = 0;
  1242. /* Find the last significant suffix. */
  1243. for (s = fn + fn_len; fn_len > 1; ) {
  1244. while (*--s != '.' && s != fn) {}
  1245. if (s == fn)
  1246. break;
  1247. s_len = fn_len - (s - fn);
  1248. fn_len = s - fn;
  1249. if (s_len == 4) {
  1250. if (strcmp(s+1, "bak") == 0
  1251. || strcmp(s+1, "old") == 0)
  1252. continue;
  1253. } else if (s_len == 5) {
  1254. if (strcmp(s+1, "orig") == 0)
  1255. continue;
  1256. } else if (s_len > 2 && had_tilde
  1257. && s[1] == '~' && isDigit(s + 2))
  1258. continue;
  1259. *len_ptr = s_len;
  1260. suf = s;
  1261. if (s_len == 1)
  1262. break;
  1263. /* Determine if the suffix is all digits. */
  1264. for (s++, s_len--; s_len > 0; s++, s_len--) {
  1265. if (!isDigit(s))
  1266. return suf;
  1267. }
  1268. /* An all-digit suffix may not be that signficant. */
  1269. s = suf;
  1270. }
  1271. return suf;
  1272. }
  1273. /* This is an implementation of the Levenshtein distance algorithm. It
  1274. * was implemented to avoid needing a two-dimensional matrix (to save
  1275. * memory). It was also tweaked to try to factor in the ASCII distance
  1276. * between changed characters as a minor distance quantity. The normal
  1277. * Levenshtein units of distance (each signifying a single change between
  1278. * the two strings) are defined as a "UNIT". */
  1279. #define UNIT (1 << 16)
  1280. uint32 fuzzy_distance(const char *s1, int len1, const char *s2, int len2)
  1281. {
  1282. uint32 a[MAXPATHLEN], diag, above, left, diag_inc, above_inc, left_inc;
  1283. int32 cost;
  1284. int i1, i2;
  1285. if (!len1 || !len2) {
  1286. if (!len1) {
  1287. s1 = s2;
  1288. len1 = len2;
  1289. }
  1290. for (i1 = 0, cost = 0; i1 < len1; i1++)
  1291. cost += s1[i1];
  1292. return (int32)len1 * UNIT + cost;
  1293. }
  1294. for (i2 = 0; i2 < len2; i2++)
  1295. a[i2] = (i2+1) * UNIT;
  1296. for (i1 = 0; i1 < len1; i1++) {
  1297. diag = i1 * UNIT;
  1298. above = (i1+1) * UNIT;
  1299. for (i2 = 0; i2 < len2; i2++) {
  1300. left = a[i2];
  1301. if ((cost = *((uchar*)s1+i1) - *((uchar*)s2+i2)) != 0) {
  1302. if (cost < 0)
  1303. cost = UNIT - cost;
  1304. else
  1305. cost = UNIT + cost;
  1306. }
  1307. diag_inc = diag + cost;
  1308. left_inc = left + UNIT + *((uchar*)s1+i1);
  1309. above_inc = above + UNIT + *((uchar*)s2+i2);
  1310. a[i2] = above = left < above
  1311. ? (left_inc < diag_inc ? left_inc : diag_inc)
  1312. : (above_inc < diag_inc ? above_inc : diag_inc);
  1313. diag = left;
  1314. }
  1315. }
  1316. return a[len2-1];
  1317. }
  1318. #define BB_SLOT_SIZE (16*1024) /* Desired size in bytes */
  1319. #define BB_PER_SLOT_BITS (BB_SLOT_SIZE * 8) /* Number of bits per slot */
  1320. #define BB_PER_SLOT_INTS (BB_SLOT_SIZE / 4) /* Number of int32s per slot */
  1321. struct bitbag {
  1322. uint32 **bits;
  1323. int slot_cnt;
  1324. };
  1325. struct bitbag *bitbag_create(int max_ndx)
  1326. {
  1327. struct bitbag *bb = new(struct bitbag);
  1328. bb->slot_cnt = (max_ndx + BB_PER_SLOT_BITS - 1) / BB_PER_SLOT_BITS;
  1329. if (!(bb->bits = (uint32**)calloc(bb->slot_cnt, sizeof (uint32*))))
  1330. out_of_memory("bitbag_create");
  1331. return bb;
  1332. }
  1333. void bitbag_set_bit(struct bitbag *bb, int ndx)
  1334. {
  1335. int slot = ndx / BB_PER_SLOT_BITS;
  1336. ndx %= BB_PER_SLOT_BITS;
  1337. if (!bb->bits[slot]) {
  1338. if (!(bb->bits[slot] = (uint32*)calloc(BB_PER_SLOT_INTS, 4)))
  1339. out_of_memory("bitbag_set_bit");
  1340. }
  1341. bb->bits[slot][ndx/32] |= 1u << (ndx % 32);
  1342. }
  1343. #if 0 /* not needed yet */
  1344. void bitbag_clear_bit(struct bitbag *bb, int ndx)
  1345. {
  1346. int slot = ndx / BB_PER_SLOT_BITS;
  1347. ndx %= BB_PER_SLOT_BITS;
  1348. if (!bb->bits[slot])
  1349. return;
  1350. bb->bits[slot][ndx/32] &= ~(1u << (ndx % 32));
  1351. }
  1352. int bitbag_check_bit(struct bitbag *bb, int ndx)
  1353. {
  1354. int slot = ndx / BB_PER_SLOT_BITS;
  1355. ndx %= BB_PER_SLOT_BITS;
  1356. if (!bb->bits[slot])
  1357. return 0;
  1358. return bb->bits[slot][ndx/32] & (1u << (ndx % 32)) ? 1 : 0;
  1359. }
  1360. #endif
  1361. /* Call this with -1 to start checking from 0. Returns -1 at the end. */
  1362. int bitbag_next_bit(struct bitbag *bb, int after)
  1363. {
  1364. uint32 bits, mask;
  1365. int i, ndx = after + 1;
  1366. int slot = ndx / BB_PER_SLOT_BITS;
  1367. ndx %= BB_PER_SLOT_BITS;
  1368. mask = (1u << (ndx % 32)) - 1;
  1369. for (i = ndx / 32; slot < bb->slot_cnt; slot++, i = mask = 0) {
  1370. if (!bb->bits[slot])
  1371. continue;
  1372. for ( ; i < BB_PER_SLOT_INTS; i++, mask = 0) {
  1373. if (!(bits = bb->bits[slot][i] & ~mask))
  1374. continue;
  1375. /* The xor magic figures out the lowest enabled bit in
  1376. * bits, and the switch quickly computes log2(bit). */
  1377. switch (bits ^ (bits & (bits-1))) {
  1378. #define LOG2(n) case 1u << n: return slot*BB_PER_SLOT_BITS + i*32 + n
  1379. LOG2(0); LOG2(1); LOG2(2); LOG2(3);
  1380. LOG2(4); LOG2(5); LOG2(6); LOG2(7);
  1381. LOG2(8); LOG2(9); LOG2(10); LOG2(11);
  1382. LOG2(12); LOG2(13); LOG2(14); LOG2(15);
  1383. LOG2(16); LOG2(17); LOG2(18); LOG2(19);
  1384. LOG2(20); LOG2(21); LOG2(22); LOG2(23);
  1385. LOG2(24); LOG2(25); LOG2(26); LOG2(27);
  1386. LOG2(28); LOG2(29); LOG2(30); LOG2(31);
  1387. }
  1388. return -1; /* impossible... */
  1389. }
  1390. }
  1391. return -1;
  1392. }
  1393. void *expand_item_list(item_list *lp, size_t item_size,
  1394. const char *desc, int incr)
  1395. {
  1396. /* First time through, 0 <= 0, so list is expanded. */
  1397. if (lp->malloced <= lp->count) {
  1398. void *new_ptr;
  1399. size_t new_size = lp->malloced;
  1400. if (incr < 0)
  1401. new_size += -incr; /* increase slowly */
  1402. else if (new_size < (size_t)incr)
  1403. new_size += incr;
  1404. else
  1405. new_size *= 2;
  1406. if (new_size < lp->malloced)
  1407. overflow_exit("expand_item_list");
  1408. /* Using _realloc_array() lets us pass the size, not a type. */
  1409. new_ptr = _realloc_array(lp->items, item_size, new_size);
  1410. if (verbose >= 4) {
  1411. rprintf(FINFO, "[%s] expand %s to %.0f bytes, did%s move\n",
  1412. who_am_i(), desc, (double)new_size * item_size,
  1413. new_ptr == lp->items ? " not" : "");
  1414. }
  1415. if (!new_ptr)
  1416. out_of_memory("expand_item_list");
  1417. lp->items = new_ptr;
  1418. lp->malloced = new_size;
  1419. }
  1420. return (char*)lp->items + (lp->count++ * item_size);
  1421. }