home *** CD-ROM | disk | FTP | other *** search
- /* Misc. functions involving the server */
- /* ------------------------------------ */
-
- #include "headers.h" /* all important stuff */
-
- /* process data from the server */
- void procData()
- {
- char readbuf[MAXREADSIZE];
-
- memset(readbuf, 0, sizeof(readbuf));
-
- /* initStream(); */
- doStreaming(); /* reads SYSLOGFILE until we gets an abort */
-
- /* do something with data here.. the data could be: */
- /* + new server information (DHCP-like) */
- /* + request to change server (server's load avg too high) */
- /* checkData(); */ /* checks for stuff like "CHNGSERV", etc. */
- }
-
-
- /* -------------------------------------------- */
-
-
- /* create directories for logs */
- void createDirs()
- {
- int res;
- DIR *dir;
-
- errno = 0;
-
- debug("checking where to create SRS directory...\n");
-
- dir = opendir("/var/log");
- if (dir == NULL)
- {
- dir = opendir("/var/adm");
- if (dir == NULL)
- {
- dir = opendir("/usr/adm");
- if (dir == NULL)
- {
- error("error finding the logs directory.. using /\n\n");
- (void)strcpy(SRSdir, "/SRS");
- }
- else
- (void)strcpy(SRSdir, "/usr/adm/SRS");
-
- }
- else
- (void)strcpy(SRSdir, "/var/adm/SRS");
- }
- else
- (void)strcpy(SRSdir, "/var/log/SRS");
-
- debug("creating %s (if it doesn't exist)\n", SRSdir);
-
- res = mkdir(SRSdir, (0766 & ~077));
- if (res == ERROR)
- if (errno != EEXIST)
- {
- (void)fprintf(stderr, "error creating %s: %s\n", SRSdir,
- strerror(errno));
-
- exit(ERROR);
- }
-
- errno = 0;
- res = chdir(SRSdir);
- if (res == ERROR)
- {
- (void)fprintf(stderr, "error with chdir() to %s: %s\n", SRSdir,
- strerror(errno));
-
- exit(ERROR);
- }
-
- res = mkdir("./certs", (0766 & ~077));
- if (res == ERROR)
- if (errno != EEXIST)
- {
- (void)fprintf(stderr, "error creating %s: %s\n", SRSdir,
- strerror(errno));
-
- exit(ERROR);
- }
-
- res = mkdir("./spool", (0766 & ~077));
- if (res == ERROR)
- if (errno != EEXIST)
- {
- (void)fprintf(stderr, "error creating %s/spool: %s\n", SRSdir,
- strerror(errno));
-
- exit(ERROR);
- }
- }
-
-
- /* --------------------------------------------- */
-
-
- /* get our Sub-ID from the server */
- void getSubID()
- {
- int count = 0; /* prevent overflows */
-
- char subIDstr[8];
- char *subidptr, *dataptr;
-
- char readbuf[MAXREADSIZE];
-
- memset(subIDstr, 0, sizeof(subIDstr));
- subidptr = subIDstr;
-
- send_data("SUBID\n"); /* request server list */
-
- (void)signal(SIGALRM, subIDTimeout);
- (void)alarm(MAXTIMEOUT); /* wait for Sub-ID */
-
- /* loop until we get Sub-ID from server */
- while(1)
- {
- memset(readbuf, 0, sizeof(readbuf));
- recv_data(readbuf, sizeof(readbuf));
-
- debug("(in getSubID) data is: %s\n", readbuf);
-
- if (strncmp(readbuf, "SUBID", 5) == 0) break;
- }
-
- (void)alarm(0); /* reset timer */
-
- dataptr = strstr(readbuf, "SUBID");
- dataptr += 6; /* skip "SUBID " */
-
- while ((*dataptr) && (*dataptr != ' ') &&
- (isprint((int)*dataptr) != 0) && (count < (int)sizeof(subID)))
- {
- *subidptr++ = *dataptr++;
- count++;
- }
-
- debug("Sub-ID = %s\n", subIDstr);
-
- subID = atoi(subIDstr);
- }
-
-
- /* ------------------------------------------------ */
-
-
- /* gets current client and server version from the server */
- void getVers()
- {
- int count = 0; /* prevent overflows */
- char *cverptr, *sverptr; /* point to data returned by server */
-
- char curcver[8], cursver[8];
- char *cptr, *sptr; /* point to curcver & cursver buffers */
-
- char readbuf[MAXREADSIZE];
-
- memset(curcver, 0, sizeof(curcver));
- memset(cursver, 0, sizeof(cursver));
-
- cptr = curcver, sptr = cursver;
-
- send_data("VERS\n"); /* request client/server version */
-
- /* if we timeout waiting for version */
-
- (void)signal(SIGALRM, verTimeout);
- (void)alarm(MAXTIMEOUT);
-
- /* loop until we get both the client and server version */
- while(1)
- {
- memset(readbuf, 0, sizeof(readbuf));
- recv_data(readbuf, sizeof(readbuf));
-
- debug("(in getVers) data is: %s\n", readbuf);
-
- cverptr = strstr(readbuf, "CVER");
- sverptr = strstr(readbuf, "SVER");
-
- if ((cverptr != NULL) && (sverptr != NULL))
- {
- debug("got client & server version.. now parsing..\n");
- break;
- }
- }
-
- (void)alarm(0); /* reset alarm */
-
- count = 0; /* reset counter */
- cverptr += 5, sverptr += 5; /* skip "XVER " */
-
- /* copy client from server into local buffer */
- while ((*cverptr) && (*cverptr != ' ') && (*cverptr != ',') &&
- (isprint((int)*cverptr) != 0) && (count < (int)sizeof(curcver)))
- {
- *cptr++ = *cverptr++;
- count++;
- }
-
- count = 0; /* reset counter */
-
- /* copy server from server into local buffer */
- while ((*sverptr) && (*sverptr != ' ') && (*sverptr != ',') &&
- (isprint((int)*sverptr) != 0) && (count < (int)sizeof(cursver)))
- {
- *sptr++ = *sverptr++;
- count++;
- }
-
- /* not floating points in version.. always "X.0" */
- if (debugging == 1)
- (void)printf("%catest client version: %s.0, "
- "latest server version: %s.0\n\n",
- (debugging == 1 ? 'l' : 'L'), curcver, cursver);
-
- if (atoi(curcver) > atoi(VER))
- {
- error("we have an outdated client..\n"
- "mailing %s to request a new one..\n\n", SRSMAILADDR);
-
- updateClient();
- }
- }
-
-
- /* --------------------------------------------- */
-
-
- /* we need to update our client software */
- void updateClient()
- {
- FILE *mailfd;
-
- int res;
- char cmd[128];
-
- memset(cmd, 0, sizeof(cmd));
-
- /* use the system's 'mail' command */
- sprintf(cmd, "`which mail` %s -s \"SRS UPDATE REQUEST\"",
- SRSMAILADDR);
-
- mailfd = popen(cmd, "w");
- if (mailfd == NULL)
- {
- error("error request new client (popen): %s\n\n", strerror(errno));
- return;
- }
-
- memset(cmd, 0, sizeof(cmd));
-
- /* actual request to be parsed by SRS staff */
- sprintf(cmd, "NEW VERSION - ID %s\n\n[Note to admin: "
- "if you get this message back with a mailing error, ]\n"
- "[Please contact RSI and request the new version. ]\n\n", ID);
-
- res = fputs(cmd, mailfd);
- if (res == ERROR)
- {
- error("error requesting new version (fputs): %s\n\n",
- strerror(errno));
-
- quit(ERROR);
- }
-
- (void)fputs(".\n", mailfd); /* terminate message */
-
- res = pclose(mailfd);
- if (res == ERROR)
- {
- error("error closing mailing pipe (pclose): %s\n\n",
- strerror(errno));
-
- quit(ERROR);
- }
-
- return;
- }
-
-
- /* ------------------------------------------------- */
-
-
- /* get server list */
- void getServList()
- {
- char readbuf[MAXREADSIZE];
-
- send_data("SERVLIST\n");
- curServ = ERROR;
-
- (void)signal(SIGALRM, listTimeout);
- (void)alarm(MAXTIMEOUT);
-
- /* read and parse each server in the list */
- while(1)
- {
- memset(readbuf, 0, sizeof(readbuf));
- recv_data(readbuf, sizeof(readbuf));
-
- debug("(in getServList) data is: %s\n", readbuf);
-
- if (strncmp(readbuf, "SERV", 4) == 0) putServ(++useServ, readbuf);
- else if (strncmp(readbuf, "DONE", 4) == 0) break; /* DONE == EOF */
-
- if (debugging == 1) (void)putchar('\n');
- }
-
- if (debugging != 1) (void)putchar('\n');
- (void)alarm(0);
- }
-
-
- /* ----------------------------------------------- */
-
-
- /* parse and put server in ServList */
- void putServ(int servNum, char *buf)
- {
- int count = 0; /* prevent any overflows */
-
- char *ipptr; /* pointer to buffer with server's IP */
- char *dataptr; /* pointer to data from server */
-
- char servname[128]; /* just to be sure it's compatible in the future */
-
- debug("parsing server servNames[%d] (server #%d)\n",
- servNum, servNum+1);
-
- memset(servname, 0, sizeof(servname));
- ipptr = servname;
-
- dataptr = strstr(buf, "SERV");
- dataptr += 5; /* skip "SERV " */
-
- count = 0;
-
- while ((*dataptr) && (*dataptr != ' ') &&
- (isprint((int)*dataptr) != 0) && (count < (int)sizeof(servname)))
- {
- *ipptr++ = *dataptr++;
- count++;
- }
-
- /* includes a port to connect to */
- if ((*dataptr == ' ') || (*dataptr == '\t'))
- {
- char port[16];
- char *portstr = port;
-
- memset(port, 0, sizeof(port));
-
- while ((*dataptr == ' ') || (*dataptr == '\t')) dataptr += 1;
- if (isdigit((int)*dataptr) != 0) servList[servNum].port = PORT;
-
- count = 0;
- while ((*dataptr) && (*dataptr != ' ') &&
- (isdigit((int)*dataptr) != 0) && (count < (int)sizeof(port)))
- {
- *portstr++ = *dataptr++;
- count++;
- }
-
- servList[servNum].port = atoi(port);
- }
-
- if (servList[servNum].port <= 0)
- servList[servNum].port = PORT;
-
- servList[servNum].name = (char *)malloc(strlen(servname)+1);
- memset(servList[servNum].name, 0, strlen(servname)+1);
- strcpy(servList[servNum].name, servname);
-
- (void)printf("%ctreaming server #%d is: %s (port %d)\n",
- (debugging != 1 ? 'S' : 's'), servNum+1,
- servList[servNum].name, servList[servNum].port);
- }
-
-
- /* ----------------------------------------------- */
-
-
- /* get "OKAY" from client */
- void getOkay()
- {
- char readbuf[MAXREADSIZE];
-
- while(1)
- {
- errno = 0;
-
- memset(readbuf, 0, sizeof(readbuf));
- recv_data(readbuf, sizeof(readbuf));
-
- if ((errors == 1) || (gotAlrm == 1))
- {
- if (done == 1) return;
-
- errors = 1;
- error("(in getOkay) timeout or error..\n\n");
-
- if (done == 1) return;
-
- if (gotInfoServ == 1) longjmp(reconnect, 1);
- else longjmp(infoconn, 1);
- }
-
- if (strncmp(readbuf, "OKAY", 4) == 0)
- {
- if (silent != 1) debug("got OKAY\n\n");
- break;
- }
-
- else if (done != 1)
- {
- error("OKAY not received.. retrying\n\n");
- continue;
- }
-
- else return;
- }
- }
-
-
- /* ------------------------------------------------- */
-
-
- /* parse and setup args */
- void getArgs(int argc, char **argv)
- {
- int opt;
-
- dbFile = errorFile = spoolFile = NULL;
-
- if (debugging != 1)
- if (argc > 1)
- {
- /* -h == help, -d == debugging enabled, -e == error file, */
- /* -s == spool file, -l == log file */
-
- /* FIX - add long option name support */
-
- while ((opt = getopt(argc, argv, "hde:l:s:p:")) != ERROR)
- {
- int testfd1;
- FILE *testfd; /* test if the user-defined files work */
-
- switch(opt)
- {
- case 'h':
- usage(argv[0]);
- exit(SUCCESS);
-
- case 'd':
- debugging = 1;
- debug("debugging enabled\n");
-
- break;
-
- case 'e':
- errorFile = optarg;
- debug("using %s to log errors\n", errorFile);
-
- while(1)
- {
- testfd1 = open(errorFile, O_CREAT | O_WRONLY | O_APPEND,
- 0600);
-
- if (testfd1 == ERROR)
- {
- if (errno == EINTR) continue;
-
- (void)fprintf(stderr, "Unable to open %s: %s\n",
- errorFile, strerror(errno));
-
- exit(ERROR);
- }
-
- else break;
- }
-
- (void)close(testfd1);
- break;
-
- case 'l':
- dbFile = optarg;
- debug("using %s to log db info\n", dbFile);
-
- while(1)
- {
- testfd1 = open(dbFile, O_CREAT | O_WRONLY | O_APPEND,
- 0600);
-
- if (testfd1 == ERROR)
- {
- if (errno == EINTR) continue;
-
- (void)fprintf(stderr, "Unable to open %s: %s\n",
- dbFile, strerror(errno));
-
- exit(ERROR);
- }
-
- else break;
- }
-
- (void)close(testfd1);
- break;
-
- case 'p':
- locPort = atoi(optarg);
-
- if ((locPort > IPPORT_RESERVED-1) ||
- (locPort < 512))
- {
- fprintf(stderr,
- "Error: port must be between 512-%d\n",
- IPPORT_RESERVED-1);
-
- exit(ERROR);
- }
-
- break;
-
- case 's':
- spoolFile = optarg;
- debug("using %s to spool system logs\n", spoolFile);
-
- while (1)
- {
- testfd = fopen(spoolFile, "a+");
-
- if (testfd == NULL)
- {
- if (errno == EINTR) continue;
-
- (void)fprintf(stderr, "Unable to open %s: %s\n",
- spoolFile, strerror(errno));
-
- exit(ERROR);
- }
-
- else break;
- }
-
- (void)chmod(spoolFile, S_IREAD | S_IWRITE);
- (void)fclose(testfd);
-
- break;
-
- case '?':
- (void)fputc('\n', stderr), usage(argv[0]);
- (void)fprintf(stderr, "Press 'Enter' to continue..\n");
- (void)getchar();
-
- break;
-
- default:
- (void)fprintf(stderr, "getopt() returned %d.. exiting\n",
- opt);
-
- exit(ERROR);
- }
- }
- }
- }
-
-
- /* ------------------------------------------------ */
-
-
- /* progress through server list */
- void nextServer()
- {
- if ((curServ == ERROR) && (connected == 1))
- {
- if (servList[curServ+1].name == NULL)
- {
- error("have no valid streaming server name in list\n\n");
- quit(ERROR);
- }
-
- if (prim == 1)
- {
- if ((strcmp(PRIMSERV, servList[curServ+1].name) == 0) &&
- (PORT == servList[curServ+1].port))
- {
- curServ += 2;
- initing = 1, errors = 1;
-
- return;
- }
- }
-
- else
- {
- if ((strcmp(SECSERV, servList[curServ+1].name) == 0) &&
- (PORT == servList[curServ+1].port))
- {
- curServ += 2;
- initing = 1, errors = 1;
-
- return;
- }
- }
- }
- }
-
-
- /* ------------------------------------------------ */
-
-
- /* do stuff with finding next server in list */
- void doServer()
- {
- if (curServ < 0)
- {
- curServ = 0;
- return;
- }
-
- /* ------------------------------------- */
-
- while(1)
- {
- if (useServ == 0)
- {
- curServ++;
- break;
- }
-
- else if ((curServ + 1) > useServ)
- {
- if ((servList[curServ].name == NULL) || (servList[0].name == NULL))
- {
- error("NULL server name.. comparing server [%d] to [0]\n\n",
- curServ);
-
- quit(ERROR);
- }
-
- else if ((strcmp(servList[curServ].name, servList[0].name) != 0) ||
- (servList[curServ].port != servList[0].port))
- {
- curServ++;
- break;
- }
-
- else curServ = 0;
- }
-
- else
- {
- if ((servList[curServ].name == NULL) || (servList[0].name == NULL))
- {
- error("NULL server name.. comparing server [%d] to [%d]\n\n",
- curServ, curServ + 1);
-
- quit(ERROR);
- }
-
- else if ((strcmp(servList[curServ].name,
- servList[curServ+1].name) != 0) ||
- (servList[curServ].port != servList[curServ+1].port))
- {
- curServ++;
- break;
- }
-
- else curServ++;
- }
- }
-
- /* ------------------------------------- */
-
- if (curServ > useServ)
- {
- if (spooling != 1)
- {
- error("reached end of server list.. now starting spooling\n\n");
-
- debug("(in parent)\n%cow forking a child to start spooling "
- "to %s/spool/%s locally\n\n", (debugging != 1 ? 'N' : 'n'),
- SRSdir, LOGFILE);
-
- connected = 0, silent = 1;
- forkSpool();
- }
-
- else
- {
- (void)sleep(MAXPAUSE * 3); /* take a break.. */
- curServ = 0; /* just keep going forever */
- }
- }
- }
-
-
- /* --------------------------------------------- */
-
-
- /* go into background and daemonize */
- void daemonize()
- {
- int res;
-
- if (start == 1)
- {
- (void)printf("Now forking..\n");
-
- res = fork();
- if (res == ERROR)
- {
- error("error forking into the background: %s\n\n",
- strerror(errno));
-
- quit(ERROR);
- }
-
- else if (res == 0)
- {
- int res1;
-
- setsid();
-
- res1 = fork();
- if (res1 == ERROR)
- {
- error("error with fork(): %s\n\n", strerror(errno));
- quit(ERROR);
- }
-
- else if (res1 == 0)
- {
- nullfd = open("/dev/null", O_RDONLY);
- if (nullfd == ERROR)
- {
- error("error opening /dev/null: %s\n\n", strerror(errno));
- quit(ERROR);
- }
-
- (void)close(STDIN), dup(nullfd);
- (void)close(STDOUT), dup(errlogfd);
- (void)close(STDERR), dup(errlogfd);
- }
-
- else exit(SUCCESS);
- }
-
- else exit(SUCCESS);
- }
-
- umask(077);
- }
-
-
- /* --------------------------------- */
-
-
- /* export 16 bit msg length.. (msg can be up to 65,535 bytes long) */
- char *exportInt(int value)
- {
- static char out[2];
-
- out[0] = value, out[1] = value >> 8;
- return out;
- }
-
- /* ----------------------- */
-
-
- /* import 16 bit msg length.. (msg can be up to 65,535 bytes long) */
- int importInt(char *value)
- {
- u_char *in = (u_char *)value;
- return ((int)in[0]) | ((int)in[1] << 8);
- }
-
-
- /* ----------------------------------------- */
-
-
- /* copy a log msg structure to a new one (to handle users) */
- void copyLogStruct(int srcstruct, int dststruct)
- {
- logs[dststruct].facility = logs[srcstruct].facility;
-
- logs[dststruct].priority.single = logs[srcstruct].priority.single;
- logs[dststruct].priority.exclude = logs[srcstruct].priority.exclude;
-
- logs[dststruct].priority.ignpri = logs[srcstruct].priority.ignpri;
- logs[dststruct].priority.priority = logs[srcstruct].priority.priority;
-
- logs[dststruct].nsync = logs[srcstruct].nsync;
- }
-
-
- /* ----------------------------------------- */
-
-
- /* get uid of SRS user */
- void getSRSuser()
- {
- int count;
- FILE *userfd;
-
- char *res;
- char *userptr, *dataptr;
-
- char buf[MAXREADSIZE/4];
- char srsuser[MAXUSERNAME+1];
-
- memset(srsuser, 0, sizeof(srsuser));
-
- userfd = fopen(USERFILE, "r");
- if (userfd == NULL)
- {
- error("error opening %s: %s\n"
- "please run install.sh and read SRS.doc\n\n", USERFILE,
- strerror(errno));
-
- quit(ERROR);
- }
-
- while(1)
- {
- memset(buf, 0, sizeof(buf));
- res = fgets(buf, sizeof(buf)-1, userfd);
-
- if (res == NULL)
- {
- if (errno == EINTR) continue;
- else if ((!feof(userfd)) && (errno > 0))
- {
- error("error reading from %s: %s\n\n", USERFILE, strerror(errno));
- quit(ERROR);
- }
-
- else
- {
- (void)fclose(userfd);
- break;
- }
- }
-
- debug("(in getSRSuser) parsing line: %s%c", buf,
- (strchr(buf, '\n') == NULL ? '\n' : '\0'));
-
- if (isprint((int)buf[0]) == 0) continue;
- else
- {
- if (buf[0] == '#') continue;
- else
- {
- if (strchr(buf, '#') != NULL) (*(strchr(buf, '#'))) = '\0';
-
- count = 0, dataptr = buf, userptr = srsuser;
- while((*dataptr) && (isprint((int)*dataptr) != 0) &&
- (count < sizeof(srsuser)))
- {
- *userptr++ = *dataptr++;
- count++;
- }
-
- pwd = getpwnam(srsuser);
-
- if ((pwd != NULL) && (pwd->pw_uid > 0)) break;
- else
- {
- if (pwd != NULL)
- error("the SRS user should not be root.. aborting\n\n");
-
- else error("error with getpwnam(%s): %s\n\n", srsuser,
- strerror(errno));
-
- quit(ERROR);
- }
- }
- }
- }
-
- (void)fclose(userfd);
-
- if (debugging == 1)
- {
- (void)putchar('\n');
- (void)write(dblogfd, "\n", 1);
- }
- }
-
-
- /* ------------------------------------ */
-
-
- /* bind to a reserved port (from highest to lowest) */
- void rbindport()
- {
- int res;
- int success = 0;
-
- int eperm = 0;
-
- int lowport = 512;
- int highport = IPPORT_RESERVED-1;
-
- while(1)
- {
- if (curport == ERROR) curport = highport;
-
- while(1)
- {
- curport--;
- if (curport < lowport) break;
-
- laddr.sin_port = htons(curport);
- if (spooling != 1) debug("attempting to bind to port %d\n", curport);
-
- while(1)
- {
- errno = 0;
- res = bind(sockfd, (struct sockaddr *)&laddr,
- sizeof(struct sockaddr));
-
- if (res == ERROR)
- {
- if (errno == EINTR) continue;
-
- if (errno != EADDRINUSE)
- {
- error("error binding to port: %s\n", strerror(errno));
- (void)write(errlogfd, "\n", 1);
- }
-
- else debug("error binding to port: %s\n", strerror(errno));
- /* ---------------- */
- if (debugging == 1)
- {
- (void)putchar('\n');
- (void)write(dblogfd, "\n", 1);
- }
-
- if ((errno == EACCES) || (errno == EPERM))
- {
- if (eperm != 1) eperm = 1;
- else quit(ERROR);
-
- # if !defined(SUN) && !defined(BSD)
- # ifdef _POSIX_SAVED_IDS
- res = setuid(0);
- # else
- res = seteuid(0);
- # endif
-
- if (res == ERROR)
- {
- error("error setting [e]uid: %s\n\n",
- strerror(errno));
-
- quit(ERROR);
- }
- # endif
- }
-
- break;
- }
-
- else
- {
- success = 1;
- break;
- }
- }
-
- if (success == 1) break;
- }
-
- # if !defined(SUN) && !defined(BSD)
- if (pwd != NULL)
- {
- # ifdef _POSIX_SAVED_IDS
- res = setuid(pwd->pw_uid);
- # else
- res = seteuid(pwd->pw_uid);
- # endif
-
- if (res == ERROR)
- {
- error("error setting [e]uid: %s\n\n", strerror(errno));
- quit(ERROR);
- }
- }
- # endif
-
- if (success == 1) break;
- }
-
- if (spooling != 1) debug("successfully bind'd to port %d\n", curport);
- }
-