|
|
1.1 ! root 1: /* xqtsub.c ! 2: System dependent functions used only by uuxqt. ! 3: ! 4: Copyright (C) 1991, 1992 Ian Lance Taylor ! 5: ! 6: This file is part of the Taylor UUCP package. ! 7: ! 8: This program is free software; you can redistribute it and/or ! 9: modify it under the terms of the GNU General Public License as ! 10: published by the Free Software Foundation; either version 2 of the ! 11: License, or (at your option) any later version. ! 12: ! 13: This program is distributed in the hope that it will be useful, but ! 14: WITHOUT ANY WARRANTY; without even the implied warranty of ! 15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 16: General Public License for more details. ! 17: ! 18: You should have received a copy of the GNU General Public License ! 19: along with this program; if not, write to the Free Software ! 20: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ! 21: ! 22: The author of the program may be contacted at [email protected] or ! 23: c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254. ! 24: */ ! 25: ! 26: #include "uucp.h" ! 27: ! 28: #if USE_RCS_ID ! 29: const char xqtsub_rcsid[] = "$Id: xqtsub.c,v 1.1 93/07/30 08:03:41 bin Exp Locker: bin $"; ! 30: #endif ! 31: ! 32: #include "uudefs.h" ! 33: #include "uuconf.h" ! 34: #include "system.h" ! 35: #include "sysdep.h" ! 36: ! 37: #include <ctype.h> ! 38: #include <errno.h> ! 39: ! 40: #if HAVE_FCNTL_H ! 41: #include <fcntl.h> ! 42: #else ! 43: #if HAVE_SYS_FILE_H ! 44: #include <sys/file.h> ! 45: #endif ! 46: #endif ! 47: ! 48: #ifndef O_RDONLY ! 49: #define O_RDONLY 0 ! 50: #define O_WRONLY 1 ! 51: #define O_RDWR 2 ! 52: #endif ! 53: ! 54: #ifndef O_NOCTTY ! 55: #define O_NOCTTY 0 ! 56: #endif ! 57: ! 58: #ifndef FD_CLOEXEC ! 59: #define FD_CLOEXEC 1 ! 60: #endif ! 61: ! 62: #if HAVE_OPENDIR ! 63: #if HAVE_DIRENT_H ! 64: #include <dirent.h> ! 65: #else /* ! HAVE_DIRENT_H */ ! 66: #include <sys/dir.h> ! 67: #define dirent direct ! 68: #endif /* ! HAVE_DIRENT_H */ ! 69: #endif /* HAVE_OPENDIR */ ! 70: ! 71: /* Get a value for EX_TEMPFAIL. */ ! 72: ! 73: #if HAVE_SYSEXITS_H ! 74: #include <sysexits.h> ! 75: #endif ! 76: ! 77: #ifndef EX_TEMPFAIL ! 78: #define EX_TEMPFAIL 75 ! 79: #endif ! 80: ! 81: /* Get the full pathname of the command to execute, given the list of ! 82: permitted commands and the allowed path. */ ! 83: ! 84: char * ! 85: zsysdep_find_command (zcmd, pzcmds, pzpath, pferr) ! 86: const char *zcmd; ! 87: char **pzcmds; ! 88: char **pzpath; ! 89: boolean *pferr; ! 90: { ! 91: char **pz; ! 92: ! 93: *pferr = FALSE; ! 94: ! 95: for (pz = pzcmds; *pz != NULL; pz++) ! 96: { ! 97: char *zslash; ! 98: ! 99: if (strcmp (*pz, "ALL") == 0) ! 100: break; ! 101: ! 102: zslash = strrchr (*pz, '/'); ! 103: if (zslash != NULL) ! 104: ++zslash; ! 105: else ! 106: zslash = *pz; ! 107: if (strcmp (zslash, zcmd) == 0 ! 108: || strcmp (*pz, zcmd) == 0) ! 109: { ! 110: /* If we already have an absolute path, we can get out ! 111: immediately. */ ! 112: if (**pz == '/') ! 113: return zbufcpy (*pz); ! 114: break; ! 115: } ! 116: } ! 117: ! 118: /* If we didn't find this command, get out. */ ! 119: if (*pz == NULL) ! 120: return NULL; ! 121: ! 122: /* We didn't find an absolute pathname, so we must look through ! 123: the path. */ ! 124: for (pz = pzpath; *pz != NULL; pz++) ! 125: { ! 126: char *zname; ! 127: struct stat s; ! 128: ! 129: zname = zsysdep_in_dir (*pz, zcmd); ! 130: if (stat (zname, &s) == 0) ! 131: return zname; ! 132: } ! 133: ! 134: *pferr = FALSE; ! 135: return NULL; ! 136: } ! 137: ! 138: /* Expand a local filename for uuxqt. This is special because uuxqt ! 139: only wants to expand filenames that start with ~ (it does not want ! 140: to prepend the current directory to other names) and if the ~ is ! 141: double, it is turned into a single ~. This returns NULL to ! 142: indicate that no change was required; it has no way to return ! 143: error. */ ! 144: ! 145: char * ! 146: zsysdep_xqt_local_file (qsys, zfile) ! 147: const struct uuconf_system *qsys; ! 148: const char *zfile; ! 149: { ! 150: if (*zfile != '~') ! 151: return NULL; ! 152: if (zfile[1] == '~') ! 153: { ! 154: size_t clen; ! 155: char *zret; ! 156: ! 157: clen = strlen (zfile); ! 158: zret = zbufalc (clen); ! 159: memcpy (zret, zfile + 1, clen); ! 160: return zret; ! 161: } ! 162: return zsysdep_local_file (zfile, qsys->uuconf_zpubdir); ! 163: } ! 164: ! 165: #if ! ALLOW_FILENAME_ARGUMENTS ! 166: ! 167: /* Check to see whether an argument specifies a file name; if it does, ! 168: make sure that the file may legally be sent and/or received. For ! 169: Unix, we do not permit any occurrence of "/../" in the name, nor ! 170: may it start with "../". Otherwise, if it starts with "/" we check ! 171: against the list of permitted files. */ ! 172: ! 173: boolean ! 174: fsysdep_xqt_check_file (qsys, zfile) ! 175: const struct uuconf_system *qsys; ! 176: const char *zfile; ! 177: { ! 178: size_t clen; ! 179: ! 180: clen = strlen (zfile); ! 181: if ((clen == sizeof "../" - 1 ! 182: && strcmp (zfile, "../") == 0) ! 183: || (clen >= sizeof "/.." - 1 ! 184: && strcmp (zfile + clen - (sizeof "/.." - 1), "/..") == 0) ! 185: || strstr (zfile, "/../") != NULL ! 186: || (*zfile == '/' ! 187: && (! fin_directory_list (zfile, qsys->uuconf_pzremote_send, ! 188: qsys->uuconf_zpubdir, TRUE, FALSE, ! 189: (const char *) NULL) ! 190: || ! fin_directory_list (zfile, qsys->uuconf_pzremote_receive, ! 191: qsys->uuconf_zpubdir, TRUE, FALSE, ! 192: (const char *) NULL)))) ! 193: { ! 194: ulog (LOG_ERROR, "Not permitted to refer to file \"%s\"", zfile); ! 195: return FALSE; ! 196: } ! 197: ! 198: return TRUE; ! 199: } ! 200: ! 201: #endif /* ! ALLOW_FILENAME_ARGUMENTS */ ! 202: ! 203: /* Invoke the command specified by an execute file. */ ! 204: ! 205: /*ARGSUSED*/ ! 206: boolean ! 207: fsysdep_execute (qsys, zuser, pazargs, zfullcmd, zinput, zoutput, ! 208: fshell, iseq, pzerror, pftemp) ! 209: const struct uuconf_system *qsys; ! 210: const char *zuser; ! 211: const char **pazargs; ! 212: const char *zfullcmd; ! 213: const char *zinput; ! 214: const char *zoutput; ! 215: boolean fshell; ! 216: int iseq; ! 217: char **pzerror; ! 218: boolean *pftemp; ! 219: { ! 220: int aidescs[3]; ! 221: boolean ferr; ! 222: pid_t ipid; ! 223: int ierr; ! 224: char abxqtdir[sizeof XQTDIR + 4]; ! 225: const char *zxqtdir; ! 226: int istat; ! 227: char *zpath; ! 228: #if ALLOW_SH_EXECUTION ! 229: const char *azshargs[4]; ! 230: #endif ! 231: ! 232: *pzerror = NULL; ! 233: *pftemp = FALSE; ! 234: ! 235: aidescs[0] = SPAWN_NULL; ! 236: aidescs[1] = SPAWN_NULL; ! 237: aidescs[2] = SPAWN_NULL; ! 238: ! 239: ferr = FALSE; ! 240: ! 241: if (zinput != NULL) ! 242: { ! 243: aidescs[0] = open ((char *) zinput, O_RDONLY | O_NOCTTY, 0); ! 244: if (aidescs[0] < 0) ! 245: { ! 246: ulog (LOG_ERROR, "open (%s): %s", zinput, strerror (errno)); ! 247: ferr = TRUE; ! 248: } ! 249: else if (fcntl (aidescs[0], F_SETFD, ! 250: fcntl (aidescs[0], F_GETFD, 0) | FD_CLOEXEC) < 0) ! 251: { ! 252: ulog (LOG_ERROR, "fcntl (FD_CLOEXEC): %s", strerror (errno)); ! 253: ferr = TRUE; ! 254: } ! 255: } ! 256: ! 257: if (! ferr && zoutput != NULL) ! 258: { ! 259: aidescs[1] = creat ((char *) zoutput, IPRIVATE_FILE_MODE); ! 260: if (aidescs[1] < 0) ! 261: { ! 262: ulog (LOG_ERROR, "creat (%s): %s", zoutput, strerror (errno)); ! 263: *pftemp = TRUE; ! 264: ferr = TRUE; ! 265: } ! 266: else if (fcntl (aidescs[1], F_SETFD, ! 267: fcntl (aidescs[1], F_GETFD, 0) | FD_CLOEXEC) < 0) ! 268: { ! 269: ulog (LOG_ERROR, "fcntl (FD_CLOEXEC): %s", strerror (errno)); ! 270: ferr = TRUE; ! 271: } ! 272: } ! 273: ! 274: if (! ferr) ! 275: { ! 276: *pzerror = zstemp_file (qsys); ! 277: aidescs[2] = creat (*pzerror, IPRIVATE_FILE_MODE); ! 278: if (aidescs[2] < 0) ! 279: { ! 280: if (errno == ENOENT) ! 281: { ! 282: if (! fsysdep_make_dirs (*pzerror, FALSE)) ! 283: { ! 284: *pftemp = TRUE; ! 285: ferr = TRUE; ! 286: } ! 287: else ! 288: aidescs[2] = creat (*pzerror, IPRIVATE_FILE_MODE); ! 289: } ! 290: if (! ferr && aidescs[2] < 0) ! 291: { ! 292: ulog (LOG_ERROR, "creat (%s): %s", *pzerror, strerror (errno)); ! 293: *pftemp = TRUE; ! 294: ferr = TRUE; ! 295: } ! 296: } ! 297: if (! ferr ! 298: && fcntl (aidescs[2], F_SETFD, ! 299: fcntl (aidescs[2], F_GETFD, 0) | FD_CLOEXEC) < 0) ! 300: { ! 301: ulog (LOG_ERROR, "fcntl (FD_CLOEXEC): %s", strerror (errno)); ! 302: ferr = TRUE; ! 303: } ! 304: } ! 305: ! 306: if (iseq == 0) ! 307: zxqtdir = XQTDIR; ! 308: else ! 309: { ! 310: sprintf (abxqtdir, "%s%04d", XQTDIR, iseq); ! 311: zxqtdir = abxqtdir; ! 312: } ! 313: ! 314: if (ferr) ! 315: { ! 316: if (aidescs[0] != SPAWN_NULL) ! 317: (void) close (aidescs[0]); ! 318: if (aidescs[1] != SPAWN_NULL) ! 319: (void) close (aidescs[1]); ! 320: if (aidescs[2] != SPAWN_NULL) ! 321: (void) close (aidescs[2]); ! 322: ubuffree (*pzerror); ! 323: return FALSE; ! 324: } ! 325: ! 326: #if ALLOW_SH_EXECUTION ! 327: if (fshell) ! 328: { ! 329: azshargs[0] = "/bin/sh"; ! 330: azshargs[1] = "-c"; ! 331: azshargs[2] = zfullcmd; ! 332: azshargs[3] = NULL; ! 333: pazargs = azshargs; ! 334: } ! 335: #else ! 336: fshell = FALSE; ! 337: #endif ! 338: ! 339: if (qsys->uuconf_pzpath == NULL) ! 340: zpath = NULL; ! 341: else ! 342: { ! 343: size_t c; ! 344: char **pz; ! 345: ! 346: c = 0; ! 347: for (pz = qsys->uuconf_pzpath; *pz != NULL; pz++) ! 348: c += strlen (*pz) + 1; ! 349: zpath = zbufalc (c); ! 350: *zpath = '\0'; ! 351: for (pz = qsys->uuconf_pzpath; *pz != NULL; pz++) ! 352: { ! 353: strcat (zpath, *pz); ! 354: if (pz[1] != NULL) ! 355: strcat (zpath, ":"); ! 356: } ! 357: } ! 358: ! 359: /* Pass zchdir as zxqtdir, fnosigs as TRUE, fshell as TRUE if we ! 360: aren't already using the shell. */ ! 361: ipid = ixsspawn (pazargs, aidescs, FALSE, FALSE, zxqtdir, TRUE, ! 362: ! fshell, zpath, qsys->uuconf_zname, zuser); ! 363: ! 364: ierr = errno; ! 365: ! 366: ubuffree (zpath); ! 367: ! 368: if (aidescs[0] != SPAWN_NULL) ! 369: (void) close (aidescs[0]); ! 370: if (aidescs[1] != SPAWN_NULL) ! 371: (void) close (aidescs[1]); ! 372: if (aidescs[2] != SPAWN_NULL) ! 373: (void) close (aidescs[2]); ! 374: ! 375: if (ipid < 0) ! 376: { ! 377: ulog (LOG_ERROR, "ixsspawn: %s", strerror (ierr)); ! 378: *pftemp = TRUE; ! 379: return FALSE; ! 380: } ! 381: ! 382: istat = ixswait ((unsigned long) ipid, "Execution"); ! 383: ! 384: if (istat == EX_TEMPFAIL) ! 385: *pftemp = TRUE; ! 386: ! 387: return istat == 0; ! 388: } ! 389: ! 390: /* Lock a uuxqt process. */ ! 391: ! 392: int ! 393: ixsysdep_lock_uuxqt (zcmd, cmaxuuxqts) ! 394: const char *zcmd; ! 395: int cmaxuuxqts; ! 396: { ! 397: char ab[sizeof "LCK.XQT.9999"]; ! 398: int i; ! 399: ! 400: if (cmaxuuxqts <= 0 || cmaxuuxqts >= 10000) ! 401: cmaxuuxqts = 9999; ! 402: for (i = 0; i < cmaxuuxqts; i++) ! 403: { ! 404: sprintf (ab, "LCK.XQT.%d", i); ! 405: if (fsdo_lock (ab, TRUE, (boolean *) NULL)) ! 406: break; ! 407: } ! 408: if (i >= cmaxuuxqts) ! 409: return -1; ! 410: ! 411: if (zcmd != NULL) ! 412: { ! 413: char abcmd[sizeof "LXQ.123456789"]; ! 414: ! 415: sprintf (abcmd, "LXQ.%.9s", zcmd); ! 416: abcmd[strcspn (abcmd, " \t/")] = '\0'; ! 417: if (! fsdo_lock (abcmd, TRUE, (boolean *) NULL)) ! 418: { ! 419: (void) fsdo_unlock (ab, TRUE); ! 420: return -1; ! 421: } ! 422: } ! 423: ! 424: return i; ! 425: } ! 426: ! 427: /* Unlock a uuxqt process. */ ! 428: ! 429: boolean ! 430: fsysdep_unlock_uuxqt (iseq, zcmd, cmaxuuxqts) ! 431: int iseq; ! 432: const char *zcmd; ! 433: int cmaxuuxqts; ! 434: { ! 435: char ab[sizeof "LCK.XQT.9999"]; ! 436: boolean fret; ! 437: ! 438: fret = TRUE; ! 439: ! 440: sprintf (ab, "LCK.XQT.%d", iseq); ! 441: if (! fsdo_unlock (ab, TRUE)) ! 442: fret = FALSE; ! 443: ! 444: if (zcmd != NULL) ! 445: { ! 446: char abcmd[sizeof "LXQ.123456789"]; ! 447: ! 448: sprintf (abcmd, "LXQ.%.9s", zcmd); ! 449: abcmd[strcspn (abcmd, " \t/")] = '\0'; ! 450: if (! fsdo_unlock (abcmd, TRUE)) ! 451: fret = FALSE; ! 452: } ! 453: ! 454: return fret; ! 455: } ! 456: ! 457: /* See whether a particular uuxqt command is locked (this depends on ! 458: the implementation of fsdo_lock). */ ! 459: ! 460: boolean ! 461: fsysdep_uuxqt_locked (zcmd) ! 462: const char *zcmd; ! 463: { ! 464: char ab[sizeof "LXQ.123456789"]; ! 465: struct stat s; ! 466: ! 467: sprintf (ab, "LXQ.%.9s", zcmd); ! 468: return stat (ab, &s) == 0; ! 469: } ! 470: ! 471: /* Lock a particular execute file. */ ! 472: ! 473: boolean ! 474: fsysdep_lock_uuxqt_file (zfile) ! 475: const char *zfile; ! 476: { ! 477: char *zcopy, *z; ! 478: boolean fret; ! 479: ! 480: zcopy = zbufcpy (zfile); ! 481: ! 482: z = strrchr (zcopy, '/'); ! 483: if (z == NULL) ! 484: *zcopy = 'L'; ! 485: else ! 486: *(z + 1) = 'L'; ! 487: ! 488: fret = fsdo_lock (zcopy, TRUE, (boolean *) NULL); ! 489: ubuffree (zcopy); ! 490: return fret; ! 491: } ! 492: ! 493: /* Unlock a particular execute file. */ ! 494: ! 495: boolean ! 496: fsysdep_unlock_uuxqt_file (zfile) ! 497: const char *zfile; ! 498: { ! 499: char *zcopy, *z; ! 500: boolean fret; ! 501: ! 502: zcopy = zbufcpy (zfile); ! 503: ! 504: z = strrchr (zcopy, '/'); ! 505: if (z == NULL) ! 506: *zcopy = 'L'; ! 507: else ! 508: *(z + 1) = 'L'; ! 509: ! 510: fret = fsdo_unlock (zcopy, TRUE); ! 511: ubuffree (zcopy); ! 512: return fret; ! 513: } ! 514: ! 515: /* Lock the execute directory. Since we use a different directory ! 516: depending on which LCK.XQT.dddd file we got, there is actually no ! 517: need to create a lock file. We do make sure that the directory ! 518: exists, though. */ ! 519: ! 520: boolean ! 521: fsysdep_lock_uuxqt_dir (iseq) ! 522: int iseq; ! 523: { ! 524: const char *zxqtdir; ! 525: char abxqtdir[sizeof XQTDIR + 4]; ! 526: ! 527: if (iseq == 0) ! 528: zxqtdir = XQTDIR; ! 529: else ! 530: { ! 531: sprintf (abxqtdir, "%s%04d", XQTDIR, iseq); ! 532: zxqtdir = abxqtdir; ! 533: } ! 534: ! 535: if (mkdir (zxqtdir, S_IRWXU) < 0 ! 536: && errno != EEXIST) ! 537: { ! 538: ulog (LOG_ERROR, "mkdir (%s): %s", zxqtdir, strerror (errno)); ! 539: return FALSE; ! 540: } ! 541: ! 542: return TRUE; ! 543: } ! 544: ! 545: /* Unlock the execute directory and clear it out. The lock is ! 546: actually the LCK.XQT.dddd file, so we don't unlock it, but we do ! 547: remove all the files. */ ! 548: ! 549: boolean ! 550: fsysdep_unlock_uuxqt_dir (iseq) ! 551: int iseq; ! 552: { ! 553: const char *zxqtdir; ! 554: char abxqtdir[sizeof XQTDIR + 4]; ! 555: DIR *qdir; ! 556: ! 557: if (iseq == 0) ! 558: zxqtdir = XQTDIR; ! 559: else ! 560: { ! 561: sprintf (abxqtdir, "%s%04d", XQTDIR, iseq); ! 562: zxqtdir = abxqtdir; ! 563: } ! 564: ! 565: qdir = opendir ((char *) zxqtdir); ! 566: if (qdir != NULL) ! 567: { ! 568: struct dirent *qentry; ! 569: ! 570: while ((qentry = readdir (qdir)) != NULL) ! 571: { ! 572: char *z; ! 573: ! 574: if (strcmp (qentry->d_name, ".") == 0 ! 575: || strcmp (qentry->d_name, "..") == 0) ! 576: continue; ! 577: z = zsysdep_in_dir (zxqtdir, qentry->d_name); ! 578: if (remove (z) < 0) ! 579: { ! 580: int ierr; ! 581: ! 582: ierr = errno; ! 583: if (! fsysdep_directory (z)) ! 584: ulog (LOG_ERROR, "remove (%s): %s", z, ! 585: strerror (ierr)); ! 586: else ! 587: (void) fsysdep_rmdir (z); ! 588: } ! 589: ubuffree (z); ! 590: } ! 591: ! 592: closedir (qdir); ! 593: } ! 594: ! 595: return TRUE; ! 596: } ! 597: ! 598: /* Move files into the execution directory. */ ! 599: ! 600: boolean ! 601: fsysdep_move_uuxqt_files (cfiles, pzfrom, pzto, fto, iseq, pzinput) ! 602: int cfiles; ! 603: const char *const *pzfrom; ! 604: const char *const *pzto; ! 605: boolean fto; ! 606: int iseq; ! 607: char **pzinput; ! 608: { ! 609: char *zinput; ! 610: const char *zxqtdir; ! 611: char abxqtdir[sizeof XQTDIR + 4]; ! 612: int i; ! 613: ! 614: if (pzinput == NULL) ! 615: zinput = NULL; ! 616: else ! 617: zinput = *pzinput; ! 618: ! 619: if (iseq == 0) ! 620: zxqtdir = XQTDIR; ! 621: else ! 622: { ! 623: sprintf (abxqtdir, "%s%04d", XQTDIR, iseq); ! 624: zxqtdir = abxqtdir; ! 625: } ! 626: ! 627: for (i = 0; i < cfiles; i++) ! 628: { ! 629: const char *zfrom, *zto; ! 630: char *zfree; ! 631: ! 632: if (pzto[i] == NULL) ! 633: continue; ! 634: ! 635: zfree = zsysdep_in_dir (zxqtdir, pzto[i]); ! 636: ! 637: zfrom = pzfrom[i]; ! 638: zto = zfree; ! 639: ! 640: if (zinput != NULL && strcmp (zinput, zfrom) == 0) ! 641: { ! 642: *pzinput = zbufcpy (zto); ! 643: zinput = NULL; ! 644: } ! 645: ! 646: if (! fto) ! 647: { ! 648: const char *ztemp; ! 649: ! 650: ztemp = zfrom; ! 651: zfrom = zto; ! 652: zto = ztemp; ! 653: (void) chmod (zfrom, IPRIVATE_FILE_MODE); ! 654: } ! 655: ! 656: if (rename (zfrom, zto) < 0) ! 657: { ! 658: #if HAVE_RENAME ! 659: /* On some systems the system call rename seems to fail for ! 660: arbitrary reasons. To get around this, we always try to ! 661: copy the file by hand if the rename failed. */ ! 662: errno = EXDEV; ! 663: #endif ! 664: ! 665: if (errno != EXDEV) ! 666: { ! 667: ulog (LOG_ERROR, "rename (%s, %s): %s", zfrom, zto, ! 668: strerror (errno)); ! 669: ubuffree (zfree); ! 670: break; ! 671: } ! 672: ! 673: if (! fcopy_file (zfrom, zto, FALSE, FALSE)) ! 674: { ! 675: ubuffree (zfree); ! 676: break; ! 677: } ! 678: if (remove (zfrom) < 0) ! 679: ulog (LOG_ERROR, "remove (%s): %s", zfrom, ! 680: strerror (errno)); ! 681: } ! 682: ! 683: if (fto) ! 684: (void) chmod (zto, IPUBLIC_FILE_MODE); ! 685: ! 686: ubuffree (zfree); ! 687: } ! 688: ! 689: if (i < cfiles) ! 690: { ! 691: if (fto) ! 692: (void) fsysdep_move_uuxqt_files (i, pzfrom, pzto, FALSE, iseq, ! 693: (char **) NULL); ! 694: return FALSE; ! 695: } ! 696: ! 697: return TRUE; ! 698: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.