home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume1 / 8709 / 17 < prev    next >
Encoding:
Text File  |  1990-07-13  |  9.8 KB  |  400 lines

  1. Path: uunet!seismo!sundc!pitstop!sun!amdcad!ames!ll-xn!husc6!spdcc!m2c!necntc!ncoast!allbery
  2. From: warren@pluto.UUCP (Warren Burstein)
  3. Newsgroups: comp.sources.misc
  4. Subject: C version of uuque program
  5. Message-ID: <4769@ncoast.UUCP>
  6. Date: 29 Sep 87 20:32:35 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Organization: Industrial Automation Systems - New York, NY
  9. Lines: 387
  10. Approved: allbery@ncoast.UUCP
  11. X-Archive: comp.sources.misc/8709/17
  12.  
  13. [Boy, did this thing bounce around to get to me!  ++bsa]
  14.  
  15. I rewrote uuque.sh in C so it would be faster.
  16. It needs getopt.
  17.  
  18. I am leaving the net on Sept 16 but hope to be able to pick up
  19. my mail from this site at a later date.
  20.  
  21. - - ----------------------------------------------------------
  22. # This is a shell archive.  Remove anything before this line, then
  23. # unpack it by saving it in a file and typing "sh file".  (Files
  24. # unpacked will be owned by you and have default permissions.)
  25. #
  26. # This archive contains:
  27. # Makefile uuque.c
  28.  
  29. echo x - Makefile
  30. cat > "Makefile" << '//E*O*F Makefile//'
  31. uuque: uuque.c
  32.     cc -gx uuque.c -lgetopt -o uuque
  33. lint:
  34.     lint uuque.c
  35.  
  36. install: uuque
  37.     cp uuque /usr/local/bin/uuque
  38.     chown uucp /usr/local/bin/uuque
  39.     chmod u+s /usr/local/bin/uuque
  40.  
  41. clean:
  42.     -rm -f *.o core uuque
  43.  
  44. shar:
  45.     shar Makefile uuque.c
  46. //E*O*F Makefile//
  47.  
  48. echo x - uuque.c
  49. cat > "uuque.c" << '//E*O*F uuque.c//'
  50. /*
  51.  * The user must have access to the /usr/spool/uucp/* directories and files.
  52.  * This can be easily done by making certain users members of the daemon
  53.  * and/or uucp groups.  I have it suid uucp, this does allow everyone to
  54.  * see titles of everyone's mail as it sits in uucp queues which I don't
  55.  * think is too great a violation of privacy.  You could disable the verbose
  56.  * flag for nonprivileged users, or not let them run this at all.
  57.  *
  58.  * Original from turtlevax!ken, C code from pluto!warren, I didn't do much
  59.  * more than recode it into C.  All I added was recognition of poll files
  60.  * in the C. directory and teach it not to complain about a few flags that
  61.  * show up in D.systemX and X. files.
  62.  *
  63.  * It only works on Berkeley UUCP.
  64.  */
  65.  
  66. #include <stdio.h>
  67. #include <sys/types.h>
  68. #include <sys/dir.h>
  69. #include <sys/stat.h>
  70.  
  71. int verbose;          /* print verbose messages if set */
  72. char *sys;            /* if set, restrict listings to this system */
  73. char our_name[20];        /* local system name */
  74. char dtemplate[20];        /* holds template for data file */
  75. char xtemplate[20];        /* holds template for execute file */
  76.  
  77. char *strcpy();
  78.  
  79. main(argc, argv)
  80. char **argv;
  81. {
  82.   init();
  83.   parse_args(argc, argv);
  84.  
  85.   outgoing();
  86.   incoming();
  87. }
  88.  
  89. /*
  90.  * Get our own name by executing "uuname -l", use it to make
  91.  * templates for D and X files, and connect to UUCP work directory.
  92.  */
  93.  
  94. init() {
  95.   FILE *fp, *popen();
  96.  
  97.   fp = popen("uuname -l", "r");
  98.   (void) fgets(our_name, sizeof our_name, fp);
  99.   (void) pclose(fp);
  100.   strip_newline(our_name);
  101.  
  102.   (void) sprintf(dtemplate, "D.%s", our_name);
  103.   (void) sprintf(xtemplate, "D.%sX", our_name);
  104.  
  105.   (void) chdir("/usr/spool/uucp");
  106. }
  107.  
  108. char *optarg;
  109.  
  110. parse_args(argc, argv)
  111. char **argv;
  112. {
  113.   int c;
  114.  
  115.   while ( (c = getopt(argc, argv, "s:v")) > 0)
  116.     switch (c) {
  117.     case 'v':
  118.       verbose = 1; break;
  119.     case 's':
  120.       sys = optarg; break;
  121.     default:
  122.       usage();
  123.     }
  124. }
  125.  
  126. usage() {
  127.   die("Usage: uuque [-v] [-s system]");
  128. }
  129.  
  130. die(s)
  131. char *s;
  132. {
  133.   fprintf(stderr, "%s\n", s);
  134.   exit(1);
  135. }
  136.  
  137. outgoing() {
  138.   DIR *dirp;
  139.   struct direct *dp;
  140.   FILE *fp;
  141.   char othersys[10], job[5];
  142.   char cmdline[256], cmd[256], arg1[256], arg2[256], arg3[256];
  143.   char temp[50], xfile[50], dfile[50], fullxfile[50], from[50];
  144. #define cmdfile dp->d_name
  145.  
  146.   if ( (dirp = opendir("C.")) == NULL)
  147.     die("cannot open C. directory");
  148.  
  149.   while ( (dp = readdir(dirp)) != NULL) {
  150.     if ( !parse_filename(dp, othersys, job))
  151.       continue;
  152.  
  153.     /*
  154.      * if job number is POLL, it's not a real job, just print
  155.      * poll message
  156.      */
  157.     if (strcmp(job, "POLL") == 0) {
  158.       printf("POLL\t%s\n", othersys);
  159.       continue;
  160.     }
  161.  
  162.     if ( (fp = fopen(sprintf(temp, "C./%s", cmdfile), "r")) == NULL) {
  163.       fprintf(stderr, "cannot open %s\n", cmdfile);
  164.       continue;
  165.     }
  166.  
  167.     *xfile = *dfile = '\0';
  168.     while (fgets(cmdline, sizeof cmdline, fp)) {
  169.       (void) sscanf(cmdline, "%s %s %s %s", cmd, arg1, arg2, arg3);
  170.       strip_newline(cmdline);
  171.  
  172.       switch (*cmd) {
  173.         case 'S':      /* uucp send */
  174.         
  175.         if (substring(arg1, xtemplate))
  176.           (void) strcpy(xfile, arg1); /* remote execute file */
  177.         else if (substring(arg1, dtemplate))
  178.           /* data file */
  179.           (void) sprintf(dfile, "D.%s/%s", our_name, arg1);
  180.         else
  181.           /* Just a uucp -- no intertpretation */
  182.           printf("%d\tuucp %s %s!%s (%s)\n",
  183.              file_size(arg1), arg1, othersys, arg2, arg3);
  184.  
  185.         break;
  186.  
  187.         case 'R':      /* uucp receive */
  188.         printf("\tuucp %s!%s %s (%s)\n",
  189.              othersys, arg1, arg2, arg3);
  190.         break;
  191.  
  192.         default:
  193.         printf("Bad command in %s: %s\n", cmdfile, cmdline);
  194.       }
  195.     }
  196.     (void) fclose(fp);
  197.  
  198.     if (*xfile == '\0')  /* uucp transfer or error */
  199.       continue;
  200.  
  201.     (void) sprintf(fullxfile, "D.%sX/%s", our_name, xfile);
  202.     if ( (fp = fopen(fullxfile, "r")) == NULL) {
  203.       fprintf(stderr, "cannot open %s\n", xfile);
  204.       continue;
  205.     }
  206.  
  207.     while (fgets(cmdline, sizeof cmdline, fp)) {
  208.       (void) sscanf(cmdline, "%s %s %s", cmd, arg1, arg2);
  209.       strip_newline(cmdline);
  210.  
  211.       switch (*cmd) {
  212.         case 'U':
  213.         (void) sprintf(from, "%s!%s", arg2, arg1);
  214.         break;
  215.         case 'F': case 'I': case 'Z': case 'N':
  216.         break;
  217.         case 'C':
  218.         if (strcmp(arg1, "rmail") == 0) {
  219.           FILE *fp1 = fopen(dfile, "r");
  220.  
  221.           (void) fgets(cmdline, sizeof cmdline, fp1);
  222.           (void) sscanf(cmdline, "%s %s", temp, from);
  223.           printf("%d\t%s %s!%s (%s)\n",
  224.                file_size(dfile), arg1, othersys, arg2, from);
  225.           if (verbose)
  226.             grep("Subject:", fp1);
  227.           (void) fclose(fp1);
  228.         } else if (strcmp(arg1, "rnews") == 0) {
  229.           FILE *fp1 = fopen(dfile, "r");
  230.  
  231.           printf("%d\t%s %s (%s)\n",
  232.                file_size(dfile), arg1, othersys, from);
  233.           if (verbose) {
  234.             grep("Newsgroups:", fp1);
  235.             grep("Subject:", fp1);
  236.           }
  237.           (void) fclose(fp1);
  238.         } else
  239.           printf("%d\t%s [%s %s] (%s)\n", file_size(dfile),
  240.              cmdline, othersys, dfile, from);
  241.         break;
  242.         default:
  243.         printf("Unknown cmd in %s: %s\n", xfile, cmdline);
  244.       }
  245.     }
  246.     (void) fclose(fp);
  247.   }
  248.   closedir(dirp);
  249. }
  250.  
  251. incoming() {
  252.   DIR *dirp;
  253.   struct direct *dp;
  254.   FILE *fp;
  255.   char othersys[10], job[5];
  256.   char cmdline[256], cmd[256], arg1[256], arg2[256];
  257.   char temp[50], dfile[50], from[50], *comment;
  258.  
  259.   if ( (dirp = opendir("X.")) == NULL)
  260.     die("cannot open X. directory");
  261.  
  262.   while ( (dp = readdir(dirp)) != NULL) {
  263.     if ( !parse_filename(dp, othersys, job))
  264.       continue;
  265.  
  266.     if ( (fp = fopen(sprintf(temp, "X./%s", cmdfile), "r")) == NULL) {
  267.       fprintf(stderr, "cannot open %s\n", cmdfile);
  268.       continue;
  269.     }
  270.  
  271.     while (fgets(cmdline, sizeof cmdline, fp)) {
  272.       (void) sscanf(cmdline, "%s %s %s", cmd, arg1, arg2);
  273.       strip_newline(cmdline);
  274.  
  275.       switch (*cmd) {
  276.         case 'U':
  277.         (void) sprintf(from, "%s!%s", arg2, arg1);
  278.         break;
  279.         case 'Z': case 'N': case 'R': case 'I':
  280.         break;
  281.         case 'F':
  282.         comment = "";
  283.         if (test(sprintf(dfile, "D./%s", arg1)))
  284.           ;
  285.         else if (test(sprintf(dfile, "D.%s/%s", our_name, arg1)))
  286.           ;
  287.         else if (test(sprintf(dfile, "XTMP/%s", arg2)))
  288.           comment = "[EXECUTING]";
  289.         else
  290.           *dfile = '\0'; /* should cause us to give up */
  291.         break;
  292.  
  293.         case 'C':
  294.         if (strcmp(arg1, "rmail") == 0) {
  295.           FILE *fp1 = fopen(dfile, "r");
  296.  
  297.           (void) fgets(cmdline, sizeof cmdline, fp1);
  298.           strip_newline(cmdline);
  299.           (void) sscanf(cmdline, "%s %s", arg1, from);
  300.           printf("%d\t%s %s (%s)\n",
  301.                file_size(dfile), cmdline, comment, from);
  302.           if (verbose)
  303.             grep("^Subject:", fp1);
  304.           (void) fclose(fp1);
  305.         } else
  306.           printf("%d\t%s %s (%s)\n", file_size(dfile),
  307.              cmdline, comment, from);
  308.         break;
  309.         default:
  310.         printf("Bad cmd in %s: %s\n", cmdfile, cmdline);
  311.         break;
  312.       }
  313.     }
  314.     (void) fclose(fp);
  315.   }
  316.   closedir(dirp);
  317. }
  318.  
  319. /*
  320.  * Return true if s2 is a substring of s1.
  321.  */
  322.  
  323. substring(s1, s2)
  324. char *s1, *s2;
  325. {
  326.   return strcmpn(s1, s2, strlen(s2)) == 0;
  327. }
  328.  
  329. grep(pattern, fp)
  330. char *pattern;
  331. FILE *fp;
  332. {
  333.   char line[256];
  334.  
  335.   rewind(fp);
  336.   while (fgets(line, sizeof line, fp))
  337.     if (substring(line, pattern)) {
  338.       printf("\t%s", line);  /* already has a newline at end */
  339.       break;
  340.     }
  341. }
  342.  
  343. test(file)
  344. char *file;
  345. {
  346.   struct stat st;
  347.  
  348.   return stat(file, &st) >= 0;
  349. }
  350.  
  351. file_size(file)
  352. char *file;
  353. {
  354.   struct stat st;
  355.  
  356.   return stat(file, &st) >= 0 ? st.st_size : 0;
  357. }
  358.  
  359. /*
  360.  * Format of file is [CX].<system>gnnnn,
  361.  * parse into othersys, grade and job
  362.  *
  363.  * Return zero if name is bad, or if it doesn't match the
  364.  * system we are restricting attention to.
  365.  */
  366.  
  367. parse_filename(dp, othersys, job)
  368. struct direct *dp;
  369. char *othersys, *job;
  370. {
  371.   if (dp->d_namlen <= 7)
  372.     return 0;
  373.  
  374.   (void) strcpy(othersys, cmdfile + 2);
  375.   othersys[dp->d_namlen - 7] = '\0';
  376.   (void) strcpy(job, cmdfile + dp->d_namlen - 4);
  377.  
  378.   /*
  379.    * If sys is set, skip commands for other systems.
  380.    */
  381.    return !sys || strcmp(othersys, sys) == 0;
  382. }
  383.  
  384. strip_newline(s)
  385. char *s;
  386. {
  387.   int len = strlen(s) - 1;
  388.  
  389.   if (s[len] == '\n')
  390.     s[len] = '\0';
  391. }
  392. //E*O*F uuque.c//
  393.  
  394. exit 0
  395. - - -- 
  396. /|/~\~~\    The entire world             Warren Burstein
  397.  |__/__/_/  is a very strange carrot.
  398.  |          But the farmer               philabs!tg!pluto!warren
  399. /           is not afraid at all.        Why doesn't life come with subtitles?
  400.