home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 3 / Meeting_Pearls_III.iso / Pearls / tcp / Networking / TCP / Server / wu-ftpd / src / ftpcount.c < prev    next >
C/C++ Source or Header  |  1994-08-08  |  10KB  |  345 lines

  1. /* Copyright (c) 1993, 1994  Washington University in Saint Louis
  2.  * All rights reserved.
  3.  *
  4.  * Redistribution and use in source and binary forms, with or without
  5.  * modification, are permitted provided that the following conditions are
  6.  * met: 1. Redistributions of source code must retain the above copyright
  7.  * notice, this list of conditions and the following disclaimer. 2.
  8.  * Redistributions in binary form must reproduce the above copyright notice,
  9.  * this list of conditions and the following disclaimer in the documentation
  10.  * and/or other materials provided with the distribution. 3. All advertising
  11.  * materials mentioning features or use of this software must display the
  12.  * following acknowledgement: This product includes software developed by the
  13.  * Washington University in Saint Louis and its contributors. 4. Neither the
  14.  * name of the University nor the names of its contributors may be used to
  15.  * endorse or promote products derived from this software without specific
  16.  * prior written permission.
  17.  *
  18.  * THIS SOFTWARE IS PROVIDED BY WASHINGTON UNIVERSITY AND CONTRIBUTORS
  19.  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21.  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASHINGTON
  22.  * UNIVERSITY OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  23.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  24.  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  25.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  26.  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  27.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  28.  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  29.  * POSSIBILITY OF SUCH DAMAGE.
  30.  */
  31.  
  32. #include "config.h"
  33.  
  34. #include <stdio.h>
  35. #include <errno.h>
  36. #include <string.h>
  37. #ifdef SYSSYSLOG
  38. #include <sys/syslog.h>
  39. #else
  40. #include <syslog.h>
  41. #endif
  42. #include <signal.h>
  43. #include <time.h>
  44. #include <ctype.h>
  45.  
  46. #include <sys/types.h>
  47. #include <sys/stat.h>
  48. #include <sys/file.h>
  49. #include <sys/param.h>
  50.  
  51. #include "pathnames.h"
  52. #include "extensions.h"
  53.  
  54. #if defined(SVR4) || defined(ISC) || defined(AMIGA)
  55. #include <fcntl.h>
  56. #endif
  57.  
  58. struct c_list {
  59.     char *class;
  60.     struct c_list *next;
  61. };
  62.  
  63. extern char version[];
  64.  
  65. char *progname;
  66.  
  67. /*************************************************************************/
  68. /* FUNCTION  : parse_time                                                */
  69. /* PURPOSE   : Check a single valid-time-string against the current time */
  70. /*             and return whether or not a match occurs.                 */
  71. /* ARGUMENTS : a pointer to the time-string                              */
  72. /*************************************************************************/
  73.  
  74. int
  75. parsetime(char *whattime)
  76. {
  77.     static char *days[] =
  78.     {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Wk"};
  79.     time_t clock;
  80.     struct tm *curtime;
  81.     int wday,
  82.       start,
  83.       stop,
  84.       ltime,
  85.       validday,
  86.       loop,
  87.       match;
  88.  
  89.     (void) time(&clock);
  90.     curtime = localtime(&clock);
  91.     wday = curtime->tm_wday;
  92.     validday = 0;
  93.     match = 1;
  94.  
  95.     while (match && isalpha(*whattime) && isupper(*whattime)) {
  96.         match = 0;
  97.         for (loop = 0; loop < 8; loop++) {
  98.             if (strncmp(days[loop], whattime, 2) == NULL) {
  99.                 whattime += 2;
  100.                 match = 1;
  101.                 if ((wday == loop) | ((loop == 7) && wday && (wday < 6)))
  102.                     validday = 1;
  103.             }
  104.         }
  105.     }
  106.  
  107.     if (strncmp(whattime, "Any", 3) == NULL) {
  108.         validday = 1;
  109.         whattime += 3;
  110.     }
  111.     if (!validday)
  112.         return (0);
  113.  
  114.     if (sscanf(whattime, "%d-%d", &start, &stop) == 2) {
  115.         ltime = curtime->tm_min + 100 * curtime->tm_hour;
  116.         if ((start < stop) && ((ltime > start) && ltime < stop))
  117.             return (1);
  118.         if ((start > stop) && ((ltime > start) || ltime < stop))
  119.             return (1);
  120.     } else
  121.         return (1);
  122.  
  123.     return (0);
  124. }
  125.  
  126. /*************************************************************************/
  127. /* FUNCTION  : validtime                                                 */
  128. /* PURPOSE   : Break apart a set of valid time-strings and pass them to  */
  129. /*             parse_time, returning whether or not ANY matches occurred */
  130. /* ARGUMENTS : a pointer to the time-string                              */
  131. /*************************************************************************/
  132.  
  133. int
  134. validtime(char *ptr)
  135. {
  136.     char *nextptr;
  137.     int good;
  138.  
  139.     while (1) {
  140.         nextptr = strchr(ptr, '|');
  141.         if (strchr(ptr, '|') == NULL)
  142.             return (parsetime(ptr));
  143.         *nextptr = '\0';
  144.         good = parsetime(ptr);
  145.         *nextptr++ = '|';       /* gotta restore the | or things get skipped! */
  146.         if (good)
  147.             return (1);
  148.         ptr = nextptr;
  149.     }
  150. }
  151.  
  152. acl_getlimit(char *aclbuf, char *class)
  153. {
  154.     char *crptr,
  155.      *ptr,
  156.       linebuf[1024];
  157.     int limit;
  158.  
  159.     while (*aclbuf != NULL) {
  160.         if (strncasecmp(aclbuf, "limit", 5) == 0) {
  161.             for (crptr = aclbuf; *crptr++ != '\n';) ;
  162.             *--crptr = NULL;
  163.             strcpy(linebuf, aclbuf);
  164.             *crptr = '\n';
  165.             (void) strtok(linebuf, " \t");  /* returns "limit" */
  166.             if (strcmp(class, strtok(NULL, " \t")) == 0) {
  167.                 limit = atoi(strtok(NULL, " \t"));  /* returns limit <n> */
  168.                 if ((ptr = strtok(NULL, " \t")) && validtime(ptr))
  169.                     return (limit);
  170.             }
  171.         }
  172.         while (*aclbuf && *aclbuf++ != '\n') ;
  173.     }
  174.  
  175.     return (0);
  176.  
  177. }
  178.  
  179. acl_countusers(char *class)
  180. {
  181.     int pidfd,
  182.       count,
  183.       stat,
  184.       which;
  185.     char pidfile[1024];
  186. #ifndef AMIGA
  187.     char line[1024];
  188. #endif
  189.     pid_t buf[MAXUSERS];
  190. #ifndef AMIGA
  191.     FILE *ZeFile;
  192. #endif
  193. #if !defined(HAVE_FLOCK) && !defined(AMIGA)
  194. struct flock arg;
  195. #endif
  196.  
  197.     sprintf(pidfile, _PATH_PIDNAMES, class);
  198.     pidfd = open(pidfile, O_RDONLY, 0644);
  199.     if (pidfd == -1) {
  200.         return (0);
  201.     }
  202.     lseek(pidfd, 0, L_SET);
  203.  
  204.     count = 0;
  205.  
  206.     if (read(pidfd, buf, sizeof(buf)) == sizeof(buf)) {
  207.         for (which = 0; which < MAXUSERS; which++)
  208.         if (buf[which]) {
  209. #ifdef AMIGA
  210.             stat = 0;
  211.             count++;
  212. #else
  213.             stat = kill(buf[which], SIGCONT);
  214.             if (((stat == -1) && (errno == EPERM)) || !stat) {
  215.                 if (strcmp(progname,"ftpcount")) {
  216. #if defined(SVR4)
  217.                     sprintf(line,"/bin/ps -l -p %d",buf[which]);
  218. #elif defined(M_UNIX)
  219.                     sprintf(line,"/bin/ps -f -p %d",buf[which]);
  220. #else
  221.                     sprintf(line,"/bin/ps %d",buf[which]);
  222. #endif
  223.                     ZeFile = popen(line, "r");
  224.                     rewind(ZeFile);
  225.                     fgets(line, 1024, ZeFile);
  226.                     fgets(line, 1024, ZeFile);
  227.                     printf("%s",line);
  228.                     pclose(ZeFile);
  229.                 }
  230.                 count++;
  231.             }
  232. #endif
  233.         }
  234.     }
  235. #ifndef AMIGA
  236. #ifdef HAVE_FLOCK
  237.     flock(pidfd, LOCK_UN);
  238. #else
  239.     arg.l_type = F_UNLCK; arg.l_whence = arg.l_start = arg.l_len = 0;
  240.     fcntl(pidfd, F_SETLK, &arg);
  241. #endif
  242. #endif
  243.     close(pidfd);
  244.  
  245.     return (count);
  246. }
  247.  
  248. void
  249. new_list(struct c_list **list)
  250. {
  251.     (*list) = (struct c_list *) malloc(sizeof(struct c_list));
  252.  
  253.     (*list)->next = NULL;
  254. }
  255.  
  256. int
  257. add_list(char *class, struct c_list **list)
  258. {
  259.     struct c_list *cp;
  260.  
  261.     for (cp = (*list)->next; cp; cp = cp->next) {
  262.         if (!strcmp(cp->class, class))
  263.             return (-1);
  264.     }
  265.  
  266.     cp = (struct c_list *) malloc(sizeof(struct c_list));
  267.  
  268.     cp->class = (char *) malloc(strlen(class) + 1);
  269.     strcpy(cp->class, class);
  270.     cp->next = (*list)->next;
  271.     (*list)->next = cp;
  272.     return (1);
  273. }
  274.  
  275. main(int argc, char **argv)
  276. {
  277.     FILE *accessfile;
  278.     char class[80],
  279.       linebuf[1024],
  280.      *aclbuf,
  281.      *myaclbuf,
  282.      *crptr;
  283.     int limit;
  284.     struct stat finfo;
  285.     struct c_list *list;
  286.  
  287.     if (progname = strrchr(argv[0], '/'))  ++progname;
  288.     else  progname = argv[0];
  289.  
  290.     if (argc > 1) {
  291.         fprintf(stderr, "%s\n", version);
  292.         exit(0);
  293.     }
  294.  
  295.     if ((accessfile = fopen(_PATH_FTPACCESS, "r")) == NULL) {
  296.         if (errno != ENOENT)
  297.             perror("ftpcount: could not open() access file");
  298.         exit(1);
  299.     }
  300.     if (stat(_PATH_FTPACCESS, &finfo)) {
  301.         perror("ftpcount: could not stat() access file");
  302.         exit(1);
  303.     }
  304.     if (finfo.st_size == 0) {
  305.         printf("%s: no service classes defined, no usage count kept\n",progname);
  306.         exit(0);
  307.     } else {
  308.         if (!(aclbuf = (char *) malloc(finfo.st_size + 1))) {
  309.             perror("ftpcount: could not malloc aclbuf");
  310.             exit(1);
  311.         }
  312.         fread(aclbuf, finfo.st_size, 1, accessfile);
  313.         *(aclbuf + finfo.st_size) = '\0';
  314.     }
  315.  
  316.     (void) new_list(&list);
  317.     myaclbuf = aclbuf;
  318.     while (*myaclbuf != NULL) {
  319.         if (strncasecmp(myaclbuf, "class", 5) == 0) {
  320.             for (crptr = myaclbuf; *crptr++ != '\n';) ;
  321.             *--crptr = NULL;
  322.             strcpy(linebuf, myaclbuf);
  323.             *crptr = '\n';
  324.             (void) strtok(linebuf, " \t");  /* returns "class" */
  325.             strcpy(class, strtok(NULL, " \t")); /* returns class name */
  326.             if ((add_list(class, &list)) < 0) {
  327.                 /* we have a class with multiple "class..." lines so, only
  328.                  * display one count... */
  329.                 ;
  330.             } else {
  331.                 limit = acl_getlimit(myaclbuf, class);
  332.             if (strcmp(progname,"ftpcount")) {
  333.                 printf("Service class %s: \n", class);
  334.                 printf("   - %3d users (%3d maximum)\n\n",
  335.             acl_countusers(class), limit);
  336.         }
  337.         else
  338.                 printf("Service class %-20.20s - %3d users (%3d maximum)\n",
  339.                        class, acl_countusers(class), limit);
  340.             }
  341.         }
  342.         while (*myaclbuf && *myaclbuf++ != '\n') ;
  343.     }
  344. }
  345.