home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / CMDS / uustat.t.Z / uustat.t / uustat.c < prev    next >
Text File  |  2009-11-06  |  13KB  |  577 lines

  1. /*
  2.  * This program tries to emulate the Unix (tm) System V program 'uustat' under
  3.  * the OS-9 operating system. Uustat can display the status of previously
  4.  * issued uucp commands.
  5.  *
  6.  * This code is Copyright (C) 1989 by Helge Oldach, Hamburg, West Germany.
  7.  * It is not derived from licensed software.
  8.  *
  9.  * Permission is granted to anyone to use this software for any purpose on any
  10.  * computer system, and to redistribute it freely, subject to the following
  11.  * restrictions:
  12.  *
  13.  * 1. The author is not responsible for the consequences of use of this
  14.  *    software, no matter how awful, even if they arise from defects in it.
  15.  *
  16.  * 2. The origin of this software must not be misrepresented, either by
  17.  *    explicit claim or by omission.
  18.  *
  19.  * 3. Altered versions must be plainly marked as such, and must not be
  20.  *    misrepresented as being the original software.
  21.  *
  22.  * 4. Incorporation of this software into commercial products is permitted
  23.  *    only with the written permission of the author.
  24.  *
  25.  * If changes are made to the original software, the author would appreciate
  26.  * to receive a notice about the changes made. Please send a note to:
  27.  *
  28.  *    Address:            Electronic mail:
  29.  *    Helge Oldach            he@sephh.uucp (Sub-Net)
  30.  *    Maretstrasse 53            ..!unido!stollco!sup!he
  31.  *    D-2100 Hamburg 90
  32.  *
  33.  * Version history:
  34.  *
  35.  *    890822    initial release
  36.  *    900102    time->tm_mon is based to 0 (0 == January)
  37.  *    900115    system named does not contain processing order in X. file
  38.  */
  39.  
  40. char copyright[] = "Copyright (C) 1989 by Helge Oldach, Hamburg, West Germany";
  41.  
  42. #include <stdio.h>
  43. #include <ctype.h>
  44. #include <dir.h>
  45. #include <info.h>
  46. #include <pwd.h>
  47. #include <time.h>
  48. #include <stat.h>
  49.  
  50. #ifdef DEBUG
  51. #define DBG(level, routine, command) { \
  52.     if (debug >= level) { \
  53.         fprintf(stderr, "--- %s: ", routine); \
  54.         command; \
  55.         fprintf(stderr, "\n"); \
  56.     } \
  57. }
  58.  
  59. #else
  60. #define DBG(level, routine, command)
  61. #endif
  62.  
  63. int debug = 0, myuid, verbose = 0;
  64.  
  65. usage(str)
  66. char *str;
  67. {
  68.     fprintf(stderr, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
  69.         "Syntax: ",
  70.         _prgname(),
  71.         " [<opts>]\n",
  72.         "Function: uucp status inquiry and job control\n",
  73.         "Options:\n",
  74.         "     -k                kill all uucp requests\n",
  75.         "     -k[=]<jobid>      kill uucp request <jobid>\n",
  76.         "     -r                rejuvenate all uucp requests\n",
  77.         "     -r[=]<jobid>      rejuvenate uucp request <jobid>\n",
  78.         "     -s[=]<system>     display status for <system>\n",
  79.         "     -u[=]<user>       report requests issued by <user>\n",
  80.         "     -v                verbose mode (with -k or -r)\n",
  81. #ifdef DEBUG
  82.         "     -x[=]<num>        debug level <num>\n",
  83. #else
  84.         "",
  85. #endif
  86.         "     -?                display this help\n");
  87.     if (str != NULL)
  88.         fprintf(stderr, "%s: %s\n", _prgname(), str);
  89.     exit(0);
  90. }
  91.  
  92. getstring(to, from)
  93. char **to, **from;
  94. {
  95.     if (**from == '=')
  96.         ++*from;
  97.     if (*to != NULL)
  98.         usage("duplicate option");
  99.     else
  100.         *to = *from;
  101.     while (**from)
  102.         ++*from;
  103. }
  104.  
  105. getint(str)
  106. char **str;
  107. {
  108.     int num;
  109.  
  110.     if (isdigit(**str))
  111.         ;
  112.     else if ((**str == '+' || **str == '-' ) && isdigit((*str)[1]))
  113.         ;
  114.     else
  115.         usage("invalid integer");
  116.     num = atoi(*str);
  117.     if (**str == '+' || **str == '-')
  118.         ++*str;
  119.     while (isdigit(**str))
  120.         ++*str;
  121.     return num;
  122. }
  123.  
  124. checkuid(user, mode, jobid)
  125. char *user, *mode, *jobid;
  126. {
  127.     static char prev[MAXNAMLEN] = "";
  128.     static int stat = 0;
  129.     struct passwd *pw;
  130.  
  131.     if (myuid == 0)
  132.         return !0;
  133.  
  134.     if (user == NULL || strcmp(prev, user) == 0) {
  135.         if (user == NULL && stat == 0)
  136.             fprintf(stderr, "%s: wrong user ID to %s %s\n",
  137.                 _prgname(), mode, jobid);
  138.     } else if (*user == '\0')
  139.         stat = 0;
  140.     else {
  141.         DBG(2, "checkuid", fprintf(stderr, "\"%s\"", user))
  142.         strcpy(prev, user);
  143.         if (setpwent() != 0 || (pw = getpwnam(user)) == NULL) {
  144.             fprintf(stderr, "%s: cannot find user ID %s\n",
  145.                 _prgname(), user);
  146.             stat = 0;
  147.         } else
  148.             stat = myuid == (pw->pw_gid << 16) + pw->pw_uid;
  149.         endpwent();
  150.     }
  151.     DBG(2, "checkuid", fprintf(stderr, "%d", stat))
  152.     return stat;
  153. }
  154.  
  155. touch(file, cmd, xmit, rcv, who)
  156. char *file, *cmd, *xmit, *rcv, *who;
  157. {
  158.     FILE *fp;
  159.  
  160.     DBG(2, "touch", fprintf(stderr, "\"%s\"", xmit))
  161.     if (!checkuid(who, "rejuvenate", &xmit[2]))
  162.         return;
  163.  
  164.     if ((fp = fopen(xmit, "a+")) == NULL) {
  165.         fprintf(stderr, "%s: cannot touch %s\n", _prgname(), xmit);
  166.         return;
  167.     }
  168.     fclose(fp);
  169.     if (verbose && who == NULL)
  170.         fprintf(stderr, "%s: %s rejuvenated\n", _prgname(), &xmit[2]);
  171. }
  172.  
  173. delete(file, cmd, xmit, rcv, who)
  174. char *file, *cmd, *xmit, *rcv, *who;
  175. {
  176.     DBG(2, "delete", fprintf(stderr, "\"%s\"", xmit))
  177.     if (!checkuid(who, "kill", &xmit[2]))
  178.         return;
  179.  
  180.     if (unlink(xmit) != 0)
  181.         fprintf(stderr, "%s: cannot delete %s\n", _prgname(), xmit);
  182.     if (verbose && who == NULL)
  183.         fprintf(stderr, "%s: %s killed\n", _prgname(), &xmit[2]);
  184. }
  185.  
  186. scantime(file)
  187. char *file;
  188. {
  189.     struct stat sbuf;
  190.     struct tm *time;
  191.  
  192.     if (stat(file, &sbuf) == -1) {
  193.         fprintf(stderr, "%s: cannot stat %s\n", _prgname(), file);
  194.         sbuf.st_atime = 0;
  195.     }
  196.     time = localtime(&sbuf.st_atime);
  197.     ++time->tm_mon;
  198.     DBG(1, "scantime", fprintf(stderr, "%02d/%02d/%02d %02d:%02d",
  199.         time->tm_year, time->tm_mon, time->tm_mday,
  200.         time->tm_hour, time->tm_min))
  201.     printf("%02d/%02d/%02d-%02d:%02d  ", time->tm_year, time->tm_mon,
  202.         time->tm_mday, time->tm_hour, time->tm_min);
  203. }
  204.  
  205. scansize(file)
  206. char *file;
  207. {
  208.     struct stat sbuf;
  209.  
  210.     if (stat(file, &sbuf) == -1)
  211.         fprintf(stderr, "%s: cannot stat %s\n", _prgname(), file);
  212.     else
  213.         printf("%ld  %s", sbuf.st_size, file);
  214. }
  215.  
  216. char *scanuser(file)
  217. char *file;
  218. {
  219.     static char user[MAXNAMLEN] = "";
  220.     FILE *fp;
  221.     char line[BUFSIZ];
  222.     int first = 0;
  223.  
  224.     strcpy(user, "<unknown>");
  225.     if ((fp = fopen(file, "r")) == NULL) {
  226.         fprintf(stderr, "%s: cannot open %s\n", _prgname(), file);
  227.         return user;
  228.     }
  229.     DBG(1, "scanuser", fprintf(stderr, "\"%s\"", file))
  230.  
  231.     while (fgets(line, sizeof line, fp) != NULL) {
  232.         register char *p;
  233.  
  234.         for (p = line; *p != '\n'; ++p)
  235.             ;
  236.         *p = '\0';
  237.         if (line[0] != 'U' || line[1] != ' ')
  238.             continue;
  239.  
  240.         for (p = &line[2]; isascii(*p) && isprint(*p) && *p != ' '; ++p)
  241.             ;
  242.         *p = '\0';
  243.         DBG(3, "scanuser", fprintf(stderr, "user: |%s|", &line[2]))
  244.         strcpy(user, &line[2]);
  245.         ++first;
  246.         break;
  247.     }
  248.  
  249.     DBG(2, "scanuser", fprintf(stderr, "EOF"))
  250.     fclose(fp);
  251.     if (!first)
  252.         fprintf(stderr, "%s: no remote user in %s\n", _prgname(),
  253.             file);
  254.     return user;
  255. }
  256.  
  257. scancmd(file)
  258. char *file;
  259. {
  260.     FILE *fp;
  261.     char line[BUFSIZ];
  262.     int first = 0;
  263.  
  264.     if ((fp = fopen(file, "r")) == NULL) {
  265.         fprintf(stderr, "%s: cannot open %s\n", _prgname(), file);
  266.         return;
  267.     }
  268.     DBG(1, "scancmd", fprintf(stderr, "\"%s\"", file))
  269.  
  270.     while (fgets(line, sizeof line, fp) != NULL) {
  271.         register char *p;
  272.  
  273.         for (p = line; *p != '\n'; ++p)
  274.             ;
  275.         *p = '\0';
  276.         if (line[0] == 'C' && line[1] == ' ') {
  277.             if (first++)
  278.                 printf("; ");
  279.             printf(&line[2]);
  280.         }
  281.     }
  282.     if (!first)
  283.         fprintf(stderr, "%s: no remote command in %s\n", _prgname(),
  284.             file);
  285.  
  286.     DBG(2, "scancmd", fprintf(stderr, "EOF"))
  287.     fclose(fp);
  288. }
  289.  
  290. display(file, cmd, xmit, rcv, who, user, system)
  291. char *file, *cmd, *xmit, *rcv, *who, *user, *system;
  292. {
  293.     static char save[MAXNAMLEN];
  294.     register char *p;
  295.  
  296.     DBG(3, "display", fprintf(stderr,
  297.         "file=|%s| cmd=|%s| xmit=|%s| rcv=|%s| who=|%s| user=|%s| system=|%s|",
  298.         file == NULL ? "<NULL>" : file,
  299.         cmd == NULL ? "<NULL>" : cmd,
  300.         xmit == NULL ? "<NULL>" : xmit,
  301.         rcv == NULL ? "<NULL>" : rcv,
  302.         who == NULL ? "<NULL>" : who,
  303.         user == NULL ? "<NULL>" : user,
  304.         system == NULL ? "<NULL>" : system))
  305.  
  306.     if (cmd == NULL)
  307.         return;
  308.     if (*cmd == 'X')
  309.         who = scanuser(xmit);
  310.     if (user != NULL && strcmp(who, user) != 0)
  311.         return;
  312.     if (system != NULL && strncmp(&file[2], system, strlen(system)) != 0)
  313.         return;
  314.  
  315.     if (strcmp(save, file) == 0) {
  316.         for (p = save; *p != '\0'; ++p)
  317.             *p = ' ';
  318.         printf("%s  ", &save[2]);
  319.     } else
  320.         printf("%s  ", &file[2]);
  321.     scantime(xmit);
  322.     printf("%s  ",  cmd);
  323.     strcpy(save, &file[2]);
  324.     save[strlen(save) - (*cmd == 'S' ? 4 : 5)] = '\0';
  325.     printf("%s  ", save);
  326.     printf("%s  ", who);
  327.     switch (*rcv) {
  328.         case 'D':
  329.             scansize(xmit);
  330.             break;
  331.         case 'X':
  332.             scancmd(xmit);
  333.             break;
  334.         default:
  335.             fprintf(stderr,
  336.                 "%s: unknown remote file type %s in %s\n",
  337.                 _prgname(), *xmit, file);
  338.             break;
  339.     }
  340.     printf("\n");
  341.     strcpy(save, file);
  342.     DBG(2, "display", fprintf(stderr, "return"))
  343. }
  344.  
  345. scanline(file, line, funct, user, system)
  346. char *file, *line;
  347. int (*funct)();
  348. char *user, *system;
  349. {
  350.     char *p, *t, *cmd = NULL, *xmit = NULL, *rcv = NULL, *who = NULL;
  351.  
  352.     DBG(2, "scanline", fprintf(stderr, "|%s|", line))
  353.  
  354.     p = line;
  355.     if (p[0] == 'S' && p[1] == ' ') {
  356.         cmd = p;
  357.         *++p= '\0';
  358.         ++p;
  359.     }
  360.     DBG(3, "scanline", fprintf(stderr, "cmd: |%s|", cmd))
  361.  
  362.     for (t = p; isascii(*t) && (isalnum(*t) || *t == '.'); ++t)
  363.         ;
  364.     if (t > p && *t == ' ') {
  365.         xmit = p;
  366.         p = t;
  367.         *p++ = '\0';
  368.     }
  369.     DBG(3, "scanline", fprintf(stderr, "xmit: |%s|", xmit))
  370.  
  371.     for (t = p; isascii(*t) && (isalnum(*t) || *t == '.'); ++t)
  372.         ;
  373.     if (t > p && *t == ' ') {
  374.         rcv = p;
  375.         p = t;
  376.         *p++ = '\0';
  377.     }
  378.     DBG(3, "scanline", fprintf(stderr, "rcv: |%s|", rcv))
  379.  
  380.     for (t = p; isascii(*t) && (isalnum(*t) || *t == '.'); ++t)
  381.         ;
  382.     if (t > p && *t == ' ') {
  383.         who = p;
  384.         p = t;
  385.         *p++ = '\0';
  386.     }
  387.     DBG(3, "scanline", fprintf(stderr, "who |%s|", who))
  388.  
  389.     if (cmd == NULL || xmit == NULL || rcv == NULL || who == NULL)
  390.         fprintf(stderr, "%s: unrecognized syntax in %s\n", file);
  391.     else
  392.         (*funct)(file, cmd, xmit, rcv, who, user, system);
  393.     DBG(2, "scanline", fprintf(stderr, "return"))
  394. }
  395.  
  396. scanxline(file, line, funct, user, system)
  397. char *file, *line;
  398. int (*funct)();
  399. char *user, *system;
  400. {
  401.     char *p, *t;
  402.  
  403.     DBG(2, "scanxline", fprintf(stderr, "|%s|", line))
  404.     if (*line != 'F')
  405.         return;
  406.  
  407.     p = line;
  408.     if (p[0] == 'F' && p[1] == ' ') {
  409.         *++p = '\0';
  410.         ++p;
  411.     }
  412.     DBG(3, "scanxline", fprintf(stderr, "cmd: |%s|", line))
  413.  
  414.     for (t = p; isascii(*t) && (isalnum(*t) || *t == '.'); ++t)
  415.         ;
  416.     if (t > p)
  417.         *t++ = '\0';
  418.     DBG(3, "scanxline", fprintf(stderr, "xmit: |%s|", p))
  419.     if (t > p)
  420.         (*funct)(NULL, NULL, p, NULL, "", user, system);
  421.     else
  422.         fprintf(stderr, "%s: unrecognized syntax in %s\n", file);
  423. }
  424.  
  425. scanfile(file, funct, user, system)
  426. char *file;
  427. int (*funct)();
  428. char *user, *system;
  429. {
  430.     FILE *fp;
  431.     char line[BUFSIZ];
  432.     register char *p;
  433.  
  434.     if ((fp = fopen(file, "r")) == NULL) {
  435.         fprintf(stderr, "%s: cannot open %s\n", _prgname(), file);
  436.         return;
  437.     }
  438.     DBG(1, "scanfile", fprintf(stderr, "\"%s\"", file))
  439.  
  440.     while (fgets(line, sizeof line, fp) != NULL) {
  441.         for (p = line; *p != '\n'; ++p)
  442.             ;
  443.         *p = '\0';
  444.         if (*file == 'C')
  445.             scanline(file, line, funct, user, system);
  446.         else
  447.             scanxline(file, line, funct, user, system);
  448.         DBG(2, "scanfile", fprintf(stderr, "next line"))
  449.     }
  450.  
  451.     DBG(2, "scanfile", fprintf(stderr, "EOF"))
  452.     fclose(fp);
  453.     if (*file == 'C')
  454.         (*funct)(NULL, NULL, file, NULL, NULL, user, system);
  455.     else
  456.         (*funct)(file, "X", file, file, NULL, user, system);
  457. }
  458.  
  459. scandir(jobid, funct, user, system)
  460. char *jobid;
  461. int (*funct)();
  462. char *user, *system;
  463. {
  464.     DIR *dp;
  465.     struct direct *dir;
  466.     int done = 0;
  467.  
  468.     if (info_is_locked("lck.uucp"))
  469.         fprintf(stderr, "%s: warning\007: uucp is possibly active\n",
  470.             _prgname());
  471.  
  472.     if ((dp = opendir(".")) == NULL) {
  473.         fprintf(stderr, "%s: cannot open uucp spool directory\n",
  474.             _prgname());
  475.         return;
  476.     }
  477.  
  478.     while ((dir = readdir(dp)) != NULL) {
  479.         DBG(1, "scandir", fprintf(stderr, "\"%s\"", dir->d_name))
  480.         if ((dir->d_name[0] == 'C' || dir->d_name[0] == 'X') &&
  481.             dir->d_name[1] == '.' &&
  482.             (jobid == NULL ||
  483.             *jobid == '\0' ||
  484.             strcmp(jobid, &dir->d_name[2]) == 0)) {
  485.             scanfile(dir->d_name, funct, user, system);
  486.             ++done;
  487.         }
  488.     }
  489.  
  490.     closedir(dp);
  491.     if (done == 0 && jobid != NULL)
  492.         fprintf(stderr, "%s: cannot access job ID %s\n", _prgname(),
  493.             jobid);
  494. }
  495.  
  496. main(argc, argv)
  497. int argc;
  498. char *argv[];
  499. {
  500.     register i;
  501.     char *kill = NULL, *rejuv = NULL, *system = NULL, *user = NULL;
  502.     struct passwd *pw;
  503.     static char uucpdir[BUFSIZ] = "";
  504.  
  505.     myuid = getuid();
  506.  
  507.     if (setpwent() != 0 ||
  508.         (pw = getpwnam("uucp")) == NULL ||
  509.         setuid((pw->pw_gid << 16) + pw->pw_uid) == -1)
  510.         fprintf(stderr, "%s: cannot set user ID to uucp\n",
  511.             _prgname());
  512.     endpwent();
  513.  
  514.     if (info_str("UUCP.SPOOL", uucpdir, sizeof uucpdir) == NULL)
  515.         strcpy(uucpdir, "/h0/SPOOL/UUCP");
  516.     if (chdir(uucpdir) != 0) {
  517.         fprintf(stderr, "%s: cannot chdir to uucp spool directory\n",
  518.             _prgname());
  519.         exit(0);
  520.     }
  521.  
  522.     for (i = 1; i < argc; ++i)
  523.         if (*argv[i] == '-') {
  524.             ++argv[i];
  525.             do {
  526.                 switch (tolower(*argv[i])) {
  527.                     case 'k':
  528.                         ++argv[i];
  529.                         getstring(&kill, &argv[i]);
  530.                         break;
  531.                     case 'r':
  532.                         ++argv[i];
  533.                         getstring(&rejuv, &argv[i]);
  534.                         break;
  535.                     case 'u':
  536.                         ++argv[i];
  537.                         getstring(&user, &argv[i]);
  538.                         break;
  539.                     case 's':
  540.                         ++argv[i];
  541.                         getstring(&system, &argv[i]);
  542.                         break;
  543.                     case 'v':
  544.                         ++argv[i];
  545.                         ++verbose;
  546.                         break;
  547.                     case 'x':
  548.                         if (*++argv[i] == '=')
  549.                             ++argv[i];
  550.                         debug = getint(&argv[i]);
  551.                         break;
  552.                     default:
  553.                         usage(NULL);
  554.                         break;
  555.                 }
  556.             } while (*argv[i]);
  557.         } else
  558.             usage("no arguments allowed");
  559.  
  560.     if (kill != NULL && rejuv != NULL)
  561.         fprintf(stderr, "%s: conflicting options\n", _prgname());
  562.     else if (kill == NULL && rejuv == NULL)
  563.         scandir(NULL, display, user, system);
  564.     else {
  565.         if (system != NULL || user != NULL)
  566.             fprintf(stderr, "%s: %s%s%s option%s ignored\n",
  567.                 _prgname(), user != NULL ? "-u " : "",
  568.                 user != NULL && system != NULL ? "and " : "",
  569.                 system != NULL ? "-s " : "",
  570.                 user != NULL && system != NULL ? "s" : "");
  571.         if (kill != NULL)
  572.             scandir(kill, delete);
  573.         if (rejuv != NULL)
  574.             scandir(rejuv, touch);
  575.     }
  576. }
  577.