home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / unix / volume06 / s3uuque < prev    next >
Encoding:
Text File  |  1988-09-11  |  20.5 KB  |  768 lines

  1. Subject: v06i055:  uuque for System III/V in C (S3uuque)
  2. Newsgroups: mod.sources
  3. Approved: rs@mirror.UUCP
  4.  
  5. Submitted by: ihnp4!sun!cwruecmp!ncoast!allbery (Brandon S. Allbery)
  6. Mod.sources: Volume 6, Issue 55
  7. Archive-name: S3uuque
  8.  
  9. [  I edited Brandon's cover note into two manpages.  I also threw together
  10.    the quickie Makefile.  The shar file below has two different styles, one
  11.    for my stuff, one for his.  I didn't repack it into one because I liked
  12.    the renaming feature of his.  Note that also included in here is a
  13.    version of the directory-access routines.  -r$ ]
  14.  
  15. I got an overwhelming response to my announcement of this program.  So, it
  16. comes full circle back to mod.sources.
  17.  
  18. Uuque has been tested with System III uucp and should work with V7, System
  19. III and most System V uucp's.  It has not been tested with Honey DanBer uucp,
  20. as I don't have access to a system with H/D/B uucp.  If you find out that it
  21. works, or change it so it does, drop me a letter; our computer company may
  22. switch to H/D/B without warning and I'd like to be ready.
  23.  
  24. It does not yet work under the 4.2BSD uucp.  I am working on this; the program
  25. will dynamically determine whether the structure is ``flat'' or arranged in
  26. directories and act accordingly.  I'll send the new version to mod.sources
  27. when it's done.
  28.  
  29. It uses getopt, available from the mod.sources archive for non-AT&T UNIX
  30. systems.
  31.  
  32. --Brandon
  33.  
  34. --------------------------------- cut here -----------------------------------
  35. #! /bin/sh
  36. #
  37. # Shell archive created Thu., Jun. 26, 1986 by tdi2!brandon.
  38. # Contents:
  39. #
  40. #    -rw-r--r--   1 brandon  system      2625 Jun  9 13:49 dir.c
  41. #    -rw-rw-rw-   1 brandon  system      3164 Jun  9 13:49 dir.h
  42. #    -rw-r--r--   1 brandon  system      2018 Jun  9 20:47 uukill.c
  43. #    -rw-r--r--   1 brandon  system      6197 Jun 12 12:29 uuque.c
  44. #
  45. # You may unpack this archive with sh or ksh, but not csh.
  46. #
  47.  
  48. if test -r "dir.c"; then
  49.     echo "File dir.c exists.  Enter new name or RETURN to skip.  (. to replace.)"
  50.     read newname
  51.     case "$newname" in
  52.     ".")    newname="dir.c"
  53.     esac
  54. else
  55.     newname="dir.c"
  56. fi
  57. if test -z "$newname"; then
  58.     echo "shx - $newname (skipped)"
  59. else
  60.     case "$newname" in
  61.     "$sfile")
  62.         echo "shx - $sfile (as $newname)"
  63.         ;;
  64.     *)    echo "shx - $newname"
  65.     esac
  66.     sed 's/^X//' << '--EOF:dir.c--' > "$newname"
  67. X/*
  68. X *
  69. X *                N O T I C E
  70. X *
  71. X * This file is NOT a copyrighted part of the UNaXcess distribution.  These
  72. X * are directory-reading routines which are compatible with the Berkeley Unix
  73. X * (4.2BSD, 4.3BSD) directory routines.  They come from the Usenet news
  74. X * distribution and are in the public domain.
  75. X *
  76. X * To get the best use of them:  install the file "dir.h" in /usr/include
  77. X * -- standard usage calls it "ndir.h", and make a random archive of dir.o and
  78. X * put it in /usr/lib/libndir.a .  It is then available with "-lndir".
  79. X *
  80. X * Bell System {III, V} sites, just make an archive -- it is only one file
  81. X * anyway.  Other sites will have to run ranlib on the archive to keep ld
  82. X * happy.
  83. X */
  84. X
  85. X#include <sys/types.h>
  86. X#include "dir.h"
  87. X
  88. X#ifndef BSD
  89. X
  90. X/*
  91. X * close a directory.
  92. X */
  93. Xclosedir(dirp)
  94. X        register DIR *dirp;
  95. X{
  96. X        close(dirp->dd_fd);
  97. X        dirp->dd_fd = -1;
  98. X        dirp->dd_loc = 0;
  99. X        free(dirp);
  100. X}
  101. X
  102. X
  103. X
  104. X/*
  105. X * open a directory.
  106. X */
  107. XDIR *
  108. Xopendir(name)
  109. X        char *name;
  110. X{
  111. X        register DIR *dirp;
  112. X        register int fd;
  113. X
  114. X        if ((fd = open(name, 0)) == -1)
  115. X                return NULL;
  116. X        if ((dirp = (DIR *)malloc(sizeof(DIR))) == NULL) {
  117. X                close (fd);
  118. X                return NULL;
  119. X        }
  120. X        dirp->dd_fd = fd;
  121. X        dirp->dd_loc = 0;
  122. X        return dirp;
  123. X}
  124. X
  125. X
  126. X
  127. X/*
  128. X * read an old style directory entry and present it as a new one
  129. X */
  130. X#define ODIRSIZ 14
  131. X
  132. Xstruct  olddirect {
  133. X        ino_t   od_ino;
  134. X        char    od_name[ODIRSIZ];
  135. X};
  136. X
  137. X/*
  138. X * get next entry in a directory.
  139. X */
  140. Xstruct direct *
  141. Xreaddir(dirp)
  142. X        register DIR *dirp;
  143. X{
  144. X        register struct olddirect *dp;
  145. X        static struct direct dir;
  146. X
  147. X        for (;;) {
  148. X                if (dirp->dd_loc == 0) {
  149. X                        dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf, 
  150. X                            DIRBLKSIZ);
  151. X                        if (dirp->dd_size <= 0)
  152. X                                return NULL;
  153. X                }
  154. X                if (dirp->dd_loc >= dirp->dd_size) {
  155. X                        dirp->dd_loc = 0;
  156. X                        continue;
  157. X                }
  158. X                dp = (struct olddirect *)(dirp->dd_buf + dirp->dd_loc);
  159. X                dirp->dd_loc += sizeof(struct olddirect);
  160. X                if (dp->od_ino == 0)
  161. X                        continue;
  162. X                dir.d_ino = dp->od_ino;
  163. X                strncpy(dir.d_name, dp->od_name, ODIRSIZ);
  164. X                dir.d_name[ODIRSIZ] = '\0'; /* insure null termination */
  165. X                dir.d_namlen = strlen(dir.d_name);
  166. X                dir.d_reclen = DIRBLKSIZ;
  167. X                return (&dir);
  168. X        }
  169. X}
  170. X
  171. X#endif BSD
  172. --EOF:dir.c--
  173. fi
  174.  
  175. if test -r "dir.h"; then
  176.     echo "File dir.h exists.  Enter new name or RETURN to skip.  (. to replace.)"
  177.     read newname
  178.     case "$newname" in
  179.     ".")    newname="dir.h"
  180.     esac
  181. else
  182.     newname="dir.h"
  183. fi
  184. if test -z "$newname"; then
  185.     echo "shx - $newname (skipped)"
  186. else
  187.     case "$newname" in
  188.     "$sfile")
  189.         echo "shx - $sfile (as $newname)"
  190.         ;;
  191.     *)    echo "shx - $newname"
  192.     esac
  193.     sed 's/^X//' << '--EOF:dir.h--' > "$newname"
  194. X/*
  195. X *
  196. X *                N O T I C E
  197. X *
  198. X * This file is NOT a copyrighted part of the UNaXcess distribution.  These
  199. X * are directory-reading routines which are compatible with the Berkeley Unix
  200. X * (4.2BSD, 4.3BSD) directory routines.  They come from the Usenet news
  201. X * distribution and are in the public domain.
  202. X *
  203. X * To get the best use of them:  install the file "dir.h" in /usr/include
  204. X * -- standard usage calls it "ndir.h", and make a random archive of dir.o and
  205. X * put it in /usr/lib/libndir.a .  It is then available with "-lndir".
  206. X *
  207. X * Bell System {III, V} sites, just make an archive -- it is only one file
  208. X * anyway.  Other sites will have to run ranlib on the archive to keep ld
  209. X * happy.
  210. X */
  211. X
  212. X/*    dir.h    4.4    82/07/25    */
  213. X
  214. X#ifdef BSD
  215. X#include <sys/dir.h>
  216. X#else
  217. X
  218. X/*
  219. X * A directory consists of some number of blocks of DIRBLKSIZ
  220. X * bytes, where DIRBLKSIZ is chosen such that it can be transferred
  221. X * to disk in a single atomic operation (e.g. 512 bytes on most machines).
  222. X *
  223. X * Each DIRBLKSIZ byte block contains some number of directory entry
  224. X * structures, which are of variable length.  Each directory entry has
  225. X * a struct direct at the front of it, containing its inode number,
  226. X * the length of the entry, and the length of the name contained in
  227. X * the entry.  These are followed by the name padded to a 4 byte boundary
  228. X * with null bytes.  All names are guaranteed null terminated.
  229. X * The maximum length of a name in a directory is MAXNAMLEN.
  230. X *
  231. X * The macro DIRSIZ(dp) gives the amount of space required to represent
  232. X * a directory entry.  Free space in a directory is represented by
  233. X * entries which have dp->d_reclen >= DIRSIZ(dp).  All DIRBLKSIZ bytes
  234. X * in a directory block are claimed by the directory entries.  This
  235. X * usually results in the last entry in a directory having a large
  236. X * dp->d_reclen.  When entries are deleted from a directory, the
  237. X * space is returned to the previous entry in the same directory
  238. X * block by increasing its dp->d_reclen.  If the first entry of
  239. X * a directory block is free, then its dp->d_ino is set to 0.
  240. X * Entries other than the first in a directory do not normally have
  241. X * dp->d_ino set to 0.
  242. X */
  243. X#define DIRBLKSIZ    512
  244. X#define    MAXNAMLEN    255
  245. X
  246. Xstruct    direct {
  247. X    long    d_ino;            /* inode number of entry */
  248. X    short    d_reclen;        /* length of this record */
  249. X    short    d_namlen;        /* length of string in d_name */
  250. X    char    d_name[MAXNAMLEN + 1];    /* name must be no longer than this */
  251. X};
  252. X
  253. X/*
  254. X * The DIRSIZ macro gives the minimum record length which will hold
  255. X * the directory entry.  This requires the amount of space in struct direct
  256. X * without the d_name field, plus enough space for the name with a terminating
  257. X * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
  258. X */
  259. X#ifdef DIRSIZ
  260. X#undef DIRSIZ
  261. X#endif
  262. X#define DIRSIZ(dp) \
  263. X    ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
  264. X
  265. X#ifndef KERNEL
  266. X/*
  267. X * Definitions for library routines operating on directories.
  268. X */
  269. Xtypedef struct _dirdesc {
  270. X    int    dd_fd;
  271. X    long    dd_loc;
  272. X    long    dd_size;
  273. X    char    dd_buf[DIRBLKSIZ];
  274. X} DIR;
  275. X#ifndef NULL
  276. X#define NULL 0
  277. X#endif
  278. Xextern    DIR *opendir();
  279. Xextern    struct direct *readdir();
  280. Xextern    closedir();
  281. X#endif KERNEL
  282. X
  283. X#endif BSD
  284. --EOF:dir.h--
  285. fi
  286.  
  287. if test -r "uukill.c"; then
  288.     echo "File uukill.c exists.  Enter new name or RETURN to skip.  (. to replace.)"
  289.     read newname
  290.     case "$newname" in
  291.     ".")    newname="uukill.c"
  292.     esac
  293. else
  294.     newname="uukill.c"
  295. fi
  296. if test -z "$newname"; then
  297.     echo "shx - $newname (skipped)"
  298. else
  299.     case "$newname" in
  300.     "$sfile")
  301.         echo "shx - $sfile (as $newname)"
  302.         ;;
  303.     *)    echo "shx - $newname"
  304.     esac
  305.     sed 's/^X//' << '--EOF:uukill.c--' > "$newname"
  306. X/*
  307. X * uukill
  308. X * uucp job killer
  309. X * s3 version (in C) by Brandon Allbery
  310. X */
  311. X
  312. X#include <stdio.h>
  313. X#include "dir.h"
  314. X
  315. Xmain(argc, argv)
  316. Xchar **argv; {
  317. X    int fndjob, jkstat;
  318. X
  319. X    if (argc < 2) {
  320. X        fprintf(stderr, "usage: uukill job ...\n");
  321. X        exit(1);
  322. X    }
  323. X    if (chdir("/usr/spool/uucp") < 0) {
  324. X        perror("/usr/spool/uucp");
  325. X        exit(3);
  326. X    }
  327. X    fndjob = 0;
  328. X    for (argc--, argv++; argc > 0; argc--, argv++)
  329. X        switch (uukill(*argv)) {
  330. X            case -1:
  331. X                fndjob = 2;
  332. X                break;
  333. X            case 0:
  334. X                fprintf(stderr, "uukill: no such job: %s\n", *argv);
  335. X                if (fndjob < 2)
  336. X                    fndjob = 1;
  337. X                continue;
  338. X        }
  339. X    exit(fndjob);
  340. X}
  341. X
  342. Xuukill(jobid)
  343. Xchar *jobid; {
  344. X    DIR *spool;
  345. X    struct direct *job;
  346. X    char jid[8];
  347. X    int cnt;
  348. X    
  349. X    if ((spool = opendir(".")) == NULL) {
  350. X        perror("uukill: cannot open spool directory");
  351. X        exit(3);
  352. X    }
  353. X    while ((job = readdir(spool)) != NULL) {
  354. X        if (job->d_name[0] != 'C' || job->d_name[1] != '.')
  355. X            continue;
  356. X        strcpy(jid, &job->d_name[strlen(job->d_name) - 4]);
  357. X        if (strcmp(jobid, jid) != 0)
  358. X            continue;
  359. X        return koutq(job, jid);
  360. X    }
  361. X    closedir(spool);
  362. X    return 0;
  363. X}
  364. X
  365. Xkoutq(job, jid)
  366. Xchar *jid;
  367. Xstruct direct *job; {
  368. X    FILE *jfile;
  369. X    char cmd[2], xline[512], xtmp[128], otmp[128], utmp[18];
  370. X    
  371. X    if ((jfile = fopen(job->d_name, "r")) < 0) {
  372. X        fprintf(stderr, "uukill: cannot kill %s: ", jid);
  373. X        perror("");
  374. X        return -1;
  375. X    }
  376. X    while (fgets(xline, sizeof xline, jfile) != NULL) {
  377. X        sscanf(xline, "%s %s %s %s", cmd, xtmp, otmp, utmp);
  378. X        switch (cmd[0]) {
  379. X            case 'S':
  380. X                if (!okkill(utmp)) {
  381. X                    fprintf(stderr, "uukill: job %s, permission denied\n", jid);
  382. X                    return 0;
  383. X                }
  384. X                if (xtmp[0] == 'D' && xtmp[1] == '.')
  385. X                    if (unlink(xtmp) < 0)
  386. X                        return 0;
  387. X                break;
  388. X            case 'R':
  389. X                if (!okkill(utmp)) {
  390. X                    fprintf(stderr, "uukill: job %s, permission denied\n", jid);
  391. X                    return 0;
  392. X                }
  393. X            default:
  394. X                fprintf(stderr, "uukill: invalid cmd %s: %s", job->d_name, xline);
  395. X                return 0;
  396. X        }
  397. X    }
  398. X    return unlink(job->d_name) == 0;
  399. X}
  400. X
  401. Xokkill(uid)
  402. Xchar *uid; {
  403. X    if (getuid() == 0)
  404. X        return 1;
  405. X    return strcmp(uid, cuserid(NULL)) == 0;
  406. X}
  407. --EOF:uukill.c--
  408. fi
  409.  
  410. if test -r "uuque.c"; then
  411.     echo "File uuque.c exists.  Enter new name or RETURN to skip.  (. to replace.)"
  412.     read newname
  413.     case "$newname" in
  414.     ".")    newname="uuque.c"
  415.     esac
  416. else
  417.     newname="uuque.c"
  418. fi
  419. if test -z "$newname"; then
  420.     echo "shx - $newname (skipped)"
  421. else
  422.     case "$newname" in
  423.     "$sfile")
  424.         echo "shx - $sfile (as $newname)"
  425.         ;;
  426.     *)    echo "shx - $newname"
  427.     esac
  428.     sed 's/^X//' << '--EOF:uuque.c--' > "$newname"
  429. X/*
  430. X * uuque.c
  431. X * uucp queue lister
  432. X * s3 version (in C) by Brandon Allbery
  433. X */
  434. X
  435. X#include <stdio.h>
  436. X#include <sys/utsname.h>
  437. X#include <sys/types.h>
  438. X#include <sys/stat.h>
  439. X#include "dir.h"
  440. X
  441. Xstruct utsname luuname;
  442. Xchar qsys[8], jobsys[8], jid[8];
  443. Xint verbose, jobnames, jobs;
  444. X
  445. Xlong uuque(), outq();
  446. X
  447. Xmain(argc, argv)
  448. Xchar **argv; {
  449. X    extern int optind;
  450. X    extern char *optarg;
  451. X    char optch;
  452. X    long total;
  453. X
  454. X    verbose = 0;
  455. X    jobnames = 0;
  456. X    jobs = 0;
  457. X    while ((optch = getopt(argc, argv, "vs:j")) != EOF)
  458. X        switch (optch) {
  459. X            case 'v':
  460. X                verbose = !verbose;
  461. X                break;
  462. X            case 'j':
  463. X                jobnames = !jobnames;
  464. X                break;
  465. X            case 's':
  466. X                strncpy(qsys, optarg, 7);
  467. X                qsys[7] = '\0';
  468. X                break;
  469. X            case '?':
  470. X                exit(1);
  471. X        }
  472. X    if (argv[optind] != NULL) {
  473. X        fprintf(stderr, "Usage: uuque [-v] [-j] [-ssystem]\n");
  474. X        exit(1);
  475. X    }
  476. X    uname(&luuname);
  477. X    if (chdir("/usr/spool/uucp") < 0) {
  478. X        perror("/usr/spool/uucp");
  479. X        exit(2);
  480. X    }
  481. X    total = uuque('C');    /* print send queue */
  482. X    uuque('X');    /* print rcv queue */
  483. X    if (jobs == 0)
  484. X        printf("No jobs queued.\n");
  485. X    else
  486. X        printf("%s%7ld total for %d jobs\n", (jobnames? "     ": ""), total, jobs);
  487. X    exit(0);
  488. X}
  489. X
  490. Xlong uuque(sr)
  491. Xchar sr; {
  492. X    DIR *spool;
  493. X    struct direct *job;
  494. X    int cnt;
  495. X    long bytes;
  496. X    
  497. X    if ((spool = opendir(".")) == NULL) {
  498. X        fprintf(stderr, "uuque: cannot open spool directory\n");
  499. X        exit(2);
  500. X    }
  501. X    bytes = 0;
  502. X    while ((job = readdir(spool)) != NULL) {
  503. X        if (job->d_name[0] != sr || job->d_name[1] != '.')
  504. X            continue;
  505. X        for (cnt = 2; cnt < strlen(job->d_name) - 5; cnt++)
  506. X            jobsys[cnt - 2] = job->d_name[cnt];
  507. X        jobsys[cnt - 2] = '\0';
  508. X        strcpy(jid, &job->d_name[strlen(job->d_name) - 4]);
  509. X        if (qsys[0] != '\0' && strcmp(jobsys, qsys) != 0)
  510. X            continue;
  511. X        if (jobs++ == 0)
  512. X            printf("%s   SIZE JOB\n", (jobnames? "ID   ": ""));
  513. X        if (sr == 'C')
  514. X            bytes += outq(job);
  515. X        else
  516. X            inq(job);
  517. X    }
  518. X    closedir(spool);
  519. X    return bytes;
  520. X}
  521. X
  522. Xlong outq(job)
  523. Xstruct direct *job; {
  524. X    FILE *jfile, *cfile;
  525. X    char cmd[2], xline[512], xfile[15], dfile[15], xtmp[128], dtmp[15], otmp[128], utmp[18], from[128], ftmp[150];
  526. X    struct stat statbuf;
  527. X    int pj;
  528. X    long tsize;
  529. X    
  530. X    if ((jfile = fopen(job->d_name, "r")) < 0)
  531. X        return 0;
  532. X    xfile[0] = '\0';
  533. X    dfile[0] = '\0';
  534. X    pj = 0;
  535. X    tsize = 0;
  536. X    while (fgets(xline, sizeof xline, jfile) != NULL) {
  537. X        sscanf(xline, "%s %s %s %s", cmd, xtmp, otmp, utmp);
  538. X        switch (cmd[0]) {
  539. X            case 'S':
  540. X                sprintf(dtmp, "D.%.7sX", luuname.nodename);
  541. X                if (strncmp(xtmp, dtmp, strlen(dtmp)) == 0)
  542. X                    strcpy(xfile, xtmp);
  543. X                else if (xtmp[0] == 'D' && xtmp[1] == '.')
  544. X                    strcpy(dfile, xtmp);
  545. X                else {
  546. X                    stat(xtmp, &statbuf);
  547. X                    printf("%s%s%7ld uucp %s %s!%s (%s)\n", (jobnames? (pj? "    ": jid): ""), (jobnames? " ": ""), statbuf.st_size, xtmp, jobsys, otmp, utmp);
  548. X                    tsize += statbuf.st_size;
  549. X                    pj++;
  550. X                }
  551. X                break;
  552. X            case 'R':
  553. X                printf("%s%s        uucp %s!%s %s (%s)\n", (jobnames? (pj? "    ": jid): ""), (jobnames? " ": ""), jobsys, xtmp, otmp, utmp);
  554. X                pj++;
  555. X                break;
  556. X            default:
  557. X                fprintf(stderr, "uuque: invalid cmd %s: %s", job->d_name, xline);
  558. X        }
  559. X    }
  560. X    fclose(jfile);
  561. X    if (xfile[0] == '\0')
  562. X        return tsize;
  563. X    if ((jfile = fopen(xfile, "r")) == NULL)
  564. X        return tsize;
  565. X    from[0] = '\0';
  566. X    while (fgets(xline, sizeof xline, jfile) != NULL) {
  567. X        sscanf(xline, "%s %s %s %s", cmd, xtmp, otmp, utmp);
  568. X        switch (cmd[0]) {
  569. X            case 'U':
  570. X                sprintf(from, "%s!%s", otmp, xtmp);
  571. X                break;
  572. X            case 'F':
  573. X            case 'I':
  574. X            case 'Z':
  575. X                break;
  576. X            case 'C':
  577. X                stat(dfile, &statbuf);
  578. X                if (strcmp(xtmp, "rmail") == 0) {
  579. X                    if ((cfile = fopen(dfile, "r")) != NULL) {
  580. X                        fgets(ftmp, sizeof ftmp, cfile);
  581. X                        fclose(cfile);
  582. X                        sscanf(ftmp, "From %s ", from);
  583. X                    }
  584. X                }
  585. X                printf("%s%s%7ld %s %s!%s (%s)\n", (jobnames? (pj? "    ": jid): ""), (jobnames? " ": ""), statbuf.st_size, xtmp, jobsys, otmp, from);
  586. X                if (verbose && (strcmp(xtmp, "rmail") == 0 || strcmp(xtmp, "rnews") == 0) && (cfile = fopen(dfile, "r")) != NULL) {
  587. X                    while (fgets(xline, sizeof xline, cfile) != NULL) {
  588. X                        if (strncmp(xline, "Subject: ", 9) == 0)
  589. X                            printf("%s        %s", (jobnames? "     ": ""), xline);
  590. X                        else if (strncmp(xline, "Newsgroups: ", 12) == 0)
  591. X                            printf("%s        %s", (jobnames? "": "     "), xline);
  592. X                        else if (xline[0] == '\n')
  593. X                            break;
  594. X                    }
  595. X                    fclose(cfile);
  596. X                }
  597. X                return statbuf.st_size;
  598. X            default:
  599. X                fprintf(stderr, "uuque: invalid command %s: %s", xfile, xline);
  600. X        }
  601. X    }
  602. X}
  603. X
  604. Xinq(job)
  605. Xstruct direct *job; {
  606. X    FILE *jfile, *cfile;
  607. X    char xline[512], cmd[2], utmp[50], stmp[50], from[128], dtmp[50], dfile[50], ftmp[150], xargs[100];
  608. X    int isxqt;
  609. X    struct stat statbuf;
  610. X    int pj;
  611. X    
  612. X    pj = 0;
  613. X    isxqt = 0;
  614. X    if ((jfile = fopen(job->d_name, "r")) == NULL)
  615. X        return;
  616. X    while (fgets(xline, sizeof xline, jfile) != NULL) {
  617. X        xargs[0] = '\0';
  618. X        sscanf(xline, "%s %s %s %[^\n]", cmd, utmp, stmp, xargs);
  619. X        switch (cmd[0]) {
  620. X            case 'U':
  621. X                sprintf(from, "%s!%s", stmp, utmp);
  622. X                break;
  623. X            case 'Z':
  624. X            case 'I':
  625. X                break;
  626. X            case 'F':
  627. X                if (stat(utmp, &statbuf) == 0)
  628. X                    strcpy(dfile, utmp);
  629. X                else {
  630. X                    sprintf(dtmp, "/usr/lib/uucp/.XQTDIR/%s", stmp);
  631. X                    if (stat(dtmp, &statbuf) == 0) {
  632. X                        strcpy(dfile, dtmp);
  633. X                        isxqt = 1;
  634. X                    }
  635. X                    else
  636. X                        return;
  637. X                }
  638. X                break;
  639. X            case 'C':
  640. X                if (strcmp(utmp, "rmail") == 0)
  641. X                    if ((cfile = fopen(dfile, "r")) != NULL) {
  642. X                        fgets(ftmp, sizeof ftmp, cfile);
  643. X                        fclose(cfile);
  644. X                        sscanf(ftmp, "From %s ", from);
  645. X                    }
  646. X                stat(dfile, &statbuf);
  647. X                printf("%s%s%7ld%s %s%s%s%s\n", (jobnames? (pj? "    ": jid): ""), (jobnames? " ": ""), statbuf.st_size, utmp, (xargs[0] == '\0'? "": " "), (xargs[0] == '\0'? "": xargs), (isxqt? " [Executing]": ""));
  648. X                if (verbose && (strcmp(utmp, "rmail") == 0 || strcmp(utmp, "rnews") == 0) && (cfile = fopen(dfile, "r")) != NULL) {
  649. X                    while (fgets(xline, sizeof xline, cfile) != NULL) {
  650. X                        if (strncmp(xline, "Subject: ", 9) == 0)
  651. X                            printf("%s        %s", (jobnames? "     ": ""), xline);
  652. X                        else if (strncmp(xline, "Newsgroups: ", 12) == 0)
  653. X                            printf("%s        %s", (jobnames? "     ": ""), xline);
  654. X                        else if (xline[0] == '\n')
  655. X                            break;
  656. X                    }
  657. X                    fclose(cfile);
  658. X                }
  659. X                return;
  660. X            default:
  661. X                fprintf(stderr, "uuque: bad cmd in %s: %s", job->d_name, xline);
  662. X        }
  663. X    }
  664. X}
  665. --EOF:uuque.c--
  666. fi
  667.  
  668. echo x - Makefile
  669. sed 's/^XX//' > "Makefile" <<'@//E*O*F Makefile//'
  670. XXCFLAGS=-O
  671.  
  672. XXall:    uukill uuque
  673.  
  674. XXdir.o uukill.o uuque.o: dir.h
  675.  
  676. XXuukill: dir.o uukill.o
  677. XX    cc $(CFLAGS) -o uukill uukill.o dir.o
  678.  
  679. XXuuque:    dir.o uuque.o
  680. XX    cc $(CFLAGS) -o uuque uuque.o dir.o
  681.  
  682. @//E*O*F Makefile//
  683. chmod u=rw,g=rw,o=rw Makefile
  684.  
  685. echo x - uukill.1
  686. sed 's/^XX//' > "uukill.1" <<'@//E*O*F uukill.1//'
  687.  
  688. XX.TH UUKILL 1 LOCAL
  689. XX.SH NAME
  690. XXuukill \- remove job from UUCP queue
  691. XX.SH SYNOPSIS
  692. XX.B uukill
  693. XX.I jobid
  694. XX.SH DESCRIPTION
  695. XX.I Uukill
  696. XXtakes a job ID displayed by the
  697. XX.IR uuque (1L)
  698. XXprogram and removes the spool files for that job.
  699. XXYou must not only have read/write access in the UUCP spool directory,
  700. XXbut only the superuser or the owner of a job can kill the job.
  701. XXIt has been tested with SystemIII UUCP, and should work with V7, SystemIII
  702. XXand some System V UUCP's.
  703. XXIt has not been tested with Honey DanBer UUCP.
  704. XXIt does not yet work under the 4.2BSD UUCP, although this is being
  705. XXworked on; the program will dynamically determine whether the structure
  706. XXis ``flat'' or arranged in directories and act accordingly.
  707. XX.SH BUGS
  708. XXShould be more secure so that it can run setuid.
  709. @//E*O*F uukill.1//
  710. chmod u=rw,g=rw,o=rw uukill.1
  711.  
  712. echo x - uuque.1
  713. sed 's/^XX//' > "uuque.1" <<'@//E*O*F uuque.1//'
  714. XX.TH UUQUE 1 LOCAL
  715. XX.SH NAME
  716. XXuuque \- Show uucp job queue
  717. XX.SH SYNOPSIS
  718. XX.B uuque
  719. XX[
  720. XX.I \-j
  721. XX] [
  722. XX.I \-v
  723. XX] [
  724. XX.IR \-s site
  725. XX]
  726. XX.SH DESCRIPTION
  727. XX.I Uuque
  728. XXis a program to print out status information about the UUCP queues for
  729. XXthe indicated site.
  730. XXIt has been tested with SystemIII UUCP, and should work with V7, SystemIII
  731. XXand some System V UUCP's.
  732. XXIt has not been tested with Honey DanBer UUCP.
  733. XXIt does not yet work under the 4.2BSD UUCP, although this is being
  734. XXworked on; the program will dynamically determine whether the structure
  735. XXis ``flat'' or arranged in directories and act accordingly.
  736. XX.PP
  737. XXThe program displays the jobs spooled for the indicated site, their size,
  738. XXand a total size of all the jobs.
  739. XXTwo flags may be specified to get additional output:
  740. XX.TP \-j
  741. XXPrint the job ID's with each job.
  742. XX.TP \-v
  743. XXPrint the subjects and newsgroups of news and/or mail messages.
  744. XX.PP
  745. XXYou must have read permission in
  746. XX.I /usr/spool/uucp
  747. XXfor this program to work.
  748. XX.SH BUGS
  749. XXOnly one system can be displayed at a time.
  750. @//E*O*F uuque.1//
  751. chmod u=rw,g=rw,o=rw uuque.1
  752.  
  753. echo Inspecting for damage in transit...
  754. temp=/tmp/sharin$$; dtemp=/tmp/sharout$$
  755. trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
  756. cat > $temp <<\!!!
  757.       12      26     183 Makefile
  758.       22     139     759 uukill.1
  759.       36     184     994 uuque.1
  760.       70     349    1936 total
  761. !!!
  762. wc  Makefile uukill.1 uuque.1 | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
  763. if test -s $dtemp
  764. then echo "Ouch [diff of wc output]:" ; cat $dtemp
  765. else echo "No problems found."
  766. fi
  767. exit 0
  768.