00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 #include <sys/types.h>
00087 #include <stdio.h>
00088 #include <ctype.h>
00089 #include <string.h>
00090 #include <unistd.h>
00091 #include <stdlib.h>
00092 #include <signal.h>
00093 #include <errno.h>
00094 #include <fcntl.h>
00095 #include <limits.h>
00096 #include <time.h>
00097 #include <sys/ioctl.h>
00098 #include <sys/select.h>
00099 #include <sys/wait.h>
00100 #include <net/netlib.h>
00101 #include <net/hton.h>
00102 #include <net/gen/in.h>
00103 #include <net/gen/udp.h>
00104 #include <net/gen/udp_io.h>
00105 #include <net/gen/netdb.h>
00106
00107 #define SYSLOG_NAMES
00108 #include <syslog.h>
00109 #define KLOGD 1
00110
00111 #define MAXLINE 512
00112 #define MAXSVLINE 256
00113
00114 #define DEFUPRI (LOG_USER|LOG_NOTICE)
00115 #define DEFSPRI (LOG_KERN|LOG_CRIT)
00116
00117
00118 #define IGN_CONS 0x001
00119 #define SYNC_FILE 0x002
00120 #define ADDDATE 0x004
00121 #define MARK 0x008
00122
00123 #define CTTY "/dev/log"
00124
00125 #define dprintf if(DbgOpt!=0)printf
00126 #if debug == 0
00127 #define DEBUG(statement)
00128 #else
00129 #define DEBUG(statement) statement
00130 #endif
00131 #if !defined PIDFILE
00132 #define PIDFILE "/var/run/syslogd.pid"
00133 #endif
00134
00135 #define UNAMESZ 8
00136 #define MAXUNAMES 20
00137 #define MAXFNAME 200
00138 #define MAXHOSTNAMELEN 64
00139
00140
00141
00142
00143 #define TIMERINTVL 30
00144 #define INTERVAL1 30
00145 #define INTERVAL2 60
00146 #define MAXREPEAT ((sizeof(repeatinterval)/sizeof(repeatinterval[0]))-1)
00147 #define REPEATTIME(f) ((f)->f_time+repeatinterval[(f)->f_repeatcount])
00148 #define BACKOFF(f) {if(++(f)->f_repeatcount>MAXREPEAT)(f)->f_repeatcount=MAXREPEAT;}
00149
00150
00151 #define F_UNUSED 0
00152 #define F_FILE 1
00153 #define F_TTY 2
00154 #define F_CONSOLE 3
00155 #define F_FORW 4
00156 #define F_USERS 5
00157 #define F_WALL 6
00158
00159 #define max(a,b) ((a)>=(b)?(a):(b))
00160
00161
00162 struct filed {
00163 struct filed *f_next;
00164 short f_type;
00165 short f_file;
00166 time_t f_time;
00167 char f_pmask[LOG_NFACILITIES + 1];
00168 union {
00169 char f_uname[MAXUNAMES][UNAMESZ + 1];
00170 char f_fname[MAXFNAME];
00171 } f_un;
00172 char f_prevline[MAXSVLINE];
00173 char f_lasttime[16];
00174 char f_prevhost[MAXHOSTNAMELEN + 1];
00175 int f_prevpri;
00176 int f_prevlen;
00177 int f_prevcount;
00178 int f_repeatcount;
00179 int f_flags;
00180 };
00181
00182 static const char *const TypeNames[] =
00183 {
00184 "UNUSED", "FILE", "TTY", "CONSOLE", "FORW", "USERS", "WALL", NULL,
00185 };
00186
00187 static struct filed *Files = NULL;
00188 static struct filed consfile;
00189 static int DbgOpt = 0;
00190 static char LocalHostName[MAXHOSTNAMELEN + 1];
00191 static int Initialized = 0;
00192 static int MarkInterval = 20 * 60;
00193 static int MarkSeq = 0;
00194 static time_t now;
00195
00196 static const char *ConfFile = "/etc/syslog.conf";
00197 static const char *PidFile = PIDFILE;
00198 static const char ctty[] = CTTY;
00199
00200 static const char ProgName[] = "syslogd:";
00201 static const char version[] = "1.3 (Minix)";
00202 static const char usage[] =
00203 "usage:\tsyslogd [-d] [-m markinterval] [-f conf-file]\n"
00204 "\t\t[-p listeningport] [-v] [-?]\n" ;
00205 static const int repeatinterval[] =
00206 {INTERVAL1, INTERVAL2,};
00207
00208
00209
00210
00211
00212
00213 void wallmsg(struct filed * fLog, char *message)
00214 {
00215
00216 return;
00217 }
00218
00219
00220
00221
00222
00223 void fprintlog(struct filed * fLog, int flags, char *message)
00224 {
00225 int len;
00226 char line[MAXLINE + 1];
00227 char repbuf[80];
00228
00229 if (message == NULL) {
00230 if (fLog->f_prevcount > 1) {
00231 sprintf(repbuf, "last message repeated %d times", fLog->f_prevcount);
00232 message = repbuf;
00233 } else
00234 message = fLog->f_prevline;
00235 }
00236 snprintf(line, sizeof(line), "%s %s %s",
00237 fLog->f_lasttime, fLog->f_prevhost, message);
00238 DEBUG(dprintf("Logging to %s", TypeNames[fLog->f_type]);)
00239 fLog->f_time = now;
00240 switch (fLog->f_type) {
00241 case F_UNUSED:
00242 DEBUG(dprintf("\n");)
00243 break;
00244 case F_CONSOLE:
00245 if (flags & IGN_CONS) {
00246 case F_FORW:
00247 DEBUG(dprintf(" (ignored)\n");)
00248 break;
00249 }
00250 case F_TTY:
00251 case F_FILE:
00252 DEBUG(dprintf(" %s\n", fLog->f_un.f_fname);)
00253 strcat(line, fLog->f_type != F_FILE ? "\r\n" : "\n");
00254 len = strlen(line);
00255 if (write(fLog->f_file, line, len) != len) {
00256 ;
00257 } else if (flags & SYNC_FILE)
00258 sync();
00259 break;
00260 case F_USERS:
00261 case F_WALL:
00262 DEBUG(dprintf("\n");)
00263 strcat(line, "\r\n");
00264 wallmsg(fLog, line);
00265 break;
00266 }
00267 fLog->f_prevcount = 0;
00268 return;
00269 }
00270
00271
00272
00273
00274
00275
00276 void logmsg(int pri, char *msg, char *from, int flags)
00277 {
00278 struct filed *f;
00279 int fac, prilev;
00280 int omask, msglen;
00281 char *timestamp;
00282
00283 DEBUG(dprintf("logmsg: pri %o, flags %x, from %s, msg %s\n", pri, flags, from, msg);)
00284
00285
00286
00287
00288 msglen = strlen(msg);
00289 if (msglen < 16 || msg[3] != ' ' || msg[6] != ' ' ||
00290 msg[9] != ':' || msg[12] != ':' || msg[15] != ' ')
00291 flags |= ADDDATE;
00292
00293 time(&now);
00294 if (flags & ADDDATE)
00295 timestamp = ctime(&now) + 4;
00296 else {
00297 timestamp = msg;
00298 msg += 16;
00299 msglen -= 16;
00300 }
00301
00302
00303 fac = (flags & MARK) ? LOG_NFACILITIES : LOG_FAC(pri);
00304 prilev = LOG_PRI(pri);
00305
00306
00307 if (!Initialized) {
00308
00309 f = &consfile;
00310 f->f_file = open(ctty, O_WRONLY | O_NOCTTY);
00311 if (f->f_file >= 0) {
00312 if (!DbgOpt) setsid();
00313 fprintlog(f, flags, msg);
00314 close(f->f_file);
00315 }
00316 } else {
00317 for (f = Files; f; f = f->f_next) {
00318
00319
00320 if (f->f_pmask[fac] < prilev || f->f_pmask[fac] == INTERNAL_NOPRI)
00321 continue;
00322
00323 if (f->f_type == F_CONSOLE && (flags & IGN_CONS)) continue;
00324
00325
00326 if ((flags & MARK) && (now - f->f_time) < MarkInterval / 2)
00327 continue;
00328
00329
00330 if ((flags & MARK) == 0 && msglen == f->f_prevlen &&
00331 !strcmp(msg, f->f_prevline) &&
00332 !strcmp(from, f->f_prevhost)) {
00333 strncpy(f->f_lasttime, timestamp, 15);
00334 f->f_prevcount += 1;
00335 DEBUG(dprintf("msg repeated %d times, %ld sec of %d\n",
00336 f->f_prevcount, now - f->f_time,
00337 repeatinterval[f->f_repeatcount]);)
00338
00339
00340
00341
00342 if (now > REPEATTIME(f)) {
00343 fprintlog(f, flags, (char *) NULL);
00344 BACKOFF(f);
00345 }
00346 } else {
00347
00348 if (f->f_prevcount) fprintlog(f, 0, (char *) NULL);
00349 f->f_repeatcount = 0;
00350 strncpy(f->f_lasttime, timestamp, 15);
00351 strncpy(f->f_prevhost, from, sizeof(f->f_prevhost));
00352 if (msglen < MAXSVLINE) {
00353 f->f_prevlen = msglen;
00354 f->f_prevpri = pri;
00355 strcpy(f->f_prevline, msg);
00356 fprintlog(f, flags, (char *) NULL);
00357 } else {
00358 f->f_prevline[0] = 0;
00359 f->f_prevlen = 0;
00360 fprintlog(f, flags, msg);
00361 }
00362 }
00363 }
00364 }
00365
00366
00367
00368
00369 return;
00370 }
00371
00372
00373
00374
00375
00376 void logerror(char *type)
00377 {
00378 char buf[100];
00379
00380 if (errno == 0) sprintf(buf, "%s %s", ProgName, type);
00381
00382 else if (errno >= _NERROR)
00383 sprintf(buf, "%s %s - error %d", ProgName, type, errno);
00384
00385 else
00386 sprintf(buf, "%s %s - %s", ProgName, type, strerror(errno));
00387
00388 errno = 0;
00389 dprintf("%s\n", buf);
00390 logmsg(LOG_SYSLOG | LOG_ERR, buf, LocalHostName, ADDDATE);
00391 return;
00392 }
00393
00394
00395
00396
00397
00398 void die(int sig)
00399 {
00400 struct filed *f;
00401 char buf[100];
00402
00403 for (f = Files; f != NULL; f = f->f_next) {
00404
00405 if (f->f_prevcount) fprintlog(f, 0, NULL);
00406 }
00407 if (sig >= 0) {
00408 DEBUG(dprintf("%s exiting on signal %d\n", ProgName, sig);)
00409 sprintf(buf, "exiting on signal %d", sig);
00410 errno = 0;
00411 logerror(buf);
00412 }
00413 unlink(PidFile);
00414 exit(sig == (-1) ? EXIT_FAILURE : EXIT_SUCCESS);
00415 }
00416
00417
00418
00419
00420
00421
00422 void domark(int sig)
00423 {
00424 struct filed *f;
00425
00426 now = time(NULL);
00427 MarkSeq += TIMERINTVL;
00428 if (MarkSeq >= MarkInterval) {
00429 logmsg(LOG_INFO, "-- MARK --", LocalHostName, ADDDATE | MARK);
00430 MarkSeq = 0;
00431 }
00432 for (f = Files; f; f = f->f_next) {
00433 if (f->f_prevcount && now >= REPEATTIME(f)) {
00434 DEBUG(dprintf("flush %s: repeated %d times, %d sec.\n",
00435 TypeNames[f->f_type], f->f_prevcount,
00436 repeatinterval[f->f_repeatcount]);)
00437 fprintlog(f, 0, NULL);
00438 BACKOFF(f);
00439 }
00440 }
00441 signal(SIGALRM, domark);
00442 alarm(TIMERINTVL);
00443 return;
00444 }
00445
00446
00447
00448
00449
00450 int decode(char *name, const struct _code *codetab)
00451 {
00452 const struct _code *c;
00453 char *p;
00454 char buf[40];
00455
00456 DEBUG(dprintf("symbolic name: %s", name);)
00457 if (isdigit(*name)) return (atoi(name));
00458
00459 strcpy(buf, name);
00460 for (p = buf; *p; p += 1) {
00461 if (isupper(*p)) *p = tolower(*p);
00462 }
00463 for (c = codetab; c->c_name; c += 1) {
00464 if (!strcmp(buf, c->c_name)) {
00465 DEBUG(dprintf(" ==> %d\n", c->c_val);)
00466 return (c->c_val);
00467 }
00468 }
00469 return (-1);
00470 }
00471
00472
00473
00474
00475
00476 void cfline(char *line, struct filed * fLog)
00477 {
00478 char *p, *q, *bp;
00479 int ix, pri;
00480 char buf[MAXLINE];
00481 char xbuf[200];
00482
00483 DEBUG(dprintf("cfline(%s)\n", line);)
00484
00485
00486 errno = 0;
00487
00488
00489 memset(fLog, 0, sizeof(*fLog));
00490 for (ix = 0; ix <= LOG_NFACILITIES; ix += 1)
00491 fLog->f_pmask[ix] = INTERNAL_NOPRI;
00492
00493
00494 for (p = line; *p && *p != '\t';) {
00495
00496
00497 for (q = p; *q && *q != '\t' && *q++ != '.';) continue;
00498
00499
00500 for (bp = buf; *q && !strchr("\t,;", *q);) *bp++ = *q++;
00501 *bp = '\0';
00502
00503
00504 while (strchr(", ;", *q)) q++;
00505
00506
00507 pri = decode(buf, PriNames);
00508 if (pri < 0) {
00509 sprintf(xbuf, "unknown priority name \"%s\"", buf);
00510 logerror(xbuf);
00511 return;
00512 }
00513
00514
00515 while (*p && !strchr("\t.;", *p)) {
00516 for (bp = buf; *p && !strchr("\t,;.", *p);) *bp++ = *p++;
00517 *bp = '\0';
00518 if (*buf == '*') {
00519 for (ix = 0; ix <= LOG_NFACILITIES; ix += 1)
00520 if ((fLog->f_pmask[ix] < pri) ||
00521 (fLog->f_pmask[ix] == INTERNAL_NOPRI)) {
00522 fLog->f_pmask[ix] = pri;
00523 }
00524 } else {
00525 ix = decode(buf, FacNames);
00526 if (ix < 0) {
00527 sprintf(xbuf, "unknown facility name \"%s\"", buf);
00528 logerror(xbuf);
00529 return;
00530 }
00531 if ((fLog->f_pmask[ix >> 3] < pri) ||
00532 (fLog->f_pmask[ix >> 3] == INTERNAL_NOPRI)) {
00533 fLog->f_pmask[ix >> 3] = pri;
00534 }
00535 }
00536 while (*p == ',' || *p == ' ') p++;
00537 }
00538 p = q;
00539 }
00540
00541
00542 while (*p == '\t' || *p == ' ') p++;
00543
00544 DEBUG(dprintf("leading char in action: %c\n", *p);)
00545 switch (*p) {
00546 case '@':
00547 break;
00548
00549 case '/':
00550 strcpy(fLog->f_un.f_fname, p);
00551 DEBUG(dprintf("filename: %s\n", p); )
00552 if ((fLog->f_file = open(p, O_WRONLY | O_APPEND | O_CREAT | O_NOCTTY, 0644)) < 0) {
00553 fLog->f_file = F_UNUSED;
00554 sprintf(xbuf, "unknown file/device (%s)", p);
00555 logerror(xbuf);
00556 break;
00557 }
00558 if (isatty(fLog->f_file)) {
00559 if (!DbgOpt) setsid();
00560 fLog->f_type = F_TTY;
00561 } else
00562 fLog->f_type = F_FILE;
00563 if (strcmp(p, ctty) == 0) fLog->f_type = F_CONSOLE;
00564 break;
00565
00566 case '*':
00567 DEBUG(dprintf("write-all\n");)
00568 fLog->f_type = F_WALL;
00569 break;
00570
00571 default:
00572 DEBUG(dprintf("users: %s\n", p); )
00573 for (ix = 0; ix < MAXUNAMES && *p; ix += 1) {
00574 for (q = p; *q && *q != ',';) q += 1;
00575 strncpy(fLog->f_un.f_uname[ix], p, UNAMESZ);
00576 if ((q - p) > UNAMESZ)
00577 fLog->f_un.f_uname[ix][UNAMESZ] = '\0';
00578 else
00579 fLog->f_un.f_uname[ix][q - p] = '\0';
00580 while (*q == ',' || *q == ' ') q++;
00581 p = q;
00582 }
00583 fLog->f_type = F_USERS;
00584 break;
00585 }
00586 }
00587
00588
00589
00590
00591
00592
00593 void printline(char *hname, char *msg)
00594 {
00595 char line[MAXLINE + 1];
00596 char *p = msg, *q = line;
00597 int ch, pri = DEFUPRI;
00598
00599
00600 if (*p == '<') {
00601 pri = 0;
00602 while (isdigit(*++p)) {
00603 if ((*p - '0') < 8) {
00604
00605 pri = 10 * pri + (*p - '0');
00606 } else
00607 pri = 10 * pri + 7;
00608 }
00609 if (*p == '>') ++p;
00610 }
00611 if (pri & ~(LOG_FACMASK | LOG_PRIMASK)) pri = DEFUPRI;
00612
00613
00614 if (LOG_FAC(pri) == LOG_KERN) pri = LOG_MAKEPRI(LOG_USER, LOG_PRI(pri));
00615
00616
00617 while ((ch = *p++ & 0177) != '\0' && q < &line[sizeof(line) - 1]) {
00618 if (ch == '\n')
00619 *q++ = ' ';
00620 else if (iscntrl(ch)) {
00621 *q++ = '^';
00622 *q++ = ch ^ 0100;
00623 } else
00624 *q++ = ch;
00625 }
00626 *q = '\0';
00627
00628 logmsg(pri, line, hname, 0);
00629 return;
00630 }
00631
00632
00633
00634
00635
00636
00637 void printkline(char *hname, char *msg)
00638 {
00639 char line[MAXLINE + 1];
00640 char *p = msg, *q = line;
00641 int ch, pri = DEFUPRI;
00642
00643
00644 snprintf(line, sizeof(line), "kernel: %s", msg);
00645
00646 logmsg(LOG_KERN | LOG_INFO, line, hname, ADDDATE);
00647 return;
00648 }
00649
00650
00651
00652
00653
00654
00655 void init(int sig)
00656 {
00657 int i;
00658 FILE *cf;
00659 struct filed *fLog, *next, **nextp;
00660 char *p;
00661 char cline[BUFSIZ];
00662
00663 DEBUG(dprintf("init\n");)
00664
00665
00666 Initialized = 0;
00667 for (fLog = Files; fLog != NULL; fLog = next) {
00668
00669
00670 if (fLog->f_prevcount) fprintlog(fLog, 0, NULL);
00671
00672 switch (fLog->f_type) {
00673 case F_FILE:
00674 case F_TTY:
00675 case F_CONSOLE: close(fLog->f_file); break;
00676 }
00677 next = fLog->f_next;
00678 free((char *) fLog);
00679 }
00680 Files = NULL;
00681 nextp = &Files;
00682
00683
00684 if ((cf = fopen(ConfFile, "r")) != NULL) {
00685
00686 fLog = NULL;
00687 while (fgets(cline, sizeof(cline), cf) != NULL) {
00688
00689
00690 for (p = cline; isspace(*p); p += 1);
00691 if (*p == '\0' || *p == '#') continue;
00692 for (p = strchr(cline, '\0'); isspace(*--p););
00693 *++p = '\0';
00694 fLog = (struct filed *) calloc(1, sizeof(*fLog));
00695 *nextp = fLog;
00696 nextp = &fLog->f_next;
00697 cfline(cline, fLog);
00698 }
00699
00700
00701 fclose(cf);
00702 Initialized = 1;
00703 DEBUG (
00704 if (DbgOpt) {
00705 for (fLog = Files; fLog; fLog = fLog->f_next) {
00706 for (i = 0; i <= LOG_NFACILITIES; i += 1)
00707 if (fLog->f_pmask[i] == INTERNAL_NOPRI)
00708 printf("X ");
00709 else
00710 printf("%d ", fLog->f_pmask[i]);
00711 printf("%s: ", TypeNames[fLog->f_type]);
00712 switch (fLog->f_type) {
00713 case F_FILE:
00714 case F_TTY:
00715 case F_CONSOLE:
00716 printf("%s", fLog->f_un.f_fname);
00717 break;
00718 case F_FORW:
00719 break;
00720 case F_USERS:
00721 for (i = 0; i < MAXUNAMES && *fLog->f_un.f_uname[i]; i += 1)
00722 printf("%s, ", fLog->f_un.f_uname[i]);
00723 break;
00724 }
00725 printf("\n");
00726 }
00727 }
00728 )
00729 logmsg(LOG_SYSLOG | LOG_INFO, "syslogd: restart", LocalHostName, ADDDATE);
00730 signal(SIGHUP, init);
00731 DEBUG(dprintf("%s restarted\n", ProgName);)
00732 } else {
00733 DEBUG(dprintf("cannot open %s\n", ConfFile);)
00734 *nextp = (struct filed *) calloc(1, sizeof(*fLog));
00735 cfline("*.ERR\t" CTTY, *nextp);
00736 (*nextp)->f_next = (struct filed *) calloc(1, sizeof(*fLog));
00737 cfline("*.PANIC\t*", (*nextp)->f_next);
00738 Initialized = 1;
00739 }
00740 return;
00741 }
00742
00743
00744
00745
00746
00747 void daemonize(char *line)
00748 {
00749 int lfd, len, pid;
00750
00751 if ((lfd = open(PidFile, O_CREAT | O_RDWR, 0600)) > 0) {
00752 len = read(lfd, line, 10);
00753 line[len] = '\0';
00754 close(lfd);
00755 if ((kill(len = atoi(line), 0) < 0 && errno == ESRCH) || len == 0) {
00756 if (!DbgOpt) {
00757
00758 if ((pid = fork()) > 0) {
00759
00760 lfd = open(PidFile, O_TRUNC | O_WRONLY);
00761 len = sprintf(line, "%5d", pid);
00762 write(lfd, line, len);
00763 close(lfd);
00764
00765
00766 exit(EXIT_SUCCESS);
00767 }
00768 sleep(1);
00769 setsid();
00770 chdir("/");
00771
00772 for (lfd = STDERR_FILENO + 1; lfd < OPEN_MAX; lfd += 1)
00773 close(lfd);
00774 }
00775 } else {
00776 fprintf(stderr, "\n%s already running\n", ProgName);
00777 exit(EXIT_FAILURE);
00778 }
00779 } else {
00780 fprintf(stderr, "\n%s can't open %s (%s)\n", ProgName, PidFile, strerror(errno));
00781 exit(EXIT_FAILURE);
00782 }
00783 return;
00784 }
00785
00786
00787
00788
00789
00790 int main(int argc, char **argv)
00791 {
00792 char *p, *udpdev, *eol;
00793 int nfd, kfd, len, fdmax;
00794 int ch, port = 0;
00795 fd_set fdset;
00796 struct nwio_udpopt udpopt;
00797 struct servent *sp;
00798 char line[MAXLINE + 1];
00799
00800 while ((ch = getopt(argc, argv, "df:m:p:v?")) != EOF) {
00801 switch ((char) ch) {
00802 case 'd':
00803 DbgOpt += 1;
00804 break;
00805 case 'f':
00806 ConfFile = optarg;
00807 break;
00808 case 'm':
00809 MarkInterval = atoi(optarg) * 60;
00810 break;
00811 case 'p':
00812 port = atoi(optarg);
00813 break;
00814 case 'v':
00815 fprintf(stderr, "%s version %s\n", ProgName, version);
00816 return EXIT_FAILURE;
00817 case '?':
00818 default:
00819 fprintf(stderr, usage);
00820 return EXIT_FAILURE;
00821 }
00822 }
00823 if (argc -= optind) {
00824 fprintf(stderr, usage);
00825 return EXIT_FAILURE;
00826 }
00827
00828 daemonize(line);
00829
00830
00831 gethostname(LocalHostName, sizeof(LocalHostName) - 1);
00832 if ((p = strchr(LocalHostName, '.'))) *p = '\0';
00833
00834 udpdev = (p = getenv("UDP_DEVICE")) ? p : UDP_DEVICE;
00835 sp = getservbyname("syslog", "udp");
00836
00837 signal(SIGTERM, die);
00838 signal(SIGINT, DbgOpt ? die : SIG_IGN);
00839 signal(SIGQUIT, DbgOpt ? die : SIG_IGN);
00840 signal(SIGALRM, domark);
00841
00842 alarm(TIMERINTVL);
00843
00844
00845 nfd = open(udpdev, O_NONBLOCK | O_RDONLY);
00846
00847
00848 udpopt.nwuo_flags = NWUO_SHARED | NWUO_LP_SET | NWUO_EN_LOC |
00849 NWUO_DI_BROAD | NWUO_RP_SET | NWUO_RA_SET |
00850 NWUO_RWDATONLY | NWUO_DI_IPOPT;
00851 udpopt.nwuo_locport = udpopt.nwuo_remport =
00852 port == 0 ? sp->s_port : htons(port);
00853 udpopt.nwuo_remaddr = udpopt.nwuo_locaddr = htonl(0x7F000001L);
00854
00855 if(nfd >= 0) {
00856 while (ioctl(nfd, NWIOSUDPOPT, &udpopt) < 0 ||
00857 ioctl(nfd, NWIOGUDPOPT, &udpopt) < 0) {
00858 if (errno == EAGAIN) {
00859 sleep(1);
00860 continue;
00861 }
00862 logerror("Set/Get UDP options failed");
00863 return EXIT_FAILURE;
00864 }
00865 }
00866
00867
00868 kfd = open("/dev/klog", O_NONBLOCK | O_RDONLY);
00869
00870 if(kfd < 0 && nfd < 0) {
00871 logerror("open /dev/klog and udp device failed - can't log anything");
00872 return EXIT_FAILURE;
00873 }
00874
00875 fdmax = max(nfd, kfd) + 1;
00876
00877 DEBUG(dprintf("off & running....\n");)
00878
00879 init(-1);
00880
00881 for (;;) {
00882
00883 FD_ZERO(&fdset);
00884 if(nfd >= 0) FD_SET(nfd, &fdset);
00885 if(kfd >= 0) FD_SET(kfd, &fdset);
00886
00887 if (select(fdmax, &fdset, NULL, NULL, NULL) <= 0) {
00888 sleep(1);
00889 continue;
00890
00891 }
00892 if (nfd >= 0 && FD_ISSET(nfd, &fdset)) {
00893
00894
00895 len = read(nfd, line, MAXLINE);
00896 if (len > 0) {
00897 line[len] = '\0';
00898 dprintf("got a message (%d, %#x)\n", nfd, len);
00899 printline(LocalHostName, line);
00900
00901 } else if (len < 0) {
00902 if (errno != EINTR)
00903 {
00904 logerror("Receive error from UDP channel");
00905 close(nfd);
00906 nfd= -1;
00907 }
00908
00909 } else {
00910 logerror("UDP channel has closed");
00911 close(nfd);
00912 die(-1);
00913 }
00914 }
00915 if (kfd >= 0 && FD_ISSET(kfd, &fdset)) {
00916 static char linebuf[5*1024];
00917
00918
00919 len = read(kfd, linebuf, sizeof(linebuf)-2);
00920 dprintf("got a message (%d, %#x)\n", kfd, len);
00921 for (ch = 0; ch < len; ch += 1)
00922 if (linebuf[ch] == '\0') linebuf[ch] = ' ';
00923 if (linebuf[len - 1] == '\n') len -= 1;
00924 linebuf[len] = '\n';
00925 linebuf[len + 1] = '\0';
00926 p = linebuf;
00927 while(eol = strchr(p, '\n')) {
00928 *eol = '\0';
00929 printkline(LocalHostName, p);
00930 p = eol+1;
00931 }
00932 }
00933 }
00934
00935 }
00936