/* MAIN - Dyn DNS update entry point.*/ int inadyn_main(int argc, char* argv[]) { int restart = 0; BOOL os_handler_installed = FALSE; RC_TYPE rc = RC_OK; DYN_DNS_CLIENT *p_dyndns = NULL; do { /* create DYN_DNS_CLIENT object */ rc = dyn_dns_construct(&p_dyndns); if (rc != RC_OK) { break; } /* install signal handler */ if (!os_handler_installed) { rc = os_install_signal_handler(p_dyndns); if (rc != RC_OK) { logit(LOG_WARNING, MODULE_TAG "Failed installing OS signal handler: %s", errorcode_get_name(rc)); break; } os_handler_installed = TRUE; } rc = dyn_dns_main(p_dyndns, argc, argv); if (rc == RC_RESTART) { restart = 1; /* do some cleanup if restart requested */ rc = dyn_dns_destruct(p_dyndns); if (rc != RC_OK) { logit(LOG_WARNING, MODULE_TAG "Failed cleaning up before restart: %s, ignoring...", errorcode_get_name(rc)); } } else { /* Error, or OK. In either case exit outer loop. */ restart = 0; } } while (restart); if (rc != RC_OK) { logit(LOG_WARNING, MODULE_TAG "Failed %sstarting daemon: %s", restart ? "re" : "", errorcode_get_name(rc)); } /* Cleanup */ dyn_dns_destruct(p_dyndns); os_close_dbg_output(); return (int)rc; }
int main(int argc, char *argv[]) { int restart = 0; int os_handler_installed = 0; int rc = 0; ddns_t *ctx = NULL; do { rc = init_context(&ctx); if (rc != 0) break; if (!os_handler_installed) { rc = os_install_signal_handler(ctx); if (rc != 0) { logit(LOG_WARNING, "Failed installing OS signal handler: %s", errorcode_get_name(rc)); break; } os_handler_installed = 1; } rc = dyn_dns_main(ctx, argc, argv); if (rc == RC_RESTART) { restart = 1; /* do some cleanup if restart requested */ rc = free_context(ctx); if (rc != 0) logit(LOG_WARNING, "Failed cleaning up before restart: %s, ignoring...", errorcode_get_name(rc)); } else { /* Error, or OK. In either case exit outer loop. */ restart = 0; } } while (restart); if (rc != 0) logit(LOG_WARNING, "Failed %sstarting daemon: %s", restart ? "re" : "", errorcode_get_name(rc)); /* Cleanup */ free_context(ctx); os_close_dbg_output(); return (int)rc; }
/** * Install signal handler for signals HUP, INT, TERM and USR1 * * Also block exactly the handled signals, only for the duration * of the handler. All other signals are left alone. */ int os_install_signal_handler(void *ctx) { int rc = 0; static int installed = 0; struct sigaction sa; if (!installed) { sa.sa_flags = 0; sa.sa_handler = unix_signal_handler; rc = sigemptyset(&sa.sa_mask) || sigaddset(&sa.sa_mask, SIGHUP) || sigaddset(&sa.sa_mask, SIGINT) || sigaddset(&sa.sa_mask, SIGTERM) || sigaddset(&sa.sa_mask, SIGUSR1) || sigaddset(&sa.sa_mask, SIGUSR2) || sigaction(SIGHUP, &sa, NULL) || sigaction(SIGINT, &sa, NULL) || sigaction(SIGUSR1, &sa, NULL) || sigaction(SIGUSR2, &sa, NULL) || sigaction(SIGTERM, &sa, NULL); installed = 1; } if (rc) { logit(LOG_WARNING, "Failed installing signal handler: %s", errorcode_get_name(rc)); return RC_OS_INSTALL_SIGHANDLER_FAILED; } param = ctx; return 0; }
/* the real action: - increment the forced update times counter - detect current IP - connect to an HTTP server - parse the response for IP addr - for all the names that have to be maintained - get the current DYN DNS address from DYN DNS server - compare and update if neccessary */ RC_TYPE dyn_dns_update_ip(DYN_DNS_CLIENT *p_self) { RC_TYPE rc; if (p_self == NULL) { return RC_INVALID_POINTER; } do { /*ask IP server something so he will respond and give me my IP */ rc = do_ip_server_transaction(p_self); if (rc != RC_OK) { DBG_PRINTF((LOG_WARNING,"W: DYNDNS: Error '%s' (0x%x) when talking to IP server\n", errorcode_get_name(rc), rc)); break; } if (p_self->dbg.level > 1) { DBG_PRINTF((LOG_DEBUG,"DYNDNS: IP server response: %s\n", p_self->p_work_buffer)); } /*extract my IP, check if different than previous one*/ rc = do_parse_my_ip_address(p_self); if (rc != RC_OK) { break; } if (p_self->dbg.level > 1) { DBG_PRINTF((LOG_WARNING,"W: DYNDNS: My IP address: %s\n", p_self->info.my_ip_address.name)); } /*step through aliases list, resolve them and check if they point to my IP*/ rc = do_check_alias_update_table(p_self); if (rc != RC_OK) { break; } /*update IPs marked as not identical with my IP*/ rc = do_update_alias_table(p_self); if (rc != RC_OK) { break; } } while(0); return rc; }
/* MAIN - Dyn DNS update entry point.*/ int inadyn_main(int argc, char* argv[]) { RC_TYPE rc = RC_OK; DYN_DNS_CLIENT *p_dyndns = NULL; do { /* create DYN_DNS_CLIENT object */ rc = dyn_dns_construct(&p_dyndns); if (rc != RC_OK) { break; } rc = dyn_dns_main(p_dyndns, argc, argv); } while(0); /* end of program */ if (rc != 0) { print_help_page(); /* log error*/ DBG_PRINTF((LOG_WARNING,"W:" MODULE_TAG "Main: Error '%s' (0x%x).\n", errorcode_get_name(rc), rc)); } /* destroy DYN_DNS_CLIENT object*/ rc = dyn_dns_destruct(p_dyndns); if (rc != RC_OK) { DBG_PRINTF((LOG_WARNING,"W:" MODULE_TAG "Main: Error '%s' (0x%x) in dyn_dns_destruct().\n", errorcode_get_name(rc), rc)); } os_close_dbg_output(); return (int) rc; }
/* the real action: - increment the forced update times counter - detect current IP - connect to an HTTP server - parse the response for IP addr - for all the names that have to be maintained - get the current DYN DNS address from DYN DNS server - compare and update if neccessary */ RC_TYPE dyn_dns_update_ip(DYN_DNS_CLIENT *p_self) { RC_TYPE rc = RC_OK; if (p_self == NULL) { return RC_INVALID_POINTER; } do { if (nvram_match("ddns_wan_ip","1")) { char new_ip_str[32]; int wan_link = check_wan_link(0); char *wan_ipaddr = NULL; if (nvram_match("wan_proto", "pptp")) { wan_ipaddr = wan_link ? nvram_safe_get("pptp_get_ip") : nvram_safe_get("wan_ipaddr"); } else if (!strcmp(nvram_safe_get("wan_proto"), "pppoe")) { wan_ipaddr = wan_link ? nvram_safe_get("wan_ipaddr") : "0.0.0.0"; } else if (!strcmp(nvram_safe_get("wan_proto"), "3g")) { wan_ipaddr = wan_link ? nvram_safe_get("wan_ipaddr") : "0.0.0.0"; } else if (nvram_match("wan_proto", "l2tp")) { wan_ipaddr = wan_link ? nvram_safe_get("l2tp_get_ip") : nvram_safe_get("wan_ipaddr"); } else if (nvram_match("wan_proto", "disabled")) { wan_ipaddr = "0.0.0.0"; } else { wan_ipaddr = nvram_safe_get("wan_ipaddr"); } if (!strcmp(wan_ipaddr,"0.0.0.0")) { DBG_PRINTF((LOG_WARNING,"W: DYNDNS: Error: device has no WAN Address\n")); rc = RC_ERROR; break; } strcpy(new_ip_str,wan_ipaddr); p_self->info.my_ip_has_changed = (strcmp(new_ip_str, p_self->info.my_ip_address.name) != 0); strcpy(p_self->info.my_ip_address.name, new_ip_str); rc = RC_OK; }else{ /*ask IP server something so he will respond and give me my IP */ rc = do_ip_server_transaction(p_self); if (rc != RC_OK) { DBG_PRINTF((LOG_WARNING,"W: DYNDNS: Error '%s' (0x%x) when talking to IP server\n", errorcode_get_name(rc), rc)); break; } if (p_self->dbg.level > 1) { DBG_PRINTF((LOG_DEBUG,"DYNDNS: IP server response: %s\n", p_self->p_work_buffer)); } /*extract my IP, check if different than previous one*/ rc = do_parse_my_ip_address(p_self); if (rc != RC_OK) { break; } } if (p_self->dbg.level > 1) { DBG_PRINTF((LOG_WARNING,"W: DYNDNS: My IP address: %s\n", p_self->info.my_ip_address.name)); } /*step through aliases list, resolve them and check if they point to my IP*/ rc = do_check_alias_update_table(p_self); if (rc != RC_OK) { break; } /*update IPs marked as not identical with my IP*/ rc = do_update_alias_table(p_self); if (rc != RC_OK) { break; } } while(0); return rc; }
/* Actions: - read the configuration options - perform various init actions as specified in the options - create and init dyn_dns object. - launch the IP update action loop */ int dyn_dns_main(DYN_DNS_CLIENT *p_dyndns, int argc, char* argv[]) { RC_TYPE rc = RC_OK; int iterations = 0; BOOL quit_flag = FALSE; BOOL init_flag; BOOL os_handler_installed = FALSE; FILE *fp; if (p_dyndns == NULL) { return RC_INVALID_POINTER; } /* read cmd line options and set object properties*/ rc = get_config_data(p_dyndns, argc, argv); if (rc != RC_OK || p_dyndns->abort) { return rc; } /*if logfile provided, redirect output to log file*/ if (strlen(p_dyndns->dbg.p_logfilename) != 0) { rc = os_open_dbg_output(DBG_FILE_LOG, "", p_dyndns->dbg.p_logfilename); if (rc != RC_OK) { return rc; } } if (p_dyndns->debug_to_syslog == TRUE || (p_dyndns->run_in_background == TRUE)) { if (get_dbg_dest() == DBG_STD_LOG) /*avoid file and syslog output */ { rc = os_open_dbg_output(DBG_SYS_LOG, "INADYN", NULL); if (rc != RC_OK) { return rc; } } } if (p_dyndns->change_persona) { OS_USER_INFO os_usr_info; memset(&os_usr_info, 0, sizeof(os_usr_info)); os_usr_info.gid = p_dyndns->sys_usr_info.gid; os_usr_info.uid = p_dyndns->sys_usr_info.uid; rc = os_change_persona(&os_usr_info); if (rc != RC_OK) { return rc; } } /*if silent required, close console window*/ if (p_dyndns->run_in_background == TRUE) { rc = close_console_window(); if (rc != RC_OK) { return rc; } if (get_dbg_dest() == DBG_SYS_LOG) { fclose(stdout); } } dyn_dns_print_hello(NULL); if ((fp=fopen(p_dyndns->ip_cache, "r"))) { fgets (p_dyndns->info.my_ip_address.name, sizeof (p_dyndns->info.my_ip_address.name),fp); fclose(fp); DBG_PRINTF((LOG_INFO, MODULE_TAG "IP read from cache file is '%s'. No update required.\n", p_dyndns->info.my_ip_address.name)); } /* the real work here */ do { /* init object */ init_flag = FALSE; rc = dyn_dns_init(p_dyndns); if (rc != RC_OK) { break; } init_flag = TRUE; rc = get_encoded_user_passwd(p_dyndns); if (rc != RC_OK) { break; } if (!os_handler_installed) { rc = os_install_signal_handler(p_dyndns); if (rc != RC_OK) { DBG_PRINTF((LOG_WARNING,"DYNDNS: Error '%s' (0x%x) installing OS signal handler\n", errorcode_get_name(rc), rc)); break; } os_handler_installed = TRUE; } /*update IP address in a loop*/ while(1) { rc = dyn_dns_update_ip(p_dyndns); if (rc != RC_OK) { DBG_PRINTF((LOG_WARNING,"W:'%s' (0x%x) updating the IPs. (it %d)\n", errorcode_get_name(rc), rc, iterations)); } /* check if the user wants us to stop */ ++iterations; if (iterations >= p_dyndns->total_iterations && p_dyndns->total_iterations != 0) { break; } p_dyndns->sleep_sec = rc == RC_DYNDNS_RSP_RETRY_LATER ? DYNDNS_ERROR_UPDATE_PERIOD : DYNDNS_DEFAULT_SLEEP; /* also sleep the time set in the ->sleep_sec data memeber*/ dyn_dns_wait_for_cmd(p_dyndns); if (p_dyndns->cmd == CMD_STOP) { DBG_PRINTF((LOG_DEBUG,"STOP command received. Exiting.\n")); rc = RC_OK; break; } if (rc == RC_OK) { if (p_dyndns->dbg.level > 0) { DBG_PRINTF((LOG_DEBUG,".")); } p_dyndns->times_since_last_update ++; } else { dyn_dns_shutdown(p_dyndns); init_flag = FALSE; break; } } /*if everything ok here we should exit. End of program*/ if (rc == RC_OK) { break; } } while(quit_flag == FALSE); if (init_flag == TRUE) { /* dyn_dns_shutdown object */ rc = dyn_dns_shutdown(p_dyndns); } return rc; }
/** MAIN - Dyn DNS update entry point Actions: - read the configuration options - perform various init actions as specified in the options - create and init dyn_dns object. - launch the IP update action loop */ int dyn_dns_main(DYN_DNS_CLIENT *p_dyndns, int argc, char* argv[]) { RC_TYPE rc = RC_OK; int iterations = 0; BOOL os_handler_installed = FALSE; if (p_dyndns == NULL) { return RC_INVALID_POINTER; } /* read cmd line options and set object properties*/ rc = get_config_data(p_dyndns, argc, argv); if (rc != RC_OK || p_dyndns->abort) { return rc; } /*if logfile provided, redirect output to log file*/ if (strlen(p_dyndns->dbg.p_logfilename) != 0) { rc = os_open_dbg_output(DBG_FILE_LOG, "", p_dyndns->dbg.p_logfilename); if (rc != RC_OK) { return rc; } } if (p_dyndns->debug_to_syslog == TRUE || (p_dyndns->run_in_background == TRUE)) { if (get_dbg_dest() == DBG_STD_LOG) /*avoid file and syslog output */ { rc = os_open_dbg_output(DBG_SYS_LOG, "INADYN", NULL); if (rc != RC_OK) { return rc; } } } if (p_dyndns->change_persona) { OS_USER_INFO os_usr_info; memset(&os_usr_info, 0, sizeof(os_usr_info)); os_usr_info.gid = p_dyndns->sys_usr_info.gid; os_usr_info.uid = p_dyndns->sys_usr_info.uid; rc = os_change_persona(&os_usr_info); if (rc != RC_OK) { return rc; } } /*if silent required, close console window*/ if (p_dyndns->run_in_background == TRUE) { rc = close_console_window(); if (rc != RC_OK) { return rc; } if (get_dbg_dest() == DBG_SYS_LOG) { fclose(stdout); } } dyn_dns_print_hello(NULL); /* the real work here */ do { /* init object */ rc = dyn_dns_init(p_dyndns); if (rc != RC_OK) { break; } rc = get_encoded_user_passwd(p_dyndns); if (rc != RC_OK) { break; } if (!os_handler_installed) { rc = os_install_signal_handler(p_dyndns); if (rc != RC_OK) { DBG_PRINTF((LOG_WARNING,"DYNDNS: Error '%s' (0x%x) installing OS signal handler\n", errorcode_get_name(rc), rc)); break; } os_handler_installed = TRUE; } /*update IP address in a loop*/ while(1) { rc = dyn_dns_update_ip(p_dyndns); if (rc != RC_OK) { DBG_PRINTF((LOG_WARNING,"W:'%s' (0x%x) updating the IPs. (it %d)\n", errorcode_get_name(rc), rc, iterations)); if (rc == RC_DYNDNS_RSP_NOTOK) { DBG_PRINTF((LOG_ERR,"E: The response of DYNDNS svr was an error! Aborting.\n")); break; } } else /*count only the successful iterations */ { ++iterations; } /* check if the user wants us to stop */ if (iterations >= p_dyndns->total_iterations && p_dyndns->total_iterations != 0) { break; } /* also sleep the time set in the ->sleep_sec data memeber*/ dyn_dns_wait_for_cmd(p_dyndns); if (p_dyndns->cmd == CMD_STOP) { DBG_PRINTF((LOG_DEBUG,"STOP command received. Exiting.\n")); rc = RC_OK; break; } if (rc == RC_OK) { if (p_dyndns->dbg.level > 0) { DBG_PRINTF((LOG_DEBUG,".")); } p_dyndns->times_since_last_update ++; } } } while(FALSE); return rc; }