void sigtrace(int s) { if (s == SIGUSR2) traceoff(); else if (ftrace == NULL && savetracename) traceon(savetracename); else bumploglevel(); }
int ripd(int argc, char *argv[]) { int n, nfd, tflags = 0, ch; struct timeval *tvp, waittime; struct itimerval itval; struct rip *query = msg; fd_set ibits; sigset_t sigset, osigset; while ((ch = getopt(argc, argv, "sqtdg")) != EOF) { switch (ch) { case 's': supplier = 1; break; case 'q': supplier = 0; break; case 't': tflags++; break; case 'd': debug++; setlogmask(LOG_UPTO(LOG_DEBUG)); break; case 'g': gateway = 1; break; default: fprintf(stderr, "%% Incomplete command\r\n"); return(1); } } getkversion(); sock = getsocket(); assert(sock>=0); openlog("ripd", LOG_PID | LOG_ODELAY, LOG_DAEMON); if (debug == 0 && tflags == 0) { switch (fork()) { case -1: perror("fork"); exit(1); case 0: break; /* child */ default: exit(0); /* parent */ } close(0); close(1); close(2); setsid(); setlogmask(LOG_UPTO(LOG_WARNING)); } else { setlogmask(LOG_UPTO(LOG_DEBUG)); } /* pid */ pidfile = fopen( "/var/run/ripd.pid", "w" ) ; if (pidfile==NULL) { fprintf(stderr,"%% Error write pid\n"); return (-1); } else fprintf(pidfile,"%d", (int) getpid()); fclose(pidfile); /* * Any extra argument is considered * a tracing log file. * * Note: because traceon() redirects stderr, anything planning to * crash on startup should do so before this point. */ if (argc > optind) { traceon(argv[optind]); } while (tflags-- > 0) { bumploglevel(); } gettimeofday(&now, NULL); /* * Collect an initial view of the world by * checking the interface configuration and the gateway kludge * file. Then, send a request packet on all * directly connected networks to find out what * everyone else thinks. */ rtinit(); ifinit(); gwkludge(); if (gateway > 0) { rtdefault(); } if (supplier < 0) { supplier = 0; } query->rip_cmd = RIPCMD_REQUEST; query->rip_vers = RIPVERSION; if (sizeof(query->rip_nets[0].rip_dst.sa_family) > 1) { /* XXX */ query->rip_nets[0].rip_dst.sa_family = htons((u_short)AF_UNSPEC); } else { /* unreachable code (at least on most platforms) */ query->rip_nets[0].rip_dst.sa_family = AF_UNSPEC; } query->rip_nets[0].rip_metric = htonl((u_long)HOPCNT_INFINITY); toall(sndmsg, 0, NULL); signal(SIGALRM, timer); signal(SIGHUP, hup); signal(SIGTERM, hup); signal(SIGINT, rtdeleteall); signal(SIGUSR1, sigtrace); signal(SIGUSR2, sigtrace); itval.it_interval.tv_sec = TIMER_RATE; itval.it_value.tv_sec = TIMER_RATE; itval.it_interval.tv_usec = 0; itval.it_value.tv_usec = 0; srandom(time(NULL) ^ getpid()); if (setitimer(ITIMER_REAL, &itval, (struct itimerval *)NULL) < 0) { syslog(LOG_ERR, "setitimer: %m\n"); } FD_ZERO(&ibits); nfd = sock + 1; /* 1 + max(fd's) */ for (;;) { FD_SET(sock, &ibits); /* * If we need a dynamic update that was held off, * needupdate will be set, and nextbcast is the time * by which we want select to return. Compute time * until dynamic update should be sent, and select only * until then. If we have already passed nextbcast, * just poll. */ if (needupdate) { waittime = nextbcast; timevalsub(&waittime, &now); if (waittime.tv_sec < 0) { waittime.tv_sec = 0; waittime.tv_usec = 0; } if (traceactions) fprintf(ftrace, "select until dynamic update %ld/%ld sec/usec\n", (long)waittime.tv_sec, (long)waittime.tv_usec); tvp = &waittime; } else { tvp = (struct timeval *)NULL; } n = select(nfd, &ibits, 0, 0, tvp); if (n <= 0) { /* * Need delayed dynamic update if select returned * nothing and we timed out. Otherwise, ignore * errors (e.g. EINTR). */ if (n < 0) { if (errno == EINTR) continue; syslog(LOG_ERR, "select: %m"); } sigemptyset(&sigset); sigaddset(&sigset, SIGALRM); sigprocmask(SIG_BLOCK, &sigset, &osigset); if (n == 0 && needupdate) { if (traceactions) fprintf(ftrace, "send delayed dynamic update\n"); (void) gettimeofday(&now, (struct timezone *)NULL); toall(supply, RTS_CHANGED, (struct interface *)NULL); lastbcast = now; needupdate = 0; nextbcast.tv_sec = 0; } sigprocmask(SIG_SETMASK, &osigset, NULL); continue; } gettimeofday(&now, (struct timezone *)NULL); sigemptyset(&sigset); sigaddset(&sigset, SIGALRM); sigprocmask(SIG_BLOCK, &sigset, &osigset); if (FD_ISSET(sock, &ibits)) { process(sock); } /* handle ICMP redirects */ sigprocmask(SIG_SETMASK, &osigset, NULL); } }
int main(int argc, char *argv[]) { int _argc = 0; char *_argv[5]; pid_t pid; int execed = 0; int n, nfd, tflags = 0, ch; struct timeval *tvp, waittime; struct itimerval itval; fd_set ibits; sigset_t sigset, osigset; while ((ch = getopt(argc, argv, "D012bsqtdg")) != EOF) { switch (ch) { case 'D': execed = 1; break; case '0': ripversion = 0; break; case '1': ripversion = 1; break; case '2': ripversion = 2; break; case 'b': multicast = 0; break; case 's': supplier = 1; break; case 'q': supplier = 0; break; case 't': tflags++; break; case 'd': debug++; setlogmask(LOG_UPTO(LOG_DEBUG)); break; case 'g': gateway = 1; break; default: fprintf(stderr, "usage: routed [ -1bsqtdg ]\n"); exit(1); } } // Modified by Mason Yu sleep(2); /* if(!check_pid()) { // Commented by Mason Yu //write_cfg(); exit(1); } */ if (!execed) { if ((pid = vfork()) < 0) { fprintf(stderr, "vfork failed\n"); exit(1); } else if (pid != 0) { exit(0); } for (_argc=0; _argc < argc; _argc++ ) _argv[_argc] = argv[_argc]; _argv[0] = runPath; _argv[argc++] = "-D"; _argv[argc++] = NULL; execv(_argv[0], _argv); /* Not reached */ fprintf(stderr, "Couldn't exec\n"); _exit(1); } else { setsid(); } getkversion(); sock = getsocket(); assert(sock>=0); openlog("routed", LOG_PID | LOG_ODELAY, LOG_DAEMON); #if 0 if (debug == 0 && tflags == 0) { #ifndef EMBED switch (fork()) { case -1: perror("fork"); exit(1); case 0: break; /* child */ default: exit(0); /* parent */ } #endif close(0); close(1); close(2); setsid(); setlogmask(LOG_UPTO(LOG_WARNING)); } else #endif { setlogmask(LOG_UPTO(LOG_DEBUG)); } /* * Any extra argument is considered * a tracing log file. * * Note: because traceon() redirects stderr, anything planning to * crash on startup should do so before this point. */ if (argc > 1) { traceon(argv[argc - 1]); } while (tflags-- > 0) { bumploglevel(); } gettimeofday(&now, NULL); /* * Collect an initial view of the world by * checking the interface configuration and the gateway kludge * file. Then, send a request packet on all * directly connected networks to find out what * everyone else thinks. */ read_cfg(); rtinit(); ifinit(); gwkludge(); if (gateway > 0) { rtdefault(); } if (supplier < 0) { supplier = 0; } signal(SIGALRM, timer); signal(SIGHUP, hup); signal(SIGTERM, hup); signal(SIGTERM, terminate_routed); //RTK WiSOC modify for deleting all route entry signal(SIGINT, rtdeleteall); signal(SIGUSR1, sigtrace); signal(SIGUSR2, sigtrace); itval.it_interval.tv_sec = TIMER_RATE; itval.it_value.tv_sec = TIMER_RATE; itval.it_interval.tv_usec = 0; itval.it_value.tv_usec = 0; srandom(time(NULL) ^ getpid()); if (setitimer(ITIMER_REAL, &itval, (struct itimerval *)NULL) < 0) { syslog(LOG_ERR, "setitimer: %m\n"); } // Kaohj //#ifdef EMBED //WiSOC we use pid file for system init write_pid(); //#endif rip_request_send(); rip_input_init(); DISPLAY_BANNER; FD_ZERO(&ibits); nfd = sock + 1; /* 1 + max(fd's) */ for (;;) { FD_SET(sock, &ibits); /* * If we need a dynamic update that was held off, * needupdate will be set, and nextbcast is the time * by which we want select to return. Compute time * until dynamic update should be sent, and select only * until then. If we have already passed nextbcast, * just poll. */ if (needupdate) { waittime = nextbcast; timevalsub(&waittime, &now); if (waittime.tv_sec < 0) { waittime.tv_sec = 0; waittime.tv_usec = 0; } if (traceactions) fprintf(ftrace, "select until dynamic update %ld/%ld sec/usec\n", (long)waittime.tv_sec, (long)waittime.tv_usec); tvp = &waittime; } else { tvp = (struct timeval *)NULL; } n = select(nfd, &ibits, 0, 0, tvp); if (n <= 0) { /* * Need delayed dynamic update if select returned * nothing and we timed out. Otherwise, ignore * errors (e.g. EINTR). */ if (n < 0) { if (errno == EINTR) continue; syslog(LOG_ERR, "select: %m"); } sigemptyset(&sigset); sigaddset(&sigset, SIGALRM); sigprocmask(SIG_BLOCK, &sigset, &osigset); if (n == 0 && needupdate) { if (traceactions) fprintf(ftrace, "send delayed dynamic update\n"); (void) gettimeofday(&now, (struct timezone *)NULL); toall(supply, RTS_CHANGED, (struct interface *)NULL); lastbcast = now; needupdate = 0; nextbcast.tv_sec = 0; } sigprocmask(SIG_SETMASK, &osigset, NULL); continue; } gettimeofday(&now, (struct timezone *)NULL); sigemptyset(&sigset); sigaddset(&sigset, SIGALRM); sigprocmask(SIG_BLOCK, &sigset, &osigset); if (FD_ISSET(sock, &ibits)) { process(sock); } /* handle ICMP redirects */ sigprocmask(SIG_SETMASK, &osigset, NULL); } }