/** * DHCP manual mode handler. * - Blocking Function * - Used only at DHCP manual mode (DHCP mode could be chosen at wizconfig.h file) * - DHCP_MANUAL mode does not need a loop structure, but if there is no loop structure, \n * you should handle renew & rebind with your own way, or just ignore renew & rebind action * * @param action The action you want to do. (@ref dhcp_action) * @param renew For returning renew time when DHCP be bound (NULL will be ignored) * @param rebind For returning rebind time when DHCP be bound (NULL will be ignored) * @return RET_OK: Success * @return RET_NOK: Error */ int8 dhcp_manual(dhcp_action action, uint32 *renew, uint32 *rebind) // blocking function { dhcp_state curstt = di.state; if(dhcp_alarm == TRUE) return RET_NOK; while(curstt != DHCP_STATE_INIT && curstt != DHCP_STATE_BOUND) { dhcp_run(); curstt = di.state; } if(curstt == DHCP_STATE_INIT) { di.action = DHCP_ACT_START; memset(&workinfo, 0, sizeof(workinfo)); workinfo.dhcp = NETINFO_DHCP; SetNetInfo(&workinfo); // ToDo: Set zero IP & SN do { dhcp_run(); curstt = di.state; } while((curstt != DHCP_STATE_INIT || di.action != DHCP_ACT_START) && curstt != DHCP_STATE_BOUND); if(curstt != DHCP_STATE_BOUND) return RET_NOK; if(renew) *renew = di.renew_time; if(rebind) *rebind = di.rebind_time; } else if(curstt == DHCP_STATE_BOUND) { if(action == DHCP_ACT_START) { if(renew) *renew = 0; if(rebind) *rebind = 0; return RET_OK; } else if(action == DHCP_ACT_RENEW) { // renew SET_STATE(DHCP_STATE_SELECTING); di.action = DHCP_ACT_RENEW; di.xid++; } else if(action == DHCP_ACT_REBIND) { // rebind SET_STATE(DHCP_STATE_SELECTING); di.action = DHCP_ACT_REBIND; di.xid++; } else { ERRA("wrong action(%d)", action); return RET_NOK; } curstt = di.state; while(curstt != DHCP_STATE_INIT && curstt != DHCP_STATE_BOUND) { dhcp_run(); curstt = di.state; } if(curstt != DHCP_STATE_BOUND) return RET_NOK; if(renew) *renew = di.renew_time; if(rebind) *rebind = di.rebind_time; } return RET_OK; }
int8 dhcp_manual(int8 action, uint8 *saved_ip, uint32 *renew, uint32 *rebind) // blocking function { int8 curstt = dhcp_get_state(); if(dhcp_alarm == TRUE) return RET_NOK; while(curstt != DHCP_STATE_INIT && curstt != DHCP_STATE_BOUND) { dhcp_run(); curstt = dhcp_get_state(); } if(curstt == DHCP_STATE_INIT) { di.action = DHCP_ACT_START; memset(&workinfo, 0, sizeof(workinfo)); if(saved_ip) memcpy(workinfo.IP, saved_ip, 4); workinfo.DHCP = NETINFO_DHCP_BUSY; SetNetInfo(&workinfo); do { dhcp_run(); curstt = dhcp_get_state(); } while((curstt != DHCP_STATE_INIT || workinfo.DHCP == NETINFO_DHCP_BUSY) && curstt != DHCP_STATE_BOUND); if(curstt != DHCP_STATE_BOUND) return RET_NOK; if(renew) *renew = di.renew_time; if(rebind) *rebind = di.rebind_time; } else if(curstt == DHCP_STATE_BOUND) { if(action == DHCP_ACT_START) { if(renew) *renew = 0; if(rebind) *rebind = 0; return RET_OK; } else if(action == DHCP_ACT_RENEW) { // renew SET_STATE(DHCP_STATE_SELECTING); di.action = DHCP_ACT_RENEW; di.xid++; } else if(action == DHCP_ACT_REBIND) { // rebind SET_STATE(DHCP_STATE_SELECTING); di.action = DHCP_ACT_REBIND; di.xid++; } else { ERRA("wrong action(%d)", action); return RET_NOK; } curstt = dhcp_get_state(); while(curstt != DHCP_STATE_INIT && curstt != DHCP_STATE_BOUND) { dhcp_run(); curstt = dhcp_get_state(); } if(curstt != DHCP_STATE_BOUND) return RET_NOK; if(renew) *renew = di.renew_time; if(rebind) *rebind = di.rebind_time; } return RET_OK; }
static void dhcp_alarm_cb(int8 arg) // for DHCP auto mode { if(dhcp_alarm == FALSE) return; if(arg == 0) { if(di.state == DHCP_STATE_BOUND) { alarm_set(wizpf_tick_conv(FALSE, di.renew_time), dhcp_alarm_cb, 1); alarm_set(wizpf_tick_conv(FALSE, di.rebind_time), dhcp_alarm_cb, 2); } if(di.state == DHCP_STATE_FAILED) { di.state = DHCP_STATE_INIT; di.action = DHCP_ACT_START; } dhcp_run(); } else if(arg == 1) { // renew SET_STATE(DHCP_STATE_SELECTING); di.action = DHCP_ACT_RENEW; di.xid++; alarm_set(10, dhcp_alarm_cb, 0); } else if(arg == 2) { // rebind SET_STATE(DHCP_STATE_SELECTING); di.action = DHCP_ACT_REBIND; di.xid++; alarm_set(10, dhcp_alarm_cb, 0); } }
static void dhcp_alarm_cb(int8 arg) // for alarm mode { if(dhcp_alarm == FALSE) return; if(arg == 0) { if(workinfo.DHCP == NETINFO_DHCP_FAIL) { workinfo.DHCP = NETINFO_DHCP_BUSY; di.action = DHCP_ACT_START; } if(dhcp_get_state() == DHCP_STATE_IP_CHECK) { alarm_set(wizpf_tick_conv(FALSE, di.renew_time), dhcp_alarm_cb, 1); alarm_set(wizpf_tick_conv(FALSE, di.rebind_time), dhcp_alarm_cb, 2); } dhcp_run(); } else if(arg == 1) { // renew SET_STATE(DHCP_STATE_SELECTING); di.action = DHCP_ACT_RENEW; di.xid++; alarm_set(10, dhcp_alarm_cb, 0); } else if(arg == 2) { // rebind SET_STATE(DHCP_STATE_SELECTING); di.action = DHCP_ACT_REBIND; di.xid++; alarm_set(10, dhcp_alarm_cb, 0); } }
int main(void) { #define TCP_LISTEN_PORT 5000 #define UDP_LISTEN_PORT 5000 int8 ret, root; uint32 tick = 0; ret = platform_init(); if(ret != RET_OK) { goto FAIL_TRAP; } ret = network_init(SOCK_DHCP, NULL, NULL); if(ret != RET_OK) { ERRA("network_init fail - ret(%d)", ret); goto FAIL_TRAP; } printf("\r\n-----------------------------------\r\n"); printf("SMTP Client using W5200\r\n"); printf("-----------------------------------\r\n\r\n"); menu_init(); root = menu_add("Network setting", 0, NULL); menu_add("Show", root, mn_show_network); menu_add("Static Set", root, mn_set_network); menu_add("Loopback", 0, mn_loopback); menu_add("LED Test", 0, mn_set_led); root = menu_add("App Test", 0, NULL); menu_add("DNS", root, mn_dns); menu_add("BASE64", root, mn_base64); menu_add("eMail", root, mn_email); menu_print_tree(); while(1) { #if (USE_DHCP == VAL_ENABLE) dhcp_run(); #endif menu_run(); if(lb_tcp) loopback_tcps(7, (uint16)TCP_LISTEN_PORT); if(lb_udp) loopback_udp(7, (uint16)UDP_LISTEN_PORT); if(wizpf_tick_elapse(tick) > 1000) { wizpf_led_act(WIZ_LED3, VAL_TOG); tick = wizpf_get_systick(); } } FAIL_TRAP: wizpf_led_trap(10); }
int main(int argc, char **argv) { options_t options; int doversion = 0; int dohelp = 0; int userclasses = 0; int opt; int option_index = 0; char prefix[IF_NAMESIZE + 3]; pid_t pid; int debug = 0; int i; int pidfd = -1; int sig = 0; const struct option longopts[] = { {"arp", no_argument, NULL, 'a'}, {"script", required_argument, NULL, 'c'}, {"debug", no_argument, NULL, 'd'}, {"hostname", optional_argument, NULL, 'h'}, {"classid", optional_argument, NULL, 'i'}, {"release", no_argument, NULL, 'k'}, {"leasetime", required_argument, NULL, 'l'}, {"metric", required_argument, NULL, 'm'}, {"renew", no_argument, NULL, 'n'}, {"persistent", no_argument, NULL, 'p'}, {"inform", optional_argument, NULL, 's'}, {"request", optional_argument, NULL, 'r'}, {"timeout", required_argument, NULL, 't'}, {"userclass", required_argument, NULL, 'u'}, {"exit", no_argument, NULL, 'x'}, {"lastlease", no_argument, NULL, 'E'}, {"fqdn", required_argument, NULL, 'F'}, {"nogateway", no_argument, NULL, 'G'}, {"sethostname", no_argument, NULL, 'H'}, {"clientid", optional_argument, NULL, 'I'}, {"noipv4ll", no_argument, NULL, 'L'}, {"nomtu", no_argument, NULL, 'M'}, {"nontp", no_argument, NULL, 'N'}, {"nodns", no_argument, NULL, 'R'}, {"test", no_argument, NULL, 'T'}, {"nonis", no_argument, NULL, 'Y'}, {"help", no_argument, &dohelp, 1}, {"version", no_argument, &doversion, 1}, {NULL, 0, NULL, 0} }; /* Close any un-needed fd's */ for (i = getdtablesize() - 1; i >= 3; --i) close (i); openlog (PACKAGE, LOG_PID, LOG_LOCAL0); memset (&options, 0, sizeof (options_t)); options.script = (char *) DEFAULT_SCRIPT; snprintf (options.classid, CLASS_ID_MAX_LEN, "%s %s", PACKAGE, VERSION); options.classid_len = strlen (options.classid); options.doarp = true; options.dodns = true; options.domtu = true; options.donis = true; options.dontp = true; options.dogateway = true; options.daemonise = true; options.doinform = false; options.doipv4ll = true; options.timeout = DEFAULT_TIMEOUT; gethostname (options.hostname, sizeof (options.hostname)); if (strcmp (options.hostname, "(none)") == 0 || strcmp (options.hostname, "localhost") == 0) memset (options.hostname, 0, sizeof (options.hostname)); /* Don't set any optional arguments here so we retain POSIX * compatibility with getopt */ while ((opt = getopt_long(argc, argv, "c:dh:i:kl:m:npr:s:t:u:xAEF:GHI:LMNRTY", longopts, &option_index)) != -1) { switch (opt) { case 0: if (longopts[option_index].flag) break; logger (LOG_ERR, "option `%s' should set a flag", longopts[option_index].name); exit (EXIT_FAILURE); break; case 'c': options.script = optarg; break; case 'd': debug++; switch (debug) { case 1: setloglevel (LOG_DEBUG); break; case 2: options.daemonise = false; break; } break; case 'h': if (! optarg) memset (options.hostname, 0, sizeof (options.hostname)); else if (strlen (optarg) > MAXHOSTNAMELEN) { logger (LOG_ERR, "`%s' too long for HostName string, max is %d", optarg, MAXHOSTNAMELEN); exit (EXIT_FAILURE); } else strlcpy (options.hostname, optarg, sizeof (options.hostname)); break; case 'i': if (! optarg) { memset (options.classid, 0, sizeof (options.classid)); options.classid_len = 0; } else if (strlen (optarg) > CLASS_ID_MAX_LEN) { logger (LOG_ERR, "`%s' too long for ClassID string, max is %d", optarg, CLASS_ID_MAX_LEN); exit (EXIT_FAILURE); } else options.classid_len = strlcpy (options.classid, optarg, sizeof (options.classid)); break; case 'k': sig = SIGHUP; break; case 'l': STRINGINT (optarg, options.leasetime); if (options.leasetime <= 0) { logger (LOG_ERR, "leasetime must be a positive value"); exit (EXIT_FAILURE); } break; case 'm': STRINGINT (optarg, options.metric); break; case 'n': sig = SIGALRM; break; case 'p': options.persistent = true; break; case 's': options.doinform = true; if (! optarg || strlen (optarg) == 0) { options.request_address.s_addr = 0; break; } else { char *slash = strchr (optarg, '/'); if (slash) { int cidr; /* nullify the slash, so the -r option can read the * address */ *slash++ = '\0'; if (sscanf (slash, "%d", &cidr) != 1) { logger (LOG_ERR, "`%s' is not a valid CIDR", slash); exit (EXIT_FAILURE); } options.request_netmask = inet_cidrtoaddr (cidr); } /* fall through */ } case 'r': if (! options.doinform) options.dorequest = true; if (strlen (optarg) > 0 && ! inet_aton (optarg, &options.request_address)) { logger (LOG_ERR, "`%s' is not a valid IP address", optarg); exit (EXIT_FAILURE); } break; case 't': STRINGINT (optarg, options.timeout); if (options.timeout < 0) { logger (LOG_ERR, "timeout must be a positive value"); exit (EXIT_FAILURE); } break; case 'u': { int offset = 0; for (i = 0; i < userclasses; i++) offset += (int) options.userclass[offset] + 1; if (offset + 1 + strlen (optarg) > USERCLASS_MAX_LEN) { logger (LOG_ERR, "userclass overrun, max is %d", USERCLASS_MAX_LEN); exit (EXIT_FAILURE); } userclasses++; memcpy (options.userclass + offset + 1 , optarg, strlen (optarg)); options.userclass[offset] = strlen (optarg); options.userclass_len += (strlen (optarg)) + 1; } break; case 'x': sig = SIGTERM; break; case 'A': #ifndef ENABLE_ARP logger (LOG_ERR, "arp support not compiled into dhcpcd"); exit (EXIT_FAILURE); #endif options.doarp = false; break; case 'E': #ifndef ENABLE_INFO logger (LOG_ERR, "info support not compiled into dhcpcd"); exit (EXIT_FAILURE); #endif options.dolastlease = true; break; case 'F': if (strncmp (optarg, "none", strlen (optarg)) == 0) options.fqdn = FQDN_NONE; else if (strncmp (optarg, "ptr", strlen (optarg)) == 0) options.fqdn = FQDN_PTR; else if (strncmp (optarg, "both", strlen (optarg)) == 0) options.fqdn = FQDN_BOTH; else { logger (LOG_ERR, "invalid value `%s' for FQDN", optarg); exit (EXIT_FAILURE); } break; case 'G': options.dogateway = false; break; case 'H': options.dohostname++; break; case 'I': if (optarg) { if (strlen (optarg) > CLIENT_ID_MAX_LEN) { logger (LOG_ERR, "`%s' is too long for ClientID, max is %d", optarg, CLIENT_ID_MAX_LEN); exit (EXIT_FAILURE); } options.clientid_len = strlcpy (options.clientid, optarg, sizeof (options.clientid)); /* empty string disabled duid */ if (options.clientid_len == 0) options.clientid_len = -1; } else { memset (options.clientid, 0, sizeof (options.clientid)); options.clientid_len = -1; } break; case 'L': options.doipv4ll = false; break; case 'M': options.domtu = false; break; case 'N': options.dontp = false; break; case 'R': options.dodns = false; break; case 'T': #ifndef ENABLE_INFO logger (LOG_ERR, "info support not compiled into dhcpcd"); exit (EXIT_FAILURE); #endif options.test = true; options.persistent = true; break; case 'Y': options.donis = false; break; case '?': usage (); exit (EXIT_FAILURE); default: usage (); exit (EXIT_FAILURE); } } if (doversion) printf (""PACKAGE" "VERSION"\n"); if (dohelp) usage (); if (optind < argc) { if (strlen (argv[optind]) > IF_NAMESIZE) { logger (LOG_ERR, "`%s' is too long for an interface name (max=%d)", argv[optind], IF_NAMESIZE); exit (EXIT_FAILURE); } strlcpy (options.interface, argv[optind], sizeof (options.interface)); } else { /* If only version was requested then exit now */ if (doversion || dohelp) exit (EXIT_SUCCESS); logger (LOG_ERR, "no interface specified"); exit (EXIT_FAILURE); } if (strchr (options.hostname, '.')) { if (options.fqdn == FQDN_DISABLE) options.fqdn = FQDN_BOTH; } else options.fqdn = FQDN_DISABLE; if (options.request_address.s_addr == 0 && options.doinform) { if ((options.request_address.s_addr = get_address (options.interface)) != 0) options.keep_address = true; } if (geteuid ()) { logger (LOG_ERR, "you need to be root to run "PACKAGE); exit (EXIT_FAILURE); } snprintf (prefix, IF_NAMESIZE, "%s: ", options.interface); setlogprefix (prefix); snprintf (options.pidfile, sizeof (options.pidfile), PIDFILE, options.interface); chdir ("/"); umask (022); if (mkdir (CONFIGDIR, S_IRUSR |S_IWUSR |S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) && errno != EEXIST ) { logger (LOG_ERR, "mkdir(\"%s\",0): %s\n", CONFIGDIR, strerror (errno)); exit (EXIT_FAILURE); } if (mkdir (ETCDIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) && errno != EEXIST ) { logger (LOG_ERR, "mkdir(\"%s\",0): %s\n", ETCDIR, strerror (errno)); exit (EXIT_FAILURE); } if (options.test) { if (options.dorequest || options.doinform) { logger (LOG_ERR, "cannot test with --inform or --request"); exit (EXIT_FAILURE); } if (options.dolastlease) { logger (LOG_ERR, "cannot test with --lastlease"); exit (EXIT_FAILURE); } if (sig != 0) { logger (LOG_ERR, "cannot test with --release or --renew"); exit (EXIT_FAILURE); } } if (sig != 0 ) { int killed = -1; pid = read_pid (options.pidfile); if (pid != 0) logger (LOG_INFO, "sending signal %d to pid %d", sig, pid); if (! pid || (killed = kill (pid, sig))) logger (sig == SIGALRM ? LOG_INFO : LOG_ERR, ""PACKAGE" not running"); if (pid != 0 && (sig != SIGALRM || killed != 0)) unlink (options.pidfile); if (killed == 0) exit (EXIT_SUCCESS); if (sig != SIGALRM) exit (EXIT_FAILURE); } if (! options.test) { if ((pid = read_pid (options.pidfile)) > 0 && kill (pid, 0) == 0) { logger (LOG_ERR, ""PACKAGE" already running on pid %d (%s)", pid, options.pidfile); exit (EXIT_FAILURE); } pidfd = open (options.pidfile, O_WRONLY | O_CREAT | O_NONBLOCK, 0660); if (pidfd == -1) { logger (LOG_ERR, "open `%s': %s", options.pidfile, strerror (errno)); exit (EXIT_FAILURE); } /* Lock the file so that only one instance of dhcpcd runs on an interface */ if (flock (pidfd, LOCK_EX | LOCK_NB) == -1) { logger (LOG_ERR, "flock `%s': %s", options.pidfile, strerror (errno)); exit (EXIT_FAILURE); } /* dhcpcd.sh should not interhit this fd */ if ((i = fcntl (pidfd, F_GETFD, 0)) == -1 || fcntl (pidfd, F_SETFD, i | FD_CLOEXEC) == -1) logger (LOG_ERR, "fcntl: %s", strerror (errno)); logger (LOG_INFO, PACKAGE " " VERSION " starting"); } /* Seed random */ srandomdev (); if (dhcp_run (&options, &pidfd)) { if (pidfd > -1) close (pidfd); unlink (options.pidfile); exit (EXIT_FAILURE); } exit (EXIT_SUCCESS); }
int main(int argc, char **argv) { options_t options; /* Sanitize our fd's */ int zero; if ((zero = open (_PATH_DEVNULL, O_RDWR, 0)) >= 0) { while (zero < 3) zero = dup (zero); close(zero); } openlog (PACKAGE, LOG_PID, LOG_LOCAL0); memset (&options, 0, sizeof (options_t)); options.script = DEFAULT_SCRIPT; snprintf (options.classid, CLASS_ID_MAX_LEN, "%s %s", PACKAGE, VERSION); options.doarp = false; options.dodns = true; options.dontp = true; options.dogateway = true; options.timeout = DEFAULT_TIMEOUT; int doversion = 0; int dohelp = 0; int userclasses = 0; const struct option longopts[] = { {"arp", no_argument, NULL, 'a'}, {"script",required_argument, NULL, 'c'}, {"debug", no_argument, NULL, 'd'}, {"hostname", required_argument, NULL, 'h'}, {"classid", required_argument, NULL, 'i'}, {"release", no_argument, NULL, 'k'}, {"leasetime", required_argument, NULL, 'l'}, {"metric", required_argument, NULL, 'm'}, {"renew", no_argument, NULL, 'n'}, {"persistent", no_argument, NULL, 'p'}, {"request", required_argument, NULL, 's'}, {"timeout", required_argument, NULL, 't'}, {"userclass", required_argument, NULL, 'u'}, {"fqdn", optional_argument, NULL, 'F'}, {"nogateway", no_argument, NULL, 'G'}, {"sethostname", no_argument, NULL, 'H'}, {"clientid", required_argument, NULL, 'I'}, {"nontp", no_argument, NULL, 'N'}, {"nodns", no_argument, NULL, 'R'}, {"nonis", no_argument, NULL, 'Y'}, {"help", no_argument, &dohelp, 1}, {"version", no_argument, &doversion, 1}, {NULL, 0, NULL, 0} }; int ch; int option_index = 0; while ((ch = getopt_long(argc, argv, "ac:dh:i:kl:m:nps:t:u:F:GHI:NRY", longopts, &option_index)) != -1) switch (ch) { case 0: if (longopts[option_index].flag) break; logger (LOG_ERR, "option `%s' should set a flag", longopts[option_index].name); exit (EXIT_FAILURE); break; case 'a': options.doarp = true; break; case 'c': options.script = optarg; break; case 'd': setloglevel(LOG_DEBUG); break; case 'h': if (strlen (optarg) > HOSTNAME_MAX_LEN) { logger(LOG_ERR, "`%s' too long for HostName string, max is %d", optarg, HOSTNAME_MAX_LEN); exit (EXIT_FAILURE); } else options.hostname = optarg; break; case 'i': if (strlen(optarg) > CLASS_ID_MAX_LEN) { logger (LOG_ERR, "`%s' too long for ClassID string, max is %d", optarg, CLASS_ID_MAX_LEN); exit (EXIT_FAILURE); } else sprintf(options.classid, "%s", optarg); break; case 'k': options.signal = SIGHUP; break; case 'l': STRINGINT (optarg, options.leasetime); if (options.leasetime <= 0) { logger (LOG_ERR, "leasetime must be a positive value"); exit (EXIT_FAILURE); } break; case 'm': STRINGINT(optarg, options.metric); break; case 'n': options.signal = SIGALRM; break; case 'p': options.persistent = true; break; case 's': if (! inet_aton (optarg, &options.requestaddress)) { logger (LOG_ERR, "`%s' is not a valid IP address", optarg); exit (EXIT_FAILURE); } break; case 't': STRINGINT (optarg, options.timeout); if (options.timeout < 0) { logger (LOG_ERR, "timeout must be a positive value"); exit (EXIT_FAILURE); } break; case 'u': { int i; int offset = 0; for (i = 0; i < userclasses; i++) offset += (int) options.userclass[offset] + 1; if (offset + 1 + strlen (optarg) > USERCLASS_MAX_LEN) { logger (LOG_ERR, "userclass overrun, max is %d", USERCLASS_MAX_LEN); exit (EXIT_FAILURE); } userclasses++; memcpy (options.userclass + offset + 1 , optarg, strlen (optarg)); options.userclass[offset] = strlen (optarg); } break; case 'F': if (strcmp (optarg, "none") == 0) options.fqdn = FQDN_NONE; else if (strcmp (optarg, "ptr") == 0) options.fqdn = FQDN_PTR; else if (strcmp (optarg, "both") == 0) options.fqdn = FQDN_BOTH; else { logger (LOG_ERR, "invalid value `%s' for FQDN", optarg); exit (EXIT_FAILURE); } break; case 'G': options.dogateway = false; break; case 'H': options.dohostname = true; break; case 'I': if (strlen (optarg) > CLIENT_ID_MAX_LEN) { logger (LOG_ERR, "`%s' is too long for ClientID, max is %d", optarg, CLIENT_ID_MAX_LEN); exit (EXIT_FAILURE); } else sprintf(options.clientid, "%s", optarg); break; case 'N': options.dontp = false; break; case 'R': options.dodns = false; break; case 'Y': options.donis = false; break; case '?': usage (); exit (EXIT_FAILURE); default: usage (); exit (EXIT_FAILURE); } if (doversion) printf (""PACKAGE" "VERSION"\n"); if (dohelp) usage (); if (optind < argc) { if (strlen (argv[optind]) > IF_NAMESIZE) { logger (LOG_ERR, "`%s' is too long for an interface name (max=%d)", argv[optind], IF_NAMESIZE); exit (EXIT_FAILURE); } options.interface = argv[optind]; } else { /* If only version was requested then exit now */ if (doversion || dohelp) exit (EXIT_SUCCESS); logger (LOG_ERR, "no interface specified", options.interface); exit (EXIT_FAILURE); } if (geteuid ()) { logger (LOG_ERR, "you need to be root to run "PACKAGE); exit (EXIT_FAILURE); } char prefix[IF_NAMESIZE + 3]; snprintf (prefix, IF_NAMESIZE, "%s: ", options.interface); setlogprefix (prefix); snprintf (options.pidfile, sizeof (options.pidfile), PIDFILE, options.interface); if (options.signal != 0) exit (kill_pid (options.pidfile, options.signal)); umask (022); if (readpid (options.pidfile)) { logger (LOG_ERR, ""PACKAGE" already running (%s)", options.pidfile); exit (EXIT_FAILURE); } if (mkdir (CONFIGDIR, S_IRUSR |S_IWUSR |S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) && errno != EEXIST ) { logger( LOG_ERR, "mkdir(\"%s\",0): %m\n", CONFIGDIR); exit (EXIT_FAILURE); } if (mkdir (ETCDIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) && errno != EEXIST ) { logger (LOG_ERR, "mkdir(\"%s\",0): %m\n", ETCDIR); exit (EXIT_FAILURE); } logger (LOG_INFO, PACKAGE " " VERSION " starting"); if (dhcp_run (&options)) exit (EXIT_FAILURE); exit (EXIT_SUCCESS); }
int main(int argc, char **argv) { options_t *options; int userclasses = 0; int opt; int option_index = 0; char *prefix; pid_t pid; int debug = 0; int i; int pidfd = -1; int sig = 0; /* Close any un-needed fd's */ for (i = getdtablesize() - 1; i >= 3; --i) close (i); openlog (PACKAGE, LOG_PID, LOG_LOCAL0); options = xmalloc (sizeof (options_t)); memset (options, 0, sizeof (options_t)); options->script = (char *) DEFAULT_SCRIPT; snprintf (options->classid, CLASS_ID_MAX_LEN, "%s %s", PACKAGE, VERSION); options->classid_len = strlen (options->classid); options->doarp = true; options->dodns = true; options->domtu = true; options->donis = true; options->dontp = true; options->dogateway = true; options->daemonise = true; options->doinform = false; options->doipv4ll = true; options->timeout = DEFAULT_TIMEOUT; gethostname (options->hostname, sizeof (options->hostname)); if (strcmp (options->hostname, "(none)") == 0 || strcmp (options->hostname, "localhost") == 0) memset (options->hostname, 0, sizeof (options->hostname)); /* Don't set any optional arguments here so we retain POSIX * compatibility with getopt */ while ((opt = getopt_long(argc, argv, EXTRA_OPTS "c:dh:i:kl:m:npr:s:t:u:xAEF:GHI:LMNRTY", longopts, &option_index)) != -1) { switch (opt) { case 0: if (longopts[option_index].flag) break; logger (LOG_ERR, "option `%s' should set a flag", longopts[option_index].name); exit (EXIT_FAILURE); break; case 'c': options->script = optarg; break; case 'd': debug++; switch (debug) { case 1: setloglevel (LOG_DEBUG); break; case 2: options->daemonise = false; break; } break; #ifdef THERE_IS_NO_FORK case 'f': options->daemonised = true; close_fds (); break; case 'g': dhcpcd_skiproutes = xstrdup (optarg); break; #endif case 'h': if (! optarg) memset (options->hostname, 0, sizeof (options->hostname)); else if (strlen (optarg) > MAXHOSTNAMELEN) { logger (LOG_ERR, "`%s' too long for HostName string, max is %d", optarg, MAXHOSTNAMELEN); exit (EXIT_FAILURE); } else strlcpy (options->hostname, optarg, sizeof (options->hostname)); break; case 'i': if (! optarg) { memset (options->classid, 0, sizeof (options->classid)); options->classid_len = 0; } else if (strlen (optarg) > CLASS_ID_MAX_LEN) { logger (LOG_ERR, "`%s' too long for ClassID string, max is %d", optarg, CLASS_ID_MAX_LEN); exit (EXIT_FAILURE); } else options->classid_len = strlcpy (options->classid, optarg, sizeof (options->classid)); break; case 'k': sig = SIGHUP; break; case 'l': STRINGINT (optarg, options->leasetime); if (options->leasetime <= 0) { logger (LOG_ERR, "leasetime must be a positive value"); exit (EXIT_FAILURE); } break; case 'm': STRINGINT (optarg, options->metric); break; case 'n': sig = SIGALRM; break; case 'p': options->persistent = true; break; case 's': options->doinform = true; options->doarp = false; if (! optarg || strlen (optarg) == 0) { options->request_address.s_addr = 0; break; } else { char *slash = strchr (optarg, '/'); if (slash) { int cidr; /* nullify the slash, so the -r option can read the * address */ *slash++ = '\0'; if (sscanf (slash, "%d", &cidr) != 1 || inet_cidrtoaddr (cidr, &options->request_netmask) != 0) { logger (LOG_ERR, "`%s' is not a valid CIDR", slash); exit (EXIT_FAILURE); } } /* fall through */ } case 'r': if (! options->doinform) options->dorequest = true; if (strlen (optarg) > 0 && ! inet_aton (optarg, &options->request_address)) { logger (LOG_ERR, "`%s' is not a valid IP address", optarg); exit (EXIT_FAILURE); } break; case 't': STRINGINT (optarg, options->timeout); if (options->timeout < 0) { logger (LOG_ERR, "timeout must be a positive value"); exit (EXIT_FAILURE); } break; case 'u': { int offset = 0; for (i = 0; i < userclasses; i++) offset += (int) options->userclass[offset] + 1; if (offset + 1 + strlen (optarg) > USERCLASS_MAX_LEN) { logger (LOG_ERR, "userclass overrun, max is %d", USERCLASS_MAX_LEN); exit (EXIT_FAILURE); } userclasses++; memcpy (options->userclass + offset + 1 , optarg, strlen (optarg)); options->userclass[offset] = strlen (optarg); options->userclass_len += (strlen (optarg)) + 1; } break; case 'x': sig = SIGTERM; break; case 'A': #ifndef ENABLE_ARP logger (LOG_ERR, "arp support not compiled into dhcpcd"); exit (EXIT_FAILURE); #endif options->doarp = false; break; case 'E': #ifndef ENABLE_INFO logger (LOG_ERR, "info support not compiled into dhcpcd"); exit (EXIT_FAILURE); #endif options->dolastlease = true; break; case 'F': if (strncmp (optarg, "none", strlen (optarg)) == 0) options->fqdn = FQDN_NONE; else if (strncmp (optarg, "ptr", strlen (optarg)) == 0) options->fqdn = FQDN_PTR; else if (strncmp (optarg, "both", strlen (optarg)) == 0) options->fqdn = FQDN_BOTH; else { logger (LOG_ERR, "invalid value `%s' for FQDN", optarg); exit (EXIT_FAILURE); } break; case 'G': options->dogateway = false; break; case 'H': options->dohostname++; break; case 'I': if (optarg) { if (strlen (optarg) > CLIENT_ID_MAX_LEN) { logger (LOG_ERR, "`%s' is too long for ClientID, max is %d", optarg, CLIENT_ID_MAX_LEN); exit (EXIT_FAILURE); } options->clientid_len = strlcpy (options->clientid, optarg, sizeof (options->clientid)); /* empty string disabled duid */ if (options->clientid_len == 0) options->clientid_len = -1; } else { memset (options->clientid, 0, sizeof (options->clientid)); options->clientid_len = -1; } break; case 'L': options->doipv4ll = false; break; case 'M': options->domtu = false; break; case 'N': options->dontp = false; break; case 'R': options->dodns = false; break; case 'T': #ifndef ENABLE_INFO logger (LOG_ERR, "info support not compiled into dhcpcd"); exit (EXIT_FAILURE); #endif options->test = true; options->persistent = true; break; case 'Y': options->donis = false; break; case '?': usage (); exit (EXIT_FAILURE); default: usage (); exit (EXIT_FAILURE); } } if (doversion) { printf (""PACKAGE" "VERSION"\n"); printf ("Compile time options:" #ifdef ENABLE_ARP " ARP" #endif #ifdef ENABLE_DUID " DUID" #endif #ifdef ENABLE_INFO " INFO" #endif #ifdef ENABLE_INFO_COMPAT " INFO_COMPAT" #endif #ifdef ENABLE_IPV4LL " IPV4LL" #endif #ifdef ENABLE_NIS " NIS" #endif #ifdef ENABLE_NTP " NTP" #endif #ifdef THERE_IS_NO_FORK " THERE_IS_NO_FORK" #endif "\n"); } if (dohelp) usage (); #ifdef THERE_IS_NO_FORK dhcpcd_argv = argv; dhcpcd_argc = argc; /* We need the full path to the dhcpcd */ if (*argv[0] == '/') strlcpy (dhcpcd, argv[0], sizeof (dhcpcd)); else { char pwd[PATH_MAX]; if (! getcwd (pwd, PATH_MAX)) { logger (LOG_ERR, "getcwd: %s", strerror (errno)); exit (EXIT_FAILURE); } snprintf (dhcpcd, sizeof (dhcpcd), "%s/%s", pwd, argv[0]); } #endif if (optind < argc) { if (strlen (argv[optind]) > IF_NAMESIZE) { logger (LOG_ERR, "`%s' is too long for an interface name (max=%d)", argv[optind], IF_NAMESIZE); exit (EXIT_FAILURE); } strlcpy (options->interface, argv[optind], sizeof (options->interface)); } else { /* If only version was requested then exit now */ if (doversion || dohelp) exit (EXIT_SUCCESS); logger (LOG_ERR, "no interface specified"); exit (EXIT_FAILURE); } if (strchr (options->hostname, '.')) { if (options->fqdn == FQDN_DISABLE) options->fqdn = FQDN_BOTH; } else options->fqdn = FQDN_DISABLE; if (options->request_address.s_addr == 0 && options->doinform) { if ((options->request_address.s_addr = get_address (options->interface)) != 0) options->keep_address = true; } if (IN_LINKLOCAL (options->request_address.s_addr)) { logger (LOG_ERR, "you are not allowed to request a link local address"); exit (EXIT_FAILURE); } if (geteuid ()) { logger (LOG_ERR, "you need to be root to run "PACKAGE); exit (EXIT_FAILURE); } prefix = xmalloc (sizeof (char) * (IF_NAMESIZE + 3)); snprintf (prefix, IF_NAMESIZE, "%s: ", options->interface); setlogprefix (prefix); snprintf (options->pidfile, sizeof (options->pidfile), PIDFILE, options->interface); free (prefix); chdir ("/"); umask (022); if (mkdir (CONFIGDIR, S_IRUSR |S_IWUSR |S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) && errno != EEXIST ) { logger (LOG_ERR, "mkdir(\"%s\",0): %s\n", CONFIGDIR, strerror (errno)); exit (EXIT_FAILURE); } if (mkdir (ETCDIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) && errno != EEXIST ) { logger (LOG_ERR, "mkdir(\"%s\",0): %s\n", ETCDIR, strerror (errno)); exit (EXIT_FAILURE); } if (options->test) { if (options->dorequest || options->doinform) { logger (LOG_ERR, "cannot test with --inform or --request"); exit (EXIT_FAILURE); } if (options->dolastlease) { logger (LOG_ERR, "cannot test with --lastlease"); exit (EXIT_FAILURE); } if (sig != 0) { logger (LOG_ERR, "cannot test with --release or --renew"); exit (EXIT_FAILURE); } } if (sig != 0) { int killed = -1; pid = read_pid (options->pidfile); if (pid != 0) logger (LOG_INFO, "sending signal %d to pid %d", sig, pid); if (! pid || (killed = kill (pid, sig))) logger (sig == SIGALRM ? LOG_INFO : LOG_ERR, ""PACKAGE" not running"); if (pid != 0 && (sig != SIGALRM || killed != 0)) unlink (options->pidfile); if (killed == 0) exit (EXIT_SUCCESS); if (sig != SIGALRM) exit (EXIT_FAILURE); } if (! options->test && ! options->daemonised) { if ((pid = read_pid (options->pidfile)) > 0 && kill (pid, 0) == 0) { logger (LOG_ERR, ""PACKAGE" already running on pid %d (%s)", pid, options->pidfile); exit (EXIT_FAILURE); } pidfd = open (options->pidfile, O_WRONLY | O_CREAT | O_NONBLOCK, 0660); if (pidfd == -1) { logger (LOG_ERR, "open `%s': %s", options->pidfile, strerror (errno)); exit (EXIT_FAILURE); } /* Lock the file so that only one instance of dhcpcd runs on an interface */ if (flock (pidfd, LOCK_EX | LOCK_NB) == -1) { logger (LOG_ERR, "flock `%s': %s", options->pidfile, strerror (errno)); exit (EXIT_FAILURE); } /* dhcpcd.sh should not interhit this fd */ if ((i = fcntl (pidfd, F_GETFD, 0)) == -1 || fcntl (pidfd, F_SETFD, i | FD_CLOEXEC) == -1) logger (LOG_ERR, "fcntl: %s", strerror (errno)); writepid (pidfd, getpid ()); logger (LOG_INFO, PACKAGE " " VERSION " starting"); } /* Seed random */ srandomdev (); i = EXIT_FAILURE; if (dhcp_run (options, &pidfd) == 0) i = EXIT_SUCCESS; /* If we didn't daemonise then we need to punt the pidfile now */ if (pidfd > -1) { close (pidfd); unlink (options->pidfile); } free (options); #ifdef THERE_IS_NO_FORK /* There may have been an error before the dhcp_run function * clears this, so just do it here to be safe */ free (dhcpcd_skiproutes); #endif logger (LOG_INFO, "exiting"); exit (i); }
int main(void) { dhcp dhcp_session; int dhcp_state; http_server http; http_socket httpsock[4]; http_content httpcontent[4]; char oled_msg[17]; char *pnt; int step; api_init(); uart_puts(" * eCowLogic firmware \r\n"); hw_systick( hw_getfreq() / 1000 ); dhcp_session.socket = 2; dhcp_session.buffer = (u8 *)buffer_dhcp; dhcp_init(&dhcp_session); oled_pos(1, 0); oled_puts("Reseau (DHCP) "); step = 0; while(1) { dhcp_state = dhcp_run(&dhcp_session); if (dhcp_state == DHCP_IP_LEASED) break; step++; oled_pos(1, 13); if (step == 1) oled_puts(". "); if (step == 2) oled_puts(".. "); if (step == 3) oled_puts("..."); if (step == 4) { step = 0; dhcp_session.tick_1s++; uart_putc('.'); oled_puts(" "); } delay(250); } pnt = oled_msg; pnt += b2ds(pnt, dhcp_session.dhcp_my_ip[0]); *pnt++ = '.'; pnt += b2ds(pnt, dhcp_session.dhcp_my_ip[1]); *pnt++ = '.'; pnt += b2ds(pnt, dhcp_session.dhcp_my_ip[2]); *pnt++ = '.'; pnt += b2ds(pnt, dhcp_session.dhcp_my_ip[3]); for ( ; pnt < (oled_msg + 16); pnt++) *pnt = ' '; oled_msg[16] = 0; uart_puts("DHCP: LEASED ! "); uart_puts(oled_msg); uart_puts("\r\n"); oled_pos(1, 0); oled_puts(oled_msg); spi_init(); pld_init(); //net_init(); /* Init HTTP content */ strcpy(httpcontent[0].name, "/pld"); httpcontent[0].wildcard = 0; httpcontent[0].cgi = cgi_ng_pld; httpcontent[0].next = &httpcontent[1]; /* Init HTTP content */ strcpy(httpcontent[1].name, "/spi"); httpcontent[1].wildcard = 0; httpcontent[1].cgi = cgi_spi; httpcontent[1].next = &httpcontent[2]; /* Init HTTP content */ strcpy(httpcontent[2].name, "/infos"); httpcontent[2].wildcard = 0; httpcontent[2].cgi = cgi_info; httpcontent[2].next = &httpcontent[3]; /* Init HTTP content */ strcpy(httpcontent[3].name, "/"); httpcontent[3].wildcard = 1; httpcontent[3].cgi = cgi_ng_page; httpcontent[3].next = 0; /* Init HTTP socket */ httpsock[0].id = 4; httpsock[0].state = 0; httpsock[0].server = &http; httpsock[0].next = &httpsock[1]; /* Init HTTP socket */ httpsock[1].id = 5; httpsock[1].state = 0; httpsock[1].server = &http; httpsock[1].next = &httpsock[2]; /* Init HTTP socket */ httpsock[2].id = 6; httpsock[2].state = 0; httpsock[2].server = &http; httpsock[2].next = &httpsock[3]; /* Init HTTP socket */ httpsock[3].id = 7; httpsock[3].state = 0; httpsock[3].server = &http; httpsock[3].next = 0; /* Init the new HTTP layer */ http.port = 80; http.err404 = 0; http.err403 = 0; http.keepalive = 10; http.socks = &httpsock[0]; http.contents = &httpcontent[0]; http_init(&http); while(1) { http_run(&http); } }
int main(int argc, char **argv) { options_t options; int doversion = 0; int dohelp = 0; int userclasses = 0; int ch; int option_index = 0; char prefix[IF_NAMESIZE + 3]; pid_t pid; int debug = 0; int i; const struct option longopts[] = { {"arp", no_argument, NULL, 'a'}, {"script", required_argument, NULL, 'c'}, {"debug", no_argument, NULL, 'd'}, {"hostname", required_argument, NULL, 'h'}, {"classid", required_argument, NULL, 'i'}, {"release", no_argument, NULL, 'k'}, {"leasetime", required_argument, NULL, 'l'}, {"metric", required_argument, NULL, 'm'}, {"renew", no_argument, NULL, 'n'}, {"persistent", no_argument, NULL, 'p'}, {"request", required_argument, NULL, 's'}, {"timeout", required_argument, NULL, 't'}, {"userclass", required_argument, NULL, 'u'}, {"fqdn", optional_argument, NULL, 'F'}, {"nogateway", no_argument, NULL, 'G'}, {"sethostname", no_argument, NULL, 'H'}, {"clientid", required_argument, NULL, 'I'}, {"nomtu", no_argument, NULL, 'M'}, {"nontp", no_argument, NULL, 'N'}, {"nodns", no_argument, NULL, 'R'}, {"nonis", no_argument, NULL, 'Y'}, {"help", no_argument, &dohelp, 1}, {"version", no_argument, &doversion, 1}, {NULL, 0, NULL, 0} }; /* Close any un-needed fd's */ for (i = getdtablesize() - 1; i >= 3; --i) close (i); openlog (PACKAGE, LOG_PID, LOG_LOCAL0); memset (&options, 0, sizeof (options_t)); options.script = (char *) DEFAULT_SCRIPT; snprintf (options.classid, CLASS_ID_MAX_LEN, "%s %s", PACKAGE, VERSION); options.doarp = false; options.dodns = true; options.domtu = true; options.donis = true; options.dontp = true; options.dogateway = true; options.daemonise = true; options.timeout = DEFAULT_TIMEOUT; while ((ch = getopt_long(argc, argv, "ac:dh:i:kl:m:nps:t:u:F:GHI:MNRY", longopts, &option_index)) != -1) switch (ch) { case 0: if (longopts[option_index].flag) break; logger (LOG_ERR, "option `%s' should set a flag", longopts[option_index].name); exit (EXIT_FAILURE); break; case 'a': options.doarp = true; break; case 'c': options.script = optarg; break; case 'd': debug++; switch (debug) { case 1: setloglevel (LOG_DEBUG); break; case 2: options.daemonise = false; break; } break; case 'h': if (strlen (optarg) > sizeof (options.hostname)) { logger (LOG_ERR, "`%s' too long for HostName string, max is %d", optarg, sizeof (options.hostname)); exit (EXIT_FAILURE); } else strlcpy (options.hostname, optarg, sizeof (options.hostname)); break; case 'i': if (strlen (optarg) > CLASS_ID_MAX_LEN) { logger (LOG_ERR, "`%s' too long for ClassID string, max is %d", optarg, CLASS_ID_MAX_LEN); exit (EXIT_FAILURE); } else strlcpy (options.classid, optarg, sizeof (options.classid)); break; case 'k': options.signal = SIGHUP; break; case 'l': STRINGINT (optarg, options.leasetime); if (options.leasetime <= 0) { logger (LOG_ERR, "leasetime must be a positive value"); exit (EXIT_FAILURE); } break; case 'm': STRINGINT (optarg, options.metric); break; case 'n': options.signal = SIGALRM; break; case 'p': options.persistent = true; break; case 's': if (! inet_aton (optarg, &options.requestaddress)) { logger (LOG_ERR, "`%s' is not a valid IP address", optarg); exit (EXIT_FAILURE); } break; case 't': STRINGINT (optarg, options.timeout); if (options.timeout < 0) { logger (LOG_ERR, "timeout must be a positive value"); exit (EXIT_FAILURE); } break; case 'u': { int offset = 0; for (i = 0; i < userclasses; i++) offset += (int) options.userclass[offset] + 1; if (offset + 1 + strlen (optarg) > USERCLASS_MAX_LEN) { logger (LOG_ERR, "userclass overrun, max is %d", USERCLASS_MAX_LEN); exit (EXIT_FAILURE); } userclasses++; memcpy (options.userclass + offset + 1 , optarg, strlen (optarg)); options.userclass[offset] = strlen (optarg); options.userclass_len += (strlen (optarg)) + 1; } break; case 'F': if (strncmp (optarg, "none", strlen (optarg)) == 0) options.fqdn = FQDN_NONE; else if (strncmp (optarg, "ptr", strlen (optarg)) == 0) options.fqdn = FQDN_PTR; else if (strncmp (optarg, "both", strlen (optarg)) == 0) options.fqdn = FQDN_BOTH; else { logger (LOG_ERR, "invalid value `%s' for FQDN", optarg); exit (EXIT_FAILURE); } break; case 'G': options.dogateway = false; break; case 'H': options.dohostname = true; break; case 'I': if (strlen (optarg) > CLIENT_ID_MAX_LEN) { logger (LOG_ERR, "`%s' is too long for ClientID, max is %d", optarg, CLIENT_ID_MAX_LEN); exit (EXIT_FAILURE); } else strlcpy (options.clientid, optarg, sizeof (options.clientid)); break; case 'M': options.domtu = false; break; case 'N': options.dontp = false; break; case 'R': options.dodns = false; break; case 'Y': options.donis = false; break; case '?': usage (); exit (EXIT_FAILURE); default: usage (); exit (EXIT_FAILURE); } if (doversion) printf (""PACKAGE" "VERSION"\n"); if (dohelp) usage (); if (optind < argc) { if (strlen (argv[optind]) > IF_NAMESIZE) { logger (LOG_ERR, "`%s' is too long for an interface name (max=%d)", argv[optind], IF_NAMESIZE); exit (EXIT_FAILURE); } strlcpy (options.interface, argv[optind], sizeof (options.interface)); } else { /* If only version was requested then exit now */ if (doversion || dohelp) exit (EXIT_SUCCESS); logger (LOG_ERR, "no interface specified"); exit (EXIT_FAILURE); } /* If we are given a hostname use it and set FQDN if it contains a . */ if (! options.hostname[0]) { gethostname (options.hostname, sizeof (options.hostname)); if (strcmp (options.hostname, "(none)") == 0 || strcmp (options.hostname, "localhost") == 0) memset (options.hostname, 0, sizeof (options.hostname)); } if (strchr (options.hostname, '.')) { if (options.fqdn == FQDN_DISABLE) options.fqdn = FQDN_BOTH; } else options.fqdn = FQDN_DISABLE; if (geteuid ()) { logger (LOG_ERR, "you need to be root to run "PACKAGE); exit (EXIT_FAILURE); } snprintf (prefix, IF_NAMESIZE, "%s: ", options.interface); setlogprefix (prefix); snprintf (options.pidfile, sizeof (options.pidfile), PIDFILE, options.interface); if (options.signal != 0) { int killed = -1; pid = read_pid (options.pidfile); if (pid != 0) logger (LOG_INFO, "sending signal %d to pid %d", options.signal, pid); if (! pid || (killed = kill (pid, options.signal))) logger (options.signal == SIGALRM ? LOG_INFO : LOG_ERR, ""PACKAGE" not running"); if (pid != 0 && (options.signal != SIGALRM || killed != 0)) unlink (options.pidfile); if (killed == 0) exit (EXIT_SUCCESS); if (options.signal != SIGALRM) exit (EXIT_FAILURE); } chdir ("/"); umask (022); if (mkdir (CONFIGDIR, S_IRUSR |S_IWUSR |S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) && errno != EEXIST ) { logger (LOG_ERR, "mkdir(\"%s\",0): %s\n", CONFIGDIR, strerror (errno)); exit (EXIT_FAILURE); } if (mkdir (ETCDIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) && errno != EEXIST ) { logger (LOG_ERR, "mkdir(\"%s\",0): %s\n", ETCDIR, strerror (errno)); exit (EXIT_FAILURE); } if ((pid = read_pid (options.pidfile)) > 0 && kill (pid, 0) == 0) { logger (LOG_ERR, ""PACKAGE" already running (%s)", options.pidfile); exit (EXIT_FAILURE); } make_pid (options.pidfile); logger (LOG_INFO, PACKAGE " " VERSION " starting"); if (dhcp_run (&options)) { unlink (options.pidfile); exit (EXIT_FAILURE); } exit (EXIT_SUCCESS); }