output_stdout_buffer_c::output_stdout_buffer_c(const unsigned int &color_param) : color(color_param) { dont_close_handle_ = true; handle_t handle = GetStdHandle(STD_OUTPUT_HANDLE); init_handle(handle); }
void extract_cpio_gz(int fd) { archive_handle_t *archive_handle; unsigned char magic[2]; /* Initialise */ archive_handle = init_handle(); archive_handle->seek = seek_by_char; //archive_handle->action_header = header_list; archive_handle->action_data = data_extract_all; archive_handle->flags |= ARCHIVE_PRESERVE_DATE; archive_handle->flags |= ARCHIVE_CREATE_LEADING_DIRS; archive_handle->src_fd = fd; archive_handle->offset = 0; bb_xread_all(archive_handle->src_fd, &magic, 2); if ((magic[0] != 0x1f) || (magic[1] != 0x8b)) { bb_error_msg_and_die("Invalid gzip magic"); } check_header_gzip(archive_handle->src_fd); bb_xchdir("/"); // Install RPM's to root archive_handle->src_fd = open_transformer(archive_handle->src_fd, inflate_gunzip); archive_handle->offset = 0; while (get_header_cpio(archive_handle) == EXIT_SUCCESS); }
static void extract_cpio(int fd, const char *source_rpm) { archive_handle_t *archive_handle; if (source_rpm != NULL) { /* Binary rpm (it was built from some SRPM), install to root */ xchdir("/"); } /* else: SRPM, install to current dir */ /* Initialize */ archive_handle = init_handle(); archive_handle->seek = seek_by_read; archive_handle->action_data = data_extract_all; #if 0 /* For testing (rpm -i only lists the files in internal cpio): */ archive_handle->action_header = header_list; archive_handle->action_data = data_skip; #endif archive_handle->ah_flags = ARCHIVE_RESTORE_DATE | ARCHIVE_CREATE_LEADING_DIRS /* compat: overwrite existing files. * try "rpm -i foo.src.rpm" few times in a row - * standard rpm will not complain. */ | ARCHIVE_REPLACE_VIA_RENAME; archive_handle->src_fd = fd; /*archive_handle->offset = 0; - init_handle() did it */ setup_unzip_on_fd(archive_handle->src_fd, /*fail_if_not_compressed:*/ 1); while (get_header_cpio(archive_handle) == EXIT_SUCCESS) continue; }
input_file_buffer_c::input_file_buffer_c(const std::string &file_name) { handle_t handle = CreateFile(file_name.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (handle == INVALID_HANDLE_VALUE) { PANIC(get_win_last_error_string()); } init_handle(handle); }
output_file_buffer_c::output_file_buffer_c(const std::string &file_name) { handle_t handle = CreateFile(file_name.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (handle == INVALID_HANDLE_VALUE) { PANIC(get_win_last_error_string()); } init_handle(handle); }
int cpio_main(int argc, char **argv) { archive_handle_t *archive_handle; char *cpio_filename = NULL; unsigned opt; /* Initialise */ archive_handle = init_handle(); archive_handle->src_fd = STDIN_FILENO; archive_handle->seek = seek_by_read; archive_handle->flags = ARCHIVE_EXTRACT_NEWER | ARCHIVE_PRESERVE_DATE; opt = getopt32(argc, argv, "ituvF:dm", &cpio_filename); /* One of either extract or test options must be given */ if ((opt & (CPIO_OPT_TEST | CPIO_OPT_EXTRACT)) == 0) { bb_show_usage(); } if (opt & CPIO_OPT_TEST) { /* if both extract and test options are given, ignore extract option */ if (opt & CPIO_OPT_EXTRACT) { opt &= ~CPIO_OPT_EXTRACT; } archive_handle->action_header = header_list; } if (opt & CPIO_OPT_EXTRACT) { archive_handle->action_data = data_extract_all; } if (opt & CPIO_OPT_UNCONDITIONAL) { archive_handle->flags |= ARCHIVE_EXTRACT_UNCONDITIONAL; archive_handle->flags &= ~ARCHIVE_EXTRACT_NEWER; } if (opt & CPIO_OPT_VERBOSE) { if (archive_handle->action_header == header_list) { archive_handle->action_header = header_verbose_list; } else { archive_handle->action_header = header_list; } } if (cpio_filename) { /* CPIO_OPT_FILE */ archive_handle->src_fd = xopen(cpio_filename, O_RDONLY); archive_handle->seek = seek_by_jump; } if (opt & CPIO_OPT_CREATE_LEADING_DIR) { archive_handle->flags |= ARCHIVE_CREATE_LEADING_DIRS; } while (optind < argc) { archive_handle->filter = filter_accept_list; llist_add_to(&(archive_handle->accept), argv[optind]); optind++; } while (get_header_cpio(archive_handle) == EXIT_SUCCESS); return EXIT_SUCCESS; }
int ar_main(int argc UNUSED_PARAM, char **argv) { archive_handle_t *archive_handle; unsigned opt, t; archive_handle = init_handle(); /* --: prepend '-' to the first argument if required */ /* -1: at least one param is reqd */ /* one of p,t,x[,r] is required */ opt_complementary = "--:-1:p:t:x"IF_FEATURE_AR_CREATE(":r"); opt = getopt32(argv, "voc""ptx"IF_FEATURE_AR_CREATE("r")); argv += optind; t = opt / FIRST_CMD; if (t & (t-1)) /* more than one of p,t,x[,r] are specified */ bb_show_usage(); if (opt & AR_CMD_PRINT) { archive_handle->action_data = data_extract_to_stdout; } if (opt & AR_CMD_LIST) { archive_handle->action_header = header_list; } if (opt & AR_CMD_EXTRACT) { archive_handle->action_data = data_extract_all; } if (opt & AR_OPT_PRESERVE_DATE) { archive_handle->ah_flags |= ARCHIVE_RESTORE_DATE; } if (opt & AR_OPT_VERBOSE) { archive_handle->action_header = header_verbose_list_ar; } #if ENABLE_FEATURE_AR_CREATE archive_handle->ar__name = *argv; #endif archive_handle->src_fd = xopen(*argv++, (opt & AR_CMD_INSERT) ? O_RDWR | O_CREAT : O_RDONLY ); if (*argv) archive_handle->filter = filter_accept_list; while (*argv) { llist_add_to_end(&archive_handle->accept, *argv++); } #if ENABLE_FEATURE_AR_CREATE if (opt & AR_CMD_INSERT) return write_ar_archive(archive_handle); #endif unpack_ar_archive(archive_handle); return EXIT_SUCCESS; }
static int write_ar_archive(archive_handle_t *handle) { struct stat st; archive_handle_t *out_handle; char *temp_fn = NULL; xfstat(handle->src_fd, &st, handle->ar__name); /* if archive exists, create a new handle for output. * we create it in place of the old one. */ if (st.st_size != 0) { out_handle = init_handle(); #if !ENABLE_PLATFORM_MINGW32 xunlink(handle->ar__name); out_handle->src_fd = xopen(handle->ar__name, O_WRONLY | O_CREAT | O_TRUNC); #else /* can't unlink open file, create temporary output file */ temp_fn = xasprintf("%sXXXXXX", handle->ar__name); out_handle->src_fd = xmkstemp(temp_fn); #endif out_handle->accept = handle->accept; } else { out_handle = handle; } handle->ar__out = out_handle; xwrite(out_handle->src_fd, AR_MAGIC "\n", AR_MAGIC_LEN + 1); out_handle->offset += AR_MAGIC_LEN + 1; /* skip to the end of the archive if we have to append stuff */ if (st.st_size != 0) { handle->filter = filter_replaceable; handle->action_data = copy_data; unpack_ar_archive(handle); } while (write_ar_header(out_handle) == 0) continue; /* optional, since we exit right after we return */ if (ENABLE_FEATURE_CLEAN_UP || ENABLE_PLATFORM_MINGW32) { close(handle->src_fd); if (out_handle->src_fd != handle->src_fd) close(out_handle->src_fd); } #if ENABLE_PLATFORM_MINGW32 if ( temp_fn != NULL ) { xrename(temp_fn, handle->ar__name); free(temp_fn); } #endif return EXIT_SUCCESS; }
int ar_main(int argc, char **argv) { static const char msg_unsupported_err[] ALIGN1 = "archive %s is not supported"; archive_handle_t *archive_handle; unsigned opt; char magic[8]; archive_handle = init_handle(); /* Prepend '-' to the first argument if required */ opt_complementary = "--:p:t:x:-1:p--tx:t--px:x--pt"; opt = getopt32(argv, "ptxovcr"); if (opt & AR_CTX_PRINT) { archive_handle->action_data = data_extract_to_stdout; } if (opt & AR_CTX_LIST) { archive_handle->action_header = header_list; } if (opt & AR_CTX_EXTRACT) { archive_handle->action_data = data_extract_all; } if (opt & AR_OPT_PRESERVE_DATE) { archive_handle->flags |= ARCHIVE_PRESERVE_DATE; } if (opt & AR_OPT_VERBOSE) { archive_handle->action_header = header_verbose_list_ar; } if (opt & AR_OPT_CREATE) { bb_error_msg_and_die(msg_unsupported_err, "creation"); } if (opt & AR_OPT_INSERT) { bb_error_msg_and_die(msg_unsupported_err, "insertion"); } archive_handle->src_fd = xopen(argv[optind++], O_RDONLY); while (optind < argc) { archive_handle->filter = filter_accept_list; llist_add_to(&(archive_handle->accept), argv[optind++]); } xread(archive_handle->src_fd, magic, 7); if (strncmp(magic, "!<arch>", 7) != 0) { bb_error_msg_and_die("invalid ar magic"); } archive_handle->offset += 7; while (get_header_ar(archive_handle) == EXIT_SUCCESS) continue; return EXIT_SUCCESS; }
char *utils_get_mac_addr(char *interface) { int buflen = 20; char *buf = NULL; struct nl_handle *nlh = NULL; struct nl_cache *cache = NULL; struct rtnl_link *link = NULL; struct nl_addr *addr = NULL; if (zstr(interface)) { return NULL; } if (init_handle(&nlh) != 0) { return NULL; } if ((cache = rtnl_link_alloc_cache(nlh)) == NULL) { return NULL; } if ((link = rtnl_link_get_by_name(cache, interface)) == NULL) { goto mac2str_error2; } if ((addr = rtnl_link_get_addr(link)) == NULL) { goto mac2str_error3; } if ((buf = calloc(sizeof(char *), buflen)) == NULL) { goto mac2str_error4; } buf = nl_addr2str(addr, buf, buflen); mac2str_error4: nl_addr_destroy(addr); mac2str_error3: rtnl_link_put(link); mac2str_error2: nl_close(nlh); nl_handle_destroy(nlh); return buf; }
static int write_ar_archive(archive_handle_t *handle) { struct stat st; archive_handle_t *out_handle; if (fstat(handle->src_fd, &st) == -1) bb_simple_perror_msg_and_die(handle->ar__name); /* if archive exists, create a new handle for output. * we create it in place of the old one. */ if (st.st_size != 0) { out_handle = init_handle(); xunlink(handle->ar__name); out_handle->src_fd = xopen(handle->ar__name, O_WRONLY | O_CREAT | O_TRUNC); out_handle->accept = handle->accept; } else { out_handle = handle; } handle->ar__out = out_handle; xwrite(out_handle->src_fd, AR_MAGIC "\n", AR_MAGIC_LEN + 1); out_handle->offset += AR_MAGIC_LEN + 1; /* skip to the end of the archive if we have to append stuff */ if (st.st_size != 0) { handle->filter = filter_replaceable; handle->action_data = copy_data; unpack_ar_archive(handle); } while (write_ar_header(out_handle) == 0) continue; /* optional, since we exit right after we return */ if (ENABLE_FEATURE_CLEAN_UP) { close(handle->src_fd); if (out_handle->src_fd != handle->src_fd) close(out_handle->src_fd); } return EXIT_SUCCESS; }
void IMB_processor_apply_threaded(int buffer_lines, int handle_size, void *init_customdata, void (init_handle) (void *handle, int start_line, int tot_line, void *customdata), void *(do_thread) (void *)) { const int lines_per_task = 64; TaskScheduler *task_scheduler = BLI_task_scheduler_get(); TaskPool *task_pool; void *handles; int total_tasks = (buffer_lines + lines_per_task - 1) / lines_per_task; int i, start_line; task_pool = BLI_task_pool_create(task_scheduler, do_thread); handles = MEM_callocN(handle_size * total_tasks, "processor apply threaded handles"); start_line = 0; for (i = 0; i < total_tasks; i++) { int lines_per_current_task; void *handle = ((char *) handles) + handle_size * i; if (i < total_tasks - 1) lines_per_current_task = lines_per_task; else lines_per_current_task = buffer_lines - start_line; init_handle(handle, start_line, lines_per_current_task, init_customdata); BLI_task_pool_push(task_pool, processor_apply_func, handle, false, TASK_PRIORITY_LOW); start_line += lines_per_task; } /* work and wait until tasks are done */ BLI_task_pool_work_and_wait(task_pool); /* Free memory. */ MEM_freeN(handles); BLI_task_pool_free(task_pool); }
/* This function should not be called more than once */ unsigned int init(void) { char **xlines, **clines; char *conftok = (char*)callocm(CONF_MAX_ITEMLEN, sizeof(char)); unsigned int i = 0, xcount = 0, ccount = 0, acount = 0; /* Don't get this confused with the word "account" */ extern q_maxbytes, q_maxqueue; /* For making sure when these variables are tested, they are set to NULL first. */ init_handle(&q_first); init_handle(&q_last); init_handle(&event_first); init_handle(&event_last); init_handle(&chan_first); init_handle(&chan_last); init_handle(&user_first); init_handle(&user_last); init_handle(&me); init_handle(&bc_first); init_handle(&bc_last); init_handle(&dcc_first); init_handle(&dcc_last); eventloop_running = 0; bot.cid = 0; bot.connected = 0; xstrcpy(bot.config, XION_CONFIG, 260); bot.admin_current_count = 0; bot.current_try = 1; q_first = NULL; /*X:Line*/ xcount = get_confitem(&xlines, 'X'); if(!xcount) { make_error("No X:lines in configuration file."); freem(conftok); return 0; } /*nickname*/ xstrcpy(bot.nick, get_itemtok(conftok, xlines[0], 2), 32); /*altnick*/ xstrcpy(bot.altnick, get_itemtok(conftok, xlines[0], 3), 32); /*username*/ xstrcpy(bot.username, get_itemtok(conftok, xlines[0], 4), 12); /*fullname*/ xstrcpy(bot.info, get_itemtok(conftok, xlines[0], 5), 256); xstrcpy(bot.info, conf_replace_alias(conftok), 256); /*C:Line*/ ccount = get_confitem(&clines, 'C'); if(!ccount) { make_error("No C:lines in configuration file."); freem(conftok); free_2d_array(xlines, xcount); return 0; } /*servaddr*/ xstrcpy(bot.servaddr, get_itemtok(conftok, clines[0], 2), 256); /*servport*/ bot.servport = atoi(get_itemtok(conftok, clines[0], 3)); /*servpass*/ xstrcpy(bot.servpass, get_itemtok(conftok, clines[0], 4), 256); /*S:Lines*/ /*maxretry*/ irc_subconftok(conftok, 'S', "maxretry", 3); bot.maxretry = atoi(conftok); /*pingtimeout*/ irc_subconftok(conftok, 'S', "pingtimeout", 3); bot.ping_timeout = atoi(conftok); /*freshlog*/ irc_subconftok(conftok, 'S', "freshlog", 3); bot.fresh_log = (atoi(conftok) ? 1 : 0); /*antiflood*/ irc_subconftok(conftok, 'S', "antiflood", 5); bot.floodcheck = (atoi(conftok) ? 1 : 0); irc_subconftok(conftok, 'S', "antiflood", 3); q_maxbytes = (unsigned int)atoi(conftok); irc_subconftok(conftok, 'S', "antiflood", 4); q_maxqueue = (unsigned int)atoi(conftok); /*ctrigger*/ irc_subconftok(conftok, 'S', "ctrigger", 3); conf_replace_alias(conftok); bot.ctrigger = conftok[0]; /*ptrigger*/ irc_subconftok(conftok, 'S', "ptrigger", 3); conf_replace_alias(conftok); bot.ptrigger = conftok[0]; /*A:Lines*/ if(bot.admin_array != NULL) free_2d_array(bot.admin_array, bot.admin_lines); acount = get_confitem(&bot.admin_array, 'A'); bot.admin_lines = acount; if(acount) { for(i = 0;i < bot.admin_lines;i++) { get_itemtok(conftok, bot.admin_array[i], 3); if((istrcmp(conftok, ";")) || (istrcmp(conftok, "*"))) adm_loginuser(get_itemtok(conftok, bot.admin_array[i], 2), get_itemtok(conftok, bot.admin_array[i], 4), atoi(get_itemtok(conftok, bot.admin_array[i], 5))); } } /* URL Module: mod-weburlcache.c */ urlmod_init(); freem(conftok); free_2d_array(xlines, xcount); free_2d_array(clines, ccount); event_call(EVENT_INIT, 0); return 1; }
/** * shishi: * * Initializes the Shishi library, and primes logging so that future * warnings and informational messages are printed on %stderr. * If this function fails, it may send its own diagnostic errors * to %stderr. * * Return value: Returns a Shishi library handle, or %NULL on error. **/ Shishi * shishi (void) { return init_handle (SHISHI_OUTPUTTYPE_STDERR); }
/** * shishi_server: * * Initializes the Shishi library, and primes logging so that future * warnings and informational messages are sent to the syslog system. * If this function fails, it may print diagnostic errors in the syslog. * * Return value: Returns a Shishi library handle, or %NULL on error. **/ Shishi * shishi_server (void) { return init_handle (SHISHI_OUTPUTTYPE_SYSLOG); }
input_stdin_buffer_c::input_stdin_buffer_c() { dont_close_handle_ = true; handle_t handle = GetStdHandle(STD_INPUT_HANDLE); init_handle(handle); }
int dpkg_deb_main(int argc UNUSED_PARAM, char **argv) { archive_handle_t *ar_archive; archive_handle_t *tar_archive; llist_t *control_tar_llist = NULL; unsigned opt; const char *extract_dir; /* Setup the tar archive handle */ tar_archive = init_handle(); /* Setup an ar archive handle that refers to the gzip sub archive */ ar_archive = init_handle(); ar_archive->dpkg__sub_archive = tar_archive; ar_archive->filter = filter_accept_list_reassign; llist_add_to(&ar_archive->accept, (char*)"data.tar"); llist_add_to(&control_tar_llist, (char*)"control.tar"); #if ENABLE_FEATURE_SEAMLESS_GZ llist_add_to(&ar_archive->accept, (char*)"data.tar.gz"); llist_add_to(&control_tar_llist, (char*)"control.tar.gz"); #endif #if ENABLE_FEATURE_SEAMLESS_BZ2 llist_add_to(&ar_archive->accept, (char*)"data.tar.bz2"); llist_add_to(&control_tar_llist, (char*)"control.tar.bz2"); #endif #if ENABLE_FEATURE_SEAMLESS_LZMA llist_add_to(&ar_archive->accept, (char*)"data.tar.lzma"); llist_add_to(&control_tar_llist, (char*)"control.tar.lzma"); #endif #if ENABLE_FEATURE_SEAMLESS_XZ llist_add_to(&ar_archive->accept, (char*)"data.tar.xz"); llist_add_to(&control_tar_llist, (char*)"control.tar.xz"); #endif /* Must have 1 or 2 args */ opt_complementary = "-1:?2:c--efXx:e--cfXx:f--ceXx:X--cefx:x--cefX"; opt = getopt32(argv, "cefXx"); argv += optind; //argc -= optind; extract_dir = argv[1]; if (opt & DPKG_DEB_OPT_CONTENTS) { // -c tar_archive->action_header = header_verbose_list; if (extract_dir) bb_show_usage(); } if (opt & DPKG_DEB_OPT_FIELD) { // -f /* Print the entire control file */ //TODO: standard tool accepts an optional list of fields to print ar_archive->accept = control_tar_llist; llist_add_to(&(tar_archive->accept), (char*)"./control"); tar_archive->filter = filter_accept_list; tar_archive->action_data = data_extract_to_stdout; if (extract_dir) bb_show_usage(); } if (opt & DPKG_DEB_OPT_CONTROL) { // -e ar_archive->accept = control_tar_llist; tar_archive->action_data = data_extract_all; if (!extract_dir) extract_dir = "./DEBIAN"; } if (opt & (DPKG_DEB_OPT_EXTRACT_VERBOSE | DPKG_DEB_OPT_EXTRACT)) { // -Xx if (opt & DPKG_DEB_OPT_EXTRACT_VERBOSE) tar_archive->action_header = header_list; tar_archive->action_data = data_extract_all; if (!extract_dir) bb_show_usage(); } /* Standard tool supports "-" */ tar_archive->src_fd = ar_archive->src_fd = xopen_stdin(argv[0]); if (extract_dir) { mkdir(extract_dir, 0777); /* bb_make_directory(extract_dir, 0777, 0) */ xchdir(extract_dir); } /* Do it */ unpack_ar_archive(ar_archive); /* Cleanup */ if (ENABLE_FEATURE_CLEAN_UP) close(ar_archive->src_fd); return EXIT_SUCCESS; }
int ip_addr(char *ip4addr, char *interface, cmd_t cmd) { struct nl_handle *nlh = NULL; struct rtnl_addr *addr = NULL; struct nl_addr *nl_addr = NULL; uint32_t binaddr = 0; int iface_idx = -1; int err,ret = 0; if (init_handle(&nlh) != 0) { return -1; } iface_idx = if_nametoindex(interface); if (iface_idx < 0) { return -1; } addr = rtnl_addr_alloc (); if (!addr) { return -1; } if (inet_pton(AF_INET, ip4addr, &binaddr) == 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "not valid ip address\n"); ret = -1; goto out; } nl_addr = nl_addr_build (AF_INET, &binaddr, sizeof(binaddr)); if (!nl_addr) { ret = -1; goto out; } rtnl_addr_set_local (addr, nl_addr); nl_addr_put (nl_addr); rtnl_addr_set_ifindex (addr, iface_idx); switch (cmd) { case ADD_IP: err = rtnl_addr_add (nlh, addr, 0); if ( err == -17 ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s is already on %s interface\n", ip4addr, interface); ret = 0; } else if ( err < 0 ) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error %d returned from rtnl_addr_add():\n%s\n", err, nl_geterror()); ret = -1; } else { ret = 0; } break; case DEL_IP: err = rtnl_addr_delete (nlh, addr, 0); if (err == -99) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s is not present on %s interface\n", ip4addr, interface); ret = 0; } else if (err < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error %d returned from rtnl_addr_delete():\n%s\n", err, nl_geterror()); ret = -1; } else { ret = 0; } break; } out: if (addr) { rtnl_addr_put (addr); } if (nlh) { nl_close(nlh); nl_handle_destroy(nlh); } return ret; }
int dpkg_deb_main(int argc, char **argv) { archive_handle_t *ar_archive; archive_handle_t *tar_archive; llist_t *control_tar_llist = NULL; unsigned opt; const char *extract_dir; int need_args; /* Setup the tar archive handle */ tar_archive = init_handle(); /* Setup an ar archive handle that refers to the gzip sub archive */ ar_archive = init_handle(); ar_archive->dpkg__sub_archive = tar_archive; ar_archive->filter = filter_accept_list_reassign; llist_add_to(&ar_archive->accept, (char*)"data.tar"); llist_add_to(&control_tar_llist, (char*)"control.tar"); #if ENABLE_FEATURE_SEAMLESS_GZ llist_add_to(&ar_archive->accept, (char*)"data.tar.gz"); llist_add_to(&control_tar_llist, (char*)"control.tar.gz"); #endif #if ENABLE_FEATURE_SEAMLESS_BZ2 llist_add_to(&ar_archive->accept, (char*)"data.tar.bz2"); llist_add_to(&control_tar_llist, (char*)"control.tar.bz2"); #endif #if ENABLE_FEATURE_SEAMLESS_LZ llist_add_to(&ar_archive->accept, (char*)"data.tar.lz"); llist_add_to(&control_tar_llist, (char*)"control.tar.lz"); #endif #if ENABLE_FEATURE_SEAMLESS_LZMA llist_add_to(&ar_archive->accept, (char*)"data.tar.lzma"); llist_add_to(&control_tar_llist, (char*)"control.tar.lzma"); #endif #if ENABLE_FEATURE_SEAMLESS_XZ llist_add_to(&ar_archive->accept, (char*)"data.tar.xz"); llist_add_to(&control_tar_llist, (char*)"control.tar.xz"); #endif opt_complementary = "c--efXx:e--cfXx:f--ceXx:X--cefx:x--cefX"; opt = getopt32(argv, "cefXx"); argv += optind; argc -= optind; if (opt & DPKG_DEB_OPT_CONTENTS) { tar_archive->action_header = header_verbose_list; } extract_dir = NULL; need_args = 1; if (opt & DPKG_DEB_OPT_CONTROL) { ar_archive->accept = control_tar_llist; tar_archive->action_data = data_extract_all; if (1 == argc) { extract_dir = "./DEBIAN"; } else { need_args++; } } if (opt & DPKG_DEB_OPT_FIELD) { /* Print the entire control file * it should accept a second argument which specifies a * specific field to print */ ar_archive->accept = control_tar_llist; llist_add_to(&(tar_archive->accept), (char*)"./control"); tar_archive->filter = filter_accept_list; tar_archive->action_data = data_extract_to_stdout; } if (opt & DPKG_DEB_OPT_EXTRACT) { tar_archive->action_header = header_list; } if (opt & (DPKG_DEB_OPT_EXTRACT_VERBOSE | DPKG_DEB_OPT_EXTRACT)) { tar_archive->action_data = data_extract_all; need_args = 2; } if (need_args != argc) { bb_show_usage(); } tar_archive->src_fd = ar_archive->src_fd = xopen(argv[0], O_RDONLY); /* Work out where to extract the files */ /* 2nd argument is a dir name */ if (argv[1]) { extract_dir = argv[1]; } if (extract_dir) { mkdir(extract_dir, 0777); /* bb_make_directory(extract_dir, 0777, 0) */ xchdir(extract_dir); } /* Do it */ unpack_ar_archive(ar_archive); /* Cleanup */ if (ENABLE_FEATURE_CLEAN_UP) close(ar_archive->src_fd); return EXIT_SUCCESS; }
int tar_main(int argc, char **argv) { char (*get_header_ptr)(archive_handle_t *) = get_header_tar; archive_handle_t *tar_handle; char *base_dir = NULL; const char *tar_filename = "-"; unsigned long opt; unsigned long ctx_flag = 0; if (argc < 2) { bb_show_usage(); } /* Prepend '-' to the first argument if required */ if (argv[1][0] != '-') { char *tmp; bb_xasprintf(&tmp, "-%s", argv[1]); argv[1] = tmp; } /* Initialise default values */ tar_handle = init_handle(); tar_handle->flags = ARCHIVE_CREATE_LEADING_DIRS | ARCHIVE_PRESERVE_DATE | ARCHIVE_EXTRACT_UNCONDITIONAL; bb_opt_complementaly = "c~tx:t~cx:x~ct:X*:T*"; #ifdef CONFIG_FEATURE_TAR_LONG_OPTIONS bb_applet_long_options = tar_long_options; #endif opt = bb_getopt_ulflags(argc, argv, tar_options, &base_dir, /* Change to dir <optarg> */ &tar_filename /* archive filename */ #ifdef CONFIG_FEATURE_TAR_FROM , NULL, &(tar_handle->reject) #endif ); /* Check one and only one context option was given */ if(opt & 0x80000000UL) { bb_show_usage(); } #ifdef CONFIG_FEATURE_TAR_CREATE ctx_flag = opt & (CTX_CREATE | CTX_TEST | CTX_EXTRACT); #else ctx_flag = opt & (CTX_TEST | CTX_EXTRACT); #endif if (ctx_flag == 0) { bb_show_usage(); } if(ctx_flag & CTX_TEST) { if ((tar_handle->action_header == header_list) || (tar_handle->action_header == header_verbose_list)) { tar_handle->action_header = header_verbose_list; } else { tar_handle->action_header = header_list; } } if(ctx_flag & CTX_EXTRACT) { if (tar_handle->action_data != data_extract_to_stdout) tar_handle->action_data = data_extract_all; } if(opt & TAR_OPT_2STDOUT) { /* To stdout */ tar_handle->action_data = data_extract_to_stdout; } if(opt & TAR_OPT_VERBOSE) { if ((tar_handle->action_header == header_list) || (tar_handle->action_header == header_verbose_list)) { tar_handle->action_header = header_verbose_list; } else { tar_handle->action_header = header_list; } } if (opt & TAR_OPT_KEEP_OLD) { tar_handle->flags &= ~ARCHIVE_EXTRACT_UNCONDITIONAL; } #ifdef CONFIG_FEATURE_TAR_GZIP if(opt & TAR_OPT_GZIP) { get_header_ptr = get_header_tar_gz; } #endif #ifdef CONFIG_FEATURE_TAR_BZIP2 if(opt & TAR_OPT_BZIP2) { get_header_ptr = get_header_tar_bz2; } #endif #ifdef CONFIG_FEATURE_TAR_COMPRESS if(opt & TAR_OPT_UNCOMPRESS) { get_header_ptr = get_header_tar_Z; } #endif #ifdef CONFIG_FEATURE_TAR_FROM if(opt & TAR_OPT_EXCLUDE_FROM) { tar_handle->reject = append_file_list_to_list(tar_handle->reject); } #endif /* Check if we are reading from stdin */ if ((argv[optind]) && (*argv[optind] == '-')) { /* Default is to read from stdin, so just skip to next arg */ optind++; } /* Setup an array of filenames to work with */ /* TODO: This is the same as in ar, separate function ? */ while (optind < argc) { char *filename_ptr = last_char_is(argv[optind], '/'); if (filename_ptr) { *filename_ptr = '\0'; } tar_handle->accept = llist_add_to(tar_handle->accept, argv[optind]); optind++; } if ((tar_handle->accept) || (tar_handle->reject)) { tar_handle->filter = filter_accept_reject_list; } /* Open the tar file */ { FILE *tar_stream; int flags; #ifdef CONFIG_FEATURE_TAR_CREATE if (opt & CTX_CREATE) { /* Make sure there is at least one file to tar up. */ if (tar_handle->accept == NULL) { bb_error_msg_and_die("Cowardly refusing to create an empty archive"); } tar_stream = stdout; flags = O_WRONLY | O_CREAT | O_EXCL; unlink(tar_filename); } else #endif { tar_stream = stdin; flags = O_RDONLY; } if ((tar_filename[0] == '-') && (tar_filename[1] == '\0')) { tar_handle->src_fd = fileno(tar_stream); tar_handle->seek = seek_by_char; } else { tar_handle->src_fd = bb_xopen(tar_filename, flags); } } if ((base_dir) && (chdir(base_dir))) { bb_perror_msg_and_die("Couldnt chdir to %s", base_dir); } #ifdef CONFIG_FEATURE_TAR_CREATE /* create an archive */ if (opt & CTX_CREATE) { int verboseFlag = FALSE; int gzipFlag = FALSE; # ifdef CONFIG_FEATURE_TAR_GZIP if (get_header_ptr == get_header_tar_gz) { gzipFlag = TRUE; } # endif /* CONFIG_FEATURE_TAR_GZIP */ # ifdef CONFIG_FEATURE_TAR_BZIP2 if (get_header_ptr == get_header_tar_bz2) { bb_error_msg_and_die("Creating bzip2 compressed archives is not currently supported."); } # endif /* CONFIG_FEATURE_TAR_BZIP2 */ if ((tar_handle->action_header == header_list) || (tar_handle->action_header == header_verbose_list)) { verboseFlag = TRUE; } writeTarFile(tar_handle->src_fd, verboseFlag, opt & TAR_OPT_DEREFERNCE, tar_handle->accept, tar_handle->reject, gzipFlag); } else #endif /* CONFIG_FEATURE_TAR_CREATE */ { while (get_header_ptr(tar_handle) == EXIT_SUCCESS); /* Ckeck that every file that should have been extracted was */ while (tar_handle->accept) { if (find_list_entry(tar_handle->reject, tar_handle->accept->data) == NULL) { if (find_list_entry(tar_handle->passed, tar_handle->accept->data) == NULL) { bb_error_msg_and_die("%s: Not found in archive\n", tar_handle->accept->data); } } tar_handle->accept = tar_handle->accept->link; } } #ifdef CONFIG_FEATURE_CLEAN_UP if (tar_handle->src_fd != STDIN_FILENO) { close(tar_handle->src_fd); } #endif /* CONFIG_FEATURE_CLEAN_UP */ return(EXIT_SUCCESS); }
"extract\0" No_argument "i" "list\0" No_argument "t" #if ENABLE_FEATURE_CPIO_O "create\0" No_argument "o" "format\0" Required_argument "H" #if ENABLE_FEATURE_CPIO_P "pass-through\0" No_argument "p" #endif #endif "verbose\0" No_argument "v" "quiet\0" No_argument "\xff" "to-stdout\0" No_argument "\xfe" ; #endif archive_handle = init_handle(); /* archive_handle->src_fd = STDIN_FILENO; - done by init_handle */ archive_handle->ah_flags = ARCHIVE_EXTRACT_NEWER; /* As of now we do not enforce this: */ /* -i,-t,-o,-p are mutually exclusive */ /* -u,-d,-m make sense only with -i or -p */ /* -L makes sense only with -o or -p */ #if !ENABLE_FEATURE_CPIO_O /* no parameters */ opt_complementary = "=0"; opt = getopt32(argv, OPTION_STR, &cpio_filename); if (opt & CPIO_OPT_FILE) { /* -F */ xmove_fd(xopen(cpio_filename, O_RDONLY), STDIN_FILENO); }
int tar_main(int argc UNUSED_PARAM, char **argv) { char FAST_FUNC (*get_header_ptr)(archive_handle_t *) = get_header_tar; archive_handle_t *tar_handle; char *base_dir = NULL; const char *tar_filename = "-"; unsigned opt; int verboseFlag = 0; #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM llist_t *excludes = NULL; #endif /* Initialise default values */ tar_handle = init_handle(); tar_handle->ah_flags = ARCHIVE_CREATE_LEADING_DIRS | ARCHIVE_PRESERVE_DATE | ARCHIVE_EXTRACT_UNCONDITIONAL; /* Apparently only root's tar preserves perms (see bug 3844) */ if (getuid() != 0) tar_handle->ah_flags |= ARCHIVE_NOPRESERVE_PERM; /* Prepend '-' to the first argument if required */ opt_complementary = "--:" // first arg is options "tt:vv:" // count -t,-v "?:" // bail out with usage instead of error return "X::T::" // cumulative lists #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM "\xff::" // cumulative lists for --exclude #endif IF_FEATURE_TAR_CREATE("c:") "t:x:" // at least one of these is reqd IF_FEATURE_TAR_CREATE("c--tx:t--cx:x--ct") // mutually exclusive IF_NOT_FEATURE_TAR_CREATE("t--x:x--t"); // mutually exclusive #if ENABLE_FEATURE_TAR_LONG_OPTIONS applet_long_options = tar_longopts; #endif opt = getopt32(argv, "txC:f:Opvk" IF_FEATURE_TAR_CREATE( "ch" ) IF_FEATURE_SEAMLESS_BZ2( "j" ) IF_FEATURE_SEAMLESS_LZMA("a" ) IF_FEATURE_TAR_FROM( "T:X:") IF_FEATURE_SEAMLESS_GZ( "z" ) IF_FEATURE_SEAMLESS_Z( "Z" ) , &base_dir // -C dir , &tar_filename // -f filename IF_FEATURE_TAR_FROM(, &(tar_handle->accept)) // T IF_FEATURE_TAR_FROM(, &(tar_handle->reject)) // X #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM , &excludes // --exclude #endif , &verboseFlag // combined count for -t and -v , &verboseFlag // combined count for -t and -v ); argv += optind; if (verboseFlag) tar_handle->action_header = header_verbose_list; if (verboseFlag == 1) tar_handle->action_header = header_list; if (opt & OPT_EXTRACT) tar_handle->action_data = data_extract_all; if (opt & OPT_2STDOUT) tar_handle->action_data = data_extract_to_stdout; if (opt & OPT_KEEP_OLD) tar_handle->ah_flags &= ~ARCHIVE_EXTRACT_UNCONDITIONAL; if (opt & OPT_NOPRESERVE_OWN) tar_handle->ah_flags |= ARCHIVE_NOPRESERVE_OWN; if (opt & OPT_NOPRESERVE_PERM) tar_handle->ah_flags |= ARCHIVE_NOPRESERVE_PERM; if (opt & OPT_NUMERIC_OWNER) tar_handle->ah_flags |= ARCHIVE_NUMERIC_OWNER; if (opt & OPT_GZIP) get_header_ptr = get_header_tar_gz; if (opt & OPT_BZIP2) get_header_ptr = get_header_tar_bz2; if (opt & OPT_LZMA) get_header_ptr = get_header_tar_lzma; if (opt & OPT_COMPRESS) get_header_ptr = get_header_tar_Z; #if ENABLE_FEATURE_TAR_FROM tar_handle->reject = append_file_list_to_list(tar_handle->reject); #if ENABLE_FEATURE_TAR_LONG_OPTIONS /* Append excludes to reject */ while (excludes) { llist_t *next = excludes->link; excludes->link = tar_handle->reject; tar_handle->reject = excludes; excludes = next; } #endif tar_handle->accept = append_file_list_to_list(tar_handle->accept); #endif /* Setup an array of filenames to work with */ /* TODO: This is the same as in ar, separate function ? */ while (*argv) { /* kill trailing '/' unless the string is just "/" */ char *cp = last_char_is(*argv, '/'); if (cp > *argv) *cp = '\0'; llist_add_to_end(&tar_handle->accept, *argv); argv++; } if (tar_handle->accept || tar_handle->reject) tar_handle->filter = filter_accept_reject_list; /* Open the tar file */ { FILE *tar_stream; int flags; if (opt & OPT_CREATE) { /* Make sure there is at least one file to tar up. */ if (tar_handle->accept == NULL) bb_error_msg_and_die("empty archive"); tar_stream = stdout; /* Mimicking GNU tar 1.15.1: */ flags = O_WRONLY | O_CREAT | O_TRUNC; } else { tar_stream = stdin; flags = O_RDONLY; } if (LONE_DASH(tar_filename)) { tar_handle->src_fd = fileno(tar_stream); tar_handle->seek = seek_by_read; } else { if (ENABLE_FEATURE_TAR_AUTODETECT && flags == O_RDONLY) { get_header_ptr = get_header_tar; tar_handle->src_fd = open_zipped(tar_filename); if (tar_handle->src_fd < 0) bb_perror_msg_and_die("can't open '%s'", tar_filename); } else { tar_handle->src_fd = xopen(tar_filename, flags); } } } if (base_dir) xchdir(base_dir); #ifdef CHECK_FOR_CHILD_EXITCODE /* We need to know whether child (gzip/bzip/etc) exits abnormally */ signal(SIGCHLD, handle_SIGCHLD); #endif /* create an archive */ if (opt & OPT_CREATE) { #if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 int zipMode = 0; if (ENABLE_FEATURE_SEAMLESS_GZ && (opt & OPT_GZIP)) zipMode = 1; if (ENABLE_FEATURE_SEAMLESS_BZ2 && (opt & OPT_BZIP2)) zipMode = 2; #endif /* NB: writeTarFile() closes tar_handle->src_fd */ return writeTarFile(tar_handle->src_fd, verboseFlag, opt & OPT_DEREFERENCE, tar_handle->accept, tar_handle->reject, zipMode); } while (get_header_ptr(tar_handle) == EXIT_SUCCESS) continue; /* Check that every file that should have been extracted was */ while (tar_handle->accept) { if (!find_list_entry(tar_handle->reject, tar_handle->accept->data) && !find_list_entry(tar_handle->passed, tar_handle->accept->data) ) { bb_error_msg_and_die("%s: not found in archive", tar_handle->accept->data); } tar_handle->accept = tar_handle->accept->link; } if (ENABLE_FEATURE_CLEAN_UP /* && tar_handle->src_fd != STDIN_FILENO */) close(tar_handle->src_fd); return EXIT_SUCCESS; }
int dpkg_deb_main(int argc, char **argv) { archive_handle_t *ar_archive; archive_handle_t *tar_archive; llist_t *control_tar_llist = NULL; unsigned long opt; char *extract_dir = NULL; short argcount = 1; /* Setup the tar archive handle */ tar_archive = init_handle(); /* Setup an ar archive handle that refers to the gzip sub archive */ ar_archive = init_handle(); ar_archive->sub_archive = tar_archive; ar_archive->filter = filter_accept_list_reassign; #ifdef CONFIG_FEATURE_DEB_TAR_GZ ar_archive->accept = llist_add_to(NULL, "data.tar.gz"); control_tar_llist = llist_add_to(NULL, "control.tar.gz"); #endif #ifdef CONFIG_FEATURE_DEB_TAR_BZ2 ar_archive->accept = llist_add_to(ar_archive->accept, "data.tar.bz2"); control_tar_llist = llist_add_to(control_tar_llist, "control.tar.bz2"); #endif bb_opt_complementally = "?c--efXx:e--cfXx:f--ceXx:X--cefx:x--cefX"; opt = bb_getopt_ulflags(argc, argv, "cefXx"); if (opt & DPKG_DEB_OPT_CONTENTS) { tar_archive->action_header = header_verbose_list; } if (opt & DPKG_DEB_OPT_CONTROL) { ar_archive->accept = control_tar_llist; tar_archive->action_data = data_extract_all; if (optind + 1 == argc) { extract_dir = "./DEBIAN"; } else { argcount++; } } if (opt & DPKG_DEB_OPT_FIELD) { /* Print the entire control file * it should accept a second argument which specifies a * specific field to print */ ar_archive->accept = control_tar_llist; tar_archive->accept = llist_add_to(NULL, "./control"); tar_archive->filter = filter_accept_list; tar_archive->action_data = data_extract_to_stdout; } if (opt & DPKG_DEB_OPT_EXTRACT) { tar_archive->action_header = header_list; } if (opt & (DPKG_DEB_OPT_EXTRACT_VERBOSE | DPKG_DEB_OPT_EXTRACT)) { tar_archive->action_data = data_extract_all; argcount = 2; } if ((optind + argcount) != argc) { bb_show_usage(); } tar_archive->src_fd = ar_archive->src_fd = bb_xopen(argv[optind++], O_RDONLY); /* Workout where to extract the files */ /* 2nd argument is a dir name */ if (argv[optind]) { extract_dir = argv[optind]; } if (extract_dir) { mkdir(extract_dir, 0777); chdir(extract_dir); } unpack_ar_archive(ar_archive); /* Cleanup */ close (ar_archive->src_fd); return(EXIT_SUCCESS); }
extern int unzip_main(int argc, char **argv) { union { unsigned char raw[26]; struct { unsigned short version; /* 0-1 */ unsigned short flags; /* 2-3 */ unsigned short method; /* 4-5 */ unsigned short modtime; /* 6-7 */ unsigned short moddate; /* 8-9 */ unsigned int crc32 __attribute__ ((packed)); /* 10-13 */ unsigned int cmpsize __attribute__ ((packed));; /* 14-17 */ unsigned int ucmpsize __attribute__ ((packed));; /* 18-21 */ unsigned short filename_len; /* 22-23 */ unsigned short extra_len; /* 24-25 */ } formated __attribute__ ((packed)); } zip_header; archive_handle_t *archive_handle; unsigned int total_size = 0; unsigned int total_entries = 0; char *base_dir = NULL; int opt = 0; /* Initialise */ archive_handle = init_handle(); archive_handle->action_data = NULL; archive_handle->action_header = header_list_unzip; while ((opt = getopt(argc, argv, "lnopqd:")) != -1) { switch (opt) { case 'l': /* list */ archive_handle->action_header = header_verbose_list_unzip; archive_handle->action_data = data_skip; break; case 'n': /* never overwright existing files */ break; case 'o': archive_handle->flags = ARCHIVE_EXTRACT_UNCONDITIONAL; break; case 'p': /* extract files to stdout */ archive_handle->action_data = data_extract_to_stdout; break; case 'q': /* Extract files quietly */ archive_handle->action_header = header_skip; break; case 'd': /* Extract files to specified base directory*/ base_dir = optarg; break; #if 0 case 'x': /* Exclude the specified files */ archive_handle->filter = filter_accept_reject_list; break; #endif default: bb_show_usage(); } } if (argc == optind) { bb_show_usage(); } printf("Archive: %s\n", argv[optind]); if (archive_handle->action_header == header_verbose_list_unzip) { printf(" Length Date Time Name\n"); printf(" -------- ---- ---- ----\n"); } if (*argv[optind] == '-') { archive_handle->src_fd = fileno(stdin); archive_handle->seek = seek_by_char; } else { archive_handle->src_fd = bb_xopen(argv[optind++], O_RDONLY); } if ((base_dir) && (chdir(base_dir))) { bb_perror_msg_and_die("Couldnt chdir"); } while (optind < argc) { archive_handle->filter = filter_accept_list; archive_handle->accept = llist_add_to(archive_handle->accept, argv[optind]); optind++; } while (1) { unsigned int magic; int dst_fd; /* TODO Endian issues */ archive_xread_all(archive_handle, &magic, 4); archive_handle->offset += 4; if (magic == ZIP_CDS_MAGIC) { break; } else if (magic != ZIP_FILEHEADER_MAGIC) { bb_error_msg_and_die("Invlaide zip magic"); } /* Read the file header */ archive_xread_all(archive_handle, zip_header.raw, 26); archive_handle->offset += 26; archive_handle->file_header->mode = S_IFREG | 0777; if (zip_header.formated.method != 8) { bb_error_msg_and_die("Unsupported compression method %d\n", zip_header.formated.method); } /* Read filename */ archive_handle->file_header->name = xmalloc(zip_header.formated.filename_len + 1); archive_xread_all(archive_handle, archive_handle->file_header->name, zip_header.formated.filename_len); archive_handle->offset += zip_header.formated.filename_len; archive_handle->file_header->name[zip_header.formated.filename_len] = '\0'; /* Skip extra header bits */ archive_handle->file_header->size = zip_header.formated.extra_len; data_skip(archive_handle); archive_handle->offset += zip_header.formated.extra_len; /* Handle directories */ archive_handle->file_header->mode = S_IFREG | 0777; if (last_char_is(archive_handle->file_header->name, '/')) { archive_handle->file_header->mode ^= S_IFREG; archive_handle->file_header->mode |= S_IFDIR; } /* Data section */ archive_handle->file_header->size = zip_header.formated.cmpsize; if (archive_handle->action_data) { archive_handle->action_data(archive_handle); } else { dst_fd = bb_xopen(archive_handle->file_header->name, O_WRONLY | O_CREAT); inflate(archive_handle->src_fd, dst_fd); close(dst_fd); chmod(archive_handle->file_header->name, archive_handle->file_header->mode); /* Validate decompression - crc */ if (zip_header.formated.crc32 != (gunzip_crc ^ 0xffffffffL)) { bb_error_msg("Invalid compressed data--crc error"); } /* Validate decompression - size */ if (gunzip_bytes_out != zip_header.formated.ucmpsize) { bb_error_msg("Invalid compressed data--length error"); } } /* local file descriptor section */ archive_handle->offset += zip_header.formated.cmpsize; /* This ISNT unix time */ archive_handle->file_header->mtime = zip_header.formated.modtime | (zip_header.formated.moddate << 16); archive_handle->file_header->size = zip_header.formated.ucmpsize; total_size += archive_handle->file_header->size; total_entries++; archive_handle->action_header(archive_handle->file_header); /* Data descriptor section */ if (zip_header.formated.flags & 4) { /* skip over duplicate crc, compressed size and uncompressed size */ unsigned short i; for (i = 0; i != 12; i++) { archive_xread_char(archive_handle); } archive_handle->offset += 12; } } /* Central directory section */ if (archive_handle->action_header == header_verbose_list_unzip) { printf(" -------- -------\n"); printf("%9d %d files\n", total_size, total_entries); } return(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { struct radclock_handle *handle; struct radclock_config *conf; int is_daemon = 0; /* File and command line reading */ int ch; /* Mask variable used to know which parameter to update */ uint32_t param_mask = 0; /* PID lock file for daemon */ int daemon_pid_fd = 0; /* Initialize PID lockfile to a default value */ const char *pid_lockfile = DAEMON_LOCK_FILE; /* Misc */ int err; /* turn off buffering to allow results to be seen immediately if JDEBUG*/ #ifdef WITH_JDEBUG setvbuf(stdout, (char *)NULL, _IONBF, 0); setvbuf(stderr, (char *)NULL, _IONBF, 0); #endif /* * Register Signal handlers. We use sigaction() instead of signal() to catch * signals. The main reason concerns the SIGHUP signal. In Linux, the * syscalls are restarted as soon as the signal handler returns. This * prevent pcap_breakloop() to do its job (see pcap man page). Using * sigaction() we can overwrite the default flag to prevent this behavior */ sigset_t block_mask; sigfillset (&block_mask); struct sigaction sig_struct; sig_struct.sa_handler = signal_handler; sig_struct.sa_mask = block_mask; sig_struct.sa_flags = 0; sigaction(SIGHUP, &sig_struct, NULL); /* hangup signal (1) */ sigaction(SIGTERM, &sig_struct, NULL); /* software termination signal (15) */ sigaction(SIGUSR1, &sig_struct, NULL); /* user signal 1 (30) */ sigaction(SIGUSR2, &sig_struct, NULL); /* user signal 2 (31) */ /* Initialise verbose data to defaults */ verbose_data.handle = NULL; verbose_data.is_daemon = 0; verbose_data.verbose_level = 0; verbose_data.fd = NULL; strcpy(verbose_data.logfile, ""); pthread_mutex_init(&(verbose_data.vmutex), NULL); /* Management of configuration options */ conf = (struct radclock_config *) malloc(sizeof(struct radclock_config)); JDEBUG_MEMORY(JDBG_MALLOC, conf); memset(conf, 0, sizeof(struct radclock_config)); /* * The command line arguments are given the priority and override possible * values of the configuration file But the configuration file is parsed * after the command line because we need to know if we are running a daemon * or not (configuration file is different if we run a daemon or not). Use * the param_mask variable to indicate which values have to be updated from * the config file */ /* Initialize the physical parameters, and other config parameters. */ config_init(conf); /* Init the mask we use to signal configuration updates */ param_mask = UPDMASK_NOUPD; /* Reading the command line arguments */ while ((ch = getopt(argc, argv, "dxvhc:i:l:n:t:r:w:s:a:o:p:P:U:D:V")) != -1) switch (ch) { case 'x': SET_UPDATE(param_mask, UPDMASK_SERVER_IPC); conf->server_ipc = BOOL_OFF; break; case 'c': strcpy(conf->conffile, optarg); break; case 'd': is_daemon = 1; break; case 'l': strcpy(conf->logfile, optarg); break; case 'n': if (strlen(optarg) > MAXLINE) { fprintf(stdout, "ERROR: parameter too long\n"); exit (1); } SET_UPDATE(param_mask, UPDMASK_HOSTNAME); strcpy(conf->hostname, optarg); break; case 'p': SET_UPDATE(param_mask, UPDMASK_POLLPERIOD); if ( atoi(optarg) < RAD_MINPOLL ) { conf->poll_period = RAD_MINPOLL; fprintf(stdout, "Warning: Poll period too small, set to %d\n", conf->poll_period); } else conf->poll_period = atoi(optarg); if ( conf->poll_period > RAD_MAXPOLL ) { conf->poll_period = RAD_MAXPOLL; fprintf(stdout, "Warning: Poll period too big, set to %d\n", conf->poll_period); } break; case 't': if (strlen(optarg) > MAXLINE) { fprintf(stdout, "ERROR: parameter too long\n"); exit (1); } SET_UPDATE(param_mask, UPDMASK_TIME_SERVER); strcpy(conf->time_server, optarg); break; case 'i': if (strlen(optarg) > MAXLINE) { fprintf(stdout, "ERROR: parameter too long\n"); exit (1); } SET_UPDATE(param_mask, UPDMASK_NETWORKDEV); strcpy(conf->network_device, optarg); break; case 'r': if (strlen(optarg) > MAXLINE) { fprintf(stdout, "ERROR: parameter too long\n"); exit (1); } SET_UPDATE(param_mask, UPDMASK_SYNC_IN_PCAP); strcpy(conf->sync_in_pcap, optarg); break; case 'w': if (strlen(optarg) > MAXLINE) { fprintf(stdout, "ERROR: parameter too long\n"); exit (1); } SET_UPDATE(param_mask, UPDMASK_SYNC_OUT_PCAP); strcpy(conf->sync_out_pcap, optarg); break; case 's': if (strlen(optarg) > MAXLINE) { fprintf(stdout, "ERROR: parameter too long\n"); exit (1); } SET_UPDATE(param_mask, UPDMASK_SYNC_IN_ASCII); strcpy(conf->sync_in_ascii, optarg); break; case 'a': if (strlen(optarg) > MAXLINE) { fprintf(stdout, "ERROR: parameter too long\n"); exit (1); } SET_UPDATE(param_mask, UPDMASK_SYNC_OUT_ASCII); strcpy(conf->sync_out_ascii, optarg); break; case 'o': if (strlen(optarg) > MAXLINE) { fprintf(stdout, "ERROR: parameter too long\n"); exit (1); } SET_UPDATE(param_mask, UPDMASK_CLOCK_OUT_ASCII); strcpy(conf->clock_out_ascii, optarg); break; case 'P': if (strlen(optarg) > MAXLINE) { fprintf(stdout, "ERROR: parameter too long\n"); exit (1); } SET_UPDATE(param_mask, UPDMASK_PID_FILE); pid_lockfile = optarg; break; case 'v': SET_UPDATE(param_mask, UPDMASK_VERBOSE); conf->verbose_level++; break; case 'U': SET_UPDATE(param_mask, UPD_NTP_UPSTREAM_PORT); conf->ntp_upstream_port = atoi(optarg); break; case 'D': SET_UPDATE(param_mask, UPD_NTP_DOWNSTREAM_PORT); conf->ntp_downstream_port = atoi(optarg); break; case 'V': fprintf(stdout, "%s version %s\n", PACKAGE_NAME, PACKAGE_VERSION); case 'h': case '?': default: usage(); } argc -= optind; argv += optind; /* Little hack to deal with parsing of long options in the command line */ if (conf->verbose_level > 0) SET_UPDATE(param_mask, UPDMASK_VERBOSE); /* Create the radclock handle */ clock_handle = create_handle(conf, is_daemon); if (!clock_handle) { verbose(LOG_ERR, "Could not create clock handle"); return (-1); } handle = clock_handle; /* * Have not parsed the config file yet, so will have to do it again since it * may not be the right settings. Handles config parse messages in the right * log file though. So far clock has not been sent to init, no syscall * registered, pass a NULL pointer to verbose. */ set_verbose(handle, handle->conf->verbose_level, 0); set_logger(logger_verbose_bridge); /* Daemonize now, so that we can open the log files and close connection to * stdin since we parsed the command line */ if (handle->is_daemon) { struct stat sb; if (stat(RADCLOCK_RUN_DIRECTORY, &sb) < 0) { if (mkdir(RADCLOCK_RUN_DIRECTORY, 0755) < 0) { verbose(LOG_ERR, "Cannot create %s directory. Run as root or " "(!daemon && !server)", RADCLOCK_RUN_DIRECTORY); return (1); } } /* Check this everytime in case something happened */ chmod(RADCLOCK_RUN_DIRECTORY, 00755); if (!(daemonize(pid_lockfile, &daemon_pid_fd))) { fprintf(stderr, "Error: did not manage to create the daemon\n"); exit(EXIT_FAILURE); } } /* * Retrieve configuration from the config file (write it down if it does not * exist) That should be the only occasion when get_config() is called and * the param_mask is not positioned to UPDMASK_NOUPD !!! Only the * parameters not specified on the command line are updated */ if (!config_parse(handle->conf, ¶m_mask, handle->is_daemon)) return (0); /* * Now that we have the configuration to use (verbose level), let's * initialise the verbose level to correct value */ set_verbose(handle, handle->conf->verbose_level, 0); set_logger(logger_verbose_bridge); /* Check for incompatible configurations and correct them */ if (( handle->conf->synchro_type == SYNCTYPE_SPY ) || ( handle->conf->synchro_type == SYNCTYPE_PIGGY )) { if (handle->conf->server_ntp == BOOL_ON) { verbose(LOG_ERR, "Configuration error. Disabling NTP server " "(incompatible with spy or piggy mode)."); handle->conf->server_ntp = BOOL_OFF; } if ( handle->conf->adjust_sysclock == BOOL_ON ) { verbose(LOG_ERR, "Configuration error. Disabling adjust system " "clock (incompatible with spy or piggy mode)."); handle->conf->adjust_sysclock = BOOL_OFF; } } /* Diagnosis output for the configuration used */ config_print(LOG_NOTICE, handle->conf); /* Reinit the mask that counts updated values */ param_mask = UPDMASK_NOUPD; // TODO extract extra checks from is_live_source and make an input fix // function instead, would be clearer // TODO the conf->network_device business is way too messy /* * Need to know if we are replaying data or not. If not, no need to create * shared global data on the system or open a BPF. This define input to the * init of the radclock handle */ if (!is_live_source(handle)) handle->run_mode = RADCLOCK_SYNC_DEAD; else handle->run_mode = RADCLOCK_SYNC_LIVE; /* Init clock handle and private data */ if (handle->run_mode == RADCLOCK_SYNC_LIVE) { err = clock_init_live(handle->clock, &handle->rad_data); if (err) { verbose(LOG_ERR, "Could not initialise the RADclock"); return (1); } } /* Init radclock specific stuff */ err = init_handle(handle); if (err) { verbose(LOG_ERR, "Radclock process specific init failed."); return (1); } /* * Now 2 cases. Either we are running live or we are replaying some data. * If we run live, we will spawn some threads and do some smart things. If * we replay data, no need to do all of that, we access data and process it * in the same thread. */ if (handle->run_mode == RADCLOCK_SYNC_DEAD) { // TODO : manage peers better !! struct bidir_peer peer; /* Some basic initialisation which is required */ init_peer_stamp_queue(&peer); peer.stamp_i = 0; // TODO XXX Need to manage peers better !! /* Register active peer */ handle->active_peer = (void *)&peer; while (1) { err = process_rawdata(handle, &peer); if (err < 0) break; } destroy_peer_stamp_queue(&peer); } /* * We loop in here in case we are rehashed. Threads are (re-)created every * time we loop in */ else { while (err == 0) { err = start_live(handle); if (err == 0) { if (rehash_daemon(handle, param_mask)) verbose(LOG_ERR, "SIGHUP - Failed to rehash daemon !!."); } } } // TODO: look into making the stats a separate structure. Could be much // TODO: easier to manage long int n_stamp; unsigned int ref_count; n_stamp = ((struct bidir_output *)handle->algo_output)->n_stamps; ref_count = ((struct stampsource*)(handle->stamp_source))->ntp_stats.ref_count; verbose(LOG_NOTICE, "%u NTP packets captured", ref_count); verbose(LOG_NOTICE,"%ld missed NTP packets", ref_count - 2 * n_stamp); verbose(LOG_NOTICE, "%ld valid timestamp tuples extracted", n_stamp); /* Close output files */ close_output_stamp(handle); /* Print out last good phat value */ verbose(LOG_NOTICE, "Last estimate of the clock source period: %12.10lg", RAD_DATA(handle)->phat); /* Say bye and close syslog */ verbose(LOG_NOTICE, "RADclock stopped"); if (handle->is_daemon) closelog (); unset_verbose(); /* Free the lock file */ if (handle->is_daemon) { write(daemon_pid_fd, "", 0); lockf(daemon_pid_fd, F_ULOCK, 0); } // TODO: all the destructors have to be re-written destroy_source(handle, (struct stampsource *)(handle->stamp_source)); /* Clear thread stuff */ pthread_mutex_destroy(&(handle->globaldata_mutex)); pthread_mutex_destroy(&(handle->wakeup_mutex)); pthread_cond_destroy(&(handle->wakeup_cond)); /* Detach IPC shared memory if were running as IPC server. */ if (handle->conf->server_ipc == BOOL_ON) shm_detach(handle->clock); /* Free the clock structure. All done. */ pthread_mutex_destroy(&(handle->pcap_queue->rdb_mutex)); pthread_mutex_destroy(&(handle->ieee1588eq_queue->rdb_mutex)); free(handle->pcap_queue); free(handle->ieee1588eq_queue); free(handle); handle = NULL; clock_handle = NULL; exit(EXIT_SUCCESS); }