int main(int argc, char **argv) { if (argc == 5 && !strcmp(argv[1], "split")) { struct string_list list = STRING_LIST_INIT_DUP; int i; const char *s = argv[2]; int delim = *argv[3]; int maxsplit = atoi(argv[4]); i = string_list_split(&list, s, delim, maxsplit); printf("%d\n", i); write_list(&list); string_list_clear(&list, 0); return 0; } if (argc == 5 && !strcmp(argv[1], "split_in_place")) { struct string_list list = STRING_LIST_INIT_NODUP; int i; char *s = xstrdup(argv[2]); int delim = *argv[3]; int maxsplit = atoi(argv[4]); i = string_list_split_in_place(&list, s, delim, maxsplit); printf("%d\n", i); write_list(&list); string_list_clear(&list, 0); free(s); return 0; } if (argc == 4 && !strcmp(argv[1], "filter")) { /* * Retain only the items that have the specified prefix. * Arguments: list|- prefix */ struct string_list list = STRING_LIST_INIT_DUP; const char *prefix = argv[3]; parse_string_list(&list, argv[2]); filter_string_list(&list, 0, prefix_cb, (void *)prefix); write_list_compact(&list); string_list_clear(&list, 0); return 0; } if (argc == 3 && !strcmp(argv[1], "remove_duplicates")) { struct string_list list = STRING_LIST_INIT_DUP; parse_string_list(&list, argv[2]); string_list_remove_duplicates(&list, 0); write_list_compact(&list); string_list_clear(&list, 0); return 0; } fprintf(stderr, "%s: unknown function name: %s\n", argv[0], argv[1] ? argv[1] : "(there was none)"); return 1; }
static void parse_record_int(RECDB *recdb, char **pname, struct record_data **prd) { int c; *pname = parse_qstring(recdb); c = parse_skip_ws(recdb); if (c == EOF) { if (!*pname) return; free(*pname); ABORT(recdb, EXPECTED_RECORD_DATA, EOF); } if (c == '=') c = parse_skip_ws(recdb); dbungetc(c, recdb); *prd = malloc(sizeof(**prd)); switch (c) { case '"': /* Don't use SET_RECORD_QSTRING, since that does an extra strdup() of the string. */ (*prd)->type = RECDB_QSTRING; (*prd)->d.qstring = parse_qstring(recdb); break; case '{': SET_RECORD_OBJECT(*prd, parse_object(recdb)); break; case '(': SET_RECORD_STRING_LIST(*prd, parse_string_list(recdb)); break; default: ABORT(recdb, EXPECTED_START_RECORD_DATA, c); } if ((c = parse_skip_ws(recdb)) != ';') ABORT(recdb, EXPECTED_SEMICOLON, c); }
/* * client-lease-declaration :== * BOOTP | * INTERFACE string | * FIXED_ADDR ip_address | * FILENAME string | * SERVER_NAME string | * OPTION option-decl | * RENEW time-decl | * REBIND time-decl | * EXPIRE time-decl */ void parse_client_lease_declaration(FILE *cfile, struct client_lease *lease) { char *val; int token; switch (next_token(&val, cfile)) { case TOK_BOOTP: lease->is_bootp = 1; break; case TOK_INTERFACE: token = next_token(&val, cfile); if (token != TOK_STRING) { parse_warn("expecting interface name (in quotes)."); skip_to_semi(cfile); break; } if (strcmp(ifi->name, val) != 0) { parse_warn("wrong interface name. Expecting '%s'.", ifi->name); skip_to_semi(cfile); break; } break; case TOK_FIXED_ADDR: if (!parse_ip_addr(cfile, &lease->address)) return; break; case TOK_MEDIUM: parse_string_list(cfile, &lease->medium, 0); return; case TOK_FILENAME: lease->filename = parse_string(cfile); return; case TOK_SERVER_NAME: lease->server_name = parse_string(cfile); return; case TOK_RENEW: lease->renewal = parse_date(cfile); return; case TOK_REBIND: lease->rebind = parse_date(cfile); return; case TOK_EXPIRE: lease->expiry = parse_date(cfile); return; case TOK_OPTION: parse_option_decl(cfile, lease->options); return; default: parse_warn("expecting lease declaration."); skip_to_semi(cfile); break; } token = next_token(&val, cfile); if (token != ';') { parse_warn("expecting semicolon."); skip_to_semi(cfile); } }
/* * client-lease-declaration :== * BOOTP | * INTERFACE string | * FIXED_ADDR ip_address | * FILENAME string | * SERVER_NAME string | * OPTION option-decl | * RENEW time-decl | * REBIND time-decl | * EXPIRE time-decl */ void parse_client_lease_declaration(FILE *cfile, struct client_lease *lease, struct interface_info **ipp) { int token; char *val; struct interface_info *ip; switch (next_token(&val, cfile)) { case BOOTP: lease->is_bootp = 1; break; case INTERFACE: token = next_token(&val, cfile); if (token != STRING) { parse_warn("expecting interface name (in quotes)."); skip_to_semi(cfile); break; } ip = interface_or_dummy(val); *ipp = ip; break; case FIXED_ADDR: if (!parse_ip_addr(cfile, &lease->address)) return; break; case MEDIUM: parse_string_list(cfile, &lease->medium, 0); return; case FILENAME: lease->filename = parse_string(cfile); return; case SERVER_NAME: lease->server_name = parse_string(cfile); return; case RENEW: lease->renewal = parse_date(cfile); return; case REBIND: lease->rebind = parse_date(cfile); return; case EXPIRE: lease->expiry = parse_date(cfile); return; case OPTION: parse_option_decl(cfile, lease->options); return; default: parse_warn("expecting lease declaration."); skip_to_semi(cfile); break; } token = next_token(&val, cfile); if (token != SEMI) { parse_warn("expecting semicolon."); skip_to_semi(cfile); } }
static char *modem_read_new_version(const char *dirname, char *version, size_t size) { ssize_t prop_count; struct modem_prop props[100]; struct modem_prop *prop_tmp; prop_count = parse_string_list(dirname, props, ARRAY_SIZE(props)); if (prop_count < 0) { error_msg("parse_string_list"); return NULL; } prop_tmp = modem_find_prop(props, prop_count, MODEM_VERSION_PROP_NAME); if (prop_tmp == NULL) { return NULL; } text_ncopy(version, prop_tmp->value, size); return version; }
static cmd_ln_val_t * cmd_ln_val_init(int t, const char *str) { cmd_ln_val_t *v; anytype_t val; char *e_str; if (!str) { /* For lack of a better default value. */ memset(&val, 0, sizeof(val)); } else { int valid = 1; e_str = arg_resolve_env(str); switch (t) { case ARG_INTEGER: case REQARG_INTEGER: if (sscanf(e_str, "%ld", &val.i) != 1) valid = 0; break; case ARG_FLOATING: case REQARG_FLOATING: if (e_str == NULL || e_str[0] == 0) valid = 0; val.fl = atof_c(e_str); break; case ARG_BOOLEAN: case REQARG_BOOLEAN: if ((e_str[0] == 'y') || (e_str[0] == 't') || (e_str[0] == 'Y') || (e_str[0] == 'T') || (e_str[0] == '1')) { val.i = TRUE; } else if ((e_str[0] == 'n') || (e_str[0] == 'f') || (e_str[0] == 'N') || (e_str[0] == 'F') | (e_str[0] == '0')) { val.i = FALSE; } else { E_ERROR("Unparsed boolean value '%s'\n", str); valid = 0; } break; case ARG_STRING: case REQARG_STRING: val.ptr = ckd_salloc(e_str); break; case ARG_STRING_LIST: val.ptr = parse_string_list(e_str); break; default: E_ERROR("Unknown argument type: %d\n", t); valid = 0; } ckd_free(e_str); if (valid == 0) return NULL; } v = ckd_calloc(1, sizeof(*v)); memcpy(v, &val, sizeof(val)); v->type = t; return v; }
/* * client-declaration :== * TOK_SEND option-decl | * TOK_DEFAULT option-decl | * TOK_SUPERSEDE option-decl | * TOK_APPEND option-decl | * TOK_PREPEND option-decl | * TOK_MEDIA string-list | * hardware-declaration | * TOK_REQUEST option-list | * TOK_REQUIRE option-list | * TOK_TIMEOUT number | * TOK_RETRY number | * TOK_SELECT_TIMEOUT number | * TOK_REBOOT number | * TOK_BACKOFF_CUTOFF number | * TOK_INITIAL_INTERVAL number | * TOK_SCRIPT string | * interface-declaration | * TOK_LEASE client-lease-statement | * TOK_ALIAS client-lease-statement | * TOK_REJECT reject-statement */ void parse_client_statement(FILE *cfile) { char *val; int token, code; switch (next_token(&val, cfile)) { case TOK_SEND: parse_option_decl(cfile, &config->send_options[0]); return; case TOK_DEFAULT: code = parse_option_decl(cfile, &config->defaults[0]); if (code != -1) config->default_actions[code] = ACTION_DEFAULT; return; case TOK_SUPERSEDE: code = parse_option_decl(cfile, &config->defaults[0]); if (code != -1) config->default_actions[code] = ACTION_SUPERSEDE; return; case TOK_APPEND: code = parse_option_decl(cfile, &config->defaults[0]); if (code != -1) config->default_actions[code] = ACTION_APPEND; return; case TOK_PREPEND: code = parse_option_decl(cfile, &config->defaults[0]); if (code != -1) config->default_actions[code] = ACTION_PREPEND; return; case TOK_MEDIA: parse_string_list(cfile, &config->media, 1); return; case TOK_HARDWARE: parse_hardware_param(cfile, &ifi->hw_address); return; case TOK_REQUEST: config->requested_option_count = parse_option_list(cfile, config->requested_options); return; case TOK_REQUIRE: memset(config->required_options, 0, sizeof(config->required_options)); parse_option_list(cfile, config->required_options); return; case TOK_LINK_TIMEOUT: parse_lease_time(cfile, &config->link_timeout); return; case TOK_TIMEOUT: parse_lease_time(cfile, &config->timeout); return; case TOK_RETRY: parse_lease_time(cfile, &config->retry_interval); return; case TOK_SELECT_TIMEOUT: parse_lease_time(cfile, &config->select_interval); return; case TOK_REBOOT: parse_lease_time(cfile, &config->reboot_timeout); return; case TOK_BACKOFF_CUTOFF: parse_lease_time(cfile, &config->backoff_cutoff); return; case TOK_INITIAL_INTERVAL: parse_lease_time(cfile, &config->initial_interval); return; case TOK_SCRIPT: config->script_name = parse_string(cfile); return; case TOK_INTERFACE: parse_interface_declaration(cfile); return; case TOK_LEASE: parse_client_lease_statement(cfile, 1); return; case TOK_ALIAS: parse_client_lease_statement(cfile, 2); return; case TOK_REJECT: parse_reject_statement(cfile); return; default: parse_warn("expecting a statement."); skip_to_semi(cfile); break; } token = next_token(&val, cfile); if (token != ';') { parse_warn("semicolon expected."); skip_to_semi(cfile); } }
List *mms_mmbox_search(char *mmbox_root, char *user, List *state, List *flag_cmds, int start, int limit, List *msgrefs) { int tmpfd = -1; FILE *fp = NULL; char linbuf[1024]; Octstr *home = user_mmbox_dir(mmbox_root,user); List *flags = NULL; List *dflist = NULL; int ifd = -1; int ct; ifd = open_mmbox_index(octstr_get_cstr(home),1); if (ifd < 0) goto done; if ((tmpfd = dup(ifd)) < 0 || (fp = fdopen(tmpfd, "r")) == NULL) { error(0, "mmbox.search_index: %s Failed to dup descriptor for index " "file, fp = %p: error = %s\n", octstr_get_cstr(home), fp, strerror(errno)); goto done; } flags = make_mm_flags(NULL, flag_cmds); ct = 1; dflist = gwlist_create(); while (fgets(linbuf, sizeof linbuf, fp) != NULL) { char idx[128], xstate[32]; List *xflags = NULL; int i, size; int match = (!state && (!msgrefs || gwlist_len(msgrefs) == 0) && (!xflags || gwlist_len(xflags) == 0)); sscanf(linbuf, "%s %s %d%n", idx, xstate, &size, &i); /* search: by id list if given, by states if given, by flags if given */ if (!match && state && gwlist_search(state, xstate, (gwlist_item_matches_t *)_x_octstr_str_compare) != NULL) match = 1; /* For the rest we only match if nothing else matched. Save time */ replace_slash(idx); if (!match && msgrefs && gwlist_search(msgrefs, idx, (gwlist_item_matches_t *)_x_octstr_str_compare) != NULL) match = 1; if (!match && flag_cmds && ((xflags = parse_string_list(linbuf + i)) != NULL && gwlist_search(xflags, flags, (gwlist_item_matches_t *)string_in_list) != NULL)) match = 1; if (match && ct >= start && gwlist_len(dflist) <= limit) { Octstr *x = octstr_create(idx); /* octstr_replace(x, octstr_imm("/"), octstr_imm("-")); */ gwlist_append(dflist, x); } ct++; if (xflags) gwlist_destroy(xflags, (gwlist_item_destructor_t *)octstr_destroy); } done: if (fp) unlock_and_fclose(fp); else if (tmpfd) unlock_and_close(tmpfd); if (ifd > 0) unlock_and_close(ifd); if (flags) gwlist_destroy(flags, (gwlist_item_destructor_t *)octstr_destroy); if (home) octstr_destroy(home); return dflist; }
int kowhai_protocol_parse(void* proto_packet, int packet_size, struct kowhai_protocol_t* protocol) { int required_size = sizeof(struct kowhai_protocol_header_t); memset(protocol, 0, sizeof(struct kowhai_protocol_t)); // check packet is large enough for header if (packet_size < required_size) return KOW_STATUS_PACKET_BUFFER_TOO_SMALL; memcpy(&protocol->header, proto_packet, required_size); switch (protocol->header.command) { case KOW_CMD_GET_VERSION: return KOW_STATUS_OK; case KOW_CMD_GET_VERSION_ACK: return parse_version((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload); case KOW_CMD_GET_TREE_LIST: return KOW_STATUS_OK; case KOW_CMD_GET_TREE_LIST_ACK: case KOW_CMD_GET_TREE_LIST_ACK_END: case KOW_CMD_GET_FUNCTION_LIST_ACK: case KOW_CMD_GET_FUNCTION_LIST_ACK_END: return parse_id_list((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload); case KOW_CMD_READ_DATA: return parse_symbols((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload, &required_size); case KOW_CMD_WRITE_DATA: case KOW_CMD_WRITE_DATA_END: case KOW_CMD_WRITE_DATA_ACK: case KOW_CMD_READ_DATA_ACK: case KOW_CMD_READ_DATA_ACK_END: return parse_data_payload((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload); case KOW_CMD_READ_DESCRIPTOR: // read descriptor command requires no more parameters return KOW_STATUS_OK; case KOW_CMD_READ_DESCRIPTOR_ACK: case KOW_CMD_READ_DESCRIPTOR_ACK_END: return parse_descriptor_payload((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload); case KOW_CMD_GET_FUNCTION_LIST: case KOW_CMD_GET_FUNCTION_DETAILS: // get function list/details command requires no more parameters return KOW_STATUS_OK; case KOW_CMD_GET_FUNCTION_DETAILS_ACK: return parse_function_details((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload.spec.function_details); case KOW_CMD_CALL_FUNCTION: case KOW_CMD_CALL_FUNCTION_ACK: case KOW_CMD_CALL_FUNCTION_RESULT: case KOW_CMD_CALL_FUNCTION_RESULT_END: return parse_function_call((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload); case KOW_CMD_CALL_FUNCTION_FAILED: return KOW_STATUS_OK; case KOW_CMD_EVENT: case KOW_CMD_EVENT_END: return parse_event((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload); case KOW_CMD_GET_SYMBOL_LIST: return KOW_STATUS_OK; case KOW_CMD_GET_SYMBOL_LIST_ACK: case KOW_CMD_GET_SYMBOL_LIST_ACK_END: return parse_string_list((void*)((uint8_t*)proto_packet + required_size), packet_size - required_size, &protocol->payload); // error codes case KOW_CMD_ERROR_INVALID_COMMAND: case KOW_CMD_ERROR_INVALID_FUNCTION_ID: case KOW_CMD_ERROR_INVALID_PAYLOAD_OFFSET: case KOW_CMD_ERROR_INVALID_PAYLOAD_SIZE: case KOW_CMD_ERROR_INVALID_SEQUENCE: case KOW_CMD_ERROR_INVALID_SYMBOL_PATH: case KOW_CMD_ERROR_INVALID_TREE_ID: case KOW_CMD_ERROR_NO_DATA: return KOW_STATUS_OK; default: return KOW_STATUS_INVALID_PROTOCOL_COMMAND; } }
/* * client-declaration :== * SEND option-decl | * DEFAULT option-decl | * SUPERSEDE option-decl | * PREPEND option-decl | * APPEND option-decl | * hardware-declaration | * REQUEST option-list | * REQUIRE option-list | * TIMEOUT number | * RETRY number | * REBOOT number | * SELECT_TIMEOUT number | * SCRIPT string | * interface-declaration | * LEASE client-lease-statement | * ALIAS client-lease-statement */ void parse_client_statement(FILE *cfile, struct interface_info *ip, struct client_config *config) { int token; char *val; struct option *option; switch (next_token(&val, cfile)) { case SEND: parse_option_decl(cfile, &config->send_options[0]); return; case DEFAULT: option = parse_option_decl(cfile, &config->defaults[0]); if (option) config->default_actions[option->code] = ACTION_DEFAULT; return; case SUPERSEDE: option = parse_option_decl(cfile, &config->defaults[0]); if (option) config->default_actions[option->code] = ACTION_SUPERSEDE; return; case APPEND: option = parse_option_decl(cfile, &config->defaults[0]); if (option) config->default_actions[option->code] = ACTION_APPEND; return; case PREPEND: option = parse_option_decl(cfile, &config->defaults[0]); if (option) config->default_actions[option->code] = ACTION_PREPEND; return; case MEDIA: parse_string_list(cfile, &config->media, 1); return; case HARDWARE: if (ip) parse_hardware_param(cfile, &ip->hw_address); else { parse_warn("hardware address parameter %s", "not allowed here."); skip_to_semi(cfile); } return; case REQUEST: config->requested_option_count = parse_option_list(cfile, config->requested_options); return; case REQUIRE: memset(config->required_options, 0, sizeof(config->required_options)); parse_option_list(cfile, config->required_options); return; case TIMEOUT: parse_lease_time(cfile, &config->timeout); return; case RETRY: parse_lease_time(cfile, &config->retry_interval); return; case SELECT_TIMEOUT: parse_lease_time(cfile, &config->select_interval); return; case REBOOT: parse_lease_time(cfile, &config->reboot_timeout); return; case BACKOFF_CUTOFF: parse_lease_time(cfile, &config->backoff_cutoff); return; case INITIAL_INTERVAL: parse_lease_time(cfile, &config->initial_interval); return; case SCRIPT: config->script_name = parse_string(cfile); return; case INTERFACE: if (ip) parse_warn("nested interface declaration."); parse_interface_declaration(cfile, config); return; case LEASE: parse_client_lease_statement(cfile, 1); return; case ALIAS: parse_client_lease_statement(cfile, 2); return; case REJECT: parse_reject_statement(cfile, config); return; default: parse_warn("expecting a statement."); skip_to_semi(cfile); break; } token = next_token(&val, cfile); if (token != SEMI) { parse_warn("semicolon expected."); skip_to_semi(cfile); } }