/** * readline() 関数テスト * * @return なし */ void test_readline(void) { char nolf_data[] = "test"; /* 改行なし文字列 */ /* 正常系 */ result = exec_readline(test_data, sizeof(test_data)); /* 改行削除 */ if (test_data[strlen(test_data) - 1] == '\n') test_data[strlen(test_data) - 1] = '\0'; cut_assert_equal_string(test_data, (char *)result); memfree((void **)&result, NULL); /* 異常系 */ /* 改行ない場合 */ result = exec_readline(nolf_data, sizeof(nolf_data)); dbglog("result=%s", result); cut_assert_null((char *)result); /* ファイルポインタがNULLの場合 */ result = _readline((FILE *)NULL); cut_assert_null((char *)result); }
char *readline(const char *prompt, struct rls *rls) { if (prompt == NULL || rls == NULL) return NULL; if (write(rls->fdout, prompt, strlen(prompt))) ; rls->prompt = (char *)prompt; if (_readline(rls) == 0) return NULL; return rls->kbuffer; }
// read MalVal *READ(char prompt[], char *str) { char *line; MalVal *ast; if (str) { line = str; } else { line = _readline(prompt); if (!line) { _error("EOF"); return NULL; } } ast = read_str(line); if (!str) { free(line); } return ast; }
void command_line_prompt_words (const char* prompt, const char* def, const StrList* possibilities, int multi_word) { char* line; char* real_prompt; char* _def = (char*) def; int _def_needs_free = 0; if (!def && str_list_length (possibilities) == 1) { _def = str_list_convert_node (possibilities); _def_needs_free = 1; } if (opt_script_mode) { if (_def) { command_line_push_line (_def, 0); if (_def_needs_free) free (_def); } return; } do { real_prompt = _construct_prompt (prompt, _def, possibilities); line = _readline (real_prompt, possibilities); free (real_prompt); if (!line) { /* readline returns NULL to indicate EOF. Treat that like an interrupt. */ got_ctrl_c = 1; break; } if (!strlen (line)) { if (_def) command_line_push_line (_def, 0); } else { command_line_push_line (line, multi_word); } free (line); } while (!command_line_get_word_count () && !_def); if (_def_needs_free) free (_def); }
/** * ソケット送信 * * @param[in] sock ソケット * @return ステータス */ static st_client send_sock(int sock) { int retval = 0; /* 戻り値 */ size_t length = 0; /* 長さ */ ssize_t slen = 0; /* 送信するバイト数 */ expr = _readline(stdin); if (!expr) return EX_ALLOC_ERR; if (*expr == '\0') { /* 文字列長ゼロ */ memfree((void **)&expr, NULL); return EX_EMPTY; } if (!strcmp((char *)expr, "quit") || !strcmp((char *)expr, "exit")) return EX_QUIT; length = strlen((char *)expr) + 1; dbgdump(expr, length, "stdin: expr=%zu", length); if (g_tflag) start_timer(&start_time); /* データ設定 */ slen = set_client_data(&sdata, expr, length); if (slen < 0) /* メモリ確保できない */ return EX_ALLOC_ERR; dbglog("slen=%zd", slen); if (g_gflag) outdump(sdata, slen, "send: sdata=%p, length=%zd", sdata, slen); stddump(sdata, slen, "send: sdata=%p, length=%zd", sdata, slen); /* データ送信 */ retval = send_data(sock, sdata, (size_t *)&slen); if (retval < 0) /* エラー */ return EX_SEND_ERR; memfree((void **)&expr, (void **)&sdata, NULL); return EX_SUCCESS; }
// Iterate records, calling factory_cb and handler_cb for each record. void lsreg_iterate(lsreg_rec_factory_cb *factory_cb, lsreg_rec_handler_cb *handler_cb, void *something) { FILE *f; size_t skip_lines; enum kLSRegParseStatus status; char *linebuf; const size_t linebufsize = 1024; if((f = lsreg_regdump_open()) == NULL) { return; } linebuf = (char *)malloc(sizeof(char)*linebufsize+1); skip_lines = 3; while(skip_lines--) { if(_readline(linebuf, linebufsize, f) == NULL) { // error occured free(linebuf); return; } } // Parse sections do { lsreg_rec_t *record = factory_cb(something); lsreg_rec_init(record); status = lsreg_parse_record(f, linebuf, linebufsize, record); //lsreg_rec_dump(&record, stdout); if(handler_cb(record, something)) { break; } } while(status == kLSRegParseStatusContinue); free(linebuf); lsreg_regdump_close(f); }
void lsreg_parse(FILE *f) { size_t skip_lines; enum kLSRegParseStatus status; char *linebuf; const size_t linebufsize = 1024; linebuf = (char *)malloc(sizeof(char)*linebufsize+1); skip_lines = 3; while(skip_lines--) { if(_readline(linebuf, linebufsize, f) == NULL) { // error occured free(linebuf); return; } } // Parse sections do { lsreg_rec_t record; lsreg_rec_init(&record); status = lsreg_parse_record(f, linebuf, linebufsize, &record); lsreg_rec_dump(&record, stdout); lsreg_rec_free_members(&record); /* lsreg_bundle_t bundle; lsreg_bundle_init(&bundle); done = lsreg_parse_bundle_section(f, linebuf, linebufsize, &bundle); //if(bundle.library_items) lsreg_bundle_dump(&bundle, stdout);*/ } while(status == kLSRegParseStatusContinue); free(linebuf); }
int lsreg_parse_record(FILE *f, char *linebuf, size_t linebufsize, lsreg_rec_t *rec) { char *line, *keyend, *key, *val; size_t linelen, keylen, vallen; int passed_main; enum kLSRegParseStatus status; lsreg_parser_func *parser; // Init passed_main = 0; status = kLSRegParseStatusContinue; rec->type = kLSRegRecTypeUnknown; parser = NULL; // Detect record type if((line = _readline(linebuf, linebufsize, f)) == NULL) { return 1; // done! } linelen = strlen(line); if(linelen > 7) { // Parse id rec->uid = (unsigned int)atoi(strchr(line, ':')+1); if(memcmp(line, "bundle", 6) == 0) { rec->type = kLSRegRecTypeBundle; rec->rec = malloc(sizeof(lsreg_bundle_t)); lsreg_bundle_init((lsreg_bundle_t *)rec->rec); ((lsreg_bundle_t *)rec->rec)->uid = rec->uid; parser = lsreg_parse_bundle; } else if(memcmp(line, "volume", 6) == 0) { rec->type = kLSRegRecTypeVolume; rec->rec = malloc(sizeof(lsreg_volume_t)); lsreg_volume_init((lsreg_volume_t *)rec->rec); ((lsreg_volume_t *)rec->rec)->uid = rec->uid; parser = lsreg_parse_volume; } else if(memcmp(line, "handler", 7) == 0) { rec->type = kLSRegRecTypeHandler; rec->rec = malloc(sizeof(lsreg_handler_t)); lsreg_handler_init((lsreg_handler_t *)rec->rec); ((lsreg_handler_t *)rec->rec)->uid = rec->uid; parser = lsreg_parse_handler; } } if(parser == NULL) { log_error("Unsupported record type"); return kLSRegParseStatusDone; } while( (line = _readline(linebuf, linebufsize, f)) ) { linelen = strlen(line); if(linelen == 0) { // Skip empty line continue; } if(line[0] == '-') { // End of section break; } if(passed_main) { // Passed main info - read off remaining lines continue; } if(linelen > 1 && line[0] == '\t' && line[1] == '-') { // End of main info passed_main = 1; continue; } // Now, a line passed all checks down here is probably a key-value pair. if((keyend = (char *)memchr(line, ':', linelen)) == NULL) { log_error("Unable to parse line '%s'", line); continue; } // Find key and value keylen = keyend-line; vallen = linelen-keylen-1; // -1 is for ':' val = line; val += keylen+1; val = _memltrim(val, &vallen); if(vallen) { vallen--; // Remove LN and... val[vallen] = '\0'; // ...replace it with \0 } key = _memltrim(line, &keylen); // Handle key-value assignment record type-wise... status = parser(f, linebuf, linebufsize, line, linelen, key, keylen, val, vallen, rec); // If not continue, stop and return if(status != kLSRegParseStatusContinue) { return status; } } return (line == NULL) ? kLSRegParseStatusDone : kLSRegParseStatusContinue; }
result_t console_base::readLine(const char *msg, std::string &retVal, exlib::AsyncEvent *ac) { #ifndef _WIN32 static bool _init = false; static char *(*_readline)(const char *); static void (*_add_history)(char *); if (!_init) { _init = true; #ifdef MacOS void *handle = dlopen("libreadline.dylib", RTLD_LAZY); #else void *handle = dlopen("libreadline.so", RTLD_LAZY); #endif if (handle) { _readline = (char *(*)(const char *))dlsym(handle, "readline"); _add_history = (void (*)(char *))dlsym(handle, "add_history"); } } #endif if (!ac) { flushLog(); return CALL_E_NOSYNC; } #ifndef _WIN32 if (_readline && _add_history) { char *line; if ((line = _readline(msg)) != NULL) { if (*line) { _add_history(line); retVal = line; } free(line); } } else #endif { char *line; logger::std_out(msg); if ((line = read_line()) != NULL) { retVal = line; free(line); } } return 0; }
/* * hostsfile_clusterlist_setup * * hostsfile clusterlist module setup function */ static int hostsfile_clusterlist_setup(nodeupdown_t handle) { int fd = -1, len; char buf[NODEUPDOWN_BUFFERLEN]; char *p; if (!(hosts = list_create((ListDelF)free))) { #ifndef NDEBUG fprintf(stderr, "list_create: %s\n", strerror(errno)); #endif /* NDEBUG */ nodeupdown_set_errnum(handle, NODEUPDOWN_ERR_OUTMEM); goto cleanup; } if ((fd = open(NODEUPDOWN_CLUSTERLIST_HOSTSFILE_DEFAULT, O_RDONLY)) < 0) { #ifndef NDEBUG fprintf(stderr, "open: %s\n", strerror(errno)); #endif /* NDEBUG */ /* no nodes, just get out */ if (errno == ENOENT) goto out; nodeupdown_set_errnum(handle, NODEUPDOWN_ERR_CLUSTERLIST_MODULE); goto cleanup; } while ((len = _readline(handle, fd, buf, NODEUPDOWN_BUFFERLEN)) > 0) { char *hostPtr; char *str; if ((len = _remove_comments(buf, len)) == 0) continue; if ((len = _remove_trailing_whitespace(buf, len)) == 0) continue; if (!(hostPtr = _move_past_whitespace(buf))) continue; if (hostPtr[0] == '\0') continue; if (strchr(hostPtr, ' ') || strchr(hostPtr, '\t')) { #ifndef NDEBUG fprintf(stderr, "parse error\n"); #endif /* NDEBUG */ nodeupdown_set_errnum(handle, NODEUPDOWN_ERR_CLUSTERLIST_MODULE); goto cleanup; } if (strlen(hostPtr) > NODEUPDOWN_MAXHOSTNAMELEN) { #ifndef NDEBUG fprintf(stderr, "parse error\n"); #endif /* NDEBUG */ nodeupdown_set_errnum(handle, NODEUPDOWN_ERR_CLUSTERLIST_MODULE); goto cleanup; } /* Shorten hostname if necessary */ if ((p = strchr(hostPtr, '.'))) *p = '\0'; if (!(str = strdup(hostPtr))) { nodeupdown_set_errnum(handle, NODEUPDOWN_ERR_OUTMEM); goto cleanup; } if (!list_append(hosts, str)) { #ifndef NDEBUG fprintf(stderr, "list_append: %s\n", strerror(errno)); #endif /* NDEBUG */ nodeupdown_set_errnum(handle, NODEUPDOWN_ERR_CLUSTERLIST_MODULE); goto cleanup; } } out: /* ignore potential error, just return result */ close(fd); return 0; cleanup: /* ignore potential error, just return result */ close(fd); return -1; }
cfg_st *cfg_load(char *path) { FILE *fp = fopen(path, "r"); if (NULL == fp) { return NULL; } struct cfg_section *sec_head = NULL; struct cfg_section *sec_prev = NULL; struct cfg_section *sec_curr = NULL; struct cfg_obj *obj_curr = NULL; struct cfg_obj *obj_prev = NULL; char *line = NULL; size_t n = 0; ssize_t len = 0; while ((len = _readline(&line, &n, fp)) != -1) { char *s = line; #ifdef __DEBUG__ printf("1_readline:%s\n",s); #endif if (is_comment(&s)) continue; len = strlen(s); if (len>2 && s[0]=='[' && s[len-1]==']') { char *name = s + 1; *(name+len-1-1) = '\0'; trim(name); if ((sec_curr = find_section(sec_head, name)) == NULL) { if ((sec_curr = create_section(sec_head, name)) == NULL) { free(line); return NULL; } if (sec_head == NULL) sec_head = sec_curr; if (sec_prev != NULL) sec_prev->next = sec_curr; sec_prev = sec_curr; obj_prev = NULL; } else { obj_prev = sec_curr->obj; while (obj_prev->next != NULL) obj_prev = obj_prev->next; } continue; } char *delimiter = strchr(s, '='); if (delimiter == NULL) continue; *delimiter = '\0'; char *name = s; trim(name); char *value = delimiter + 1; delimiter = strchr(value, '#'); if (NULL != delimiter) { *delimiter = '\0'; } trim(value); if (sec_curr == NULL) { if ((sec_curr = create_section(sec_head, "global")) == NULL) { free(line); return NULL; } if (sec_head == NULL) sec_head = sec_curr; sec_prev = sec_curr; obj_prev = NULL; } if ((obj_curr = find_obj(sec_curr, name)) == NULL) { obj_curr = create_obj(sec_head, name, value); if (obj_curr == NULL) { free(line); return NULL; } if (obj_prev) obj_prev->next = obj_curr; if (sec_curr->obj == NULL) sec_curr->obj = obj_curr; obj_prev = obj_curr; } else { char *old_value = obj_curr->value; if ((obj_curr->value = strdup(value)) == NULL) { cfg_free(sec_head); free(line); return NULL; } free(old_value); } } free(line); fclose(fp); if (sec_head == NULL) { if ((sec_head = calloc(1, sizeof(struct cfg_section))) == NULL) return NULL; } #ifdef __DEBUG__ ini_print(sec_head); #endif return sec_head; }
result_t console_base::readLine(const char *msg, std::string &retVal, exlib::AsyncEvent *ac) { #ifndef _WIN32 static bool _init = false; static char *(*_readline)(const char *); static void (*_add_history)(char *); if (!_init) { _init = true; #ifdef MacOS void *handle = dlopen("libreadline.dylib", RTLD_LAZY); #else const char *readline_dylib_names[] = { "libreadline.so.6", "libreadline.so.5", "libreadline.so" }; const size_t readline_dylib_names_size = ARRAYSIZE(readline_dylib_names); void *handle = 0; for (size_t i = 0; i < readline_dylib_names_size; i++) { handle = dlopen(readline_dylib_names[i], RTLD_LAZY); if (handle) break; } #endif if (handle) { _readline = (char *(*)(const char *))dlsym(handle, "readline"); _add_history = (void (*)(char *))dlsym(handle, "add_history"); } } #endif if (!ac) { flushLog(); return CHECK_ERROR(CALL_E_NOSYNC); } #ifndef _WIN32 if (_readline && _add_history) { char *line = _readline(msg); if (!line) return CHECK_ERROR(LastError()); if (*line) { _add_history(line); retVal = line; } free(line); } else #endif { s_std.out(msg); char *line = read_line(); if (!line) return CHECK_ERROR(LastError()); retVal = line; free(line); } return 0; }
result_t console_base::readLine(exlib::string msg, exlib::string &retVal, AsyncEvent *ac) { if (!ac) return CHECK_ERROR(CALL_E_LONGSYNC); flushLog(); #ifndef _WIN32 static bool _init = false; static char *(*_readline)(const char *); static void (*_add_history)(char *); #ifdef DEBUG #ifdef __clang__ static void (*_free)(void*); if (_free == 0) _free = (void (*)(void*))dlsym(RTLD_NEXT, "free"); #else #define _free __real_free #endif #else #define _free free #endif if (!_init) { _init = true; #ifdef __clang__ void *handle = dlopen("libreadline.dylib", RTLD_LAZY); #else const char *readline_dylib_names[] = { "libreadline.so.6", "libreadline.so.5", "libreadline.so" }; const size_t readline_dylib_names_size = ARRAYSIZE(readline_dylib_names); void *handle = 0; for (size_t i = 0; i < readline_dylib_names_size; i++) { handle = dlopen(readline_dylib_names[i], RTLD_LAZY); if (handle) break; } #endif if (handle) { _readline = (char *(*)(const char *))dlsym(handle, "readline"); _add_history = (void (*)(char *))dlsym(handle, "add_history"); } else { _readline = readline; _add_history = add_history; } } if (isatty(fileno(stdin))) { char *line; const char* lfptr = qstrrchr(msg.c_str(), '\n'); if (lfptr != NULL) { puts(msg.substr(0, lfptr - msg.c_str()).c_str()); line = _readline(lfptr + 1); } else line = _readline(msg.c_str()); if (!line) return CHECK_ERROR(LastError()); if (*line) { _add_history(line); retVal = line; } _free(line); } else #endif { std_logger::out(msg); char *line = read_line(); if (!line) return CHECK_ERROR(LastError()); retVal = line; free(line); } return 0; }
/** * readline() 実行 * * @param[in] data テストデータ * @param[in] length バイト数 * @return 結果文字列 */ static unsigned char * exec_readline(char *data, size_t length) { FILE *fp = NULL; /* ファイルポインタ */ int retval = 0; /* 戻り値 */ pid_t cpid = 0; /* プロセスID */ pid_t w = 0; /* wait戻り値 */ int status = 0; /* ステイタス */ ssize_t len = 0; /* writen 戻り値 */ retval = pipe(pfd); if (retval < 0) { cut_error("pipe=%d", retval); return NULL; } fp = fdopen(pfd[PIPE_R], "r"); if (!fp) { cut_error("fdopen=%p", fp); return NULL; } cpid = fork(); if (cpid < 0) { cut_error("fork(%d)", errno); return NULL; } if (cpid == 0) { /* 子プロセス */ dbglog("child"); close_fd(&pfd[PIPE_R], NULL); /* 送信 */ len = writen(pfd[PIPE_W], data, length); if (len < 0) { outlog("writen"); close_fd(&pfd[PIPE_W], NULL); exit(EXIT_FAILURE); } close_fd(&pfd[PIPE_W], NULL); exit(EXIT_SUCCESS); } else { /* 親プロセス */ dbglog("parent: cpid=%d", (int)cpid); close_fd(&pfd[PIPE_W], NULL); /* テスト関数の実行 */ /* 受信待ち */ result = _readline(fp); dbglog("result=%s", result); close_fd(&pfd[PIPE_R], NULL); w = waitpid(-1, &status, WNOHANG); if (w < 0) cut_notify("wait: status=%d(%d)", status, errno); dbglog("w=%d", (int)w); if (WEXITSTATUS(status)) { cut_notify("child error"); return NULL; } } return result; }
int lsreg_parse_bundle(FILE *f, char *linebuf, size_t linebufsize, char *line, size_t linelen, char *key, size_t keylen, char *val, size_t vallen, lsreg_rec_t *record) { char *s; lsreg_bundle_t *bundle = (lsreg_bundle_t *)record->rec; // The "library items" key is special if( (keylen == 13) && (memcmp(key, "library items", keylen) == 0) ) { // Copy normal identifier to canonical if same. // We know "library items" always comes after canonical id, // so if it's not set, we know it does not exist, thus the // normal identifier IS canonical. if(bundle->canonical_identifier.name == NULL && bundle->identifier.name != NULL) { bundle->canonical_identifier.name = strdup(bundle->identifier.name); bundle->canonical_identifier.hash = bundle->identifier.hash; } if(vallen) { size_t vsize, vlen; vsize = 2; vlen = 0; bundle->library_items = (char **)malloc(sizeof(char *)*vsize); // Add first item bundle->library_items[vlen++] = strdup(val); while( (line = _readline(linebuf, linebufsize, f)) ) { linelen = strlen(line); // Prefix signature // "\t " 1+15 if(linelen > 16 && line[0] == '\t' && line[1] == ' ' && line[2] == ' ') { if(vlen == vsize) { vsize *= 2; bundle->library_items = (char **)realloc(bundle->library_items, sizeof(char *)*vsize); } line = _memltrim(line, &linelen); STRCREATE(s, line, linelen-1); bundle->library_items[vlen++] = s; } else { // we're done reading library items. Realloc and save. bundle->library_items = (char **)realloc(bundle->library_items, sizeof(char *)*(vlen+1)); bundle->library_items[vlen] = NULL; /* sentinel */ break; } } // end while } } // <- if library items // The "properties" key is also special else if( (keylen == 10) && (memcmp(key, "properties", keylen) == 0) ) { int known_to_be_plist = 0; while( (line = _readline(linebuf, linebufsize, f)) ) { linelen = strlen(line); if(!known_to_be_plist) { if(line[0] == '\t') { log_error("Expected plist xml document but found new key. This is probably a bug."); break; } known_to_be_plist = 1; } if( (linelen > 7) && (memcmp(line, "</plist>", 8) == 0) ) { // We have now passed the properties chunk break; } } } else { // Set key and value in the bundle struct lsreg_bundle_nset(bundle, key, keylen, val, vallen); } return (line == NULL) ? kLSRegParseStatusDone : kLSRegParseStatusContinue; }
/* * hostsfile_clusterlist_setup * * hostsfile clusterlist module setup function. Open hostsfile, read * each line of the hostsfile, and save hosts into hosts list. */ static int hostsfile_clusterlist_setup(void) { int len, fd = -1; char buf[HOSTSFILE_PARSE_BUFLEN]; char *p; if (hosts) { CEREBRO_DBG(("hosts non-null")); return 0; } if (!(hosts = list_create((ListDelF)free))) { CEREBRO_ERR(("list_create: %s", strerror(errno))); goto cleanup; } if ((fd = open(CEREBRO_CLUSTERLIST_HOSTSFILE_DEFAULT, O_RDONLY)) < 0) { CEREBRO_ERR(("hostsfile '%s' cannot be opened: %s", CEREBRO_CLUSTERLIST_HOSTSFILE_DEFAULT, strerror(errno))); goto cleanup; } while ((len = _readline(fd, buf, HOSTSFILE_PARSE_BUFLEN)) > 0) { char *hostPtr; char *str; if (!(len = _remove_comments(buf, len))) continue; if (len < 0) goto cleanup; if (!(len = _remove_trailing_whitespace(buf, len))) continue; if (len < 0) goto cleanup; if (!(hostPtr = _move_past_whitespace(buf))) goto cleanup; if (hostPtr[0] == '\0') continue; if (strchr(hostPtr, ' ') || strchr(hostPtr, '\t')) { cerebro_err_output("hostsfile host contains whitespace"); goto cleanup; } if (strlen(hostPtr) > CEREBRO_MAX_NODENAME_LEN) { cerebro_err_output("hostsfile node '%s' exceeds max length", hostPtr); goto cleanup; } /* Shorten hostname if necessary */ if ((p = strchr(hostPtr, '.'))) *p = '\0'; if (!(str = strdup(hostPtr))) { CEREBRO_ERR(("strdup: %s", strerror(errno))); goto cleanup; } if (!list_append(hosts, str)) { CEREBRO_ERR(("list_append: %s", strerror(errno))); goto cleanup; } } if (len < 0) goto cleanup; /* ignore potential error, just return result */ close(fd); return 0; cleanup: /* ignore potential error, just return result */ close(fd); if (hosts) list_destroy(hosts); hosts = NULL; return -1; }
int conffile_parse(conffile_t cf, const char *filename, struct conffile_option *options, int options_len, void *app_ptr, int app_data, int flags) { int i, temp, len = 0, retval = -1; char linebuf[CONFFILE_MAX_LINELEN]; if (cf == NULL || cf->magic != CONFFILE_MAGIC) return -1; if (options == NULL || options_len <= 0) { cf->errnum = CONFFILE_ERR_PARAMETERS; return -1; } /* Ensure option array is legitimate */ for (i = 0; i < options_len; i++) { if (options[i].optionname == NULL || strlen(options[i].optionname) >= CONFFILE_MAX_OPTIONNAMELEN || options[i].option_type < CONFFILE_OPTION_IGNORE || options[i].option_type > CONFFILE_OPTION_LIST_STRING || ((options[i].option_type != CONFFILE_OPTION_IGNORE && options[i].option_type != CONFFILE_OPTION_FLAG) && options[i].callback_func == NULL) || ((options[i].option_type == CONFFILE_OPTION_LIST_INT || options[i].option_type == CONFFILE_OPTION_LIST_DOUBLE || options[i].option_type == CONFFILE_OPTION_LIST_STRING) && ((int)options[i].option_type_arg) == 0) || options[i].required_count < 0 || (options[i].option_type != CONFFILE_OPTION_IGNORE && options[i].count_ptr == NULL)) { cf->errnum = CONFFILE_ERR_PARAMETERS; return -1; } } /* Ensure flags are appropriate */ temp = flags; temp &= ~CONFFILE_FLAG_OPTION_CASESENSITIVE; temp &= ~CONFFILE_FLAG_OPTION_IGNORE_UNKNOWN; if (temp) { cf->errnum = CONFFILE_ERR_PARAMETERS; return -1; } if (_setup(cf, filename, options, options_len, app_ptr, app_data, flags) < 0) goto cleanup; while (cf->end_of_file == 0 && (len = _readline(cf, linebuf, CONFFILE_MAX_LINELEN)) > 0) { if (_parseline(cf, linebuf, len) < 0) goto cleanup; } if (len < 0) goto cleanup; cf->line_num = 0; /* Check required counts */ for (i = 0; i < cf->options_len; i++) { if (cf->options[i].count_ptr == NULL) continue; if ((*cf->options[i].count_ptr) < cf->options[i].required_count) { strcpy(cf->optionname, cf->options[i].optionname); cf->errnum = CONFFILE_ERR_PARSE_OPTION_TOOFEW; goto cleanup; } } cf->errnum = CONFFILE_ERR_SUCCESS; retval = 0; cleanup: /* ignore potential error, just return result to user */ close(cf->fd); return retval; }