home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Tools / ntail / miscfuncs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  5.3 KB  |  241 lines

  1. /* miscfuncs.c: */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Tools/ntail/RCS/miscfuncs.c,v 6.0 1991/12/18 20:32:10 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Tools/ntail/RCS/miscfuncs.c,v 6.0 1991/12/18 20:32:10 jpo Rel $
  9.  *
  10.  * $Log: miscfuncs.c,v $
  11.  * Revision 6.0  1991/12/18  20:32:10  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17.  
  18. /*
  19.  * @(#) miscfuncs.c 2.1 89/07/26 19:16:50
  20.  *
  21.  * Package:    ntail version 2
  22.  * File:    miscfuncs.c
  23.  * Description:    miscelaneous support procedures
  24.  *
  25.  * Mon Jul 10 02:56:22 1989 - Chip Rosenthal <chip@vector.Dallas.TX.US>
  26.  *    Original composition.
  27.  */
  28.  
  29. #ifndef LINT
  30. static char SCCSID[] = "@(#) miscfuncs.c 2.1 89/07/26 19:16:50";
  31. #endif
  32.  
  33. #include <stdio.h>
  34. #include <fcntl.h>
  35. #include <sys/types.h>
  36. #include <sys/stat.h>
  37. #include <isode/usr.dirent.h>
  38. #include "ntail.h"
  39.  
  40. #ifdef M_XENIX
  41. # undef  NULL
  42. # define NULL 0
  43. #endif
  44.  
  45. extern int errno;
  46.  
  47. extern char *sys_errlist[];
  48.  
  49.  
  50. /*
  51.  * Scan a directory for files not currently on a list.
  52.  */
  53. int scan_directory(dirname)
  54. char *dirname;
  55. {
  56.     register int i;
  57.     register struct dirent *dp;
  58.     register struct entry_descrip **elist, *entryp;
  59.     char *basename;
  60.     struct stat sbuf;
  61.     DIR *dirp;
  62.     static char pathname[MAXNAMLEN];
  63.  
  64.     Dprintf(stderr, ">>> scanning directory '%s'\n", dirname);
  65.     if ( (dirp=opendir(dirname)) == NULL )
  66.     return -1;
  67.  
  68.     (void) strcat( strcpy(pathname,dirname), "/" );
  69.     basename = pathname + strlen(pathname);
  70.  
  71. #define SKIP_DIR(D) \
  72.     ( D[0] == '.' && ( D[1] == '\0' || ( D[1] == '.' && D[2] == '\0' ) ) )
  73.  
  74.     while ( (dp=readdir(dirp)) != NULL ) {
  75.  
  76.     if ( SKIP_DIR(dp->d_name) )
  77.         continue;
  78.     (void) strcpy( basename, dp->d_name );
  79.     if ( stat(pathname,&sbuf) != 0 )
  80.         continue;
  81.     if ( (sbuf.st_mode&S_IFMT) != S_IFREG )
  82.         continue;
  83.  
  84.     for ( i=List_file.num, elist=List_file.list ; i > 0 ; --i, ++elist ) {
  85.         if ( strcmp( (*elist)->name, pathname ) == 0 )
  86.         break;
  87.     }
  88.     if ( i > 0 )
  89.         continue;
  90.  
  91.     for ( i=List_zap.num, elist=List_zap.list ; i > 0 ; --i, ++elist ) {
  92.         if ( strcmp( (*elist)->name, pathname ) == 0 )
  93.         break;
  94.     }
  95.     if ( i > 0 )
  96.         continue;
  97.  
  98.     entryp = new_entry( &List_file, pathname );
  99.     if ( Reset_status ) {
  100.         message( MSSG_CREATED, entryp );
  101.     } else {
  102.         entryp->mtime = sbuf.st_mtime;
  103.         entryp->size = sbuf.st_size;
  104.     }
  105.  
  106.     }
  107.  
  108.     (void) closedir(dirp);
  109.     return 0;
  110.  
  111. }
  112.  
  113.  
  114. /*
  115.  * Compare mtime of two entries.  Used by the "qsort()" in "fixup_open_files()".
  116.  */
  117. static int ecmp(ep1,ep2)
  118. register struct entry_descrip **ep1, **ep2;
  119. {
  120.     return ( (*ep2)->mtime - (*ep1)->mtime );
  121. }
  122.  
  123. /*
  124.  * Manage the open files.
  125.  *   A small number of entries in "List_file" are kept open to minimize
  126.  *   the overhead in checking for changes.  The strategy is to make sure
  127.  *   the MAX_OPEN most recently modified files are all open.
  128.  */
  129. void fixup_open_files()
  130. {
  131.     register int i;
  132.     register struct entry_descrip **elist;
  133.     extern void qsort();
  134.  
  135.     Dprintf(stderr, ">>> resorting file list\n");
  136.     (void) qsort(
  137.     (char *) List_file.list,
  138.     List_file.num,
  139.     sizeof(struct entry_descrip *),
  140.     ecmp
  141.     );
  142.     Sorted = TRUE;
  143.  
  144.     /*
  145.      * Start at the end of the list.
  146.      */
  147.     i = List_file.num - 1;
  148.     elist = &List_file.list[i];
  149.  
  150.     /*
  151.      * All the files at the end of the list should be closed.
  152.      */
  153.     for ( ; i >= MAX_OPEN ; --i, --elist ) {
  154.     if ( (*elist)->fd > 0 ) {
  155.         (void) close( (*elist)->fd );
  156.         (*elist)->fd = 0;
  157.     }
  158.     }
  159.  
  160.     /*
  161.      * The first MAX_OPEN files in the list should be open.
  162.      */
  163.     for ( ; i >= 0 ; --i, --elist ) {
  164.     if ( (*elist)->fd <= 0 )
  165.         (void) open_entry( &List_file, i );
  166.     }
  167.  
  168. }
  169.  
  170.  
  171. /*
  172.  * Standard message interface.
  173.  *   There are two reasons for this message interface.  First, it provides
  174.  *   consistent diagnostics for all the messages.  Second, it manages the
  175.  *   filename banner display whenever we switch to a different file.
  176.  *   Warning - "errno" is used in some of the messages, so care must be
  177.  *   taken not to step on it before message() can be called.
  178.  */
  179. void message(sel,e)
  180. int sel;
  181. struct entry_descrip *e;
  182. {
  183.     static char *ofile = NULL;
  184.  
  185.     /*
  186.      * Don't display the file banner if the file hasn't changed since last time.
  187.      */
  188.     if ( sel == MSSG_BANNER && ofile != NULL && strcmp(ofile,e->name) == 0 )
  189.     return;
  190.  
  191.     /*
  192.      * Make sure the message selector is within range.
  193.      */
  194.     if ( sel < 0 || sel > MSSG_UNKNOWN )
  195.     sel = MSSG_UNKNOWN;
  196.  
  197.     /*
  198.      * Display the message.
  199.      */
  200.     if ( mssg_list[sel] != NULL )
  201.     (void) printf(mssg_list[sel], e->name, sys_errlist[errno]);
  202.  
  203.     ofile = ( sel == MSSG_BANNER ? e->name : NULL );
  204. }
  205.  
  206.  
  207. /*
  208.  * Display currently opened files.
  209.  */
  210. void show_status()
  211. {
  212.     int i, n;
  213.     struct tm *tp;
  214.     static char *monname[] = {
  215.     "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  216.     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  217.     };
  218.     extern struct tm *localtime();
  219.  
  220.     (void) printf("\n*** recently changed files ***\n");
  221.     for ( i = 0, n = 0 ; i < List_file.num ; ++i ) {
  222.     if ( List_file.list[i]->fd > 0 ) {
  223.         tp = localtime(&List_file.list[i]->mtime);
  224.         (void) printf("%4d  %2d-%3s-%02d %02d:%02d:%02d  %s\n",
  225.         ++n,
  226.         tp->tm_mday, monname[tp->tm_mon], tp->tm_year,
  227.         tp->tm_hour, tp->tm_min, tp->tm_sec,
  228.         List_file.list[i]->name
  229.         );
  230.     }
  231.     }
  232.  
  233.     (void) printf( 
  234.     "currently watching:  %d files  %d dirs  %d unknown entries\n",
  235.     List_file.num, List_dir.num, List_zap.num);
  236.  
  237.     message( MSSG_NONE, (struct entry_descrip *) NULL  );
  238.  
  239. }
  240.  
  241.