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

  1. /* Misc. functions involving the server */
  2. /* ------------------------------------ */
  3.  
  4. #include "headers.h" /* all important stuff */
  5.  
  6. /* process data from the server */
  7. void procData()
  8. {
  9.    char readbuf[MAXREADSIZE];
  10.  
  11.    memset(readbuf, 0, sizeof(readbuf));
  12.  
  13.    /* initStream(); */
  14.    doStreaming(); /* reads SYSLOGFILE until we gets an abort */
  15.    
  16.    /* do something with data here.. the data could be:          */
  17.    /* + new server information (DHCP-like)                      */
  18.    /* + request to change server (server's load avg too high)   */
  19.    /* checkData(); */ /* checks for stuff like "CHNGSERV", etc. */
  20. }
  21.  
  22.  
  23. /* -------------------------------------------- */
  24.  
  25.  
  26. /* create directories for logs */
  27. void createDirs()
  28. {
  29.    int res;
  30.    DIR *dir;
  31.  
  32.    errno = 0;
  33.  
  34.    debug("checking where to create SRS directory...\n");
  35.  
  36.    dir = opendir("/var/log");
  37.    if (dir == NULL)
  38.    {
  39.       dir = opendir("/var/adm");
  40.       if (dir == NULL)
  41.       {
  42.          dir = opendir("/usr/adm");
  43.          if (dir == NULL)
  44.          {
  45.             error("error finding the logs directory.. using /\n\n");
  46.             (void)strcpy(SRSdir, "/SRS");
  47.          }
  48.          else
  49.             (void)strcpy(SRSdir, "/usr/adm/SRS");
  50.  
  51.       }
  52.       else
  53.          (void)strcpy(SRSdir, "/var/adm/SRS");
  54.    }
  55.    else
  56.       (void)strcpy(SRSdir, "/var/log/SRS");
  57.  
  58.    debug("creating %s (if it doesn't exist)\n", SRSdir);
  59.  
  60.    res = mkdir(SRSdir, (0766 & ~077));
  61.    if (res == ERROR)
  62.       if (errno != EEXIST)
  63.       {
  64.          (void)fprintf(stderr, "error creating %s: %s\n", SRSdir,
  65.                        strerror(errno));
  66.  
  67.          exit(ERROR);
  68.       }
  69.  
  70.    errno = 0;
  71.    res = chdir(SRSdir);
  72.    if (res == ERROR)
  73.    {
  74.       (void)fprintf(stderr, "error with chdir() to %s: %s\n", SRSdir,
  75.                     strerror(errno));
  76.  
  77.       exit(ERROR);
  78.    }
  79.  
  80.    res = mkdir("./certs", (0766 & ~077));
  81.    if (res == ERROR)
  82.       if (errno != EEXIST)
  83.       {
  84.          (void)fprintf(stderr, "error creating %s: %s\n", SRSdir,
  85.                        strerror(errno));
  86.  
  87.          exit(ERROR);
  88.       }
  89.  
  90.    res = mkdir("./spool", (0766 & ~077));
  91.    if (res == ERROR)
  92.       if (errno != EEXIST)
  93.       {
  94.          (void)fprintf(stderr, "error creating %s/spool: %s\n", SRSdir,
  95.                        strerror(errno));
  96.  
  97.          exit(ERROR);
  98.       }
  99. }
  100.  
  101.  
  102. /* --------------------------------------------- */
  103.  
  104.  
  105. /* get our Sub-ID from the server */
  106. void getSubID()
  107. {
  108.    int count = 0; /* prevent overflows */
  109.  
  110.    char subIDstr[8];
  111.    char *subidptr, *dataptr;
  112.  
  113.    char readbuf[MAXREADSIZE];
  114.  
  115.    memset(subIDstr, 0, sizeof(subIDstr));
  116.    subidptr = subIDstr;
  117.  
  118.    send_data("SUBID\n"); /* request server list */
  119.  
  120.    (void)signal(SIGALRM, subIDTimeout);
  121.    (void)alarm(MAXTIMEOUT); /* wait for Sub-ID */
  122.  
  123.    /* loop until we get Sub-ID from server */
  124.    while(1)
  125.    {
  126.       memset(readbuf, 0, sizeof(readbuf));
  127.       recv_data(readbuf, sizeof(readbuf));
  128.  
  129.       debug("(in getSubID) data is: %s\n", readbuf);
  130.  
  131.       if (strncmp(readbuf, "SUBID", 5) == 0) break;
  132.    }
  133.  
  134.    (void)alarm(0); /* reset timer */
  135.  
  136.    dataptr = strstr(readbuf, "SUBID");
  137.    dataptr += 6; /* skip "SUBID " */
  138.  
  139.    while ((*dataptr) && (*dataptr != ' ') &&
  140.           (isprint((int)*dataptr) != 0) && (count < (int)sizeof(subID))) 
  141.    {
  142.       *subidptr++ = *dataptr++;
  143.       count++;
  144.    }
  145.  
  146.    debug("Sub-ID = %s\n", subIDstr);
  147.  
  148.    subID = atoi(subIDstr);
  149. }
  150.  
  151.  
  152. /* ------------------------------------------------ */
  153.  
  154.  
  155. /* gets current client and server version from the server */
  156. void getVers()
  157. {
  158.    int  count = 0;               /* prevent overflows */
  159.    char *cverptr, *sverptr;      /* point to data returned by server   */
  160.  
  161.    char curcver[8], cursver[8];
  162.    char *cptr, *sptr;            /* point to curcver & cursver buffers */
  163.  
  164.    char readbuf[MAXREADSIZE];
  165.  
  166.    memset(curcver, 0, sizeof(curcver));
  167.    memset(cursver, 0, sizeof(cursver));
  168.  
  169.    cptr = curcver, sptr = cursver;
  170.  
  171.    send_data("VERS\n"); /* request client/server version */
  172.  
  173.    /* if we timeout waiting for version */
  174.  
  175.    (void)signal(SIGALRM, verTimeout);
  176.    (void)alarm(MAXTIMEOUT); 
  177.  
  178.    /* loop until we get both the client and server version */
  179.    while(1)
  180.    {
  181.       memset(readbuf, 0, sizeof(readbuf));
  182.       recv_data(readbuf, sizeof(readbuf));
  183.  
  184.       debug("(in getVers) data is: %s\n", readbuf);
  185.  
  186.       cverptr = strstr(readbuf, "CVER");
  187.       sverptr = strstr(readbuf, "SVER");
  188.  
  189.       if ((cverptr != NULL) && (sverptr != NULL))
  190.       {
  191.          debug("got client & server version.. now parsing..\n");
  192.          break;
  193.       }
  194.    }
  195.  
  196.    (void)alarm(0); /* reset alarm */
  197.  
  198.    count = 0; /* reset counter */
  199.    cverptr += 5, sverptr += 5; /* skip "XVER " */
  200.  
  201.    /* copy client from server into local buffer */
  202.    while ((*cverptr) && (*cverptr != ' ') && (*cverptr != ',') &&
  203.           (isprint((int)*cverptr) != 0) && (count < (int)sizeof(curcver))) 
  204.    {
  205.       *cptr++ = *cverptr++;
  206.       count++;
  207.    }
  208.  
  209.    count = 0; /* reset counter */
  210.  
  211.    /* copy server from server into local buffer */
  212.    while ((*sverptr) && (*sverptr != ' ') && (*sverptr != ',') &&
  213.           (isprint((int)*sverptr) != 0) && (count < (int)sizeof(cursver))) 
  214.    {
  215.       *sptr++ = *sverptr++;
  216.       count++;
  217.    }
  218.  
  219.    /* not floating points in version.. always "X.0" */
  220.    if (debugging == 1)
  221.       (void)printf("%catest client version: %s.0, "
  222.                    "latest server version: %s.0\n\n", 
  223.                    (debugging == 1 ? 'l' : 'L'), curcver, cursver);
  224.  
  225.    if (atoi(curcver) > atoi(VER)) 
  226.    {
  227.       error("we have an outdated client..\n"
  228.             "mailing %s to request a new one..\n\n", SRSMAILADDR);
  229.  
  230.       updateClient();
  231.    }
  232. }
  233.  
  234.  
  235. /* --------------------------------------------- */
  236.  
  237.  
  238. /* we need to update our client software */
  239. void updateClient()
  240. {
  241.    FILE *mailfd;
  242.  
  243.    int res;
  244.    char cmd[128];
  245.  
  246.    memset(cmd, 0, sizeof(cmd));
  247.  
  248.    /* use the system's 'mail' command */
  249.    sprintf(cmd, "`which mail` %s -s \"SRS UPDATE REQUEST\"",
  250.            SRSMAILADDR);
  251.  
  252.    mailfd = popen(cmd, "w");
  253.    if (mailfd == NULL)
  254.    {
  255.       error("error request new client (popen): %s\n\n", strerror(errno));
  256.       return;
  257.    }
  258.  
  259.    memset(cmd, 0, sizeof(cmd));
  260.  
  261.    /* actual request to be parsed by SRS staff */
  262.    sprintf(cmd, "NEW VERSION - ID %s\n\n[Note to admin: "
  263.            "if you get this message back with a mailing error, ]\n"
  264.            "[Please contact RSI and request the new version. ]\n\n", ID);
  265.  
  266.    res = fputs(cmd, mailfd);
  267.    if (res == ERROR)
  268.    {
  269.       error("error requesting new version (fputs): %s\n\n",
  270.             strerror(errno));
  271.  
  272.       quit(ERROR);
  273.    }
  274.  
  275.    (void)fputs(".\n", mailfd); /* terminate message */
  276.  
  277.    res = pclose(mailfd);
  278.    if (res == ERROR)
  279.    {
  280.       error("error closing mailing pipe (pclose): %s\n\n",
  281.             strerror(errno));
  282.  
  283.       quit(ERROR);
  284.    }
  285.    
  286.    return;
  287. }
  288.  
  289.  
  290. /* ------------------------------------------------- */
  291.  
  292.  
  293. /* get server list */
  294. void getServList()
  295. {
  296.    char readbuf[MAXREADSIZE];
  297.  
  298.    send_data("SERVLIST\n");
  299.    curServ = ERROR;
  300.  
  301.    (void)signal(SIGALRM, listTimeout);
  302.    (void)alarm(MAXTIMEOUT);
  303.  
  304.    /* read and parse each server in the list */
  305.    while(1)
  306.    {
  307.       memset(readbuf, 0, sizeof(readbuf));
  308.       recv_data(readbuf, sizeof(readbuf));
  309.  
  310.       debug("(in getServList) data is: %s\n", readbuf);
  311.  
  312.       if (strncmp(readbuf, "SERV", 4) == 0) putServ(++useServ, readbuf); 
  313.       else if (strncmp(readbuf, "DONE", 4) == 0) break; /* DONE == EOF */
  314.  
  315.       if (debugging == 1) (void)putchar('\n');
  316.    }
  317.  
  318.    if (debugging != 1) (void)putchar('\n');
  319.    (void)alarm(0);
  320. }
  321.  
  322.  
  323. /* ----------------------------------------------- */
  324.  
  325.  
  326. /* parse and put server in ServList */
  327. void putServ(int servNum, char *buf)
  328. {
  329.    int count = 0;    /* prevent any overflows */
  330.       
  331.    char *ipptr;      /* pointer to buffer with server's IP   */
  332.    char *dataptr;    /* pointer to data from server          */
  333.        
  334.    char servname[128]; /* just to be sure it's compatible in the future */
  335.        
  336.    debug("parsing server servNames[%d] (server #%d)\n", 
  337.          servNum, servNum+1);
  338.  
  339.    memset(servname, 0, sizeof(servname));
  340.    ipptr = servname;
  341.        
  342.    dataptr = strstr(buf, "SERV");
  343.    dataptr += 5; /* skip "SERV " */
  344.       
  345.    count = 0;
  346.  
  347.    while ((*dataptr) && (*dataptr != ' ') && 
  348.           (isprint((int)*dataptr) != 0) && (count < (int)sizeof(servname)))
  349.    {
  350.       *ipptr++ = *dataptr++;
  351.       count++;
  352.    }
  353.  
  354.    /* includes a port to connect to */
  355.    if ((*dataptr == ' ') || (*dataptr == '\t'))
  356.    {
  357.       char port[16];
  358.       char *portstr = port;
  359.  
  360.       memset(port, 0, sizeof(port));
  361.  
  362.       while ((*dataptr == ' ') || (*dataptr == '\t')) dataptr += 1;
  363.       if (isdigit((int)*dataptr) != 0) servList[servNum].port = PORT;
  364.  
  365.       count = 0;
  366.       while ((*dataptr) && (*dataptr != ' ') &&
  367.              (isdigit((int)*dataptr) != 0) && (count < (int)sizeof(port)))
  368.       {
  369.          *portstr++ = *dataptr++;
  370.          count++;
  371.       }
  372.  
  373.       servList[servNum].port = atoi(port);
  374.    }
  375.  
  376.    if (servList[servNum].port <= 0) 
  377.       servList[servNum].port = PORT;
  378.  
  379.    servList[servNum].name = (char *)malloc(strlen(servname)+1);
  380.    memset(servList[servNum].name, 0, strlen(servname)+1);
  381.    strcpy(servList[servNum].name, servname);
  382.  
  383.    (void)printf("%ctreaming server #%d is: %s (port %d)\n", 
  384.                 (debugging != 1 ? 'S' : 's'), servNum+1, 
  385.                 servList[servNum].name, servList[servNum].port);   
  386. }
  387.  
  388.  
  389. /* ----------------------------------------------- */
  390.       
  391.     
  392. /* get "OKAY" from client */
  393. void getOkay()
  394. {
  395.    char readbuf[MAXREADSIZE];
  396.    
  397.    while(1)
  398.    {
  399.       errno = 0;
  400.  
  401.       memset(readbuf, 0, sizeof(readbuf));
  402.       recv_data(readbuf, sizeof(readbuf));
  403.  
  404.       if ((errors == 1) || (gotAlrm == 1))
  405.       {
  406.          if (done == 1) return;
  407.  
  408.          errors = 1;
  409.          error("(in getOkay) timeout or error..\n\n");
  410.  
  411.          if (done == 1) return;
  412.  
  413.          if (gotInfoServ == 1) longjmp(reconnect, 1);
  414.          else longjmp(infoconn, 1);
  415.       }
  416.  
  417.       if (strncmp(readbuf, "OKAY", 4) == 0)
  418.       {
  419.         if (silent != 1) debug("got OKAY\n\n");
  420.         break;
  421.       } 
  422.  
  423.       else if (done != 1)
  424.       {
  425.          error("OKAY not received.. retrying\n\n");
  426.          continue;
  427.       }
  428.  
  429.       else return;
  430.    }
  431. }
  432.  
  433.  
  434. /* ------------------------------------------------- */
  435.  
  436.  
  437. /* parse and setup args */
  438. void getArgs(int argc, char **argv)
  439. {
  440.    int opt;
  441.  
  442.    dbFile = errorFile = spoolFile = NULL;
  443.  
  444.    if (debugging != 1)
  445.       if (argc > 1)
  446.       {
  447.          /* -h == help, -d == debugging enabled, -e == error file, */
  448.          /* -s == spool file, -l == log file */
  449.  
  450.          /* FIX - add long option name support */
  451.  
  452.          while ((opt = getopt(argc, argv, "hde:l:s:p:")) != ERROR)
  453.          {
  454.             int  testfd1;
  455.             FILE *testfd; /* test if the user-defined files work */
  456.  
  457.             switch(opt)
  458.             {
  459.                case 'h':
  460.                   usage(argv[0]);
  461.                   exit(SUCCESS);
  462.  
  463.                case 'd':
  464.                   debugging = 1;
  465.                   debug("debugging enabled\n");
  466.  
  467.                   break;
  468.  
  469.                case 'e':
  470.                   errorFile = optarg;
  471.                   debug("using %s to log errors\n", errorFile);
  472.  
  473.                   while(1)
  474.                   {
  475.                      testfd1 = open(errorFile, O_CREAT | O_WRONLY | O_APPEND,
  476.                                     0600);
  477.  
  478.                      if (testfd1 == ERROR)
  479.                      {
  480.                         if (errno == EINTR) continue;
  481.  
  482.                         (void)fprintf(stderr, "Unable to open %s: %s\n",
  483.                                       errorFile, strerror(errno));
  484.   
  485.                         exit(ERROR);
  486.                      }
  487.  
  488.                      else break;
  489.                   }
  490.  
  491.                   (void)close(testfd1);
  492.                   break;
  493.  
  494.                case 'l':
  495.                   dbFile = optarg;
  496.                   debug("using %s to log db info\n", dbFile);
  497.  
  498.                   while(1)
  499.                   {
  500.                      testfd1 = open(dbFile, O_CREAT | O_WRONLY | O_APPEND,
  501.                                     0600);
  502.  
  503.                      if (testfd1 == ERROR)
  504.                      {
  505.                         if (errno == EINTR) continue;
  506.  
  507.                         (void)fprintf(stderr, "Unable to open %s: %s\n",
  508.                                       dbFile, strerror(errno));
  509.  
  510.                         exit(ERROR);
  511.                      }
  512.  
  513.                      else break;
  514.                   }
  515.  
  516.                   (void)close(testfd1);
  517.                   break;
  518.  
  519.                case 'p':
  520.                   locPort = atoi(optarg);
  521.  
  522.                   if ((locPort > IPPORT_RESERVED-1) || 
  523.                       (locPort < 512))
  524.                   { 
  525.                      fprintf(stderr, 
  526.                              "Error: port must be between 512-%d\n",
  527.                              IPPORT_RESERVED-1);
  528.  
  529.                      exit(ERROR);
  530.                   }
  531.  
  532.                   break;
  533.  
  534.                case 's':
  535.                   spoolFile = optarg;
  536.                   debug("using %s to spool system logs\n", spoolFile);
  537.  
  538.                   while (1)
  539.                   {
  540.                      testfd = fopen(spoolFile, "a+");
  541.  
  542.                      if (testfd == NULL)
  543.                      {
  544.                         if (errno == EINTR) continue;
  545.  
  546.                         (void)fprintf(stderr, "Unable to open %s: %s\n",
  547.                                       spoolFile, strerror(errno));
  548.  
  549.                         exit(ERROR);
  550.                      }
  551.  
  552.                      else break;
  553.                   }
  554.  
  555.                   (void)chmod(spoolFile, S_IREAD | S_IWRITE);
  556.                   (void)fclose(testfd);
  557.  
  558.                   break;
  559.  
  560.                case '?':
  561.                   (void)fputc('\n', stderr), usage(argv[0]);
  562.                   (void)fprintf(stderr, "Press 'Enter' to continue..\n");
  563.                   (void)getchar();
  564.                   
  565.                   break;
  566.  
  567.                default:
  568.                   (void)fprintf(stderr, "getopt() returned %d.. exiting\n",
  569.                                 opt);
  570.  
  571.                   exit(ERROR);
  572.             }
  573.          }
  574.       }
  575. }
  576.  
  577.  
  578. /* ------------------------------------------------ */
  579.  
  580.  
  581. /* progress through server list */
  582. void nextServer()
  583. {
  584.    if ((curServ == ERROR) && (connected == 1))
  585.    {
  586.       if (servList[curServ+1].name == NULL)
  587.       {
  588.          error("have no valid streaming server name in list\n\n");
  589.          quit(ERROR);
  590.       }
  591.  
  592.       if (prim == 1)
  593.       {
  594.          if ((strcmp(PRIMSERV, servList[curServ+1].name) == 0) &&
  595.              (PORT == servList[curServ+1].port)) 
  596.          {
  597.             curServ += 2;
  598.             initing = 1, errors = 1;
  599.  
  600.             return;
  601.          }
  602.       }
  603.  
  604.       else
  605.       {
  606.          if ((strcmp(SECSERV, servList[curServ+1].name) == 0) &&
  607.              (PORT == servList[curServ+1].port)) 
  608.          {
  609.             curServ += 2;
  610.             initing = 1, errors = 1;
  611.  
  612.             return;
  613.          }
  614.       }
  615.    }
  616. }
  617.  
  618.  
  619. /* ------------------------------------------------ */
  620.  
  621.  
  622. /* do stuff with finding next server in list */
  623. void doServer()
  624. {
  625.    if (curServ < 0)
  626.    { 
  627.       curServ = 0;
  628.       return;
  629.    }
  630.  
  631.    /* ------------------------------------- */
  632.  
  633.    while(1)
  634.    {
  635.       if (useServ == 0)
  636.       {
  637.          curServ++;
  638.          break;
  639.       }
  640.  
  641.       else if ((curServ + 1) > useServ)
  642.       {
  643.          if ((servList[curServ].name == NULL) || (servList[0].name == NULL))
  644.          {
  645.             error("NULL server name.. comparing server [%d] to [0]\n\n",
  646.                   curServ);
  647.  
  648.             quit(ERROR);
  649.          }
  650.  
  651.          else if ((strcmp(servList[curServ].name, servList[0].name) != 0) ||
  652.                   (servList[curServ].port != servList[0].port))
  653.          {
  654.             curServ++;
  655.             break;
  656.          }
  657.  
  658.          else curServ = 0;
  659.       }
  660.  
  661.       else
  662.       {
  663.          if ((servList[curServ].name == NULL) || (servList[0].name == NULL))
  664.          {
  665.             error("NULL server name.. comparing server [%d] to [%d]\n\n",
  666.                   curServ, curServ + 1);
  667.  
  668.             quit(ERROR);
  669.          }
  670.  
  671.          else if ((strcmp(servList[curServ].name,
  672.                   servList[curServ+1].name) != 0) ||
  673.                   (servList[curServ].port != servList[curServ+1].port))
  674.          {
  675.             curServ++;
  676.             break;
  677.          }
  678.  
  679.          else curServ++;
  680.       }
  681.    }
  682.  
  683.    /* ------------------------------------- */
  684.  
  685.    if (curServ > useServ) 
  686.    {
  687.       if (spooling != 1) 
  688.       {
  689.          error("reached end of server list.. now starting spooling\n\n");
  690.  
  691.          debug("(in parent)\n%cow forking a child to start spooling "
  692.                "to %s/spool/%s locally\n\n", (debugging != 1 ? 'N' : 'n'),
  693.                SRSdir, LOGFILE);
  694.  
  695.          connected = 0, silent = 1;
  696.          forkSpool();
  697.       }
  698.  
  699.       else
  700.       {
  701.          (void)sleep(MAXPAUSE * 3); /* take a break.. */
  702.          curServ = 0; /* just keep going forever */
  703.       }
  704.    }
  705. }
  706.  
  707.  
  708. /* --------------------------------------------- */
  709.  
  710.  
  711. /* go into background and daemonize */
  712. void daemonize()
  713. {
  714.    int res;
  715.  
  716.    if (start == 1)
  717.    {
  718.       (void)printf("Now forking..\n");
  719.  
  720.       res = fork();
  721.       if (res == ERROR)
  722.       {
  723.          error("error forking into the background: %s\n\n",
  724.                strerror(errno)); 
  725.  
  726.          quit(ERROR);
  727.       } 
  728.  
  729.       else if (res == 0)
  730.       {
  731.          int res1;
  732.  
  733.          setsid();
  734.  
  735.          res1 = fork();
  736.          if (res1 == ERROR)
  737.          {
  738.             error("error with fork(): %s\n\n", strerror(errno));
  739.             quit(ERROR);
  740.          }
  741.  
  742.          else if (res1 == 0)
  743.          {
  744.             nullfd = open("/dev/null", O_RDONLY);
  745.             if (nullfd == ERROR)
  746.             {
  747.                error("error opening /dev/null: %s\n\n", strerror(errno));
  748.                quit(ERROR);
  749.             }
  750.  
  751.             (void)close(STDIN), dup(nullfd);
  752.             (void)close(STDOUT), dup(errlogfd);
  753.             (void)close(STDERR), dup(errlogfd);
  754.          }
  755.  
  756.          else exit(SUCCESS);
  757.       }
  758.  
  759.       else exit(SUCCESS);
  760.    }
  761.  
  762.    umask(077);
  763. }
  764.  
  765.  
  766. /* --------------------------------- */
  767.  
  768.  
  769. /* export 16 bit msg length.. (msg can be up to 65,535 bytes long) */
  770. char *exportInt(int value)
  771. {
  772.    static char out[2];
  773.  
  774.    out[0] = value, out[1] = value >> 8;
  775.    return out;
  776. }
  777.  
  778. /* ----------------------- */
  779.  
  780.  
  781. /* import 16 bit msg length.. (msg can be up to 65,535 bytes long) */
  782. int importInt(char *value)
  783. {
  784.    u_char *in = (u_char *)value;
  785.    return ((int)in[0]) | ((int)in[1] << 8);
  786. }
  787.  
  788.  
  789. /* ----------------------------------------- */
  790.  
  791.  
  792. /* copy a log msg structure to a new one (to handle users) */
  793. void copyLogStruct(int srcstruct, int dststruct)
  794. {
  795.    logs[dststruct].facility = logs[srcstruct].facility;
  796.  
  797.    logs[dststruct].priority.single = logs[srcstruct].priority.single;
  798.    logs[dststruct].priority.exclude = logs[srcstruct].priority.exclude;
  799.  
  800.    logs[dststruct].priority.ignpri = logs[srcstruct].priority.ignpri;
  801.    logs[dststruct].priority.priority = logs[srcstruct].priority.priority;
  802.  
  803.    logs[dststruct].nsync = logs[srcstruct].nsync;
  804. }
  805.  
  806.  
  807. /* ----------------------------------------- */
  808.  
  809.  
  810. /* get uid of SRS user */
  811. void getSRSuser()
  812. {
  813.    int count;
  814.    FILE *userfd;
  815.  
  816.    char *res;
  817.    char *userptr, *dataptr;
  818.  
  819.    char buf[MAXREADSIZE/4];
  820.    char srsuser[MAXUSERNAME+1];
  821.  
  822.    memset(srsuser, 0, sizeof(srsuser));
  823.  
  824.    userfd = fopen(USERFILE, "r");
  825.    if (userfd == NULL)
  826.    {
  827.       error("error opening %s: %s\n"
  828.             "please run install.sh and read SRS.doc\n\n", USERFILE,
  829.             strerror(errno));
  830.  
  831.       quit(ERROR);
  832.    }
  833.  
  834.    while(1)
  835.    {
  836.       memset(buf, 0, sizeof(buf));
  837.       res = fgets(buf, sizeof(buf)-1, userfd);
  838.  
  839.       if (res == NULL)
  840.       {
  841.          if (errno == EINTR) continue;
  842.          else if ((!feof(userfd)) && (errno > 0))
  843.          {
  844.             error("error reading from %s: %s\n\n", USERFILE, strerror(errno));
  845.             quit(ERROR);
  846.          }
  847.  
  848.          else
  849.          {
  850.             (void)fclose(userfd);
  851.             break;
  852.          }
  853.       }
  854.  
  855.       debug("(in getSRSuser) parsing line: %s%c", buf, 
  856.             (strchr(buf, '\n') == NULL ? '\n' : '\0'));
  857.  
  858.       if (isprint((int)buf[0]) == 0) continue; 
  859.       else
  860.       {
  861.          if (buf[0] == '#') continue;
  862.          else
  863.          {
  864.             if (strchr(buf, '#') != NULL) (*(strchr(buf, '#'))) = '\0';
  865.  
  866.             count = 0, dataptr = buf, userptr = srsuser;
  867.             while((*dataptr) && (isprint((int)*dataptr) != 0) &&
  868.                   (count < sizeof(srsuser)))
  869.             {
  870.                *userptr++ = *dataptr++;
  871.                count++;
  872.             }
  873.  
  874.             pwd = getpwnam(srsuser);
  875.  
  876.             if ((pwd != NULL) && (pwd->pw_uid > 0)) break;
  877.             else
  878.             {
  879.                if (pwd != NULL) 
  880.                   error("the SRS user should not be root.. aborting\n\n");
  881.  
  882.                else error("error with getpwnam(%s): %s\n\n", srsuser, 
  883.                           strerror(errno));
  884.  
  885.                quit(ERROR);
  886.             }
  887.          }
  888.       }
  889.    }
  890.  
  891.    (void)fclose(userfd);
  892.  
  893.    if (debugging == 1)
  894.    {
  895.       (void)putchar('\n');
  896.       (void)write(dblogfd, "\n", 1);
  897.    }
  898. }
  899.  
  900.  
  901. /* ------------------------------------ */
  902.  
  903.  
  904. /* bind to a reserved port (from highest to lowest) */
  905. void rbindport()
  906. {
  907.    int res;
  908.    int success = 0;
  909.  
  910.    int eperm = 0;
  911.  
  912.    int lowport = 512;
  913.    int highport = IPPORT_RESERVED-1;
  914.  
  915.    while(1)
  916.    {
  917.       if (curport == ERROR) curport = highport;
  918.  
  919.       while(1)
  920.       {
  921.          curport--;
  922.          if (curport < lowport) break;
  923.  
  924.          laddr.sin_port = htons(curport);
  925.          if (spooling != 1) debug("attempting to bind to port %d\n", curport);
  926.  
  927.          while(1)
  928.          {
  929.             errno = 0;
  930.             res = bind(sockfd, (struct sockaddr *)&laddr, 
  931.                        sizeof(struct sockaddr));
  932.  
  933.             if (res == ERROR)
  934.             {
  935.                if (errno == EINTR) continue;
  936.  
  937.                if (errno != EADDRINUSE)
  938.                {
  939.                   error("error binding to port: %s\n", strerror(errno));
  940.                   (void)write(errlogfd, "\n", 1);
  941.                }
  942.  
  943.                else debug("error binding to port: %s\n", strerror(errno));
  944.                /* ---------------- */
  945.                if (debugging == 1)
  946.                {
  947.                   (void)putchar('\n');
  948.                   (void)write(dblogfd, "\n", 1);
  949.                }
  950.  
  951.                if ((errno == EACCES) || (errno == EPERM))
  952.                {
  953.                   if (eperm != 1) eperm = 1;
  954.                   else quit(ERROR);
  955.  
  956. #                if !defined(SUN) && !defined(BSD)
  957. #                 ifdef _POSIX_SAVED_IDS
  958.                   res = setuid(0);
  959. #                 else
  960.                   res = seteuid(0);
  961. #                 endif
  962.  
  963.                   if (res == ERROR)
  964.                   {
  965.                      error("error setting [e]uid: %s\n\n",
  966.                            strerror(errno));
  967.  
  968.                      quit(ERROR);
  969.                   }
  970. #                endif
  971.                }
  972.  
  973.                break;
  974.             }
  975.  
  976.             else
  977.             {
  978.                success = 1;
  979.                break;
  980.             }
  981.          }
  982.  
  983.          if (success == 1) break;
  984.       }
  985.  
  986. #    if !defined(SUN) && !defined(BSD)
  987.       if (pwd != NULL)
  988.       {
  989. #        ifdef _POSIX_SAVED_IDS
  990.          res = setuid(pwd->pw_uid);
  991. #        else
  992.          res = seteuid(pwd->pw_uid);
  993. #        endif
  994.  
  995.          if (res == ERROR)
  996.          {
  997.             error("error setting [e]uid: %s\n\n", strerror(errno)); 
  998.             quit(ERROR);
  999.          }         
  1000.       }
  1001. #    endif
  1002.  
  1003.       if (success == 1) break;
  1004.    }
  1005.  
  1006.    if (spooling != 1) debug("successfully bind'd to port %d\n", curport);
  1007. }
  1008.