home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / UNIX / Networking / wu-ftpd-2.4.2b13-MIHS / src / ftpcount.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-03-03  |  10.2 KB  |  381 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. #include <stdlib.h>
  38. #ifdef SYSSYSLOG
  39. #include <sys/syslog.h>
  40. #else
  41. #include <syslog.h>
  42. #endif
  43. #include <signal.h>
  44. #include <time.h>
  45. #include <ctype.h>
  46.  
  47. #include <sys/types.h>
  48. #include <sys/stat.h>
  49. #include <sys/file.h>
  50. #include <sys/param.h>
  51.  
  52. #include "pathnames.h"
  53. #include "extensions.h"
  54.  
  55. #if defined(SVR4) || defined(ISC)
  56. #include <fcntl.h>
  57. #endif
  58.  
  59. struct c_list {
  60.     char *class;
  61.     struct c_list *next;
  62. };
  63.  
  64. extern char version[];
  65.  
  66. char *progname;
  67.  
  68. /*************************************************************************/
  69. /* FUNCTION  : parse_time                                                */
  70. /* PURPOSE   : Check a single valid-time-string against the current time */
  71. /*             and return whether or not a match occurs.                 */
  72. /* ARGUMENTS : a pointer to the time-string                              */
  73. /*************************************************************************/
  74.  
  75. int
  76. #ifdef __STDC__
  77. parsetime(char *whattime)
  78. #else
  79. parsetime(whattime)
  80. char *whattime;
  81. #endif
  82. {
  83.     static char *days[] =
  84.     {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Wk"};
  85.     time_t clock;
  86.     struct tm *curtime;
  87.     int wday,
  88.       start,
  89.       stop,
  90.       ltime,
  91.       validday,
  92.       loop,
  93.       match;
  94.  
  95.     (void) time(&clock);
  96.     curtime = localtime(&clock);
  97.     wday = curtime->tm_wday;
  98.     validday = 0;
  99.     match = 1;
  100.  
  101.     while (match && isalpha(*whattime) && isupper(*whattime)) {
  102.         match = 0;
  103.         for (loop = 0; loop < 8; loop++) {
  104.             if (strncmp(days[loop], whattime, 2) == 0) {
  105.                 whattime += 2;
  106.                 match = 1;
  107.                 if ((wday == loop) | ((loop == 7) && wday && (wday < 6)))
  108.                     validday = 1;
  109.             }
  110.         }
  111.     }
  112.  
  113.     if (strncmp(whattime, "Any", 3) == 0) {
  114.         validday = 1;
  115.         whattime += 3;
  116.     }
  117.     if (!validday)
  118.         return (0);
  119.  
  120.     if (sscanf(whattime, "%d-%d", &start, &stop) == 2) {
  121.         ltime = curtime->tm_min + 100 * curtime->tm_hour;
  122.         if ((start < stop) && ((ltime > start) && ltime < stop))
  123.             return (1);
  124.         if ((start > stop) && ((ltime > start) || ltime < stop))
  125.             return (1);
  126.     } else
  127.         return (1);
  128.  
  129.     return (0);
  130. }
  131.  
  132. /*************************************************************************/
  133. /* FUNCTION  : validtime                                                 */
  134. /* PURPOSE   : Break apart a set of valid time-strings and pass them to  */
  135. /*             parse_time, returning whether or not ANY matches occurred */
  136. /* ARGUMENTS : a pointer to the time-string                              */
  137. /*************************************************************************/
  138.  
  139. int
  140. #ifdef __STDC__
  141. validtime(char *ptr)
  142. #else
  143. validtime(ptr)
  144. char *ptr;
  145. #endif
  146. {
  147.     char *nextptr;
  148.     int good;
  149.  
  150.     while (1) {
  151.         nextptr = strchr(ptr, '|');
  152.         if (strchr(ptr, '|') == NULL)
  153.             return (parsetime(ptr));
  154.         *nextptr = '\0';
  155.         good = parsetime(ptr);
  156.         *nextptr++ = '|';       /* gotta restore the | or things get skipped! */
  157.         if (good)
  158.             return (1);
  159.         ptr = nextptr;
  160.     }
  161. }
  162.  
  163. int
  164. #ifdef __STDC__
  165. acl_getlimit(char *aclbuf, char *class)
  166. #else
  167. acl_getlimit(aclbuf,class)
  168. char *aclbuf;
  169. char *class;
  170. #endif
  171. {
  172.     char *crptr,
  173.      *ptr,
  174.       linebuf[1024];
  175.     int limit;
  176.  
  177.     while (*aclbuf != '\0') {
  178.         if (strncasecmp(aclbuf, "limit", 5) == 0) {
  179.             for (crptr = aclbuf; *crptr++ != '\n';) ;
  180.             *--crptr = '\0';
  181.             strcpy(linebuf, aclbuf);
  182.             *crptr = '\n';
  183.             (void) strtok(linebuf, " \t");  /* returns "limit" */
  184.             if (strcmp(class, strtok(NULL, " \t")) == 0) {
  185.                 limit = atoi(strtok(NULL, " \t"));  /* returns limit <n> */
  186.                 if ((ptr = strtok(NULL, " \t")) && validtime(ptr))
  187.                     return (limit);
  188.             }
  189.         }
  190.         while (*aclbuf && *aclbuf++ != '\n') ;
  191.     }
  192.  
  193.     return (-1);
  194. }
  195.  
  196. int
  197. #ifdef __STDC__
  198. acl_countusers(char *class)
  199. #else
  200. acl_countusers(class)
  201. char *class;
  202. #endif
  203. {
  204.     int pidfd,
  205.       count,
  206.       stat,
  207.       which;
  208.     char pidfile[1024];
  209.     char line[1024];
  210.     pid_t buf[MAXUSERS];
  211.     FILE *ZeFile;
  212. #ifndef HAVE_FLOCK
  213. struct flock arg;
  214. #endif
  215.  
  216.     sprintf(pidfile, _PATH_PIDNAMES, class);
  217.     pidfd = open(pidfile, O_RDONLY, 0644);
  218.     if (pidfd == -1) {
  219.         return (0);
  220.     }
  221.     lseek(pidfd, 0, L_SET);
  222.  
  223.     count = 0;
  224.  
  225.     if (read(pidfd, buf, sizeof(buf)) == sizeof(buf)) {
  226.         for (which = 0; which < MAXUSERS; which++)
  227.         if (buf[which]) {
  228.             stat = kill(buf[which], SIGCONT);
  229.             if (((stat == -1) && (errno == EPERM)) || !stat) {
  230.                 if (strcmp(progname,"ftpcount")) {
  231. #if defined(SVR4)
  232. #ifdef AIX
  233.                     sprintf(line,"/bin/ps %d",buf[which]);
  234. #elif defined(sun)
  235.                     sprintf(line,"/usr/ucb/ps auxww %d",buf[which]);
  236. #else
  237.                     sprintf(line,"/bin/ps -f -p %d",buf[which]);
  238. #endif
  239. #elif defined(M_UNIX)
  240.                     sprintf(line,"/bin/ps -f -p %d",buf[which]);
  241. #else
  242.                     sprintf(line,"/bin/ps %d",buf[which]);
  243. #endif
  244.                     ZeFile = popen(line, "r");
  245.                     fgets(line, 1024, ZeFile);
  246.                     fgets(line, 1024, ZeFile);
  247.                     printf("%s",line);
  248.                     pclose(ZeFile);
  249.                 }
  250.                 count++;
  251.             }
  252.         }
  253.     }
  254. #ifdef HAVE_FLOCK
  255.     flock(pidfd, LOCK_UN);
  256. #else
  257.     arg.l_type = F_UNLCK; arg.l_whence = arg.l_start = arg.l_len = 0;
  258.     fcntl(pidfd, F_SETLK, &arg);
  259. #endif
  260.     close(pidfd);
  261.  
  262.     return (count);
  263. }
  264.  
  265. void
  266. #ifdef __STDC__
  267. new_list(struct c_list **list)
  268. #else
  269. new_list(list)
  270. struct c_list **list;
  271. #endif
  272. {
  273.     (*list) = (struct c_list *) malloc(sizeof(struct c_list));
  274.  
  275.     (*list)->next = NULL;
  276. }
  277.  
  278. int
  279. #ifdef __STDC__
  280. add_list(char *class, struct c_list **list)
  281. #else
  282. add_list(class,list)
  283. char *class;
  284. struct c_list **list;
  285. #endif
  286. {
  287.     struct c_list *cp;
  288.  
  289.     for (cp = (*list)->next; cp; cp = cp->next) {
  290.         if (!strcmp(cp->class, class))
  291.             return (-1);
  292.     }
  293.  
  294.     cp = (struct c_list *) malloc(sizeof(struct c_list));
  295.  
  296.     cp->class = (char *) malloc(strlen(class) + 1);
  297.     strcpy(cp->class, class);
  298.     cp->next = (*list)->next;
  299.     (*list)->next = cp;
  300.     return (1);
  301. }
  302.  
  303. int
  304. #ifdef __STDC__
  305. main(int argc, char **argv)
  306. #else
  307. main(argc,argv)
  308. int argc;
  309. char **argv;
  310. #endif
  311. {
  312.     FILE *accessfile;
  313.     char class[80],
  314.       linebuf[1024],
  315.      *aclbuf,
  316.      *myaclbuf,
  317.      *crptr;
  318.     int limit;
  319.     struct stat finfo;
  320.     struct c_list *list;
  321.  
  322.     if (progname = strrchr(argv[0], '/'))  ++progname;
  323.     else  progname = argv[0];
  324.  
  325.     if (argc > 1) {
  326.         fprintf(stderr, "%s\n", version);
  327.         exit(0);
  328.     }
  329.  
  330.     if ((accessfile = fopen(_PATH_FTPACCESS, "r")) == NULL) {
  331.         if (errno != ENOENT)
  332.             perror("ftpcount: could not open() access file");
  333.         exit(1);
  334.     }
  335.     if (stat(_PATH_FTPACCESS, &finfo)) {
  336.         perror("ftpcount: could not stat() access file");
  337.         exit(1);
  338.     }
  339.     if (finfo.st_size == 0) {
  340.         printf("%s: no service classes defined, no usage count kept\n",progname);
  341.         exit(0);
  342.     } else {
  343.         if (!(aclbuf = (char *) malloc(finfo.st_size + 1))) {
  344.             perror("ftpcount: could not malloc aclbuf");
  345.             exit(1);
  346.         }
  347.         fread(aclbuf, finfo.st_size, 1, accessfile);
  348.         *(aclbuf + finfo.st_size) = '\0';
  349.     }
  350.  
  351.     (void) new_list(&list);
  352.     myaclbuf = aclbuf;
  353.     while (*myaclbuf != '\0') {
  354.         if (strncasecmp(myaclbuf, "class", 5) == 0) {
  355.             for (crptr = myaclbuf; *crptr++ != '\n';) ;
  356.             *--crptr = '\0';
  357.             strcpy(linebuf, myaclbuf);
  358.             *crptr = '\n';
  359.             (void) strtok(linebuf, " \t");  /* returns "class" */
  360.             strcpy(class, strtok(NULL, " \t")); /* returns class name */
  361.             if ((add_list(class, &list)) < 0) {
  362.                 /* we have a class with multiple "class..." lines so, only
  363.                  * display one count... */
  364.                 ;
  365.             } else {
  366.                 limit = acl_getlimit(myaclbuf, class);
  367.             if (strcmp(progname,"ftpcount")) {
  368.                 printf("Service class %s: \n", class);
  369.                 printf("   - %3d users (%3d maximum)\n\n",
  370.             acl_countusers(class), limit);
  371.         }
  372.         else
  373.                 printf("Service class %-20.20s - %3d users (%3d maximum)\n",
  374.                        class, acl_countusers(class), limit);
  375.             }
  376.         }
  377.         while (*myaclbuf && *myaclbuf++ != '\n') ;
  378.     }
  379.     exit(0);
  380. }
  381.