📄 main.c.zhh
字号:
static voidhup(sig) int sig;{ info("Hangup (SIGHUP)"); got_sighup = 1; if (conn_running) /* Send the signal to the [dis]connector process(es) also */ kill_my_pg(sig); notify(sigreceived, sig); if (waiting) siglongjmp(sigjmp, 1);}/* * term - Catch SIGTERM signal and SIGINT signal (^C/del). * * Indicates that we should initiate a graceful disconnect and exit. *//*ARGSUSED*/static voidterm(sig) int sig;{ info("Terminating on signal %d.", sig); got_sigterm = 1; if (conn_running) /* Send the signal to the [dis]connector process(es) also */ kill_my_pg(sig); notify(sigreceived, sig); if (waiting) siglongjmp(sigjmp, 1);}/* * chld - Catch SIGCHLD signal. * Sets a flag so we will call reap_kids in the mainline. */static voidchld(sig) int sig;{ got_sigchld = 1; if (waiting) siglongjmp(sigjmp, 1);}/* * toggle_debug - Catch SIGUSR1 signal. * * Toggle debug flag. *//*ARGSUSED*/static voidtoggle_debug(sig) int sig;{ debug = !debug; if (debug) { setlogmask(LOG_UPTO(LOG_DEBUG)); } else { setlogmask(LOG_UPTO(LOG_WARNING)); }}/* * open_ccp - Catch SIGUSR2 signal. * * Try to (re)negotiate compression. *//*ARGSUSED*/static voidopen_ccp(sig) int sig;{ got_sigusr2 = 1; if (waiting) siglongjmp(sigjmp, 1);}/* * bad_signal - We've caught a fatal signal. Clean up state and exit. */static voidbad_signal(sig) int sig;{ static int crashed = 0; if (crashed) _exit(127); crashed = 1; error("Fatal signal %d", sig); if (conn_running) kill_my_pg(SIGTERM); notify(sigreceived, sig); die(127);}/* * device_script - run a program to talk to the specified fds * (e.g. to run the connector or disconnector script). * stderr gets connected to the log fd or to the _PATH_CONNERRS file. *///if (device_script(connector, ttyfd, ttyfd, 0) < 0) {//connector==/usr/sbin/chat -v -f /etc/ppp/chat.ttyS1intdevice_script(program, in, out, dont_wait) char *program; int in, out; int dont_wait;{ int pid, fd; int status = -1; int errfd; ++conn_running; pid = vfork(); if (pid < 0) { --conn_running; error("Failed to create child process: %m"); return -1; } if (pid != 0) { if (dont_wait) { record_child(pid, program, NULL, NULL); status = 0; } else { while (waitpid(pid, &status, 0) < 0) { if (errno == EINTR) continue; fatal("error waiting for (dis)connection process: %m"); } --conn_running; syslog(LOG_ERR,"it here %d",status); }// error("HH:waitpid failed!:%m"); return (status == 0 ? 0 : -1); } error("child begin here!"); /* here we are executing in the child */ /* make sure fds 0, 1, 2 are occupied */ while ((fd = dup(in)) >= 0) { if (fd > 2) { close(fd); break; } } error("child begin here 1!"); /* dup in and out to fds > 2 */ in = dup(in); out = dup(out); if (log_to_fd >= 0) { errfd = dup(log_to_fd); } else { errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0600); } error("child begin here 2!"); /* close fds 0 - 2 and any others we can think of */ close(0); close(1); close(2); sys_close(); if (the_channel->close) (*the_channel->close)(); closelog(); error("child begin here new 3!"); /* dup the in, out, err fds to 0, 1, 2 */ // dup2(in, 0); error("child begin here new 3.5!");// close(in); // dup2(out, 1); // close(out); if (errfd >= 0) { dup2(errfd, 2); close(errfd); } error("child begin here 4!"); setuid(uid); if (getuid() != uid) { error("setuid failed"); exit(1); } setgid(getgid()); error("child begin here 5!"); execl("/bin/sh", "sh", "-c", program, (char *)0); error("could not exec /bin/sh: %m"); closelog(); exit(99); /* NOTREACHED */}/* * run-program - execute a program with given arguments, * but don't wait for it. * If the program can't be executed, logs an error unless * must_exist is 0 and the program file doesn't exist. * Returns -1 if it couldn't fork, 0 if the file doesn't exist * or isn't an executable plain file, or the process ID of the child. * If done != NULL, (*done)(arg) will be called later (within * reap_kids) iff the return value is > 0. */pid_trun_program(prog, args, must_exist, done, arg) char *prog; char **args; int must_exist; void (*done) __P((void *)); void *arg;{ int pid; struct stat sbuf; /* * First check if the file exists and is executable. * We don't use access() because that would use the * real user-id, which might not be root, and the script * might be accessible only to root. */ errno = EINVAL; if (stat(prog, &sbuf) < 0 || !S_ISREG(sbuf.st_mode) || (sbuf.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) == 0) { if (must_exist || errno != ENOENT) warn("Can't execute %s: %m", prog); return 0; } pid = fork(); if (pid == -1) { error("Failed to create child process for %s: %m", prog); return -1; } if (pid == 0) { int new_fd; /* Leave the current location */ (void) setsid(); /* No controlling tty. */ (void) umask (S_IRWXG|S_IRWXO); (void) chdir ("/"); /* no current directory. */ setuid(0); /* set real UID = root */ setgid(getegid()); /* Ensure that nothing of our device environment is inherited. */ sys_close(); closelog(); close (0); close (1); close (2); if (the_channel->close) (*the_channel->close)(); /* Don't pass handles to the PPP device, even by accident. */ new_fd = open (_PATH_DEVNULL, O_RDWR); if (new_fd >= 0) { if (new_fd != 0) { dup2 (new_fd, 0); /* stdin <- /dev/null */ close (new_fd); } dup2 (0, 1); /* stdout -> /dev/null */ dup2 (0, 2); /* stderr -> /dev/null */ }#ifdef BSD /* Force the priority back to zero if pppd is running higher. */ if (setpriority (PRIO_PROCESS, 0, 0) < 0) warn("can't reset priority to 0: %m"); #endif /* SysV recommends a second fork at this point. */ /* run the program */ execve(prog, args, script_env); if (must_exist || errno != ENOENT) { /* have to reopen the log, there's nowhere else for the message to go. */ reopen_log(); syslog(LOG_ERR, "Can't execute %s: %m", prog); closelog(); } _exit(-1); } if (debug) dbglog("Script %s started (pid %d)", prog, pid); record_child(pid, prog, done, arg); return pid;}/* * record_child - add a child process to the list for reap_kids * to use. */voidrecord_child(pid, prog, done, arg) int pid; char *prog; void (*done) __P((void *)); void *arg;{ struct subprocess *chp; ++n_children; chp = (struct subprocess *) malloc(sizeof(struct subprocess)); if (chp == NULL) { warn("losing track of %s process", prog); } else { chp->pid = pid; chp->prog = prog; chp->done = done; chp->arg = arg; chp->next = children; children = chp; }}/* * reap_kids - get status from any dead child processes, * and log a message for abnormal terminations. */static intreap_kids(waitfor) int waitfor;{ int pid, status; struct subprocess *chp, **prevp; if (n_children == 0) return 0; while ((pid = waitpid(-1, &status, (waitfor? 0: WNOHANG))) != -1 && pid != 0) { for (prevp = &children; (chp = *prevp) != NULL; prevp = &chp->next) { if (chp->pid == pid) { --n_children; *prevp = chp->next; break; } } if (WIFSIGNALED(status)) { warn("Child process %s (pid %d) terminated with signal %d", (chp? chp->prog: "??"), pid, WTERMSIG(status)); } else if (debug) dbglog("Script %s finished (pid %d), status = 0x%x", (chp? chp->prog: "??"), pid, status); if (chp && chp->done) (*chp->done)(chp->arg); if (chp) free(chp); } if (pid == -1) { if (errno == ECHILD) return -1; if (errno != EINTR) error("Error waiting for child process: %m"); } return 0;}/* * add_notifier - add a new function to be called when something happens. */voidadd_notifier(notif, func, arg) struct notifier **notif; notify_func func; void *arg;{ struct notifier *np; np = malloc(sizeof(struct notifier)); if (np == 0) novm("notifier struct"); np->next = *notif; np->func = func; np->arg = arg; *notif = np;}/* * remove_notifier - remove a function from the list of things to * be called when something happens. */voidremove_notifier(notif, func, arg) struct notifier **notif; notify_func func; void *arg;{ struct notifier *np; for (; (np = *notif) != 0; notif = &np->next) { if (np->func == func && np->arg == arg) { *notif = np->next; free(np); break; } }}/* * notify - call a set of functions registered with add_notify. */voidnotify(notif, val) struct notifier *notif; int val;{ struct notifier *np; while ((np = notif) != 0) { notif = np->next; (*np->func)(np->arg, val); }}/* * novm - log an error message saying we ran out of memory, and die. */voidnovm(msg) char *msg;{ fatal("Virtual memory exhausted allocating %s\n", msg);}/* * script_setenv - set an environment variable value to be used * for scripts that we run (e.g. ip-up, auth-up, etc.) */voidscript_setenv(var, value, iskey) char *var, *value; int iskey;{ size_t varl = strlen(var); size_t vl = varl + strlen(value) + 2; int i; char *p, *newstring; newstring = (char *) malloc(vl+1); if (newstring == 0) return; *newstring++ = iskey; slprintf(newstring, vl, "%s=%s", var, value); /* check if this variable is already set */ if (script_env != 0) { for (i = 0; (p = script_env[i]) != 0; ++i) { if (strncmp(p, var, varl) == 0 && p[varl] == '=') { if (p[-1] && pppdb != NULL) delete_db_key(p); free(p-1); script_env[i] = newstring; if (iskey && pppdb != NULL) add_db_key(newstring); update_db_entry(); return; } } } else { /* no space allocated for script env. ptrs. yet */ i = 0; script_env = (char **) malloc(16 * sizeof(char *)); if (script_env == 0) return; s_env_nalloc = 16; } /* reallocate script_env with more space if needed */ if (i + 1 >= s_env_nalloc) { int new_n = i + 17; char **newenv = (char **) realloc((void *)script_env, new_n * sizeof(char *)); if (newenv == 0) return; script_env = newenv; s_env_nalloc = new_n; } script_env[i] = newstring; script_env[i+1] = 0; if (pppdb != NULL) { if (iskey) add_db_key(newstring); update_db_entry(); }}/* * script_unsetenv - remove a variable from the environment * for scripts. */voidscript_unsetenv(var) char *var;{ int vl = strlen(var); int i; char *p; if (script_env == 0) return; for (i = 0; (p = script_env[i]) != 0; ++i) { if (strncmp(p, var, vl) == 0 && p[vl] == '=') { if (p[-1] && pppdb != NULL) delete_db_key(p); free(p-1); while ((script_env[i] = script_env[i+1]) != 0) ++i; break; } } if (pppdb != NULL) update_db_entry();}/* * update_db_entry - update our entry in the database. */static voidupdate_db_entry(){ TDB_DATA key, dbuf; int vlen, i; char *p, *q, *vbuf; if (script_env == NULL) return; vlen = 0; for (i = 0; (p = script_env[i]) != 0; ++i) vlen += strlen(p) + 1; vbuf = malloc(vlen); if (vbuf == 0) novm("database entry"); q = vbuf; for (i = 0; (p = script_env[i]) != 0; ++i) q += slprintf(q, vbuf + vlen - q, "%s;", p); key.dptr = db_key; key.dsize = strlen(db_key); dbuf.dptr = vbuf; dbuf.dsize = vlen; if (tdb_store(pppdb, key, dbuf, TDB_REPLACE)) error("tdb_store failed: %s", tdb_error(pppdb));}/* * add_db_key - add a key that we can use to look up our database entry. */static voidadd_db_key(str) const char *str;{ TDB_DATA key, dbuf; key.dptr = (char *) str; key.dsize = strlen(str); dbuf.dptr = db_key; dbuf.dsize = strlen(db_key); if (tdb_store(pppdb, key, dbuf, TDB_REPLACE)) error("tdb_store key failed: %s", tdb_error(pppdb));}/* * delete_db_key - delete a key for looking up our database entry. */static voiddelete_db_key(str) const char *str;{ TDB_DATA key; key.dptr = (char *) str; key.dsize = strlen(str); tdb_delete(pppdb, key);}/* * cleanup_db - delete all the entries we put in the database. */static voidcleanup_db(){ TDB_DATA key; int i; char *p; key.dptr = db_key; key.dsize = strlen(db_key); tdb_delete(pppdb, key); for (i = 0; (p = script_env[i]) != 0; ++i) if (p[-1]) delete_db_key(p);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -