home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume3 / activ / activ.c next >
C/C++ Source or Header  |  1989-02-03  |  5KB  |  357 lines

  1.  
  2. /*
  3. **  ACTIV -- keep an activioty typescript.
  4. **    whenever the user types, will prepend the time if the typein has been
  5. **    quiet for more than Interval, which defaults to 20 secs, but may be 
  6. **    overridden with -i flag.  If over two hours, pust the entire time and 
  7. **    date out.  Copies to a file.
  8. **
  9. **    Useage:
  10. **        activ [-i interval] file
  11. **
  12. **    History:
  13. **        6/23/88 -- (marc) documented
  14. **
  15. */
  16.  
  17. # include    <stdio.h>
  18. # include    <sgtty.h>
  19. # include    <signal.h>
  20. # include    <time.h>
  21. # include    <errno.h>
  22. # include    <ctype.h>
  23.  
  24. # define    MAXLINE         350
  25.  
  26. struct sgttyb    Ogttyb;
  27. char        Erasec, Eofc, Killc, Wordc;
  28. char        *Outfile;
  29. FILE        *Outf;
  30.  
  31. main(argc, argv)
  32. {
  33.     args(argc, argv);
  34.     openFile();
  35.     setty();
  36.     setend();
  37.     dialog();
  38. }
  39.  
  40. openFile()
  41. {
  42.     if (!Outfile)
  43.     {
  44.         fprintf(stderr, "usage: activ file\n");
  45.         exit (-1);
  46.     }
  47.     if (!(Outf = fopen(Outfile, "a+")))
  48.     {
  49.         perror(Outfile);
  50.         exit (-1);
  51.     }
  52.     setlinebuf(Outfile);
  53. }
  54. setty()
  55. {
  56.     struct sgttyb    ngttyb;
  57.     struct tchars    tchars;
  58.     struct ltchars    lchars;
  59.  
  60.     /* set cbreak mode */
  61.     ioctl(0, TIOCGETP, &Ogttyb);
  62.     ngttyb = Ogttyb;
  63.     ngttyb.sg_flags |= CBREAK;
  64.     ngttyb.sg_flags &= ~ECHO;
  65.  
  66.     ioctl(0, TIOCSETP, &ngttyb);
  67.     /* set editting characters */
  68.     ioctl(0, TIOCGETC, &tchars);
  69.     Eofc = tchars.t_eofc;
  70.     ioctl(0, TIOCGLTC, &lchars);
  71.     Wordc = lchars.t_werasc;
  72.  
  73.     Erasec = Ogttyb.sg_erase;
  74.     Killc = Ogttyb.sg_kill;
  75. }
  76. setend()
  77. {
  78.     int    endIt();
  79.  
  80.     /* ensure that upon SIGINT, we dump things, and close the
  81.      * file 
  82.      */
  83.     signal(SIGINT, endIt);
  84. }
  85. endIt()
  86. {
  87.     /* close file, reset tty mode to original mode */
  88.     fclose(Outf);
  89.     ioctl(0, TIOCSETP, &Ogttyb);
  90.     exit (0);
  91. }
  92. dialog()
  93. {
  94.     for (;;)
  95.     {
  96.         await_inp();
  97.         fill_line();
  98.     }
  99. }
  100. await_inp()
  101. {
  102.     int    fdt;
  103.     int    err;
  104.     extern    errno;
  105.  
  106.     for (;;)
  107.     {
  108.         fdt = 1 << 0;
  109.         err = select(32, &fdt, NULL, NULL, NULL);
  110.         if (err != -1)
  111.             return;
  112.         if (errno != EINTR)
  113.             perror("select");
  114.     }
  115. }
  116.  
  117. # define    INTERVAL    20
  118.  
  119. char    EntireLine[MAXLINE];
  120. int    LineBegin;
  121. int    OutCol;
  122. int    EdittedLine;
  123. int    ShownTill = 0;
  124. int    FirstCharOnLine = 1;
  125. char    Line[MAXLINE];
  126. long    LastTime;
  127. long    ThisTime;
  128. int    Interval = INTERVAL;
  129. int    EofIn;
  130.  
  131. fill_line()
  132. {
  133.     gettime();
  134.     get_any(Line, sizeof Line);
  135.     if (gt_interval())
  136.         FirstCharOnLine = 1;
  137.     if (FirstCharOnLine)
  138.     {
  139.         dumpline();
  140.         newline();
  141.     }
  142.     add_to_line(Line);
  143.     line_edit();        /* edit and echo. */
  144.     if (completeline())
  145.     {
  146.         dumpline();
  147.     }
  148.     if (eof_reached())
  149.     {
  150.         endIt();
  151.         /*NOTREACHED*/
  152.     }
  153. }
  154. gettime()
  155. {
  156.     ThisTime = time(NULL);
  157. }
  158. gt_interval()
  159. {
  160.     long    t = time(0);
  161.  
  162.     return (t - LastTime > Interval);
  163. }
  164. dumpline()
  165. {
  166.     int    n = strlen(EntireLine);
  167.  
  168.     fputs(EntireLine, Outf);
  169.     if (n != 0 && EntireLine[n-1] != '\n')
  170.     {
  171.         putc('\n', stdout);
  172.         putc('\n', Outf);
  173.     }
  174.     EntireLine[0] = 0;
  175.     EdittedLine = 0;
  176.     LineBegin = 0;
  177.     OutCol = 0;
  178.     fflush(Outf);
  179. }
  180. add_to_line(s)
  181. char    *s;
  182. {
  183.     strcat(EntireLine, s);
  184. }
  185. newline()
  186. {
  187.     struct tm    *tm;
  188.     char        data[40];
  189.     char        *timestring;
  190.     char        *ctime();
  191.     struct tm    *localtime();
  192.     char        *s;
  193.  
  194.     if (ThisTime - LastTime >= 2 * 60 * 60)
  195.     {
  196.         s = ctime(&ThisTime);
  197.         s[strlen(s) - 1] = 0;    /* get rid of final newline */
  198.         sprintf(data, "[%s] ", s);
  199.     }
  200.     else
  201.     {
  202.         tm = localtime(&ThisTime);
  203.         sprintf(data, "[%02d:%02d:%02d] ", tm->tm_hour, tm->tm_min,
  204.             tm->tm_sec);
  205.         s = data;
  206.     }
  207.     add_to_line(data);
  208.     LineBegin = strlen(EntireLine);
  209.     EdittedLine = LineBegin;
  210.     OutCol = 0;
  211.     LastTime = ThisTime;
  212.     fputs(data, stdout);
  213.     fflush(stdout);
  214. }
  215. line_edit()
  216. {
  217.     char    *i, *o;
  218.  
  219.     for (i = &EntireLine[EdittedLine], o = i;
  220.         *i; i++)
  221.     {
  222.         if (*i == Killc)
  223.         {
  224.             o = &EntireLine[LineBegin];
  225.             EdittedLine = LineBegin;
  226.             erase_col(OutCol);
  227.             OutCol = 0;
  228.         }
  229.         else if (*i == Erasec)
  230.         {
  231.             --o; 
  232.             if (OutCol > 0)
  233.             {
  234.                 OutCol--;
  235.                 EdittedLine--;
  236.                 erase_col(1);
  237.             }
  238.         } else if (*i == Wordc)
  239.         {
  240.             if (OutCol <= 0)
  241.                 continue;
  242.             /* skip initial spaces */
  243.             if (isspace(o[-1]))
  244.             {
  245.                 while (OutCol > 0 && isspace(*--o))
  246.                 {
  247.                     OutCol--;
  248.                     EdittedLine--;
  249.                     erase_col(1);
  250.                 }
  251.                 if (OutCol != 0)
  252.                     o++;
  253.             }
  254.             /* skip word */
  255.             while (OutCol > 0 && !isspace(*--o))
  256.             {
  257.                 OutCol--;
  258.                 EdittedLine--;
  259.                 erase_col(1);
  260.             }
  261.             if (OutCol != 0)
  262.                 o++;
  263.         }
  264.         else if (*i == Eofc)
  265.         {
  266.             EofIn++;
  267.             break;
  268.         }
  269.         else if (isgraph(*i) || isspace(*i))
  270.         {
  271.             *o++ = *i;
  272.             EdittedLine++;
  273.             OutCol++;
  274.             if (*i == '\n')
  275.             {
  276.                 *i = 0;
  277.                 *--o = 0;
  278.                 dumpline();
  279.                 /* continue till end */
  280.                 line_edit();
  281.             }
  282.             else
  283.                 putchar(*i);
  284.         }
  285.         else
  286.         {
  287.             /* can't map the file output because doing it in place,
  288.              * but can map the tty output, though i'll be confused
  289.              * backspaceing!
  290.              */
  291.             EdittedLine += 1;
  292.             OutCol += 2;
  293.             putchar('^');
  294.             putchar(*i | 0100);
  295.             *o++ = *i;
  296.         }
  297.     }
  298.     *o = 0;
  299.     fflush(stdout);
  300.     LastTime = ThisTime;
  301.     FirstCharOnLine = 0;
  302. }
  303. completeline()
  304. {
  305.     return (EntireLine[strlen(EntireLine) - 1] == '\n');
  306. }
  307. eof_reached()
  308. {
  309.     return (EofIn);
  310. }
  311. erase_col(i)
  312. {
  313.     while (--i >= 0)
  314.         fputs("\b \b", stdout);
  315.     fflush(stdout);
  316. }
  317. get_any(buf, size)
  318. char    *buf;
  319. int    size;
  320. {
  321.     int    n;
  322.  
  323.     n = read(0, buf, size);
  324.     if (n > 0)
  325.         buf[n] = 0;
  326. }
  327. args(argc, argv)
  328. int    argc;
  329. char    **argv;
  330. {
  331.     int    i;
  332.  
  333.     for (argv++; *argv; argv++)
  334.     {
  335.         if (**argv != '-')
  336.             Outfile = *argv;
  337.         else switch ((*argv)[1])
  338.         {
  339.           case 'i':    /* set interval */
  340.             if (!argv[1])
  341.                 break;
  342.             i = atoi(*++argv);
  343.             if (i > 0)
  344.                 Interval = i;
  345.             break;
  346.  
  347.           case '?':
  348.             fprintf(stderr, "usage: activ [-i interval] file\n");
  349.             break;
  350.         
  351.           default:
  352.             fprintf(stderr, "activ: unknown flag `%s'\n",
  353.                 *argv);
  354.         }
  355.     }
  356. }
  357.