main.c revision 36345
16059Samurai/* 26059Samurai * User Process PPP 36059Samurai * 46059Samurai * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 56059Samurai * 66059Samurai * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd. 76059Samurai * 86059Samurai * Redistribution and use in source and binary forms are permitted 96059Samurai * provided that the above copyright notice and this paragraph are 106059Samurai * duplicated in all such forms and that any documentation, 116059Samurai * advertising materials, and other materials related to such 126059Samurai * distribution and use acknowledge that the software was developed 136059Samurai * by the Internet Initiative Japan, Inc. The name of the 146059Samurai * IIJ may not be used to endorse or promote products derived 156059Samurai * from this software without specific prior written permission. 166059Samurai * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 176059Samurai * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 186059Samurai * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 196059Samurai * 2036345Sbrian * $Id: main.c,v 1.124 1998/05/23 22:24:43 brian Exp $ 218857Srgrimes * 226059Samurai * TODO: 236059Samurai */ 2436285Sbrian 2530715Sbrian#include <sys/param.h> 2630715Sbrian#include <sys/socket.h> 2730715Sbrian#include <netinet/in.h> 2830715Sbrian#include <netinet/in_systm.h> 2930715Sbrian#include <netinet/ip.h> 3036285Sbrian#include <sys/un.h> 3136285Sbrian#include <net/if_tun.h> 3230715Sbrian 3330715Sbrian#include <errno.h> 346059Samurai#include <fcntl.h> 3511336Samurai#include <paths.h> 3630715Sbrian#include <signal.h> 3730715Sbrian#include <stdio.h> 3830715Sbrian#include <string.h> 396059Samurai#include <sys/time.h> 406059Samurai#include <termios.h> 4118786Sjkh#include <unistd.h> 4230715Sbrian 4330715Sbrian#include "mbuf.h" 4430715Sbrian#include "log.h" 4530715Sbrian#include "defs.h" 4631061Sbrian#include "id.h" 4730715Sbrian#include "timer.h" 4830715Sbrian#include "fsm.h" 4936285Sbrian#include "lqr.h" 506059Samurai#include "hdlc.h" 5131514Sbrian#include "lcp.h" 5213389Sphk#include "ccp.h" 5336285Sbrian#include "iplist.h" 5436285Sbrian#include "throughput.h" 5536285Sbrian#include "slcompress.h" 566059Samurai#include "ipcp.h" 5736285Sbrian#include "filter.h" 5836285Sbrian#include "descriptor.h" 5936285Sbrian#include "link.h" 6036285Sbrian#include "mp.h" 6136285Sbrian#include "bundle.h" 6226142Sbrian#include "loadalias.h" 636735Samurai#include "auth.h" 6413389Sphk#include "systems.h" 6513389Sphk#include "ip.h" 6623840Sbrian#include "sig.h" 6730715Sbrian#include "main.h" 6831195Sbrian#include "tun.h" 6936285Sbrian#include "server.h" 7036285Sbrian#include "prompt.h" 7136285Sbrian#include "chat.h" 7236285Sbrian#include "chap.h" 7336285Sbrian#include "datalink.h" 746059Samurai 756735Samurai#ifndef O_NONBLOCK 766735Samurai#ifdef O_NDELAY 776735Samurai#define O_NONBLOCK O_NDELAY 786735Samurai#endif 796735Samurai#endif 806735Samurai 8125634Sbrianstatic char pid_filename[MAXPATHLEN]; 826059Samurai 8336285Sbrianstatic void DoLoop(struct bundle *, struct prompt *); 8430715Sbrianstatic void TerminalStop(int); 8531343Sbrianstatic const char *ex_desc(int); 8630715Sbrian 8736285Sbrianstatic struct bundle *SignalBundle; 8836285Sbrianstatic struct prompt *SignalPrompt; 896059Samurai 9010528Samuraivoid 9136285SbrianCleanup(int excode) 926059Samurai{ 9336285Sbrian SignalBundle->CleaningUp = 1; 9436285Sbrian if (bundle_Phase(SignalBundle) != PHASE_DEAD) 9536285Sbrian bundle_Close(SignalBundle, NULL, 1); 966059Samurai} 976059Samurai 986059Samuraivoid 9936285SbrianAbortProgram(int excode) 1006059Samurai{ 10136285Sbrian server_Close(SignalBundle); 10231061Sbrian ID0unlink(pid_filename); 10336285Sbrian log_Printf(LogPHASE, "PPP Terminated (%s).\n", ex_desc(excode)); 10436285Sbrian bundle_Close(SignalBundle, NULL, 1); 10536285Sbrian bundle_Destroy(SignalBundle); 10636285Sbrian log_Close(); 1076059Samurai exit(excode); 1086059Samurai} 1096059Samurai 1106059Samuraistatic void 11128679SbrianCloseConnection(int signo) 1126059Samurai{ 11326858Sbrian /* NOTE, these are manual, we've done a setsid() */ 11436285Sbrian sig_signal(SIGINT, SIG_IGN); 11536285Sbrian log_Printf(LogPHASE, "Caught signal %d, abort connection(s)\n", signo); 11636285Sbrian bundle_Down(SignalBundle); 11736285Sbrian sig_signal(SIGINT, CloseConnection); 1186059Samurai} 1196059Samurai 1206059Samuraistatic void 12128679SbrianCloseSession(int signo) 1226059Samurai{ 12336285Sbrian log_Printf(LogPHASE, "Signal %d, terminate.\n", signo); 12428679Sbrian Cleanup(EX_TERM); 1256059Samurai} 1266059Samurai 12736285Sbrianstatic pid_t BGPid = 0; 12836285Sbrian 12910528Samuraistatic void 13036285SbrianKillChild(int signo) 13110528Samurai{ 13236285Sbrian log_Printf(LogPHASE, "Parent: Signal %d\n", signo); 13336285Sbrian kill(BGPid, SIGINT); 13410528Samurai} 13510528Samurai 13610528Samuraistatic void 13736285SbrianTerminalCont(int signo) 13810528Samurai{ 13936285Sbrian signal(SIGCONT, SIG_DFL); 14036285Sbrian prompt_Continue(SignalPrompt); 14110528Samurai} 14210528Samurai 14326940Sbrianstatic void 14436285SbrianTerminalStop(int signo) 14526940Sbrian{ 14636285Sbrian prompt_Suspend(SignalPrompt); 14736285Sbrian signal(SIGCONT, TerminalCont); 14836285Sbrian raise(SIGSTOP); 14926940Sbrian} 15026940Sbrian 15131081Sbrianstatic void 15231081SbrianBringDownServer(int signo) 15331081Sbrian{ 15436285Sbrian /* Drops all child prompts too ! */ 15536285Sbrian server_Close(SignalBundle); 15631081Sbrian} 15731081Sbrian 15831343Sbrianstatic const char * 15925908Sbrianex_desc(int ex) 16025908Sbrian{ 16125908Sbrian static char num[12]; 16231343Sbrian static const char *desc[] = { 16331343Sbrian "normal", "start", "sock", "modem", "dial", "dead", "done", 16431343Sbrian "reboot", "errdead", "hangup", "term", "nodial", "nologin" 16531343Sbrian }; 16610528Samurai 16731962Sbrian if (ex >= 0 && ex < sizeof desc / sizeof *desc) 16825908Sbrian return desc[ex]; 16925908Sbrian snprintf(num, sizeof num, "%d", ex); 17025908Sbrian return num; 17125908Sbrian} 17225908Sbrian 17330715Sbrianstatic void 17431343SbrianUsage(void) 1756059Samurai{ 17620120Snate fprintf(stderr, 17731343Sbrian "Usage: ppp [-auto | -background | -direct | -dedicated | -ddial ]" 17831343Sbrian#ifndef NOALIAS 17931343Sbrian " [ -alias ]" 18031343Sbrian#endif 18131343Sbrian " [system]\n"); 1826059Samurai exit(EX_START); 1836059Samurai} 1846059Samurai 18531197Sbrianstatic char * 18636285SbrianProcessArgs(int argc, char **argv, int *mode) 1876059Samurai{ 18836285Sbrian int optc, labelrequired; 1896059Samurai char *cp; 1906059Samurai 19136285Sbrian optc = labelrequired = 0; 19236285Sbrian *mode = PHYS_MANUAL; 1936059Samurai while (argc > 0 && **argv == '-') { 1946059Samurai cp = *argv + 1; 19531121Sbrian if (strcmp(cp, "auto") == 0) { 19636285Sbrian *mode = PHYS_DEMAND; 19736285Sbrian labelrequired = 1; 19831121Sbrian } else if (strcmp(cp, "background") == 0) { 19936285Sbrian *mode = PHYS_1OFF; 20036285Sbrian labelrequired = 1; 20136285Sbrian } else if (strcmp(cp, "direct") == 0) 20236285Sbrian *mode = PHYS_DIRECT; 20336285Sbrian else if (strcmp(cp, "dedicated") == 0) 20436285Sbrian *mode = PHYS_DEDICATED; 20536285Sbrian else if (strcmp(cp, "ddial") == 0) { 20636285Sbrian *mode = PHYS_PERM; 20736285Sbrian labelrequired = 1; 20836285Sbrian } else if (strcmp(cp, "alias") == 0) { 20931343Sbrian#ifndef NOALIAS 21036285Sbrian if (alias_Load() != 0) 21136285Sbrian#endif 21236285Sbrian log_Printf(LogWARN, "Cannot load alias library\n"); 21328679Sbrian optc--; /* this option isn't exclusive */ 21428679Sbrian } else 2156059Samurai Usage(); 2166059Samurai optc++; 21728679Sbrian argv++; 21828679Sbrian argc--; 2196059Samurai } 2206059Samurai if (argc > 1) { 22136285Sbrian fprintf(stderr, "You may specify only one system label.\n"); 2226059Samurai exit(EX_START); 2236059Samurai } 2246059Samurai 2256059Samurai if (optc > 1) { 22636285Sbrian fprintf(stderr, "You may specify only one mode.\n"); 2276059Samurai exit(EX_START); 2286059Samurai } 22931197Sbrian 23036285Sbrian if (labelrequired && argc != 1) { 23136285Sbrian fprintf(stderr, "Destination system must be specified in" 23236285Sbrian " auto, background or ddial mode.\n"); 23336285Sbrian exit(EX_START); 23436285Sbrian } 23536285Sbrian 23631197Sbrian return argc == 1 ? *argv : NULL; /* Don't SetLabel yet ! */ 2376059Samurai} 2386059Samurai 23926940Sbrianint 24028679Sbrianmain(int argc, char **argv) 2416059Samurai{ 24225707Sbrian FILE *lockfile; 24331197Sbrian char *name, *label; 24436285Sbrian int nfds, mode; 24536285Sbrian struct bundle *bundle; 24636285Sbrian struct prompt *prompt; 24726516Sbrian 24831823Sbrian nfds = getdtablesize(); 24931823Sbrian if (nfds >= FD_SETSIZE) 25031823Sbrian /* 25131823Sbrian * If we've got loads of file descriptors, make sure they're all 25231823Sbrian * closed. If they aren't, we may end up with a seg fault when our 25331823Sbrian * `fd_set's get too big when select()ing ! 25431823Sbrian */ 25531823Sbrian while (--nfds > 2) 25631823Sbrian close(nfds); 25731823Sbrian 25830715Sbrian name = strrchr(argv[0], '/'); 25936285Sbrian log_Open(name ? name + 1 : argv[0]); 26026516Sbrian 26128679Sbrian argc--; 26228679Sbrian argv++; 26336285Sbrian label = ProcessArgs(argc, argv, &mode); 26431121Sbrian 26536285Sbrian#ifdef __FreeBSD__ 26636285Sbrian /* 26736285Sbrian * A FreeBSD hack to dodge a bug in the tty driver that drops output 26836285Sbrian * occasionally.... I must find the real reason some time. To display 26936285Sbrian * the dodgy behaviour, comment out this bit, make yourself a large 27036285Sbrian * routing table and then run ppp in interactive mode. The `show route' 27136285Sbrian * command will drop chunks of data !!! 27236285Sbrian */ 27336285Sbrian if (mode == PHYS_MANUAL) { 27436285Sbrian close(STDIN_FILENO); 27536285Sbrian if (open(_PATH_TTY, O_RDONLY) != STDIN_FILENO) { 27636285Sbrian fprintf(stderr, "Cannot open %s for input !\n", _PATH_TTY); 27736285Sbrian return 2; 27836285Sbrian } 27936285Sbrian } 28036285Sbrian#endif 28136285Sbrian 28236285Sbrian /* Allow output for the moment (except in direct mode) */ 28336285Sbrian if (mode == PHYS_DIRECT) 28436285Sbrian prompt = NULL; 28536285Sbrian else { 28636285Sbrian const char *m; 28736285Sbrian 28836285Sbrian SignalPrompt = prompt = prompt_Create(NULL, NULL, PROMPT_STD); 28936285Sbrian if (mode == PHYS_PERM) 29036285Sbrian m = "direct dial"; 29136285Sbrian else if (mode & PHYS_1OFF) 29236285Sbrian m = "background"; 29336285Sbrian else if (mode & PHYS_DEMAND) 29436285Sbrian m = "auto"; 29536285Sbrian else if (mode & PHYS_DEDICATED) 29636285Sbrian m = "dedicated"; 29736285Sbrian else if (mode & PHYS_MANUAL) 29836285Sbrian m = "interactive"; 29936285Sbrian else 30036285Sbrian m = NULL; 30136285Sbrian 30236285Sbrian if (m) 30336285Sbrian prompt_Printf(prompt, "Working in %s mode\n", m); 30436285Sbrian } 30536285Sbrian 30631121Sbrian ID0init(); 30731158Sbrian if (ID0realuid() != 0) { 30831158Sbrian char conf[200], *ptr; 30931158Sbrian 31031158Sbrian snprintf(conf, sizeof conf, "%s/%s", _PATH_PPP, CONFFILE); 31131158Sbrian do { 31231158Sbrian if (!access(conf, W_OK)) { 31336285Sbrian log_Printf(LogALERT, "ppp: Access violation: Please protect %s\n", conf); 31431158Sbrian return -1; 31531158Sbrian } 31631158Sbrian ptr = conf + strlen(conf)-2; 31731158Sbrian while (ptr > conf && *ptr != '/') 31831158Sbrian *ptr-- = '\0'; 31931158Sbrian } while (ptr >= conf); 32031158Sbrian } 32131158Sbrian 32236285Sbrian if (!system_IsValid(label, prompt, mode)) { 32331121Sbrian fprintf(stderr, "You may not use ppp in this mode with this label\n"); 32436285Sbrian if (mode == PHYS_DIRECT) { 32531157Sbrian const char *l; 32631197Sbrian l = label ? label : "default"; 32736285Sbrian log_Printf(LogWARN, "Label %s rejected -direct connection\n", l); 32831157Sbrian } 32936285Sbrian log_Close(); 33031121Sbrian return 1; 33129083Sbrian } 33231121Sbrian 33336314Sbrian if ((bundle = bundle_Create(TUN_PREFIX, mode)) == NULL) { 33436285Sbrian log_Printf(LogWARN, "bundle_Create: %s\n", strerror(errno)); 33526940Sbrian return EX_START; 3366059Samurai } 33736314Sbrian if (prompt) { 33836314Sbrian prompt->bundle = bundle; /* couldn't do it earlier */ 33936314Sbrian prompt_Printf(prompt, "Using interface: %s\n", bundle->ifp.Name); 34036314Sbrian } 34136285Sbrian SignalBundle = bundle; 34231121Sbrian 34336285Sbrian if (system_Select(bundle, "default", CONFFILE, prompt) < 0) 34436285Sbrian prompt_Printf(prompt, "Warning: No default entry found in config file.\n"); 34536285Sbrian 34636285Sbrian sig_signal(SIGHUP, CloseSession); 34736285Sbrian sig_signal(SIGTERM, CloseSession); 34836285Sbrian sig_signal(SIGINT, CloseConnection); 34936285Sbrian sig_signal(SIGQUIT, CloseSession); 35036285Sbrian sig_signal(SIGALRM, SIG_IGN); 35124753Sache signal(SIGPIPE, SIG_IGN); 3526059Samurai 35336285Sbrian if (mode == PHYS_MANUAL) 35436285Sbrian sig_signal(SIGTSTP, TerminalStop); 35536285Sbrian 35636285Sbrian sig_signal(SIGUSR2, BringDownServer); 35736285Sbrian 35831197Sbrian if (label) { 35931197Sbrian /* 36036285Sbrian * Set label both before and after system_Select ! 36136285Sbrian * This way, "set enddisc label" works during system_Select, and we 36236285Sbrian * also end up with the correct label if we have embedded load 36336285Sbrian * commands. 36431197Sbrian */ 36536285Sbrian bundle_SetLabel(bundle, label); 36636285Sbrian if (system_Select(bundle, label, CONFFILE, prompt) < 0) { 36736285Sbrian prompt_Printf(prompt, "Destination system (%s) not found.\n", label); 36836285Sbrian AbortProgram(EX_START); 3696059Samurai } 37036285Sbrian bundle_SetLabel(bundle, label); 37136285Sbrian if (mode == PHYS_DEMAND && 37236285Sbrian bundle->ncp.ipcp.cfg.peer_range.ipaddr.s_addr == INADDR_ANY) { 37336285Sbrian prompt_Printf(prompt, "You must \"set ifaddr\" with a peer address " 37436285Sbrian "in label %s for auto mode.\n", label); 37536285Sbrian AbortProgram(EX_START); 37636285Sbrian } 3776059Samurai } 37826940Sbrian 37936285Sbrian if (mode != PHYS_MANUAL) { 38036285Sbrian if (mode != PHYS_DIRECT) { 38136285Sbrian int bgpipe[2]; 38236285Sbrian pid_t bgpid; 38336285Sbrian 38436285Sbrian if (mode == PHYS_1OFF && pipe(bgpipe)) { 38536285Sbrian log_Printf(LogERROR, "pipe: %s\n", strerror(errno)); 38636285Sbrian AbortProgram(EX_SOCK); 38720813Sjkh } 3886059Samurai 38928679Sbrian bgpid = fork(); 39020813Sjkh if (bgpid == -1) { 39136285Sbrian log_Printf(LogERROR, "fork: %s\n", strerror(errno)); 39236285Sbrian AbortProgram(EX_SOCK); 39320813Sjkh } 39436285Sbrian 39520813Sjkh if (bgpid) { 39620813Sjkh char c = EX_NORMAL; 39711336Samurai 39836285Sbrian if (mode == PHYS_1OFF) { 39936285Sbrian close(bgpipe[1]); 40020813Sjkh BGPid = bgpid; 40136285Sbrian /* If we get a signal, kill the child */ 40236285Sbrian signal(SIGHUP, KillChild); 40336285Sbrian signal(SIGTERM, KillChild); 40436285Sbrian signal(SIGINT, KillChild); 40536285Sbrian signal(SIGQUIT, KillChild); 40636285Sbrian 40736285Sbrian /* Wait for our child to close its pipe before we exit */ 40836285Sbrian if (read(bgpipe[0], &c, 1) != 1) { 40936285Sbrian prompt_Printf(prompt, "Child exit, no status.\n"); 41036285Sbrian log_Printf(LogPHASE, "Parent: Child exit, no status.\n"); 41125908Sbrian } else if (c == EX_NORMAL) { 41236285Sbrian prompt_Printf(prompt, "PPP enabled.\n"); 41336285Sbrian log_Printf(LogPHASE, "Parent: PPP enabled.\n"); 41425908Sbrian } else { 41536285Sbrian prompt_Printf(prompt, "Child failed (%s).\n", ex_desc((int) c)); 41636285Sbrian log_Printf(LogPHASE, "Parent: Child failed (%s).\n", 41728679Sbrian ex_desc((int) c)); 41828679Sbrian } 41936285Sbrian close(bgpipe[0]); 42020813Sjkh } 42128679Sbrian return c; 42236285Sbrian } else if (mode == PHYS_1OFF) { 42336285Sbrian close(bgpipe[0]); 42436285Sbrian bundle->notify.fd = bgpipe[1]; 42536285Sbrian } 42620813Sjkh 42736285Sbrian /* -auto, -dedicated, -ddial & -background */ 42836285Sbrian prompt_Destroy(prompt, 0); 42936285Sbrian close(STDOUT_FILENO); 43036285Sbrian close(STDERR_FILENO); 43136285Sbrian close(STDIN_FILENO); 43226686Sbrian setsid(); 43336285Sbrian } else { 43436285Sbrian /* -direct: STDIN_FILENO gets used by modem_Open */ 43536285Sbrian prompt_TtyInit(NULL); 43636285Sbrian close(STDOUT_FILENO); 43736285Sbrian close(STDERR_FILENO); 43826686Sbrian } 4396059Samurai } else { 44036285Sbrian /* Interactive mode */ 44132129Sbrian close(STDERR_FILENO); 44236285Sbrian prompt_TtyInit(prompt); 44336285Sbrian prompt_TtyCommandMode(prompt); 44436285Sbrian prompt_Required(prompt); 4456059Samurai } 44629696Sbrian 44731962Sbrian snprintf(pid_filename, sizeof pid_filename, "%stun%d.pid", 44836285Sbrian _PATH_VARRUN, bundle->unit); 44931061Sbrian lockfile = ID0fopen(pid_filename, "w"); 45031061Sbrian if (lockfile != NULL) { 45129696Sbrian fprintf(lockfile, "%d\n", (int) getpid()); 45229696Sbrian fclose(lockfile); 45332860Sbrian } 45432860Sbrian#ifndef RELEASE_CRUNCH 45532860Sbrian else 45636285Sbrian log_Printf(LogALERT, "Warning: Can't create %s: %s\n", 45729696Sbrian pid_filename, strerror(errno)); 45832860Sbrian#endif 45929696Sbrian 46036285Sbrian log_Printf(LogPHASE, "PPP Started (%s mode).\n", mode2Nam(mode)); 46136285Sbrian DoLoop(bundle, prompt); 46236285Sbrian AbortProgram(EX_NORMAL); 4636059Samurai 46436285Sbrian return EX_NORMAL; 4656059Samurai} 4666059Samurai 4676059Samuraistatic void 46836285SbrianDoLoop(struct bundle *bundle, struct prompt *prompt) 4696059Samurai{ 4706059Samurai fd_set rfds, wfds, efds; 47136285Sbrian int i, nfds; 4726059Samurai 47336285Sbrian do { 47423598Sache nfds = 0; 47528679Sbrian FD_ZERO(&rfds); 47628679Sbrian FD_ZERO(&wfds); 47728679Sbrian FD_ZERO(&efds); 4787001Samurai 47936314Sbrian /* All our datalinks, the tun device and the MP socket */ 48036285Sbrian descriptor_UpdateSet(&bundle->desc, &rfds, &wfds, &efds, &nfds); 48125067Sbrian 48236314Sbrian /* All our prompts and the diagnostic socket */ 48336314Sbrian descriptor_UpdateSet(&server.desc, &rfds, NULL, NULL, &nfds); 48436314Sbrian 48536285Sbrian if (bundle_IsDead(bundle)) 48636285Sbrian /* Don't select - we'll be here forever */ 48736285Sbrian break; 48826551Sbrian 48936285Sbrian i = select(nfds, &rfds, &wfds, &efds, NULL); 49026696Sbrian 49136345Sbrian if (i < 0 && errno != EINTR) { 49236285Sbrian log_Printf(LogERROR, "DoLoop: select(): %s\n", strerror(errno)); 49336285Sbrian if (log_IsKept(LogTIMER)) { 49436285Sbrian struct timeval t; 49536285Sbrian 49636285Sbrian for (i = 0; i <= nfds; i++) { 49736285Sbrian if (FD_ISSET(i, &rfds)) { 49836285Sbrian log_Printf(LogTIMER, "Read set contains %d\n", i); 49936285Sbrian FD_CLR(i, &rfds); 50036285Sbrian t.tv_sec = t.tv_usec = 0; 50136285Sbrian if (select(nfds, &rfds, &wfds, &efds, &t) != -1) { 50236285Sbrian log_Printf(LogTIMER, "The culprit !\n"); 50336285Sbrian break; 50436285Sbrian } 50536285Sbrian } 50636285Sbrian if (FD_ISSET(i, &wfds)) { 50736285Sbrian log_Printf(LogTIMER, "Write set contains %d\n", i); 50836285Sbrian FD_CLR(i, &wfds); 50936285Sbrian t.tv_sec = t.tv_usec = 0; 51036285Sbrian if (select(nfds, &rfds, &wfds, &efds, &t) != -1) { 51136285Sbrian log_Printf(LogTIMER, "The culprit !\n"); 51236285Sbrian break; 51336285Sbrian } 51436285Sbrian } 51536285Sbrian if (FD_ISSET(i, &efds)) { 51636285Sbrian log_Printf(LogTIMER, "Error set contains %d\n", i); 51736285Sbrian FD_CLR(i, &efds); 51836285Sbrian t.tv_sec = t.tv_usec = 0; 51936285Sbrian if (select(nfds, &rfds, &wfds, &efds, &t) != -1) { 52036285Sbrian log_Printf(LogTIMER, "The culprit !\n"); 52136285Sbrian break; 52236285Sbrian } 52336285Sbrian } 52436285Sbrian } 52528679Sbrian } 52628679Sbrian break; 5278857Srgrimes } 5286059Samurai 52936345Sbrian sig_Handle(); 53036345Sbrian 53136345Sbrian if (i <= 0) 53236345Sbrian continue; 53336345Sbrian 53436285Sbrian for (i = 0; i <= nfds; i++) 53536285Sbrian if (FD_ISSET(i, &efds)) { 53636285Sbrian log_Printf(LogALERT, "Exception detected on descriptor %d\n", i); 53736285Sbrian break; 5386059Samurai } 53928679Sbrian 54036285Sbrian if (i <= nfds) 54136285Sbrian break; 54228536Sbrian 54336285Sbrian if (descriptor_IsSet(&server.desc, &rfds)) 54436285Sbrian descriptor_Read(&server.desc, bundle, &rfds); 54532039Sbrian 54636285Sbrian if (descriptor_IsSet(&bundle->desc, &wfds)) 54736285Sbrian descriptor_Write(&bundle->desc, bundle, &wfds); 54836285Sbrian 54936285Sbrian if (descriptor_IsSet(&bundle->desc, &rfds)) 55036285Sbrian descriptor_Read(&bundle->desc, bundle, &rfds); 55136345Sbrian 55236285Sbrian } while (bundle_CleanDatalinks(bundle), !bundle_IsDead(bundle)); 55336285Sbrian 55436285Sbrian log_Printf(LogDEBUG, "DoLoop done.\n"); 5556059Samurai} 556