📄 dhcp-client.c
字号:
/* wake up a client. send sigalarm. */static void do_wake_client(char *interface){ pid_t pid; if(file_get_pid(interface, &pid)) { ERROR_MESSAGE ("could not get PID for client running on interface %s. Maybe it's not running?", interface); return; } if(kill(pid, SIGALRM) < 0) { ERROR_MESSAGE("could not send signal to client on %s. Maybe it's not running?", interface); return; } INFO_MESSAGE("woke client on pid %u : for interface: %s", pid, interface); return;}/* delete existing cache. make sure no other client is running. */static void do_clear_cache(char *interface){ pid_t pid; client_cache_t *cc; if(!file_get_pid(interface, &pid)) { INFO_MESSAGE("%s already is running on %s. I won't delete the cache until it shuts down.", getprogname(), interface); return; } cc = client_cache_create(interface); /* now delete. */ client_cache_delete_cache(cc); client_cache_delete_tmp_cache(cc); return;}static void do_status(char *interface){ /* try to load up cache. */ client_cache_t *cache; if((cache = client_cache_create(interface)) == NULL) { FATAL_MESSAGE("could not create client cache"); } if(client_cache_is_empty(cache)) { if(client_cache_is_empty_tmp(cache)) { INFO_MESSAGE("No lease acquired for this interface."); INFO_MESSAGE(" "); } else { INFO_MESSAGE("This lease has been offered but has not been acquired yet, or the client has not been able to receive an acknowledgement from the server yet."); INFO_MESSAGE(" "); client_pretty_print_cache(cache, 1); } } else { client_pretty_print_cache(cache, 0); } return;}/* do client: perform dhcp client proper functions. */static void do_client(char *interface){ dhcp_client_control_t *dc; dhcp_client_control_context_t *dc_context; int state; INFO_MESSAGE("starting for interface %s", interface); /* Now see if another client is running on the same interface. */ if(client_process_exists(interface)) { FATAL_MESSAGE("%s already exists on interface %s use -k to kill it", getprogname(), interface); } /* setup umask: this is also done in go_background but the client * doesn't go into the background immediately. so do it now. */ umask(0); /* * Create our control object. * There are several things it does * for us: * * Read the cache, and initialize our state. * Read our configuration. * Acquire a handle on the interface control. * Acquire a handle on the rawnet driver. * */ /* "and she came from a great Desktop; and she razed the * posers leaving a blanket of ash; and we were Praised in * our Judgements;" -- from the Book of Ada (blessed be her * semicolons) */ setup_interrupt_handlers(); /* setup signal handling */ if((dc = dhcp_client_control_create(interface, promiscuous, 1)) == NULL) { ERROR_MESSAGE("encountered a fatal error. I'm exiting."); client_states[STATE_SHUTDOWN] (dc); } /* load up user guile sysconf script. */ dhcp_guile_init(dc); if(fake_hw_addr) /* Marla, you liar, you big tourist, I need this. Now get out! */ dhcp_client_control_use_fake_hw_addr(dc, fake_hw_addr); /* We're good to go. Look up state. */ state = initialize_client_state(dc); /* do first loop, returning after setup. */ state = do_client_dhcp_loop(1, dc, state); /* flush stdout to get messages out _now_ * in case things break in forking into child. */ fflush(stdout); fflush(stderr); /* Go in background now before main loop. */ if(want_background) { /* are we interactive? if so stay in foreground. * ... otherwise ... */ /* We need to destroy our client control object before * backgrounding ourselves. Since we close file * descriptors and enter a different process space. * * This accumilates to losing a _lot_ of things: * * (1) Any raw network devices, or anything else which * has a descriptor open is now closed. * * (2) Our signal handlers are gone. * * (3) Our concept of timers is gone. * * The only thing we keep is our state which ought to be * STATE_BOUND * * Unfortunately destroying the control means valuable * data like timers, and addresses are lost. we can * however make a copy of this information and just label * it a context. This way we set it after recreating the * control */ dc_context = dhcp_client_control_copy_context(dc); dhcp_client_control_destroy(dc); set_interactive(0); go_background(work_dir); setup_interrupt_handlers(); /* setup signal handling, * we lose them after we fork in go_background. */ /* set clear_interface to 0 on create call because by now we're configured fine. */ if((dc = dhcp_client_control_create(interface, promiscuous, 0)) == NULL) { ERROR_MESSAGE("encountered a fatal error. I'm exiting.", interface); client_states[STATE_SHUTDOWN] (NULL); } /* set old context information. */ dhcp_client_control_set_context(dc, dc_context); if(file_create_pid(interface)) { ERROR_MESSAGE("could not create PID file for interface: %s", interface); client_states[STATE_SHUTDOWN](NULL); } if(fake_hw_addr) /* Marla, you liar, you big tourist, I need this. Now get out! */ dhcp_client_control_use_fake_hw_addr(dc, fake_hw_addr); /* call reinitialize for things like resetting the timer. */ client_reinitialize(dc); } do_client_dhcp_loop(0, dc, state); /* perform infinite waiting loop. */ exit(0);}/* main function: called from scm_boot_guile */static void real_main(void *closure, int argc, char *argv[]){ int c, command_code = DO_CLIENT;#if !defined(HAVE_PROGNAME) __progname = argv[0];#endif /* HAVE_PROGNAME */ INFO_MESSAGE("(C) 2003 Thamer Al-Harbash <tmh@whitefang.com>"); INFO_MESSAGE("See LICENSE file for details."); INFO_MESSAGE(" "); while((c = getopt(argc, argv, "stpcdavi:m:kwhl:")) != -1) { switch (c) { /* check for command codes. */ case 'v': /* print version. */ command_code = DO_VERSION; break; case 'k': /* kill client. */ command_code = DO_KILL; break; case 'w': /* wake client. */ command_code = DO_WAKE; break; case 'c': /* clear up cache. */ command_code = DO_CLEAR; break; /* setup options. */ case 'a': want_background = 0; break; case 'i': interface = xstrdup(optarg); break; case 'm': fake_hw_addr = xstrdup(optarg); break; case 'l': if(!is_signed_numeric(optarg) || set_verbosity_level(atoi(optarg))) { ERROR_MESSAGE("illegal verbosity level: %s", optarg); exit(1); } break; case 's': command_code = DO_STATUS; break; case 'p': promiscuous = 1; break; case 'h': /* fall through. */ default: usage(argv[0]); break; } } /* if all the user wants is version information, give it to him. */ if(command_code == DO_VERSION) { do_version(NULL); exit(0); } do_change_work_dir(work_dir); /* get interface if not specified. */ if(interface == NULL) { if(get_interface[command_code] != NULL) interface = get_interface[command_code] (); } if(interface == NULL && command_code != DO_VERSION) { FATAL_MESSAGE("unable to retrieve suitable interface for this operation: %s", command_string[command_code]); } commands[command_code] (interface); exit(0);}/* actual main: boot guile up so it knows where the bottom of the stack is. */int main(int argc, char *argv[]){ scm_boot_guile(argc, argv, real_main, NULL); /* get rid of compiler warning. */ exit(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -