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