home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / w00w00 / sectools / SRS / server / src / parse.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-12  |  50.7 KB  |  1,846 lines

  1. /*  READ ME READ ME READ ME READ ME READ ME READ ME READ ME READ ME  */
  2. /*    This file is _horrendous_! Do not even attempt to follow it.   */
  3. /*    I'm going to have to wait til SRSv2 to clean it up. There is   */
  4. /*    just not enough time.                                          */
  5. /*                                                                   */
  6. /*    There is a lot of repetitious and redundant code.. and huge    */
  7. /*    function sizes. Once we clean up it will be a lot smaller      */
  8. /*  READ ME READ ME READ ME READ ME READ ME READ ME READ ME READ ME  */
  9.  
  10. /* This has functions to parse various data from server */
  11. /* ---------------------------------------------------- */
  12.  
  13. #include "headers.h" /* has all important stuff */
  14.  
  15. /* this function parses the client ID and puts it in the struct */
  16. void getID(char *str)
  17. {
  18.    int count = 0; /* prevent overflows */
  19.  
  20.    char ID[8];
  21.    char *IDptr, *dataptr;
  22.  
  23.    memset(ID, 0, sizeof(ID));
  24.    IDptr = ID, dataptr = strstr(str, "ID");
  25.  
  26.    dataptr += 3; /* skip "ID " */
  27.  
  28.    while ((*dataptr) && (*dataptr != ' ') &&
  29.           (isprint(*dataptr) != 0) && (count < (int)sizeof(ID)))
  30.    {
  31.       *IDptr++ = *dataptr++;
  32.       count++;
  33.    }
  34.  
  35.    clients[curClient].ID = atoi(ID);
  36. }
  37.  
  38.  
  39. /* ---------------------------------------- */
  40.  
  41.  
  42. /* parse options from config file */
  43. void parseSysConf(char *str)
  44. {   
  45.    register int i, j;
  46.  
  47.    int count = 0;
  48.    int didfacs = 0, numfacs = 0; 
  49.  
  50.    char filename[MAXFNAMESIZE];
  51.    char facility[16], priority[16];
  52.  
  53.    char *dataptr, *facptr, *priptr, *fnameptr;
  54.  
  55.    memset(filename, 0, sizeof(filename));
  56.    memset(facility, 0, sizeof(facility));
  57.    memset(priority, 0, sizeof(priority));
  58.  
  59.    dataptr = str;
  60.    facptr = facility, priptr = priority, fnameptr = filename;
  61.  
  62.    if ((str[0] == '\0') || (str[0] == '\n') || (isprint(str[0]) == 0)) 
  63.       return;
  64.  
  65.    else if (strchr(str, '#') != NULL)
  66.    {
  67.       if (str[0] == '#') return;
  68.       else
  69.       {
  70.          char *ptr = strchr(str, '#');
  71.          if (ptr != NULL) *ptr = '\0'; 
  72.       }   
  73.    }
  74.  
  75.    else if ((strstr(str, "ifdef(") != NULL) ||
  76.        (strstr(str, "ifndef(") != NULL) ||
  77.        (strstr(str, "elif(") != NULL) ||
  78.        (strstr(str, "else(") != NULL))
  79.    {
  80.       /* FIX - do we need to set any values to ERROR? */
  81.       error("ifdef(), ifndef(), elif(), and else() "
  82.             "aren't supported at this time\n\n");
  83.  
  84.       return;
  85.    }
  86.  
  87.    else if (strchr(str, ')') != NULL) 
  88.    {
  89.       debug("possibly the end of an ifdef().. ignoring\n");
  90.       return;
  91.    }
  92.  
  93.    /* --------------------- facility stuff ---------------------- */
  94.  
  95.    curlogfd++;
  96.    debug("(in parseSysConf) curlogfd = %d, curClient = %d\n", curlogfd,
  97.          curClient);
  98.  
  99.    if (curlogfd >= MAXLOGTYPES)
  100.    {
  101.       error("error parsing /etc/syslog.conf.. overflowed logs[]\n\n");
  102.       send_data(clients[curClient].sockfd, "ERROR: %s\n", INTPARERROR);
  103.       quit(ERROR);
  104.    }
  105.  
  106.    if (str[0] == '*') 
  107.    {
  108.       clients[curClient].logs[curlogfd].facility = ALL;
  109.  
  110.       memset(facility, 0, sizeof(facility));
  111.       strcpy(facility, "*");
  112.  
  113.       debug("facility = * (all facilities)\n\n");
  114.    }
  115.  
  116.    else if (str[0] == '-')
  117.       clients[curClient].logs[curlogfd].nsync = 1;
  118.  
  119.    /* parse facility.* */
  120.    else /* no tricks for us.. just do it normally */
  121.    {
  122.       facptr = facility;
  123.       memset(facility, 0, sizeof(facility));
  124.  
  125.       /* do manual parsing */
  126.       count = 0;
  127.       while ((*dataptr) && (*dataptr != ' ') &&
  128.              (*dataptr != '.') && (*dataptr != ',') && 
  129.              (isprint(*dataptr) != 0) && (count < (int)sizeof(facility)-1))
  130.       {
  131.          *facptr++ = *dataptr++;
  132.          count++;
  133.       }
  134.  
  135.       debug("facility = %s\n", facility);
  136.  
  137.       if (isprint(*dataptr) != 0)
  138.          debug("current seperator = %c\n", *dataptr);
  139.  
  140.       else
  141.          debug("current seperator = 0x%x (in hex)\n", *dataptr);
  142.  
  143.       if (debugging == 1)
  144.       {
  145.          (void)putchar('\n');
  146.          (void)write(dblogfd, "\n", 1);
  147.       }
  148.  
  149.       clients[curClient].logs[curlogfd].facility = facNameToVal(facility);
  150.  
  151.       if (clients[curClient].logs[curlogfd].facility == ERROR)
  152.       {
  153.          error("(in parseSysConf) error parsing line:\n%s"
  154.                "unknown facility type\n\n", str);
  155.  
  156.          send_data(clients[curClient].sockfd, "ERROR: %s\n", INTPARERROR);
  157.          quit(ERROR);
  158.       }
  159.  
  160.       clients[curClient].logs[curlogfd].facility = facNameToVal(facility);
  161.  
  162.       if (*dataptr == ',')
  163.       {
  164.          parsePri(str); /* parse the previous one */
  165.          dataptr += 1; 
  166.  
  167.          curlogfd++, numfacs = 0;
  168.          if (curlogfd >= MAXLOGTYPES)
  169.          {
  170.             error("error parsing /etc/syslog.conf.. overflowed logs[]\n\n");
  171.             send_data(clients[curClient].sockfd, "ERROR: %s\n", INTPARERROR);
  172.             quit(ERROR);
  173.          }
  174. /*
  175.          if (debugging == 1)
  176.          {
  177.             (void)putchar('\n');
  178.             (void)write(dblogfd, "\n", 1);
  179.          }
  180. */
  181.          debug("curlogfd = %d\n", curlogfd);
  182.  
  183.          debug("---before parseFac---\n");
  184.          numfacs = parseFac(dataptr, numfacs);
  185.          debug("---after parseFac---\n");
  186.  
  187.          debug("curlogfd = %d\n", curlogfd);
  188. /*
  189.          if (debugging == 1)
  190.          {
  191.             (void)putchar('\n');
  192.             (void)write(dblogfd, "\n", 1);
  193.          }
  194. */
  195.          didfacs = 1;
  196.       }
  197.    }
  198.  
  199.    /* --------------------- priority stuff ---------------------- */
  200.  
  201.    /* "*.*" probably -- try a shortcut/hack */
  202.    if (str[3] == '*') /* do we have a shortcut? */
  203.    {
  204.       clients[curClient].logs[curlogfd].priority.priority = ALL;
  205.  
  206.       memset(priority, 0, sizeof(priority));
  207.       strcpy(priority, "*");
  208.  
  209.       debug("priority = * (all priorities)\n");
  210.    }
  211.  
  212.    /* parse *.priority */
  213.    else if (didfacs != 1) /* no tricks for us.. just do it normally */
  214.    {
  215.       dataptr = strchr(str, '.');
  216.       if (dataptr == NULL)
  217.       {
  218.          error("(in sysLogConf) unable to parse:\n%s\n", str);
  219.          send_data(clients[curClient].sockfd, "ERROR: %s\n", INTPARERROR);
  220.  
  221.          quit(ERROR);
  222.       }
  223.  
  224.       dataptr += 1; /* skip '.' */
  225.  
  226.       /* can be "*.!=*" or "*.=*" */
  227.       if (*dataptr == '!') 
  228.       {
  229.          /* check for possible bugs */
  230.          if ((*(dataptr + 1)) == '*')
  231.          {
  232.             error("error parsing line (no '*' allowed after '!'):\n%s\n", str);
  233.             send_data(clients[curClient].sockfd, "ERROR: %s\n", INTPARERROR);
  234.             quit(ERROR);
  235.          }
  236.  
  237.          debug("exclude ('!') on\n");
  238.          clients[curClient].logs[curlogfd].priority.exclude = 1;
  239.       }
  240.  
  241.       if ((*dataptr == '=') || ((*(dataptr+1)) == '=')) 
  242.       {
  243.          /* check for possible bugs */
  244.          if (((*(dataptr + 1)) == '*') || ((*(dataptr + 2)) == '*'))
  245.          {
  246.             error("error parsing line (no '*' allowed after '='):\n%s\n", str);
  247.             send_data(clients[curClient].sockfd, "ERROR: %s\n", INTPARERROR);
  248.             quit(ERROR);
  249.          }
  250.  
  251.          debug("single ('=') on\n");
  252.          clients[curClient].logs[curlogfd].priority.single = 1;
  253.       }
  254.  
  255.       /* skip to next valid data to parse */
  256.       if (clients[curClient].logs[curlogfd].priority.single == 1)
  257.       {
  258.          if (clients[curClient].logs[curlogfd].priority.exclude == 1)
  259.             dataptr += 2; /* skip both '!' and '=' */
  260.  
  261.          else dataptr += 1;
  262.       }
  263.  
  264.       else if (clients[curClient].logs[curlogfd].priority.exclude == 1)
  265.          dataptr += 1;
  266.          
  267.       priptr = priority;
  268.       memset(priority, 0, sizeof(priority));
  269.       
  270.       count = 0;
  271.       while ((*dataptr) && (*dataptr != ' ') &&
  272.              (*dataptr != ';') && (isprint(*dataptr) != 0) && 
  273.              (count < (int)sizeof(priority)-1))
  274.       {
  275.          *priptr++ = *dataptr++;
  276.          count++;
  277.       }
  278.  
  279.       if (strchr(priority, '*') != NULL)
  280.       {
  281.          if (clients[curClient].logs[curlogfd].priority.exclude == 1)
  282.          {
  283.             (void)strcpy(priority, "none");
  284.             clients[curClient].logs[curlogfd].priority.priority = NONE;
  285.             debug("priority = %s (no priorities)\n", priority);
  286.          }
  287.  
  288.          else
  289.          {
  290.             clients[curClient].logs[curlogfd].priority.priority = ALL;
  291.             debug("priority = %s (all priorities)\n", priority);
  292.          }
  293.       }
  294.  
  295.       else if (strncmp(priority, "none", 4) == 0)
  296.       {
  297.          if (clients[curClient].logs[curlogfd].priority.exclude == 1)
  298.          {
  299.             (void)strcpy(priority, "all");
  300.             clients[curClient].logs[curlogfd].priority.priority = ALL;
  301.             debug("priority = !none (all priorities)\n");
  302.          }
  303.  
  304.          else
  305.          {
  306.             (void)strcpy(priority, "none");
  307.             clients[curClient].logs[curlogfd].priority.priority = NONE;
  308.             debug("priority = %s (no priorities)\n", priority);
  309.          }
  310.       }
  311.  
  312.       else 
  313.       {
  314.          if (clients[curClient].logs[curlogfd].priority.exclude == 1)
  315.          {
  316.             if (clients[curClient].logs[curlogfd].priority.single == 1)
  317.             {
  318.                clients[curClient].logs[curlogfd].priority.priority = ERROR;
  319.                clients[curClient].logs[curlogfd].priority.ignpri = 
  320.             priNameToVal(priority);
  321.             }
  322.          }
  323.  
  324.          else
  325.             clients[curClient].logs[curlogfd].priority.priority = 
  326.             priNameToVal(priority);
  327.  
  328.          debug("priority = %s\n", priority);
  329.       }
  330.  
  331.       if (isprint(*dataptr) != 0)
  332.          debug("current seperator = '%c'\n", *dataptr);
  333.  
  334.       else
  335.          debug("current seperator = 0x%x (in hex)\n", *dataptr);
  336.  
  337.       if (*dataptr == ';')
  338.       {
  339.          errors = 0, dataptr += 1;
  340.          parseFile(dataptr, didfacs, numfacs, facility, priority);
  341.  
  342.          if (errors == 1)
  343.          {
  344.             errors = 0;
  345.             return;
  346.          }
  347.  
  348.          if (debugging == 1)
  349.          {
  350.             (void)putchar('\n');
  351.             (void)write(dblogfd, "\n", 1);
  352.          }
  353.  
  354.          debug("---before parseSysConf---\n");
  355.          parseSysConf(dataptr);
  356. /*
  357.          if (debugging == 1)
  358.          {
  359.             (void)putchar('\n');
  360.             (void)write(dblogfd, "\n", 1);
  361.          }
  362. */
  363.          return;
  364.       }
  365.    }
  366.    
  367.    /* -------------- little error checking -------------- */
  368.  
  369.    if (didfacs == 1)
  370.       while ((isprint(*dataptr) != 0) && (*dataptr != ' ')) dataptr += 1;
  371.  
  372.    /* get to file name */
  373.    while ((isprint(*dataptr) == 0) || (*dataptr == ' ')) dataptr += 1;
  374.  
  375.    if (*dataptr == '\0')
  376.    {
  377.       error("error parsing line:\n%s"
  378.             "found an unexpected null..\n\n", str);
  379.  
  380.       send_data(clients[curClient].sockfd, "ERROR: %s\n", INTPARERROR);
  381.       quit(ERROR);
  382.    }
  383.  
  384.    else if (*dataptr == '\n')
  385.    {
  386.       error("error parsing line:\n%s"
  387.             "found an unexpected newline..\n\n", str);
  388.  
  389.       send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR);
  390.       quit(ERROR);
  391.    }
  392.  
  393.    /* -------------- file/device/user output ------------- */
  394.   
  395.    if (debugging == 1)
  396.    {
  397.       (void)putchar('\n');
  398.       (void)write(dblogfd, "\n", 1);
  399.    }
  400.  
  401.    debug("dataptr = '%c' (1)\n", (*dataptr));
  402.    if (*dataptr == '/')
  403.    {
  404.       char *mvptr = strrchr(dataptr, '/');
  405.       mvptr += 1, dataptr = mvptr; 
  406.  
  407.       memset(filename, 0, sizeof(filename));
  408.       if (getcwd(filename, (sizeof(filename) / 2) - 1) == NULL)
  409.       {
  410.          error("error with getcwd(): %s\n\n", strerror(errno));
  411.          send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR);
  412.          quit(ERROR);
  413.       }
  414.  
  415.       (void)strcat(filename, "/");
  416.       fnameptr += strlen(filename);
  417.  
  418.       count = 0;
  419.       while ((*dataptr) && (isprint(*dataptr) != 0) && 
  420.             (count < (((int)sizeof(filename) / 2) - 
  421.                        (int)strlen(filename) - 1)))
  422.       {
  423.          *fnameptr++ = *dataptr++;
  424.          count++;
  425.       }    
  426.  
  427.       if (didfacs != 1)
  428.          debug("logging %s.%s to: %s\n", facility, priority, filename);
  429.  
  430.       else
  431.       {
  432.          for (i = curlogfd - numfacs; i <= curlogfd; i++)
  433.          {
  434.             strcpy(facility, 
  435.                    facValToName(clients[curClient].logs[i].facility));
  436.  
  437.             if (clients[curClient].logs[i].priority.priority == ALL)
  438.                strcpy(priority, "*");
  439.  
  440.             else if (clients[curClient].logs[i].priority.priority == NONE)
  441.                strcpy(priority, "none");
  442.  
  443.             else
  444.                strcpy(priority, 
  445.                  priValToName(clients[curClient].logs[i].priority.priority));
  446.  
  447.             debug("logging %s.%s to: %s\n", facility, priority, filename);
  448.          }
  449.       }
  450.  
  451.       /* malloc filenames and open fd's */
  452.       if (didfacs != 1)
  453.       {
  454.          clients[curClient].logs[curlogfd].filename = 
  455.             (char *)malloc(strlen(filename)+1);
  456.  
  457.          if (clients[curClient].logs[curlogfd].filename == NULL)
  458.          {
  459.             error("error with malloc(): %s\n\n", strerror(errno));
  460.             send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR); 
  461.             quit(ERROR);
  462.          }
  463.  
  464.          memset(clients[curClient].logs[curlogfd].filename, 0, 
  465.                 strlen(filename)+1);
  466.  
  467.          strcpy(clients[curClient].logs[curlogfd].filename, filename);
  468.  
  469.          for (i = 0; i <= curlogfd; i++)
  470.          {
  471.             if ((clients[curClient].logs[i].filename == NULL) || 
  472.                 (clients[curClient].logs[i].fd <= 0)) continue;
  473.  
  474.             if (strcmp(clients[curClient].logs[curlogfd].filename, 
  475.                        clients[curClient].logs[i].filename) == 0)
  476.             {
  477.                clients[curClient].logs[curlogfd].fd = 
  478.             clients[curClient].logs[i].fd;
  479.  
  480.                break;
  481.             }
  482.          }
  483.  
  484.          if (clients[curClient].logs[curlogfd].fd <= 0)
  485.          {
  486.             clients[curClient].logs[curlogfd].fd =
  487.          open(clients[curClient].logs[curlogfd].filename, 
  488.                       O_CREAT | O_WRONLY | O_APPEND | O_NOCTTY, 0600);
  489.  
  490.             if (clients[curClient].logs[curlogfd].fd == ERROR)
  491.             {
  492.                error("error opening %s: %s\n\n", 
  493.                      clients[curClient].logs[curlogfd].filename, 
  494.                      strerror(errno));
  495.  
  496.                send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR); 
  497.                quit(ERROR);
  498.             }
  499.          }
  500.  
  501.          if (isatty(clients[curClient].logs[curlogfd].fd) == 1) 
  502.             debug("%s is a tty (device)\n", 
  503.                   clients[curClient].logs[curlogfd].filename);
  504.       }
  505.  
  506.       /* either a facility or colon was parsed */
  507.       else
  508.       {
  509.          for (i = curlogfd - numfacs; i <= curlogfd; i++)
  510.          {
  511.             clients[curClient].logs[i].filename = 
  512.             (char *)malloc(strlen(filename)+1);
  513.  
  514.             if (clients[curClient].logs[i].filename == NULL)
  515.             {
  516.                error("error with malloc(): %s\n\n", strerror(errno));
  517.                send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR); 
  518.                quit(ERROR);
  519.             }
  520.  
  521.             memset(clients[curClient].logs[i].filename, 0, 
  522.                    strlen(filename)+1);
  523.  
  524.             strcpy(clients[curClient].logs[i].filename, filename);
  525.  
  526.             for (j = 0; j <= curlogfd; j++)
  527.             {
  528.                if ((clients[curClient].logs[j].filename == NULL) || 
  529.                    (clients[curClient].logs[j].fd <= 0)) continue;
  530.  
  531.                if (strcmp(clients[curClient].logs[i].filename, 
  532.                           clients[curClient].logs[j].filename) == 0)
  533.                {
  534.                   clients[curClient].logs[i].fd = clients[curClient].logs[j].fd;
  535.                   break;
  536.                }
  537.             }
  538.  
  539.             if (clients[curClient].logs[i].fd <= 0)
  540.             {
  541.                clients[curClient].logs[curlogfd].fd = 
  542.           open(clients[curClient].logs[i].filename, 
  543.                        O_CREAT | O_WRONLY | O_APPEND | O_NOCTTY, 0600);
  544.  
  545.                if (clients[curClient].logs[curlogfd].fd == ERROR)
  546.                {
  547.                   error("error opening %s: %s\n\n", 
  548.                         clients[curClient].logs[i].filename, strerror(errno));
  549.  
  550.                   send_data(clients[curClient].sockfd, "ERROR: %s\n", 
  551.                             INTERROR); 
  552.  
  553.                   quit(ERROR);
  554.                }
  555.             }
  556.  
  557.             if (isatty(clients[curClient].logs[i].fd) == 1) 
  558.                debug("%s is a tty (device)\n", 
  559.                      clients[curClient].logs[i].filename);
  560.          }
  561.  
  562.          if (debugging == 1)
  563.          {
  564.             (void)putchar('\n');
  565.             (void)write(dblogfd, "\n", 1);
  566.          }
  567.       }
  568.    }
  569.  
  570.    /* determine the device, file, or host to log to */
  571.    else if (*dataptr == '@') /* '@' == remote host logging  */
  572.       parseRemHost(str);
  573.  
  574.    else if (*dataptr == '|') /* '|' == output to named pipe */
  575.       parseNamedPipe(str);
  576.  
  577.    else if (*dataptr == '*')
  578.    {
  579.       char filename[MAXFNAMESIZE];
  580.  
  581.       /* 'wall' everyone online... */
  582.  
  583.       memset(filename, 0, sizeof(filename));
  584.       if (getcwd(filename, (sizeof(filename) - 11)) == NULL)
  585.       {
  586.          error("error with getcwd(): %s\n\n", strerror(errno));
  587.          send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR); 
  588.          quit(ERROR);
  589.       }
  590.  
  591.       strcat(filename, "/wall.log");
  592.  
  593.       clients[curClient].logs[curlogfd].filename = 
  594.         malloc(strlen(filename) + 1);
  595.  
  596.       if (clients[curClient].logs[curlogfd].filename == NULL)
  597.       {
  598.          error("error with malloc(): %s\n\n", strerror(errno));
  599.          send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR); 
  600.          quit(ERROR);
  601.       }
  602.  
  603.       memset(clients[curClient].logs[curlogfd].filename, 0, 
  604.              strlen(filename) + 1);
  605.  
  606.       strcpy(clients[curClient].logs[curlogfd].filename, filename);
  607.  
  608.       error("wall'ing is not supported at this time..\n"
  609.             "outputting %s.%s to %s instead\n\n", facility, priority, 
  610.             clients[curClient].logs[curlogfd].filename);
  611.  
  612.       clients[curClient].logs[curlogfd].fd =
  613.          open(clients[curClient].logs[curlogfd].filename, 
  614.                       O_CREAT | O_WRONLY | O_APPEND, 0600);
  615.  
  616.       if (clients[curClient].logs[curlogfd].fd == ERROR)
  617.       {
  618.          error("error opening %s: %s\n\n", 
  619.                clients[curClient].logs[curlogfd].filename, strerror(errno));
  620.  
  621.          send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR); 
  622.     
  623.          quit(ERROR);
  624.       }
  625.    }
  626.  
  627.    /* check if they are users in /etc/passwd.. and if they're online */
  628.    else if (isalpha(*dataptr) != 0)
  629.    {
  630.       int new1 = 1;
  631.  
  632.       char *userptr;
  633.       char filename[MAXFNAMESIZE];
  634.  
  635.       /* just some more error checking */
  636.       if (strchr(dataptr, '/') != NULL)
  637.       {
  638.          /* FIX - send err.. follow default behavior */
  639.          error("file names must begin with '/':\n%s\n", str);
  640.          send_data(clients[curClient].sockfd, "ERROR: %s\n", INTPARERROR); 
  641.          quit(ERROR);
  642.       }
  643.  
  644.       if (debugging == 1)
  645.       {
  646.          (void)putchar('\n'); 
  647.          (void)write(dblogfd, "\n", 1);
  648.       }
  649.  
  650.       error("logging msgs to users is not supported yet..\n"
  651.             "outputting to the following instead:\n\n");
  652.  
  653.       while(1)
  654.       {
  655.          if (new1 == 1) new1 = 0;
  656.          else /* we've already been in this loop once before */
  657.          {
  658.             if (curlogfd+1 >= MAXLOGTYPES)
  659.             {
  660.                error("overflowed logs[]\n\n"); 
  661.                send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR); 
  662.                quit(ERROR);
  663.             }
  664.  
  665.             else 
  666.             {
  667.                copyLogStruct(curlogfd, curlogfd+1);
  668.                curlogfd++;
  669.             }
  670.          }
  671.  
  672.          memset(filename, 0, sizeof(filename));
  673.          if (getcwd(filename, ((sizeof(filename) / 2) - 11)) == NULL)
  674.          {
  675.             error("error with getcwd(): %s\n\n", strerror(errno));
  676.             send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR); 
  677.             quit(ERROR);
  678.          }
  679.  
  680.          clients[curClient].logs[curlogfd].filename = 
  681.         (char *)malloc(sizeof(filename) + 1);
  682.  
  683.          if (clients[curClient].logs[curlogfd].filename == NULL)
  684.          {
  685.             error("error with malloc(): %s\n\n", strerror(errno));
  686.             quit(ERROR);
  687.          }
  688.  
  689.          memset(clients[curClient].logs[curlogfd].filename, 0,
  690.                 sizeof(filename) + 1);
  691.  
  692.          strcpy(clients[curClient].logs[curlogfd].filename, filename);
  693.          strcat(clients[curClient].logs[curlogfd].filename, "/");
  694.  
  695.          userptr = clients[curClient].logs[curlogfd].filename + 
  696.                    strlen(clients[curClient].logs[curlogfd].filename);
  697.  
  698.          /* now parsing the user names.. check for ','s */
  699.          count = 0;
  700.          while ((*dataptr) && (isprint(*dataptr) != 0) &&
  701.                 (*dataptr != ',') && (count < MAXUSERNAME))
  702.          {
  703.             *userptr++ = *dataptr++;
  704.             count++;
  705.          }
  706.  
  707.          strcat(clients[curClient].logs[curlogfd].filename, "-user.log");
  708.          error("%s.%s to %s\n", facility, priority, 
  709.                clients[curClient].logs[curlogfd].filename);
  710.  
  711.          /* (void)write(errlogfd, "\n", 1); */
  712.  
  713.          clients[curClient].logs[curlogfd].fd = 
  714.             open(clients[curClient].logs[curlogfd].filename,
  715.                              O_CREAT | O_APPEND | O_WRONLY, 0600);
  716.  
  717.          if (clients[curClient].logs[curlogfd].fd == ERROR)
  718.          { 
  719.             error("error opening %s: %s\n\n", 
  720.                   clients[curClient].logs[curlogfd].filename);
  721.  
  722.             send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR); 
  723.             quit(ERROR);
  724.          }
  725.  
  726.          if (*dataptr == ',') dataptr += 1;
  727.          else break;
  728.       }
  729.  
  730.       if (debugging == 1)
  731.       {
  732.          (void)putchar('\n');
  733.          (void)write(dblogfd, "\n", 1);
  734.       }
  735.  
  736.       (void)write(errlogfd, "\n", 1);
  737.    }
  738.  
  739.    /* ---------------------------------------------------- */
  740.  
  741.    return;
  742. }
  743.  
  744.  
  745. /* ----------------------- */
  746.  
  747.  
  748. /* functions to parse specific log types ('@', '|', etc.) */ 
  749.  
  750. /* parse '@' from syslog.conf */
  751. void parseRemHost(char *str)
  752. {
  753.    register int i;
  754.  
  755.    int count = 0; /* prevent overflows */
  756.  
  757.    char *dataptr, *fnameptr;
  758.    char filename[MAXFNAMESIZE];
  759.  
  760.    dataptr = str, fnameptr = filename;
  761.    memset(filename, 0, sizeof(filename));
  762.  
  763.    if (getcwd(filename, (sizeof(filename) / 2) - 11) == NULL)
  764.    {
  765.       error("error with getcwd(): %s\n\n", strerror(errno));
  766.       send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR); 
  767.       quit(ERROR);
  768.    }
  769.  
  770.    /* strcpy(filename, "./"); */
  771.    /* fnameptr += 2; */
  772.  
  773.    strcat(filename, "/");
  774.    fnameptr += strlen(filename);
  775.  
  776.    dataptr = strchr(str, '@'), dataptr += 1;
  777.  
  778.    count = 0;
  779.    while ((*dataptr) && (*dataptr != ' ') && 
  780.           (isprint(*dataptr) != 0) && 
  781.           (count < (((int)sizeof(filename) / 2) - (int)strlen(filename) - 1)))
  782.    {
  783.          *fnameptr++ = *dataptr++;
  784.          count++;
  785.    }
  786.  
  787.    (void)strcat(filename, "-host.log");
  788.  
  789.    if (debugging == 1)
  790.    {
  791.       (void)putchar('\n');
  792.       (void)write(dblogfd, "\n", 1);
  793.    }
  794.  
  795.    error("remote logging ('@') is not supported at this time..\n"
  796.          "outputting to %s instead\n\n", filename);
  797.  
  798.    if (debugging == 1) (void)write(dblogfd, "\n", 1);
  799.  
  800.    /* curlogfd++; */
  801.  
  802.    clients[curClient].logs[curlogfd].filename = 
  803.         (char *)malloc(strlen(filename)+1);
  804.  
  805.    if (clients[curClient].logs[curlogfd].filename == NULL)
  806.    {
  807.       error("error with malloc(): %s\n\n", strerror(errno));
  808.       quit(ERROR);
  809.    }
  810.  
  811.    memset(clients[curClient].logs[curlogfd].filename, 0, strlen(filename)+1);
  812.    strcpy(clients[curClient].logs[curlogfd].filename, filename);
  813.  
  814.    for (i = 0; i <= curlogfd; i++)
  815.    {
  816.       if ((clients[curClient].logs[i].filename == NULL) || 
  817.           (clients[curClient].logs[i].fd <= 0)) continue;
  818.  
  819.       if (strcmp(clients[curClient].logs[curlogfd].filename, 
  820.                  clients[curClient].logs[i].filename) == 0)
  821.       {
  822.          clients[curClient].logs[curlogfd].fd = clients[curClient].logs[i].fd;
  823.          break;
  824.       }
  825.    }
  826.  
  827.    if (clients[curClient].logs[curlogfd].fd <= 0)
  828.    {
  829.       clients[curClient].logs[curlogfd].fd = 
  830.         open(clients[curClient].logs[curlogfd].filename, 
  831.                      O_CREAT | O_WRONLY | O_APPEND | O_NOCTTY, 0600);
  832.  
  833.       if (clients[curClient].logs[curlogfd].fd == ERROR)
  834.       {
  835.          error("error opening %s: %s\n\n", 
  836.                clients[curClient].logs[curlogfd].filename, strerror(errno));
  837.  
  838.          send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR); 
  839.          quit(ERROR);
  840.       }
  841.    }
  842.  
  843.    return;
  844. }
  845.  
  846.  
  847. /* -------------------------- */
  848.  
  849.  
  850. /* parse '|' from syslog.conf */
  851. void parseNamedPipe(char *str)
  852. {
  853.    register int i;
  854.  
  855.    int count = 0; /* prevent overflows */
  856.  
  857.    char filename[MAXFNAMESIZE];
  858.    char *dataptr, *fnameptr;
  859.  
  860.    fnameptr = filename;
  861.    memset(filename, 0, sizeof(filename));
  862.  
  863.    dataptr = strrchr(str, '/');
  864.  
  865.    if (dataptr != NULL) dataptr += 1;
  866.    else
  867.    {
  868.       error("error parsing:\n%s"
  869.             "filenames must begin with '/'\n\n", str);
  870.  
  871.       send_data(clients[curClient].sockfd, "ERROR: %s\n", INTPARERROR);
  872.       quit(ERROR);
  873.    }
  874.  
  875.    if (getcwd(filename, (sizeof(filename) / 2) - 11) == NULL)
  876.    {
  877.       error("error with getcwd(): %s\n\n", strerror(errno));
  878.       send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR);
  879.       quit(ERROR);
  880.    }
  881.  
  882.    (void)strcat(filename, "/");
  883.    fnameptr += strlen(filename);
  884.  
  885.    count = 0;
  886.    while ((*dataptr) && (isprint(*dataptr) != 0) && 
  887.           (count < (((int)sizeof(filename) / 2) - (int)strlen(filename) - 1)))
  888.    {
  889.       *fnameptr++ = *dataptr++;
  890.       count++;
  891.    }    
  892.  
  893.    (void)strcat(filename, "-pipe.log");
  894.  
  895.    if (debugging == 1) (void)write(dblogfd, "\n", 1);
  896.    error("named pipes ('|') aren't supported at this time..\n"
  897.          "outputting to %s instead\n\n", filename);
  898.  
  899.    /* open the parsed file */
  900.    /* -------------------- */
  901.    clients[curClient].logs[curlogfd].filename = 
  902.         (char *)malloc(strlen(filename)+1);
  903.  
  904.    if (clients[curClient].logs[curlogfd].filename == NULL)
  905.    {
  906.       error("error with malloc(): %s\n\n", strerror(errno));
  907.       quit(ERROR);
  908.    }
  909.  
  910.    memset(clients[curClient].logs[curlogfd].filename, 0, strlen(filename)+1);
  911.    strcpy(clients[curClient].logs[curlogfd].filename, filename);
  912.  
  913.    for (i = 0; i <= curlogfd; i++)
  914.    {
  915.       if ((clients[curClient].logs[i].filename == NULL) || 
  916.           (clients[curClient].logs[i].fd <= 0)) continue;
  917.  
  918.       else if (strcmp(clients[curClient].logs[curlogfd].filename, 
  919.                       clients[curClient].logs[i].filename) == 0)
  920.       {
  921.          clients[curClient].logs[curlogfd].fd = clients[curClient].logs[i].fd;
  922.          break;
  923.       }
  924.    }
  925.  
  926.    if (clients[curClient].logs[curlogfd].fd <= 0)
  927.    {
  928.       clients[curClient].logs[curlogfd].fd =
  929.         open(clients[curClient].logs[curlogfd].filename, 
  930.                      O_CREAT | O_WRONLY | O_APPEND | O_NOCTTY, 0600);
  931.  
  932.       if (clients[curClient].logs[curlogfd].fd == ERROR)
  933.       {
  934.          error("error opening %s: %s\n\n", 
  935.                clients[curClient].logs[curlogfd].filename, strerror(errno));
  936.  
  937.          send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR); 
  938.          quit(ERROR);
  939.       }
  940.    }
  941.  
  942.    return;
  943. }
  944.  
  945.  
  946. /* ------------------------------------------------------ */
  947.  
  948.  
  949. /* parse next facility.. called when there are multi-facilities */
  950. int parseFac(char *str, int numfacs)
  951. {
  952.    int count;
  953.  
  954.    char *facptr;
  955.    char *dataptr = str;
  956.  
  957.    char facility[16];
  958.  
  959.    facptr = facility;
  960.    memset(facility, 0, sizeof(facility));
  961.  
  962.    /* do manual parsing */
  963.    count = 0;
  964.  
  965.    while ((*dataptr) && (*dataptr != ' ') &&
  966.           (*dataptr != '.') && (*dataptr != ',') && 
  967.           (*dataptr != ';') && (isprint(*dataptr) != 0) && 
  968.           (count < (int)sizeof(facility)-1))
  969.    {
  970.       *facptr++ = *dataptr++;
  971.       count++;
  972.    }
  973.  
  974.    if (isprint(*dataptr) != 0)
  975.       debug("current seperator = %c\n", *dataptr);
  976.  
  977.    else
  978.       debug("current seperator = 0x%x (in hex)\n", *dataptr);
  979.  
  980.    clients[curClient].logs[curlogfd].facility = facNameToVal(facility);
  981.    if (clients[curClient].logs[curlogfd].facility == ERROR)
  982.    {
  983.       error("(in parseSysConf) error parsing line:\n%s"
  984.             "unknown facility type..\n\n");
  985.  
  986.       send_data(clients[curClient].sockfd, "ERROR: %s\n", INTPARERROR);
  987.       quit(ERROR);
  988.    }
  989.  
  990.    debug("(in parseFac) curlogfd = %d, facility = %s (in str = %s)\n",
  991.          numfacs, facility, 
  992.          facValToName(clients[curClient].logs[curlogfd].facility));
  993.  
  994.    if (debugging == 1)
  995.    {
  996.       (void)putchar('\n');
  997.       (void)write(dblogfd, "\n", 1);
  998.    }
  999.  
  1000.    parsePri(str);
  1001.  
  1002.    if (debugging == 1)
  1003.    {
  1004.       (void)putchar('\n');
  1005.       (void)write(dblogfd, "\n", 1);
  1006.    }
  1007.  
  1008.    numfacs++;
  1009.  
  1010.    if (*dataptr == ',') 
  1011.    {
  1012.       dataptr += 1;
  1013.  
  1014.       curlogfd++;
  1015.       if (curlogfd >= MAXLOGTYPES)
  1016.       {
  1017.          error("error parsing /etc/syslog.conf.. overflowed logs[]\n\n");
  1018.          send_data(clients[curClient].sockfd, "ERROR: %s\n", LOGOFERROR); 
  1019.          quit(ERROR);
  1020.       }
  1021.  
  1022.       numfacs = parseFac(dataptr, numfacs);
  1023.    }
  1024.  
  1025.    return numfacs;
  1026. }
  1027.  
  1028.  
  1029. /* ------------------------------------------------------ */
  1030.  
  1031.  
  1032. /* parse the priority */
  1033. void parsePri(char *str)
  1034. {
  1035.    int count = 0;
  1036.  
  1037.    char priority[16];
  1038.    char *priptr, *dataptr;
  1039.  
  1040.    dataptr = strchr(str, '.');
  1041.    if (dataptr == NULL)
  1042.    {
  1043.       error("(in sysLogConf) unable to parse:\n%s\n", str);
  1044.       send_data(clients[curClient].sockfd, "ERROR: %s\n", INTPARERROR);
  1045.       quit(ERROR);
  1046.    }
  1047.  
  1048.    dataptr += 1; /* skip '.' */
  1049.  
  1050.    /* can be "*.!=*" or "*.=*" */
  1051.    if (*dataptr == '!') 
  1052.    {
  1053.       /* check for possible bugs */
  1054.       if ((*(dataptr + 1)) == '*')
  1055.       {
  1056.          error("error parsing line (no '*' allowed after '!'):\n"
  1057.                "%s\n", str);
  1058.  
  1059.          send_data(clients[curClient].sockfd, "ERROR: %s\n", INTPARERROR);
  1060.          quit(ERROR);
  1061.       }
  1062.  
  1063.       debug("exclude ('!') on\n");
  1064.       clients[curClient].logs[curlogfd].priority.exclude = 1;
  1065.    }
  1066.  
  1067.    if ((*dataptr == '=') || ((*(dataptr+1)) == '=')) 
  1068.    {
  1069.       /* check for possible bugs */
  1070.       if (((*(dataptr + 1)) == '*') || ((*(dataptr + 2)) == '*'))
  1071.       {
  1072.          error("error parsing line (no '*' allowed after '='):\n"
  1073.                "\n%s", str);
  1074.  
  1075.          send_data(clients[curClient].sockfd, "ERROR: %s\n", INTPARERROR);
  1076.          quit(ERROR);
  1077.       }
  1078.  
  1079.       debug("single ('!') on\n");
  1080.       clients[curClient].logs[curlogfd].priority.single = 1;
  1081.    }
  1082.  
  1083.    /* skip to next valid data to parse */
  1084.    if (clients[curClient].logs[curlogfd].priority.single == 1) dataptr += 1;
  1085.    if (clients[curClient].logs[curlogfd].priority.exclude == 1) dataptr += 1;
  1086.          
  1087.    priptr = priority;
  1088.    memset(priority, 0, sizeof(priority));
  1089.       
  1090.    count = 0;
  1091.    while ((*dataptr) && (*dataptr != ' ') &&
  1092.           (*dataptr != ';') && (isprint(*dataptr) != 0) && 
  1093.           (count < (int)sizeof(priority)-1))
  1094.    {
  1095.       *priptr++ = *dataptr++;
  1096.       count++;
  1097.    }
  1098.  
  1099.  
  1100.    if (strchr(priority, '*') != NULL)
  1101.    {
  1102.       if (clients[curClient].logs[curlogfd].priority.exclude == 1)
  1103.       {
  1104.          (void)strcpy(priority, "none");
  1105.          clients[curClient].logs[curlogfd].priority.priority = NONE;
  1106.          debug("priority = %s (no priorities)\n", priority);
  1107.       }
  1108.  
  1109.       else
  1110.       {
  1111.          clients[curClient].logs[curlogfd].priority.priority = ALL;
  1112.          debug("priority = %s (all priorities)\n", priority);
  1113.       }
  1114.    }
  1115.  
  1116.    else if (strncmp(priority, "none", 4) == 0)
  1117.    {
  1118.       if (clients[curClient].logs[curlogfd].priority.exclude == 1)
  1119.       {
  1120.          /* !none == ALL.. double negatives.. */
  1121.  
  1122.          (void)strcpy(priority, "all");
  1123.          clients[curClient].logs[curlogfd].priority.priority = ALL;
  1124.          debug("priority = !none (all priorities)\n");
  1125.       }
  1126.  
  1127.       else
  1128.       {
  1129.          (void)strcpy(priority, "none");
  1130.          clients[curClient].logs[curlogfd].priority.priority = NONE;
  1131.          debug("priority = %s (no priorities)\n", priority);
  1132.       }
  1133.    }
  1134.  
  1135.    else 
  1136.    {
  1137.       if (clients[curClient].logs[curlogfd].priority.exclude == 1)
  1138.       {
  1139.          if (clients[curClient].logs[curlogfd].priority.single == 1)
  1140.          {
  1141.             clients[curClient].logs[curlogfd].priority.ignpri = 
  1142.             priNameToVal(priority);
  1143.  
  1144.             if (clients[curClient].logs[curlogfd].priority.ignpri == ERROR)
  1145.             {
  1146.                error("(in parseSysConf) error parsing line:\n%s"
  1147.                      "unknown priority..\n\n", str);
  1148.  
  1149.                send_data(clients[curClient].sockfd, "ERROR: %s\n",
  1150.                          INTPARERROR);
  1151.  
  1152.                quit(ERROR);
  1153.             }
  1154.  
  1155.             clients[curClient].logs[curlogfd].priority.priority = ERROR;
  1156.          }
  1157.       }    
  1158.      
  1159.       clients[curClient].logs[curlogfd].priority.priority = 
  1160.             priNameToVal(priority);
  1161.  
  1162.       debug("priority = %s\n", priority);
  1163.    }
  1164.  
  1165.  
  1166.    if (isprint(*dataptr) != 0)
  1167.       debug("current seperator = '%c'\n", *dataptr);
  1168.  
  1169.    else
  1170.       debug("current seperator = 0x%x (in hex)\n", *dataptr);
  1171. }
  1172.  
  1173.  
  1174. /* ------------------------------------------------------ */
  1175.  
  1176.  
  1177. /* parse the file name and things */
  1178. void parseFile(char *str, int didfacs, int numfacs, char *fac, char *pri)
  1179. {
  1180.    int count;
  1181.    register int i, j;
  1182.  
  1183.    char *fnameptr;
  1184.    char *dataptr = str;
  1185.  
  1186.    char filename[MAXFNAMESIZE];
  1187.    char facility[16], priority[16];
  1188.  
  1189.    fnameptr = filename;
  1190.  
  1191.    memset(facility, 0, sizeof(facility));
  1192.    memset(priority, 0, sizeof(priority));
  1193.    memset(filename, 0, sizeof(filename));
  1194.  
  1195.    (void)strcpy(facility, fac), (void)strcpy(priority, pri);
  1196.  
  1197.    /* -------------- little error checking -------------- */
  1198.  
  1199.    while ((isprint(*dataptr) != 0) && (*dataptr != ' ')) dataptr += 1;
  1200.    while ((isprint(*dataptr) == 0) || (*dataptr == ' ')) dataptr += 1;
  1201.  
  1202.    if (*dataptr == '\0')
  1203.    {
  1204.       error("error parsing line:\n%sfound an unexpected null..\n",
  1205.             str);
  1206.  
  1207.       send_data(clients[curClient].sockfd, "ERROR: %s\n", INTPARERROR);
  1208.       quit(ERROR);
  1209.    }
  1210.  
  1211.    else if (*dataptr == '\n')
  1212.    {
  1213.       error("error parsing line:\n%s"
  1214.             "found an unexpected newline..\n", str);
  1215.  
  1216.       send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR);
  1217.       quit(ERROR);
  1218.    }
  1219.  
  1220.    /* -------------- file/device/user output ------------- */
  1221.   
  1222.    if (debugging == 1)
  1223.    {
  1224.       (void)putchar('\n');
  1225.       (void)write(dblogfd, "\n", 1);
  1226.    }
  1227.  
  1228.    debug("dataptr = '%c' (2)\n", (*dataptr));
  1229.    if (*dataptr == '/')
  1230.    {
  1231.       char *mvptr = strrchr(dataptr, '/');
  1232.       mvptr += 1, dataptr = mvptr;
  1233.       
  1234.       memset(filename, 0, sizeof(filename));
  1235.       if (getcwd(filename, (sizeof(filename) / 2) - 1) == NULL)
  1236.       {
  1237.          error("error with getcwd(): %s\n\n", strerror(errno));
  1238.          send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR);
  1239.          quit(ERROR);
  1240.       }
  1241.  
  1242.       (void)strcat(filename, "/");
  1243.       fnameptr += strlen(filename);
  1244.  
  1245.       count = 0;
  1246.       while ((*dataptr) && (isprint(*dataptr) != 0) && 
  1247.             (count < (((int)sizeof(filename) / 2) - 
  1248.                        (int)strlen(filename) - 1)))
  1249.       {
  1250.          *fnameptr++ = *dataptr++;
  1251.          count++;
  1252.       }    
  1253.  
  1254.       if (didfacs != 1)
  1255.          debug("logging %s.%s to: %s\n", facility, priority, filename);
  1256.  
  1257.       else
  1258.       {
  1259.          for (i = curlogfd - numfacs; i <= curlogfd; i++)
  1260.          {
  1261.             strcpy(facility, 
  1262.                    facValToName(clients[curClient].logs[i].facility));
  1263.  
  1264.             if (clients[curClient].logs[i].priority.priority == ALL)
  1265.                strcpy(priority, "*");
  1266.  
  1267.  
  1268.             else if (clients[curClient].logs[i].priority.priority == NONE)
  1269.                strcpy(priority, "none");
  1270.  
  1271.             else
  1272.                strcpy(priority, 
  1273.                   priValToName(clients[curClient].logs[i].priority.priority));
  1274.  
  1275.             debug("logging %s.%s to: %s\n", facility, priority, filename);
  1276.          }
  1277.       }
  1278.  
  1279.       /* malloc filenames and open fd's */
  1280.       if (didfacs != 1)
  1281.       {
  1282.          clients[curClient].logs[curlogfd].filename = 
  1283.             (char *)malloc(strlen(filename)+1);
  1284.  
  1285.          if (clients[curClient].logs[curlogfd].filename == NULL)
  1286.          {
  1287.             error("error with malloc(): %s\n\n", strerror(errno));
  1288.             quit(ERROR);
  1289.          }
  1290.  
  1291.          memset(clients[curClient].logs[curlogfd].filename, 0, 
  1292.                 strlen(filename)+1);
  1293.  
  1294.          strcpy(clients[curClient].logs[curlogfd].filename, filename);
  1295.  
  1296.          for (i = 0; i <= curlogfd; i++)
  1297.          {
  1298.             if ((clients[curClient].logs[i].filename == NULL) || 
  1299.                 (clients[curClient].logs[i].fd <= 0)) continue;
  1300.  
  1301.             else if (strcmp(clients[curClient].logs[curlogfd].filename,
  1302.                             clients[curClient].logs[i].filename) == 0)
  1303.             {
  1304.                clients[curClient].logs[curlogfd].fd = clients[curClient].logs[i].fd;
  1305.                break;
  1306.             }
  1307.          }
  1308.  
  1309.          if (clients[curClient].logs[curlogfd].fd <= 0)
  1310.          {
  1311.             clients[curClient].logs[curlogfd].fd = 
  1312.         open(clients[curClient].logs[curlogfd].filename, 
  1313.                      O_CREAT | O_WRONLY | O_APPEND | O_NOCTTY, 0600);
  1314.  
  1315.             if (clients[curClient].logs[curlogfd].fd == ERROR)
  1316.             {
  1317.                error("error opening %s: %s\n\n", 
  1318.                      clients[curClient].logs[curlogfd].filename, 
  1319.                      strerror(errno));
  1320.  
  1321.                send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR); 
  1322.                quit(ERROR);
  1323.             }
  1324.          }
  1325.  
  1326.          if (isatty(clients[curClient].logs[curlogfd].fd) == 1) 
  1327.             debug("%s is a tty (device)\n", 
  1328.                   clients[curClient].logs[curlogfd].filename);
  1329.       }
  1330.  
  1331.       /* either a facility or colon was parsed */
  1332.       else
  1333.       {
  1334.          for (i = curlogfd - numfacs; i <= curlogfd; i++)
  1335.          {
  1336.             clients[curClient].logs[i].filename = 
  1337.             (char *)malloc(strlen(filename)+1);
  1338.  
  1339.             if (clients[curClient].logs[i].filename == NULL)
  1340.             {
  1341.                error("error with malloc(): %s\n\n", strerror(errno));
  1342.                quit(ERROR);
  1343.             }
  1344.  
  1345.             memset(clients[curClient].logs[i].filename, 0, 
  1346.                    strlen(filename)+1);
  1347.  
  1348.             strcpy(clients[curClient].logs[i].filename, filename);
  1349.  
  1350.             for (j = 0; j <= curlogfd; j++)
  1351.             {
  1352.                if ((clients[curClient].logs[j].filename == NULL) || 
  1353.                    (clients[curClient].logs[j].fd <= 0)) continue;
  1354.  
  1355.                if (strcmp(clients[curClient].logs[i].filename, 
  1356.                           clients[curClient].logs[j].filename) == 0)
  1357.                {
  1358.                   clients[curClient].logs[i].fd = clients[curClient].logs[j].fd;
  1359.                   break;
  1360.                }
  1361.             }
  1362.  
  1363.             if (clients[curClient].logs[i].fd <= 0)
  1364.             {
  1365.                clients[curClient].logs[curlogfd].fd = 
  1366.           open(clients[curClient].logs[i].filename, 
  1367.                        O_CREAT | O_WRONLY | O_APPEND | O_NOCTTY, 0600);
  1368.  
  1369.                if (clients[curClient].logs[curlogfd].fd == ERROR)
  1370.                {
  1371.                   error("error opening %s: %s\n\n", 
  1372.                         clients[curClient].logs[i].filename, strerror(errno));
  1373.  
  1374.                   send_data(clients[curClient].sockfd, "ERROR: %s\n", 
  1375.                             INTERROR); 
  1376.  
  1377.                   quit(ERROR);
  1378.                }
  1379.             }
  1380.  
  1381.             if (isatty(clients[curClient].logs[i].fd) == 1) 
  1382.                debug("%s is a tty (device)\n", 
  1383.                      clients[curClient].logs[i].filename);
  1384.          }
  1385.       }
  1386.    }
  1387.  
  1388.    /* determine the device, file, or host to log to */
  1389.    else if (*dataptr == '@') /* '@' == remote host logging  */
  1390.       parseRemHost(str);
  1391.  
  1392.    else if (*dataptr == '|') /* '|' == output to named pipe */
  1393.       parseNamedPipe(str);
  1394.  
  1395.    else if (*dataptr == '*')
  1396.    {
  1397.       char filename[MAXFNAMESIZE];
  1398.  
  1399.       /* 'wall' everyone online... */
  1400.  
  1401.       memset(filename, 0, sizeof(filename));
  1402.       if (getcwd(filename, (sizeof(filename) - 11)) == NULL)
  1403.       {
  1404.          error("error with getcwd(): %s\n\n", strerror(errno));
  1405.          quit(ERROR);
  1406.       }
  1407.  
  1408.       strcat(filename, "/wall.log");
  1409.  
  1410.       clients[curClient].logs[curlogfd].filename = 
  1411.         malloc(strlen(filename) + 1);
  1412.  
  1413.       if (clients[curClient].logs[curlogfd].filename == NULL)
  1414.       {
  1415.          error("error with malloc(): %s\n\n", strerror(errno));
  1416.          quit(ERROR);
  1417.       }
  1418.  
  1419.       memset(clients[curClient].logs[curlogfd].filename, 0, 
  1420.              strlen(filename) + 1);
  1421.  
  1422.       strcpy(clients[curClient].logs[curlogfd].filename, filename);
  1423.  
  1424.       error("wall'ing is not supported at this time..\n"
  1425.             "outputting %s.%s to %s instead\n\n", facility, priority, 
  1426.             clients[curClient].logs[curlogfd].filename);
  1427.  
  1428.       clients[curClient].logs[curlogfd].fd =
  1429.          open(clients[curClient].logs[curlogfd].filename, 
  1430.                       O_CREAT | O_WRONLY | O_APPEND, 0600);
  1431.  
  1432.       if (clients[curClient].logs[curlogfd].fd == ERROR)
  1433.       {
  1434.          error("error opening %s: %s\n\n", 
  1435.                clients[curClient].logs[curlogfd].filename, strerror(errno));
  1436.  
  1437.          quit(ERROR);
  1438.       }
  1439.    }
  1440.  
  1441.    /* check if they are users in /etc/passwd.. and if they're online */
  1442.    else if (isalpha(*dataptr) != 0)
  1443.    {
  1444.       int new1 = 1;
  1445.  
  1446.       char *userptr;
  1447.       char filename[MAXFNAMESIZE];
  1448.  
  1449.       /* just some more error checking */
  1450.       if (strchr(dataptr, '/') != NULL)
  1451.       {
  1452.          error("file names must begin with '/':\n%s\n", str);
  1453.          quit(ERROR);
  1454.       }
  1455.  
  1456.       error("logging msgs to users is not supported yet.."
  1457.             "outputting to the following instead:\n\n");
  1458.  
  1459.       while(1)
  1460.       {
  1461.          if (new1 == 1) new1 = 0;
  1462.          else /* we've already been in this loop once before */
  1463.          {
  1464.             if (curlogfd+1 >= MAXLOGTYPES)
  1465.             {
  1466.                error("overflowed logs[]\n\n"); 
  1467.                quit(ERROR);
  1468.             }
  1469.  
  1470.             else 
  1471.             {
  1472.                copyLogStruct(curlogfd, curlogfd+1);
  1473.                curlogfd++;
  1474.             }
  1475.          }
  1476.  
  1477.          memset(filename, 0, sizeof(filename));
  1478.          if (getcwd(filename, ((sizeof(filename) / 2) - 11)) == NULL)
  1479.          {
  1480.             error("error with getcwd(): %s\n\n", strerror(errno));
  1481.             quit(ERROR);
  1482.          }
  1483.  
  1484.          clients[curClient].logs[curlogfd].filename = 
  1485.         (char *)malloc(sizeof(filename) + 1);
  1486.  
  1487.          if (clients[curClient].logs[curlogfd].filename == NULL)
  1488.          {
  1489.             error("error with malloc(): %s\n\n", strerror(errno));
  1490.             quit(ERROR);
  1491.          }
  1492.  
  1493.          memset(clients[curClient].logs[curlogfd].filename, 0,
  1494.                 sizeof(filename) + 1);
  1495.  
  1496.          strcpy(clients[curClient].logs[curlogfd].filename, filename);
  1497.          strcat(clients[curClient].logs[curlogfd].filename, "/");
  1498.  
  1499.          userptr = clients[curClient].logs[curlogfd].filename + 
  1500.                    strlen(clients[curClient].logs[curlogfd].filename);
  1501.  
  1502.          /* now parsing the user names.. check for ','s */
  1503.          count = 0;
  1504.          while ((*dataptr) && (isprint(*dataptr) != 0) &&
  1505.                 (*dataptr != ',') && (count < MAXUSERNAME))
  1506.          {
  1507.             *userptr++ = *dataptr++;
  1508.             count++;
  1509.          }
  1510.  
  1511.          strcat(clients[curClient].logs[curlogfd].filename, "-user.log");
  1512.          error("%s.%s to %s\n\n", facility, priority, 
  1513.                clients[curClient].logs[curlogfd].filename);
  1514.  
  1515.          clients[curClient].logs[curlogfd].fd = 
  1516.             open(clients[curClient].logs[curlogfd].filename,
  1517.                              O_CREAT | O_APPEND | O_WRONLY, 0600);
  1518.  
  1519.          if (clients[curClient].logs[curlogfd].fd == ERROR)
  1520.          { 
  1521.             error("error opening %s: %s\n\n", 
  1522.                   clients[curClient].logs[curlogfd].filename);
  1523.  
  1524.             quit(ERROR);
  1525.          }
  1526.  
  1527.          if (*dataptr == ',') dataptr += 1;
  1528.          else break;
  1529.       }
  1530.  
  1531.       if (debugging == 1)
  1532.       {
  1533.          (void)putchar('\n');
  1534.          (void)write(dblogfd, "\n", 1);
  1535.       }
  1536.  
  1537.       (void)write(errlogfd, "\n", 1);
  1538.    }
  1539.  
  1540.    return;
  1541. }
  1542.  
  1543.  
  1544. /* ------------------------------------------------------ */
  1545.  
  1546.  
  1547. /* parse priority/facility of log message client */
  1548. void doLogging(char *str)
  1549. {
  1550.    register int i, j;
  1551.  
  1552.    int res;
  1553.    int count = 0;
  1554.  
  1555.    int restart;
  1556.    int fds[MAXLOGTYPES];
  1557.  
  1558.    int glued = 0; /* part of a glued message */
  1559.  
  1560.    int data; /* the priority/facility OR'd together  */
  1561.    int fac, pri; /* facility and priority of the message */
  1562.  
  1563.    int dup;
  1564.  
  1565.    char pristr[16]; /* priority as a string */
  1566.  
  1567.    char writebuf[MAXWRITESIZE];
  1568.  
  1569.    char gluebuf[MAXWRITESIZE];
  1570.    char dupstrs[MAXLOGTYPES][MAXFNAMESIZE];
  1571.  
  1572.    char *priptr, *dataptr, *markptr, *writeptr;
  1573.  
  1574.    memset(pristr, 0, sizeof(pristr));
  1575.    memset(writebuf, 0, sizeof(writebuf));
  1576.  
  1577.    priptr = pristr, writeptr = writebuf;
  1578.    dataptr = str;
  1579.  
  1580.    if (*dataptr != '<')
  1581.    {
  1582.       debug("incoming data did not have a \"<>\"\n");
  1583.  
  1584.       markptr = strchr(str, '!');
  1585.       if (markptr != NULL)
  1586.       {
  1587.         debug("incoming data is a marker ('!')\n");
  1588.  
  1589.         markptr += 1;
  1590.         for (i = 0; i < MAXLOGTYPES; i++)
  1591.         {
  1592.            if (clients[curClient].logs[i].filename != NULL)
  1593.            {
  1594.               dup = 0;
  1595.  
  1596.               for (j = 0; j < MAXLOGTYPES; j++)
  1597.                  if (strncmp(dupstrs[j], clients[curClient].logs[i].filename,
  1598.                              strlen(dupstrs[j])) == 0) dup = 1;
  1599.  
  1600.               if (dup != 1)
  1601.               {
  1602.                  debug("[%s] %s\n", clients[curClient].logs[i].filename,
  1603.                        markptr);
  1604.  
  1605.                  memset(gluebuf, 0, sizeof(gluebuf));
  1606.                  snprintf(gluebuf, sizeof(gluebuf)-1, "%s\n", markptr);
  1607.  
  1608.                  res = write(clients[curClient].logs[i].fd, gluebuf,
  1609.                              strlen(gluebuf));
  1610.  
  1611.                  if (res == ERROR)
  1612.                  {
  1613.                     error("error writing to %s: %s\n",
  1614.                           clients[curClient].logs[i].filename,
  1615.                           strerror(errno));
  1616.  
  1617.                     quit(ERROR);
  1618.                  }
  1619.  
  1620.                  snprintf(dupstrs[i], MAXFNAMESIZE,
  1621.                           clients[curClient].logs[i].filename);
  1622.             } 
  1623.           }
  1624.         }
  1625.  
  1626.         /* since we got an END marker, we need to sleep for 5 seconds */
  1627.  
  1628.         if (strstr(markptr, "END") != NULL)
  1629.         {
  1630.           debug("now sleeping, allowing our cron jobs to catchup."), 
  1631.           sleep (MAXPAUSE);
  1632.         }
  1633.  
  1634.         return;
  1635.       }
  1636.  
  1637.       else
  1638.       {
  1639.          if (debugging == 1)
  1640.          {
  1641.             (void)putchar('\n'); 
  1642.             (void)write(dblogfd, "\n", 1);
  1643.          }
  1644.  
  1645.          /* it is probably the next part of a truncated log */
  1646.          debug("received next part of log\n");
  1647.          glued = 1, data = prevmsg;
  1648.       
  1649.          goto Domsg;
  1650.       }
  1651.    }
  1652.  
  1653.    dataptr += 1; /* skip "<" */
  1654.  
  1655.    while (isdigit(*dataptr) != 0)
  1656.       *priptr++ = *dataptr++;
  1657.  
  1658.    if (*dataptr != '>')
  1659.    {
  1660.       error("error parsing message ('>' was expected):\n%s\n", str);
  1661.       send_data(clients[curClient].sockfd, "ERROR: %s\n", INTPARERROR);
  1662.       quit(ERROR);
  1663.    }
  1664.  
  1665.    data = atoi(pristr);
  1666.    dataptr += 1; /* skip ">" */
  1667.  
  1668. Domsg:
  1669.    count = 0;
  1670.    while ((*dataptr) && (count < (int)sizeof(writebuf)))
  1671.    {
  1672.       *writeptr++ = *dataptr++;
  1673.       count++;
  1674.    }
  1675.    
  1676.    if (glued != 1)
  1677.    {
  1678.       if ((data <= 0) || (data >= (LOG_NFACILITIES << 3)))
  1679.          data = DEFUPRI;
  1680.  
  1681.       else if (data &~ (LOG_FACMASK | LOG_PRIMASK))
  1682.         data = DEFUPRI;
  1683.  
  1684.       if (LOG_PRI(data) == LOG_KERN)
  1685.          data |= LOG_USER;
  1686.  
  1687.       prevmsg = data;
  1688.    }
  1689.  
  1690.    fac = LOG_FAC(data), pri = LOG_PRI(data);
  1691.  
  1692.    if (glued != 1)
  1693.    {
  1694.      debug("facility = %d, priority = %d\n", fac, pri);
  1695.      debug("facility = %s, priority = %s\n\n", facValToName(fac),
  1696.            priValToName(pri));
  1697.    }
  1698.  
  1699.    for (i = 0; i <= curlogfd; i++)
  1700.    {
  1701.       if ((clients[curClient].logs[i].fd <= 0) || 
  1702.           (clients[curClient].logs[i].filename == NULL)) break;
  1703.  
  1704.       else if ((clients[curClient].logs[i].facility == ALL) || 
  1705.                (clients[curClient].logs[i].facility == (fac << 3)) || 
  1706.                (fac == LOG_DAEMON))
  1707.       {
  1708.          if (clients[curClient].logs[i].priority.priority == NONE) continue;
  1709.          else if (clients[curClient].logs[i].priority.priority == ALL)
  1710.          {
  1711.             for (j = 0; j < MAXLOGTYPES; j++)
  1712.             {
  1713.                 if (fds[j] <= 0) continue;
  1714.                 else if (fds[j] == clients[curClient].logs[i].fd)
  1715.                 {
  1716.                    restart = 1; 
  1717.                    break;
  1718.                 }
  1719.             }
  1720.  
  1721.             if (restart == 1)
  1722.             {
  1723.                restart = 0;
  1724.                continue;
  1725.             }
  1726.  
  1727.             else
  1728.             {
  1729.                for (j = 0; j < MAXLOGTYPES; j++)
  1730.                   if (fds[j] <= 0) 
  1731.                   {
  1732.                      fds[j] = clients[curClient].logs[i].fd;
  1733.                      break;
  1734.                   }
  1735.             }
  1736.  
  1737.             debug("writing the following to %s:\n%s\n",
  1738.                   clients[curClient].logs[i].filename, writebuf);
  1739.  
  1740.             res = write(clients[curClient].logs[i].fd, writebuf, 
  1741.                         strlen(writebuf));
  1742.  
  1743.             if ((res == 0) || ((res == ERROR) && (errno > 0)))
  1744.             {
  1745.                error("error writing to %s: %s\n\n", 
  1746.                      clients[curClient].logs[i].filename, strerror(errno));
  1747.  
  1748.                if (res == ERROR)
  1749.                {
  1750.                   send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR);
  1751.                   quit(ERROR); 
  1752.                }
  1753.             }
  1754.  
  1755.             if (strchr(writebuf, '\n') == NULL) 
  1756.                (void)write(clients[curClient].logs[i].fd, "\n", 1);
  1757.  
  1758.             if (debugging == 1)
  1759.             {
  1760.                (void)putchar('\n');
  1761.                (void)write(dblogfd, "\n", 1);
  1762.             }
  1763.          }
  1764.  
  1765.          else if (clients[curClient].logs[i].priority.priority <= pri) 
  1766.          {
  1767.  
  1768.             if (clients[curClient].logs[i].priority.exclude == 1) 
  1769.                if (clients[curClient].logs[i].priority.ignpri <= pri) 
  1770.                {
  1771.                   if (clients[curClient].logs[i].priority.single != 1) 
  1772.                      continue;
  1773.  
  1774.                   else if (clients[curClient].logs[i].priority.ignpri == pri) 
  1775.                      continue;
  1776.                }
  1777.  
  1778.             if (clients[curClient].logs[i].priority.single == 1)
  1779.                if (clients[curClient].logs[i].priority.priority != pri) 
  1780.                   continue;
  1781.  
  1782.             for (j = 0; j < MAXLOGTYPES; j++)
  1783.             {
  1784.                 if (fds[j] <= 0) continue;
  1785.                 else if (fds[j] == clients[curClient].logs[i].fd)
  1786.                 {
  1787.                    restart = 1; 
  1788.                    break;
  1789.                 }
  1790.             }
  1791.  
  1792.             if (restart == 1)
  1793.             {
  1794.                restart = 0;
  1795.                continue;
  1796.             }
  1797.  
  1798.             else
  1799.             {
  1800.                for (j = 0; j < MAXLOGTYPES; j++)
  1801.                   if (fds[j] <= 0) 
  1802.                   {
  1803.                      fds[j] = clients[curClient].logs[i].fd;
  1804.                      break;
  1805.                   }
  1806.             }
  1807.  
  1808.             debug("writing the following to %s:\n%s\n",
  1809.                   clients[curClient].logs[i].filename, writebuf);
  1810.  
  1811.             res = write(clients[curClient].logs[i].fd, writebuf, 
  1812.                         strlen(writebuf));
  1813.  
  1814.             if ((res == 0) || ((res == ERROR) && (errno > 0)))
  1815.             {
  1816.                error("error writing to %s: %s\n\n", 
  1817.                      clients[curClient].logs[i].filename, strerror(errno));
  1818.  
  1819.                if (res == ERROR)
  1820.                {
  1821.                   send_data(clients[curClient].sockfd, "ERROR: %s\n", 
  1822.                             INTERROR);
  1823.  
  1824.                   quit(ERROR); 
  1825.                }
  1826.             }
  1827.  
  1828.             if (strchr(writebuf, '\n') == NULL) 
  1829.                (void)write(clients[curClient].logs[i].fd, "\n", 1);
  1830.  
  1831.             if (debugging == 1)
  1832.             {
  1833.                (void)putchar('\n');
  1834.                (void)write(dblogfd, "\n", 1);
  1835.             }
  1836.          }
  1837.       }
  1838.    }
  1839.  
  1840.    if (debugging == 1)
  1841.    {
  1842.       (void)putchar('\n');
  1843.       (void)write(dblogfd, "\n", 1);
  1844.    }
  1845. }
  1846.