home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / uucp / duucp-1.17 / AU-117b4-src.lha / src / uucico / uustat.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-24  |  18.4 KB  |  962 lines

  1. /*
  2.  * UUSTAT.C
  3.  *
  4.  * Copyright (c) 1993 Ville Saari, All rights reserved.
  5.  * Changes copyright 1993 by Michael B. Smith. All rights reserved.
  6.  *
  7.  * Created: 14-Sep-93 and updated 29-Oct-93 by Ville Saari
  8.  *
  9.  * CAVEAT: Ville's version was pure by default. Adding in the AmigaUUCP
  10.  *       stuff means you have to do through the DICE/SAS-C special linking
  11.  *       process to get pure back again.
  12.  */
  13.  
  14. /*#define PROCDEBUG*/
  15.  
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <stdarg.h>
  20.  
  21. #include <utility/tagitem.h>
  22. #include <exec/memory.h>
  23. #include <dos/exall.h>
  24. #include <dos/datetime.h>
  25.  
  26. #include <clib/dos_protos.h>
  27. #include <clib/exec_protos.h>
  28. #include <pragmas/dos_pragmas.h>
  29. #include <pragmas/exec_pragmas.h>
  30.  
  31. #include "config.h"
  32. #include "version.h"
  33.  
  34. IDENT (".02");
  35.  
  36. #ifdef PROCDEBUG
  37. #define DG(x)    Printf x
  38. #else
  39. #define DG(x)
  40. #endif
  41.  
  42. #define VERSION "000"
  43. #define RELEASE "2"
  44. #define UNAME "UUSTAT"
  45. #define NAME "uustat"
  46.  
  47. #define COPYRSIGN "\251"
  48. #define CSI(command) "\233" command
  49.  
  50. #define COPYRIGHT \
  51.     CSI("32;1m") UNAME CSI("0m")" V" RELEASE "." VERSION "\n"\
  52.     "Copyright " COPYRSIGN " 1993 Ville Saari, All rights reserved\n"\
  53.     "Copyright " COPYRSIGN " 1993 Michael B. Smith, All rights reserved\n"
  54.  
  55. #define USAGE \
  56.     COPYRIGHT \
  57.     "\n" \
  58.     "Usage: " NAME " [<options>]\n\n"\
  59.     "Options: -a = ALL              list all UUCP jobs\n"\
  60.     "\t -c = COMMAND <cmd>    list requests for named command\n"\
  61.     "\t _C = NCOMMAND <cmd>   list requests for other than named command\n"\
  62.     "\t -e = EXECUTIONS       list queued executions rather than job requests\n"\
  63.     "\t -i = KILLPROMPT       prompt for whether to kill each listed job\n"\
  64.     "\t -k = KILL <job>       kill specified UUCP job\n"\
  65.     "\t _K = KILLLISTED       kill each listed job\n"\
  66.     "\t -m = MACHINES         report status for all remote machines\n"\
  67.     "\t -o = OLDER <hours>    list all jobs older than given number of hours\n"\
  68.     "\t -q = NUMBER           list number of jobs for each system\n"\
  69.     "\t _Q = QUIET            don't list jobs, just take actions (-i, _K)\n"\
  70.     "\t -r = REJUVENATE <job> rejuvenate specified UUCP job\n"\
  71.     "\t -s = SYSTEM <system>  list all jobs for specified system\n"\
  72.     "\t _S = NSYSTEM <system> list all jobs for other than specified system\n"\
  73.     "\t -u = USER <user>      list all jobs for specified user\n"\
  74.     "\t _U = NUSER <user>     list all jobs for other than specified user\n"\
  75.     "\t -y = YOUNGER <hours>  list all jobs younger than given number of hours\n"
  76.  
  77. #define TEMPLATE \
  78.     "-a=ALL/S,-c=COMMAND/K,_C=NCOMMAND/K,-e=EXECUTIONS/S,-i=KILLPROMPT/S,"\
  79.     "-k=KILL/K,_K=KILLLISTED/S,-m=MACHINES/S,-o=OLDER/N,-q=NUMBER/S,"\
  80.     "_Q=QUIET/S,-r=REJUVENATE/K,-s=SYSTEM/K,_S=NSYSTEM/K,-u=USER/K,"\
  81.     "_U=NUSER/K,-y=YOUNGER/N"
  82.  
  83. static const char
  84.     version [] = "\0$VER: " NAME " " RELEASE "." VERSION " (" __DATE__ ")";
  85.  
  86. struct machine {
  87.     struct machine *next;
  88.     unsigned long commands;
  89.     unsigned long executions;
  90.     long oldestcmd;
  91.     long oldestexe;
  92.     char *message;
  93.     char name [1];
  94. };
  95.  
  96. struct arguments {
  97.     /* this order is dependent on TEMPLATE above */
  98.     long all;
  99.     char *command;
  100.     char *ncommand;
  101.     long executions;
  102.     long killprompt;
  103.     char *kill;
  104.     long killlisted;
  105.     long machines;
  106.     long *older;
  107.     long number;
  108.     long quiet;
  109.     char *rejuvenate;
  110.     char *system;
  111.     char *nsystem;
  112.     char *user;
  113.     char *nuser;
  114.     char *younger;
  115. };
  116.  
  117. /* My few Globals */
  118. extern struct DosLibrary
  119.     *DOSBase;
  120. extern struct ExecBase
  121.     *SysBase;
  122.  
  123. char
  124.     *name = NULL;
  125. int
  126.     UseSubDirs = 0;
  127. /* End globals */
  128.  
  129. char *token (char **);
  130. void linecpy (char *, char *);
  131. int kill (char *);
  132. int spc (char);
  133. void SPrintf (char *, char *, ...);
  134. void agetos (long, char *);
  135. void updatemachine (char *, char *, unsigned long, unsigned long,
  136.     struct machine **base);
  137. void process_logfile (struct arguments *args, struct machine **mbase);
  138. void process_file (struct ExAllData *, struct arguments *s, unsigned long,
  139.            struct DateStamp *, struct machine **);
  140. void scan_spool (struct arguments *args, unsigned long currenttime,
  141.          struct DateStamp *ds, struct machine **mbase);
  142.  
  143. #ifdef NULL
  144. #undef NULL
  145. #define NULL 0
  146. #endif
  147.  
  148. #ifdef __GNUC__
  149. #define __aligned
  150. #endif
  151.  
  152. int
  153. main (int argc, char **argv)
  154. {
  155.     unsigned long
  156.         rc = 20,
  157.         currenttime;
  158.     struct RDArgs
  159.         *ah;
  160.     BPTR
  161.         cd = NULL;
  162.     struct DateStamp
  163.         ds;
  164.     struct machine
  165.         *mbase = NULL;
  166.     char
  167.         *tmp;
  168.     struct arguments
  169.         args;
  170.  
  171. #if 0
  172.     SysBase = *((struct ExecBase **) 4L);
  173.  
  174.     DOSBase = (struct DosLibrary *) OpenLibrary (DOSNAME, 37);
  175.     if (!DOSBase)
  176.         return rc;
  177. #endif
  178.  
  179.     if (argc == 0)
  180.         return rc;
  181.     name = argv [0];
  182.  
  183.     if (DOSBase->dl_lib.lib_Version < 37)
  184.         return rc;
  185.  
  186.     memset ((void *) &args, 0, sizeof (args));
  187.     ah = ReadArgs (TEMPLATE, (long *) &args, 0);
  188.     if (!ah) {
  189.         PutStr (USAGE);
  190.         goto cleanup;
  191.     }
  192.  
  193.     if (!args.all && !args.command && !args.ncommand && !args.system &&
  194.         !args.nsystem && !args.user && !args.nuser) {
  195.         if (args.executions)
  196.             args.all = 1;
  197.         else {
  198.             args.user = GetUserName ();
  199.             if (!args.user) {
  200.                 Printf ("%s: Cannot find UserName\n", name);
  201.                 goto cleanup;
  202.             }
  203.         }
  204.     }
  205.  
  206.     tmp = GetConfig (USESUBDIRS, "0");
  207.     if (*tmp == 'y' || *tmp == 'Y' || *tmp == '1')
  208.         UseSubDirs = 1;
  209.  
  210.     if (!args.system && !args.nsystem)
  211.         args.all = -1;
  212.  
  213.     cd = Lock ("UUSpool:", ACCESS_READ);
  214.     if (!cd) {
  215.         Printf ("%s: Cannot lock UUSpool:\n", name);
  216.         goto cleanup;
  217.     }
  218.     cd = CurrentDir (cd);
  219.  
  220.     DateStamp (&ds);
  221.     currenttime =
  222.         ds.ds_Days * 86400 +
  223.         ds.ds_Minute * 60 +
  224.         ds.ds_Tick / 50;
  225.  
  226.     if (args.kill) {
  227.         char
  228.             namebuf [15];
  229.  
  230.         namebuf [0] = 'C';
  231.         namebuf [1] = '.';
  232.         strncpy (namebuf + 2, args.kill, 12);
  233.         namebuf [14] = 0;
  234.  
  235.         if (kill (namebuf))
  236.             rc = 0;
  237.     }
  238.     else
  239.     if (args.rejuvenate) {
  240.         char
  241.             filename [256];
  242.  
  243.         SPrintf (filename, "UUSPOOL:C.%s", args.rejuvenate);
  244.  
  245.         if (!SetFileDate (filename, &ds))
  246.             Printf ("%s: Job %s doesn't exist.\n", name, args.rejuvenate);
  247.     }
  248.     else {
  249.         process_logfile (&args, &mbase);
  250.     }
  251.  
  252.     rc = 0;
  253.  
  254.     if (args.machines) {
  255.         struct machine
  256.             *mach;
  257.  
  258.         for (mach = mbase; mach; mach = mach->next)
  259.             if (mach->message)
  260.                 Printf ("%-14s %s\n", mach->name, mach->message);
  261.  
  262.         goto cleanup;
  263.     }
  264.  
  265.     scan_spool (&args, currenttime, &ds, &mbase);
  266.  
  267.     if (args.number) {
  268.         struct machine
  269.             *mach;
  270.         char
  271.             c_age [16],
  272.             x_age [16];
  273.  
  274.         for (mach = mbase; mach; mach = mach->next) {
  275.             if (mach->commands || mach->executions) {
  276.                 agetos (mach->oldestcmd, c_age);
  277.                 agetos (mach->oldestexe, x_age);
  278.  
  279.                 Printf ("%-9s %4luC %-10s %4luX %-10s %s\n",
  280.                     mach->name,
  281.                     mach->commands, c_age,
  282.                     mach->executions, x_age,
  283.                     mach->message ? mach->message : "");
  284.             }
  285.         }
  286.     }
  287.  
  288. cleanup:
  289.  
  290.     while (mbase) {
  291.         struct machine
  292.             *next=mbase->next;
  293.  
  294.         if (mbase->message)
  295.             FreeVec (mbase->message);
  296.         FreeVec (mbase);
  297.  
  298.         mbase = next;
  299.     }
  300.  
  301.     if (cd)
  302.         UnLock (CurrentDir (cd));
  303.     if (ah)
  304.         FreeArgs (ah);
  305.  
  306. #if 0
  307.     if (DOSBase)
  308.         CloseLibrary ((struct Library *) DOSBase);
  309. #endif
  310.  
  311.     return rc;
  312. }
  313.  
  314. void agetos (long age, char *buf)
  315. {
  316.     char
  317.         *unit;
  318.  
  319.     if (age < 0)
  320.         age = 0;
  321.  
  322.     if (age < 60)
  323.         unit = "sec";
  324.     else
  325.         if ((age /= 60) < 60)
  326.             unit = "min";
  327.         else
  328.             if ((age /= 60) < 24)
  329.                 unit = "hour";
  330.             else {
  331.                 age /= 24;
  332.                 unit = "day";
  333.             }
  334.  
  335.     SPrintf (buf, "(%ld %s%s)", age, unit, age == 1 ? "" : "s");
  336.  
  337.     return;
  338. }
  339.  
  340. int spc (char c)
  341. {
  342.     return c == ' ' || c == '\t' || c == '\n' || c == '\r';
  343. }
  344.  
  345. char *
  346. token (char **p)
  347. {
  348.     char
  349.         *q;
  350.  
  351.     while (spc (**p))
  352.         (*p)++;
  353.     q=*p;
  354.  
  355.     while (!spc (**p)) {
  356.         if (!**p)
  357.             return *p;
  358.         (*p)++;
  359.     }
  360.  
  361.     *(*p)++ = 0;
  362.  
  363.     return q;
  364. }
  365.  
  366. void
  367. linecpy (char *a, char *b)
  368. {
  369.     while (spc (*b))
  370.         b++;
  371.  
  372.     while (*b && *b != '\n' && *b != '\r')
  373.         *a++ = *b++;
  374.     *a = 0;
  375.  
  376.     return;
  377. }
  378.  
  379. void
  380. scan_dir (BPTR dir, const char *patternbuffer, struct arguments *args,
  381.       unsigned long currenttime, struct DateStamp *ds,
  382.       struct machine **mbase)
  383. {
  384.     struct ExAllControl
  385.         *eac = NULL;
  386.     struct ExAllData
  387.         *eabuf = NULL,
  388.         *ead = NULL;
  389.     int
  390.         t;
  391.  
  392.     eac = AllocDosObject (DOS_EXALLCONTROL, NULL);
  393.     eabuf = (struct ExAllData *) AllocVec (2048, MEMF_ANY);
  394.     if (!eac || !eabuf) {
  395.         Printf ("%s: scan_dir memory shortage.\n", name);
  396.         goto leave;
  397.     }
  398.  
  399.     eac->eac_LastKey = 0;
  400.     eac->eac_MatchString = patternbuffer;
  401.  
  402.     do {
  403.         t = ExAll (dir, eabuf, 2048, ED_DATE, eac);
  404.  
  405.         if (t == 0 && (IoErr () != ERROR_NO_MORE_ENTRIES))
  406.             break;
  407.  
  408.         if (eac->eac_Entries == 0)
  409.             continue;
  410.  
  411.         ead = eabuf;
  412.  
  413.         do {
  414.             process_file (ead, args, currenttime, ds, mbase);
  415.         } while (ead = ead->ed_Next);
  416.  
  417.     } while (t);
  418.  
  419. leave:
  420.     if (eabuf)
  421.         FreeVec (eabuf);
  422.     if (eac)
  423.         FreeDosObject (DOS_EXALLCONTROL, eac);
  424.  
  425.     return;
  426. }
  427.  
  428. void
  429. scan_spool (struct arguments *args, unsigned long currenttime,
  430.         struct DateStamp *ds, struct machine **mbase)
  431. {
  432.     char
  433.         pat [40],
  434.         patbuf [82],
  435.         sys [40];
  436.     BPTR
  437.         mydir;
  438.  
  439.     if (args->all)
  440.         strcpy (sys, "#?");
  441.     else
  442.         if (args->nsystem)
  443.             SPrintf (sys, "~(%.7s)", args->nsystem);
  444.         else
  445.             SPrintf (sys, "%.7s", args->system);
  446.  
  447.     SPrintf (pat, "%s.%s?????%s",
  448.         args->number ? "(C|X|E)" : args->executions ? "(X|E)" : "C", sys,
  449.         args->executions && !args->all ? "#?" : "");
  450.  
  451.     ParsePatternNoCase (pat, patbuf, sizeof (patbuf));
  452.  
  453.     /* lock on UUSpool: */
  454.     mydir = ((struct Process *) FindTask (NULL))->pr_CurrentDir;
  455.  
  456.     scan_dir (mydir, patbuf, args, currenttime, ds, mbase);
  457.  
  458.     if (UseSubDirs) {
  459.         /*
  460.         ** good bet most of the files are in a subdirectory.
  461.         ** Use good old ExNext() to find the directories, and
  462.         ** recurse into them via scan_dir()
  463.         */
  464.         BPTR
  465.             subdir,
  466.             olddir;
  467.         __aligned struct FileInfoBlock
  468.             fib;
  469.  
  470. DG(("UseSubDirs\n"));
  471.         if (Examine (mydir, &fib)) {
  472.             while (ExNext (mydir, &fib)) {
  473.                 if (fib.fib_DirEntryType < 0)
  474.                     continue;
  475. DG(("searching %s\n", fib.fib_FileName));
  476.                 subdir = Lock (fib.fib_FileName, ACCESS_READ);
  477.                 if (!subdir) {
  478.                     Printf ("%s: can't read UUSpool:%s\n",
  479.                         name, fib.fib_FileName);
  480.                     continue;
  481.                 }
  482.                 olddir = CurrentDir (subdir);
  483.                 scan_dir (subdir, patbuf, args, currenttime, ds, mbase);
  484.                 UnLock (CurrentDir (olddir));
  485.             }
  486.         }
  487.     }
  488.  
  489.     return;
  490. }
  491.  
  492. int
  493. really_kill (char *cmdfile, BPTR file)
  494. {
  495.     int
  496.         success = 1;
  497.     char
  498.         line [256];
  499.  
  500. DG (("really_kill\n"));
  501.  
  502.     while (FGets (file, line, 256)) {
  503.         char
  504.             *fromname,
  505.             *p = line;
  506.  
  507. DG(("input: %s", line));
  508.         if (*token (&p) == 'S') {
  509.             fromname = token (&p);
  510.             token (&p);
  511.             token (&p);
  512.  
  513.             if (token (&p) [1] != 'c' && !DeleteFile (fromname))
  514.                 success = 0;
  515.         }
  516.     }
  517.  
  518.     Close (file);
  519.  
  520.     if (!DeleteFile (cmdfile)) {
  521. DG(("ioerr on deletefile (%s) %ld\n", cmdfile, IoErr()));
  522.         success = 0;
  523.     }
  524.  
  525.     if (!success && strlen (cmdfile) > 2)
  526.         Printf ("%s: Can't kill job %s.\n", name, cmdfile + 2);
  527.  
  528. DG(("really_kill exit\n"));
  529.     if (success)
  530.         return 0;
  531.  
  532.     return 20;
  533. }
  534.  
  535. int
  536. process_opt (char *filename, BPTR file, int opt)
  537. {
  538.     int
  539.         result = 20;
  540.  
  541.     switch (opt) {
  542.         case 1:
  543.             result = really_kill (filename, file);
  544.             break;
  545.  
  546.         default:
  547.             Printf ("%s: internal error. help me!\n", name);
  548.     }
  549.  
  550.     return result;
  551. }
  552.  
  553. int
  554. dirhandler (char *cmdfile, int opt)
  555. {
  556.     /*
  557.     **  findfile
  558.     **
  559.     **    Given a full C.* or X.* or whatever filename, find the
  560.     **    directory or subdirectory it resides in, and open the file.
  561.     */
  562.     BPTR
  563.         olddir,
  564.         exlock,
  565.         lock;
  566.     int
  567.         result = 20;
  568.     __aligned struct FileInfoBlock
  569.         fib;
  570.  
  571.     lock = Lock ("UUSpool:", ACCESS_READ);
  572.     if (!lock)
  573.         return NULL;
  574.  
  575.     olddir = CurrentDir (lock);
  576.  
  577.     if (exlock = Open (cmdfile, MODE_OLDFILE)) {
  578.         /* was in UUSpool: */
  579.         result = process_opt (cmdfile, exlock, opt);
  580.         UnLock (CurrentDir (olddir));
  581.         return result;
  582.     }
  583.  
  584.     if (UseSubDirs == 0)
  585.         return 20;
  586.  
  587.     if (Examine (lock, &fib)) {
  588.         while (ExNext (lock, &fib)) {
  589.             BPTR
  590.                 subdir;
  591.  
  592.             if (fib.fib_DirEntryType < 0)
  593.                 continue;
  594.  
  595.             subdir = CurrentDir (lock);
  596.             exlock = Open (cmdfile, MODE_OLDFILE);
  597.             if (exlock) {
  598.                 result = process_opt (cmdfile, exlock, opt);
  599.             }
  600.             CurrentDir (subdir);
  601.             if (exlock) {
  602.                 break;
  603.             }
  604.         }
  605.     }
  606.     UnLock (CurrentDir (olddir));    /* back to original directory */
  607.     UnLock (lock);
  608.  
  609.     return result;
  610. }
  611.  
  612. int kill (char *cmdfile)
  613. {
  614.     return dirhandler (cmdfile, 1);
  615. }
  616.  
  617. void SPrintf (char *buf, char *format, ...)
  618. {
  619.  
  620. #ifdef __SASC
  621. void __builtin_emit(unsigned short);
  622. #define emit __builtin_emit
  623.  
  624.     /* _SPrintf movem.l a2/a3/a6,-(sp)   */ emit(0x48e7); emit(0x0032);
  625.     /*        move.l  (4).w,a6         */ emit(0x2c78); emit(0x0004);
  626.     /*        move.l  20(sp),a0         */ emit(0x206f); emit(0x0014);
  627.     /*        lea     24(sp),a1         */ emit(0x43ef); emit(0x0018);
  628.     /*        lea     putch(pc),a2     */ emit(0x45fa); emit(0x0010);
  629.     /*        move.l  16(sp),a3         */ emit(0x266f); emit(0x0010);
  630.     /*        jsr     _LVORawDoFmt(a6) */ emit(0x4eae); emit(0xfdf6);
  631.     /*        movem.l (sp)+,a2/a3/a6   */ emit(0x4cdf); emit(0x4c00);
  632.     /*        rts              */ emit(0x4e75);
  633.     /* putch    move.b  d0,(a3)+         */ emit(0x16c0);
  634.     /*        rts              */
  635. #endif
  636. #ifdef _DCC
  637.     extern __stkargs void
  638.         VDoFmt (char *, char *, va_list);
  639.     va_list
  640.         va;
  641.  
  642.     va_start (va, format);
  643.     VDoFmt (buf, format, va);
  644.     va_end (va);
  645.     return;
  646. #endif
  647.     }
  648.  
  649. void updatemachine (char *name, char *message, unsigned long cmdage,
  650.             unsigned long exeage, struct machine **base)
  651. {
  652.     struct machine
  653.         *mach;
  654.     int
  655.         t;
  656.  
  657.     for (mach = *base; mach; mach = mach->next)
  658.         if (!memcmp (mach->name, name, (t = strlen (mach->name), t > 7 ? 7 : t)))
  659.             break;
  660.  
  661.     if (!mach) {
  662.         if (!(mach = AllocVec (sizeof *mach + strlen (name), MEMF_CLEAR)))
  663.             return;
  664.  
  665.         strcpy (mach->name, name);
  666.         mach->next = *base;
  667.         *base = mach;
  668.     }
  669.  
  670.     if (message) {
  671.         if (mach->message)
  672.             FreeVec (mach->message);
  673.         if (mach->message = AllocVec (strlen (message) + 1, 0))
  674.             strcpy (mach->message, message);
  675.     }
  676.  
  677.     if (exeage != 0x80000000) {
  678.         mach->executions++;
  679.         if (mach->oldestexe < exeage)
  680.             mach->oldestexe = exeage;
  681.     }
  682.  
  683.     if (cmdage != 0x80000000) {
  684.         mach->commands++;
  685.         if (mach->oldestcmd < cmdage)
  686.             mach->oldestcmd = cmdage;
  687.     }
  688.  
  689.     return;
  690. }
  691.  
  692. void
  693. process_logfile (struct arguments *args, struct machine **mbase)
  694. {
  695.     int
  696.         l;
  697.     BPTR
  698.         fh;
  699.     char
  700.         msg [256],
  701.         line [256],
  702.         *p,
  703.         *t;
  704.  
  705.     if (fh = Open ("UULib:L.Sys", MODE_OLDFILE)) {
  706.         while (FGets (fh, p = line, 256))
  707.             if (*(t = token (&p)))
  708.                 updatemachine (t, 0, 0x80000000, 0x80000000, mbase);
  709.  
  710.         Close (fh);
  711.     }
  712.  
  713.     if (args->machines == 0 && args->number == 0)
  714.         return;
  715.  
  716.     fh = Open ("UUSpool:Logfile", MODE_OLDFILE);
  717.     if (!fh)
  718.         return;
  719.  
  720.     while (FGets (fh, p = line, 256)) {
  721.         token (&p);
  722.  
  723.         if (!strnicmp (t = token (&p), "uucico,", 7)) {
  724.             l = strlen (t += 7);
  725.  
  726.             if (l > 2 && t [l - 2] == ',' && t [l - 1] == '-') {
  727.                 t [l-2] = 0;
  728.  
  729.                 if (strcmp (t, "AmigaUUCP")) {
  730.                     memcpy (msg, line+1, 11);
  731.                     msg [2] = '-';
  732.                     msg [5] = msg [11] = ' ';
  733.                     while (spc (*p))
  734.                         p++;
  735.                     linecpy (msg+12, p);
  736.                     updatemachine (t, msg, 0x80000000, 0x80000000, mbase);
  737.                 }
  738.             }
  739.         }
  740.     }
  741.  
  742.     Close (fh);
  743.  
  744.     return;
  745. }
  746.  
  747. void
  748. process_file (struct ExAllData *ead, struct arguments *args,
  749.           unsigned long currenttime, struct DateStamp *ds,
  750.           struct machine **mbase)
  751. {
  752.     BPTR
  753.         mydir = ((struct Process *) FindTask (NULL))->pr_CurrentDir,
  754.         cfh,
  755.         dfh;
  756.     char
  757.         *id,
  758.         date [9],
  759.         time [9],
  760.         sys [256],
  761.         user [32],
  762.         line [256],
  763.         fromfile [256],
  764.         tofile [256],
  765.         cmd [256];
  766.     unsigned long
  767.         size;
  768.     long
  769.         age;
  770.     struct machine
  771.         *mach;
  772.     int
  773.         cchar = 0,
  774.         t = 0,
  775.         l;
  776.     __aligned struct FileInfoBlock
  777.         fib;
  778.     struct DateTime
  779.         dt;
  780.  
  781.     dt.dat_Format = FORMAT_USA;
  782.     dt.dat_Flags = 0;
  783.     dt.dat_StrDay = 0;
  784.     dt.dat_StrDate = date;
  785.     dt.dat_StrTime = time;
  786.  
  787.     fromfile [255] = tofile [255] = user [31] = sys [31] = 0;
  788.  
  789.     age = currenttime -
  790.         ead->ed_Ticks / 50 -
  791.         ead->ed_Mins * 60 -
  792.         ead->ed_Days * 86400;
  793.  
  794.     id = ead->ed_Name + 2;
  795.     strncpy (sys, id, 31);
  796.     sys [strlen (sys) - 5] = 0;
  797.  
  798.     for (mach = *mbase; mach; mach = mach->next) {
  799.         l = strlen (mach->name);
  800.         l = l > 7 ? 7 : l;
  801.  
  802.         if (!memcmp (sys, mach->name, l)) {
  803.             strcpy (sys, mach->name);
  804.             break;
  805.         }
  806.     }
  807.  
  808.     if (args->number) {
  809.         if (*ead->ed_Name == 'C')
  810.             updatemachine (sys, 0, age, 0x80000000, mbase);
  811.         else
  812.             updatemachine (sys, 0, 0x80000000, age, mbase);
  813.     }
  814.     else {
  815.         dt.dat_Stamp.ds_Days = ead->ed_Days;
  816.         dt.dat_Stamp.ds_Minute = ead->ed_Mins;
  817.         dt.dat_Stamp.ds_Tick = ead->ed_Ticks;
  818.  
  819.         strcpy (user, "?");
  820.         strcpy (fromfile, user);
  821.         strcpy (tofile, user);
  822.         size = 0;
  823.         cmd [0] = 0;
  824.  
  825.         if (cfh = Open (ead->ed_Name, MODE_OLDFILE)) {
  826.             while (FGets (cfh, line, 256)) {
  827.                 char
  828.                     *p = line;
  829.  
  830.                 if (args->executions) {
  831.                     char
  832.                         *c;
  833.  
  834.                     if (*(c = token (&p)) == 'C') {
  835.                         linecpy (cmd, p);
  836.                         if (*user != '?')
  837.                             break;
  838.                     }
  839.                     else
  840.                     if (*c == 'U') {
  841.                         strcpy (user, token (&p));
  842.                         strcpy (tofile, token (&p));
  843.                         if (cmd [0])
  844.                             break;
  845.                     }
  846.                 }
  847.                 else {
  848.                     char
  849.                         *fromname,
  850.                         *toname;
  851.                     int
  852.                         cc = *line;
  853.  
  854.                     token (&p);
  855.                     fromname = token (&p);
  856.                     toname = token (&p);
  857.                     strncpy (user, token (&p), 31);
  858.  
  859.                     if (*toname == 'X' && *(toname + 1) == '.') {
  860.                         if (cmd [0] == 0) {
  861.                             if (dfh = Open (fromname, MODE_OLDFILE)) {
  862.                                 char buf [256];
  863.  
  864.                                 if (ExamineFH (dfh, &fib))
  865.                                     size += fib.fib_Size;
  866.  
  867.                                 while (FGets (dfh, buf, 256))
  868.                                     if (*buf == 'C') {
  869.                                         linecpy (cmd, buf+1);
  870.                                         break;
  871.                                     }
  872.  
  873.                                 Close (dfh);
  874.                             }
  875.                             else
  876.                                 strcpy (cmd, "?");
  877.                         }
  878.                     }
  879.                     else {
  880.                         token (&p);
  881.  
  882.                         strncpy (fromfile, token (&p), 255);
  883.                         strncpy (tofile, toname, 255);
  884.  
  885.                         if (dfh = Lock (fromname, ACCESS_READ)) {
  886.                             if (Examine (dfh, &fib))
  887.                                 size += fib.fib_Size;
  888.  
  889.                             UnLock (dfh);
  890.                         }
  891.  
  892.                         cchar = cc;
  893.                     }
  894.                 } /* !args->executions */
  895.             } /* while */
  896.  
  897.             Close (cfh);
  898.         } /* Open */
  899.  
  900.         if (!DateToStr (&dt)) {
  901.             strcpy (date, "?????");
  902.             strcpy (time, date);
  903.         }
  904.  
  905.         if (args->user && strcmp (user, args->user))
  906.             return;
  907.  
  908.         if (args->nuser && !strcmp (user, args->nuser))
  909.             return;
  910.  
  911.         if (args->older && age < *args->older * 3600)
  912.             return;
  913.  
  914.         if (args->younger && age > *args->younger * 3600)
  915.             return;
  916.  
  917.         while (cmd [t] && cmd [t] != ' ' && cmd [t] != '\t')
  918.             t++;
  919.  
  920.         if (args->command && (strncmp (cmd, args->command, t) || t != strlen (args->command)))
  921.             return;
  922.  
  923.         if (args->ncommand && !strncmp (cmd, args->ncommand, t) && t == strlen (args->ncommand))
  924.             return;
  925.  
  926.     } /* !args->number */
  927.  
  928.     if (args->executions) {
  929.         Printf ("%s %s!%s %s %s %s%s\n",
  930.             sys, tofile, user, date, time, cmd,
  931.             *ead->ed_Name == 'E' ? " (execution failed)" : "");
  932.     }
  933.     else {
  934.         Printf ("%s %s %s %s %s ",
  935.             id, sys, user, date, time);
  936.  
  937.         if (cmd [0])
  938.             Printf ("Executing %s (sending %ld bytes)\n", cmd, size);
  939.         else
  940.             if (cchar == 'R')
  941.                 Printf ("Requesting %s to %s\n", fromfile, tofile);
  942.             else
  943.                 Printf ("Sending    %s (%ld bytes) to %s\n", fromfile, size, tofile);
  944.  
  945.         if (args->killprompt || args->killlisted) {
  946.             if (args->killprompt) {
  947.                 Printf ("%s: Kill %s? ", name, id);
  948.                 Flush (Output ());
  949.                 FGets (Input (), line, 256);
  950.                 if (line [0] != 'y' && line [0] != 'Y') {
  951. DG(("Got: '%s'\n", line)); Flush (Output ());
  952.                     return;
  953.                 }
  954.             }
  955.  
  956.             kill (ead->ed_Name);
  957.         }
  958.     }
  959.  
  960.     return;
  961. }
  962.