static int request_md5(int argc, char* argv[]) { int vmid = 0; size_t storage_size = 0; if(argc == 2) { if(!is_uint32(argv[1])) goto failure; vmid = parse_uint32(argv[1]); } else if(argc == 3) { if(!is_uint32(argv[1])) goto failure; vmid = parse_uint32(argv[1]); if(!is_uint32(argv[2])) goto failure; storage_size = parse_uint32(argv[2]); } else { goto failure; } // Request MD5 value & Register Response callback handler rpc_storage_md5(rpc, vmid, storage_size, response_md5, NULL); return 0; failure: help(); exit(1); }
static int upload(int argc, char** argv) { if(argc < 3 || argc > 4) { help(); return -1; } if(!is_uint32(argv[1])) { help(); return -2; } if(strlen(argv[2]) >= 256) { help(); return -3; } if(argc == 4) { if(!is_uint32(argv[3])) { help(); return -4; } } uint32_t vmid = parse_uint32(argv[1]); FileInfo* file_info = malloc(sizeof(FileInfo)); if(file_info == NULL) { return -5; } memset(file_info, 0, sizeof(FileInfo)); file_info->fd = open(argv[2], O_RDONLY); if(file_info->fd < 0) { free(file_info); return -6; } file_info->file_size = lseek(file_info->fd, 0, SEEK_END); lseek(file_info->fd, 0, SEEK_SET); file_info->offset = 0; if(argc == 4) { uint32_t size = parse_uint32(argv[3]); if(size > file_info->file_size) { printf("File size is smaller than paramter\n"); return -7; } file_info->file_size = size; } struct timeval tv; gettimeofday(&tv, NULL); file_info->current_time = tv.tv_sec * 1000 * 1000 + tv.tv_usec; rpc_storage_upload(rpc, vmid, callback_storage_upload, file_info); return 0; }
static int download(int argc, char** argv) { if(argc < 3) { help(); return -1; } if(!is_uint32(argv[1])) { help(); return -2; } if(strlen(argv[2]) >= 256) { help(); return -3; } uint32_t vmid = parse_uint32(argv[1]); FileInfo* file_info = (FileInfo*)malloc(sizeof(FileInfo));; if(file_info == NULL) { return -4; } memset(file_info, 0, sizeof(FileInfo)); file_info->fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0755); if(file_info->fd < 0) { free(file_info); return -5; } strcpy(file_info->path, argv[2]); lseek(file_info->fd, 0, SEEK_SET); uint64_t download_size = 0; if(argc == 4) { if(!is_uint32(argv[3])) return -6; download_size = parse_uint32(argv[3]); } else { download_size = 0; } file_info->offset = 0; struct timeval tv; gettimeofday(&tv, NULL); file_info->current_time = tv.tv_sec * 1000 * 1000 + tv.tv_usec; rpc_storage_download(rpc, vmid, download_size, callback_storage_download, file_info); return 0; }
int parse_write32() { char *arg = strtok(NULL, " "); uint32_t val; if(!arg || !parse_uint32(arg, &val)) return syntax_error(arg); uint32_t addr; arg = strtok(NULL, " "); if(arg && parse_uint32(arg, &addr)) return do_write32(val, addr); else return syntax_error(arg); }
void decode_end_request( in_segment_t const &status, uint32_t &app_status, uint8_t &code ) { in_t::ptr_t ptr = status; app_status = parse_uint32(ptr); code = *ptr; }
/** * Break the netmaks string and convert them into network_pair elements in * the local_networks array. IP's are in network order. */ void parse_netmasks(const char *str) { char **masks = g_strsplit(str, ";", 0); char *p; guint32 mask_div; int i; free_networks(); if (!masks) return; for (i = 0; masks[i]; i++) /* just count */ ; number_local_networks = i; if (i == 0) { g_strfreev(masks); return; } local_networks = g_malloc(i * sizeof *local_networks); for (i = 0; masks[i]; i++) { /* Network is of the form ip/mask or ip/bits */ if ((p = strchr(masks[i], '/')) && *p) { *p++ = '\0'; if (strchr(p, '.')) { /* get the network address from the user */ if (!string_to_ip_strict(p, &local_networks[i].mask, NULL)) g_warning("parse_netmasks(): Invalid netmask: \"%s\"", p); } else { int error; mask_div = parse_uint32(p, NULL, 10, &error); mask_div = MIN(32, mask_div); if (error) g_warning("parse_netmasks(): " "Invalid CIDR prefixlen: \"%s\"", p); else local_networks[i].mask = (guint32) -1 << (32 - mask_div); } } else { /* Assume single-host */ local_networks[i].mask = -1; /* 255.255.255.255 */ } /* get the network address from the user */ if (!string_to_ip_strict(masks[i], &local_networks[i].net, NULL)) g_warning("parse_netmasks(): Invalid netmask: \"%s\"", masks[i]); } g_strfreev(masks); }
int parse_call() { char *arg = strtok(NULL, " "); uint32_t addr; if(arg && parse_uint32(arg, &addr)) return do_call(addr); else return syntax_error(arg); }
/* * scontrol_update_powercap - update the slurm powercapping configuration per the * supplied arguments * IN argc - count of arguments * IN argv - list of arguments * RET 0 if no slurm error, errno otherwise. parsing error prints * error message and returns 0 */ extern int scontrol_update_powercap (int argc, char *argv[]) { update_powercap_msg_t powercap_msg; int i; char *tag, *val; int taglen, vallen; memset(&powercap_msg, 0, sizeof(update_powercap_msg_t)); powercap_msg.powercap = (uint32_t) NO_VAL; powercap_msg.min_watts = (uint32_t) NO_VAL; powercap_msg.cur_max_watts = (uint32_t) NO_VAL; powercap_msg.adj_max_watts = (uint32_t) NO_VAL; powercap_msg.max_watts = (uint32_t) NO_VAL; for (i=0; i<argc; i++) { tag = argv[i]; val = strchr(argv[i], '='); if (val) { taglen = val - argv[i]; val++; vallen = strlen(val); } else { exit_code = 1; error("Invalid input: %s Request aborted", argv[i]); return -1; } if (strncasecmp(tag, "PowerCap", MAX(taglen, 8)) == 0) { if (strncasecmp(val, "INFINITE", MAX(vallen, 8)) == 0 ) { powercap_msg.powercap = (uint32_t) INFINITE; } else if (parse_uint32(val,&(powercap_msg.powercap))) { error("Invalid PowerCap value: %s", val); return -1; } /* for now, we can break as we do not have other args */ break; } } if (powercap_msg.powercap == (uint32_t) NO_VAL) { exit_code = 1; error("Invalid PowerCap value."); return 0; } if (slurm_update_powercap(&powercap_msg)) { exit_code = 1; return slurm_get_errno (); } else return 0; }
char * http_parse_version(http_t *ctx, const char *s) { char *endptr; uint32_t u; int error; RUNTIME_ASSERT(ctx); s = skip_prefix(s, "HTTP/"); if (!s) { /* Not a valid HTTP version */ return NULL; } u = parse_uint32(s, &endptr, 10, &error); if (error || 0 == u) { /* No valid http major version */ return NULL; } ctx->major = u; if ('.' != *endptr) { /* Missing dot after major version number */ return NULL; } s = ++endptr; u = parse_uint32(s, &endptr, 10, &error); if (error) { /* No valid http minor version */ return NULL; } if (*endptr != '\0' && !isspace((unsigned char) *endptr)) { /* Invalid http minor version */ return NULL; } ctx->minor = u; return endptr; }
static void var_set_slots(DCVariable *var, int argc, char **argv) { if (argc > 2) { warn(_("too many arguments\n")); return; } if (!parse_uint32(argv[1], &my_ul_slots)) screen_putf(_("Invalid slot number `%s'\n"), quotearg(argv[1])); if (hub_state >= DC_HUB_LOGGED_IN) send_my_info(); }
int main() { std::cout << " host is " << (is_big_endian() ? "big endian\n" : "little endian\n"); unsigned int uliteral = 0x456e7120; int sliteral = 0x456e7120; std::cout << " unsigned 0x456e7120 = " << uliteral << "\n"; std::cout << " signed 0x456e7120 = " << sliteral << "\n"; std::stringstream sstr(std::ios::binary); // Write 0x456e7120 in little endian to stream sstr << 0x20 << 0x71 << 0x6e << 0x45 << std::flush; std::cout << " " << parse_uint32(std::istreambuf_iterator<char>(sstr)) << "\n"; return 0; }
int parse_string(struct simple_buffer *buffer, uint32_t *length, const uint8_t **start) { uint32_t l; if (!parse_uint32(buffer, &l)) return 0; if (LEFT < l) return 0; *length = l; *start = HERE; ADVANCE(l); return 1; }
/** * Parse argument from specified name/value table into an unsigned 32-bit. * * @param nvt the name/value table holding arguments * @param name the argument name whose value we need to parse * @param valp where to put the parsed value * * @return TRUE if OK with the value filled in, FALSE on failure. */ static gboolean upnp_ctrl_get_uint32(nv_table_t *nvt, const char *name, guint32 *valp) { const char *value; guint32 val; int error; value = nv_table_lookup_str(nvt, name); if (NULL == value) return FALSE; val = parse_uint32(value, NULL, 10, &error); if (error) return FALSE; *valp = val; return TRUE; }
static void var_set_filelist_refresh_interval(DCVariable *var, int argc, char **argv) { unsigned int interval; if (argc > 2) { warn(_("too many arguments\n")); return; } if (argv[1][0] == '\0') { interval = 0; } else { if (!parse_uint32(argv[1], &interval)) { screen_putf(_("Invalid value `%s' for interval.\n"), quotearg(argv[1])); return; } } filelist_refresh_timeout = interval; update_request_set_filelist_refresh_timeout(filelist_refresh_timeout); }
/** * Parse hostname:port and return the hostname and port parts. * * @param hp host:port string * @param host where the pointer to the hostname is returned (static data) * @param port where the port is written to * * @return TRUE if we successfully parsed the string. */ static bool uhc_get_host_port(const char *hp, const char **host, uint16 *port) { static char hostname[MAX_HOSTLEN + 1]; const char *ep; uint32 u; int error; size_t len; char *p; g_assert(hp); g_assert(host); g_assert(port); *host = NULL; *port = 0; hostname[0] = '\0'; if (!string_to_host_or_addr(hp, &ep, NULL) || ':' != *ep) return FALSE; len = ep - hp; if (len >= sizeof hostname) return FALSE; p = mempcpy(hostname, hp, len); *p = '\0'; g_assert(':' == *ep); ep++; u = parse_uint32(ep, NULL, 10, &error); if (error || u < 1 || u > 0xffff) return FALSE; *host = hostname; /* Static data! */ *port = u; return TRUE; }
static bool process_diff(InputStream *is, struct File *file, FILE *fp, const char **error) { uint8_t data[BS]; uint32_t S; uint16_t C, A; char digest1_str[2*DS + 1]; char digest2_str[2*DS + 1]; uint32_t TC = 0, TA = 0; for (;;) { if (is->read(is, data, 8) != 8) { *error = "read failed -- file truncated?"; return false; } S = parse_uint32(data + 0); C = parse_uint16(data + 4); A = parse_uint16(data + 6); if (S == 0xffffffffu && C == 0xffffu && A == 0xffffu) break; if (C > 0x7fff || A > 0x7fff || (S < 0xffffffffu) != (C > 0)) { *error = "invalid diff data"; return false; } TC += C; TA += A; while (A > 0) { if (is->read(is, data, BS) != BS) { *error = "read failed -- file truncated?"; return false; } A -= 1; } } if (is->read(is, file->diff.digest2, DS) != DS) { *error = "read failed -- file truncated?"; return false; } hexstring(digest2_str, file->diff.digest2, DS); if (is->read(is, file->diff.digest1, DS) == DS) { /* Version 1.1 file */ hexstring(digest1_str, file->diff.digest1, DS); } else { /* Version 1.0 file; no input file digest present */ memset(file->diff.digest1, 0, DS); strcpy(digest1_str, "?"); } file->type = FILE_DIFF; file->diff.copied = TC; file->diff.added = TA; if (fp != NULL) { fprintf(fp, "%s -> %s (%d blocks, %6.3f%% new)\n", digest1_str, digest2_str, TC + TA, 100.0*TA/(TC + TA) ); } return true; }
/* * scontrol_update_job - update the slurm job configuration per the supplied * arguments * IN argc - count of arguments * IN argv - list of arguments * RET 0 if no slurm error, errno otherwise. parsing error prints * error message and returns 0 */ extern int scontrol_update_job (int argc, char *argv[]) { bool update_size = false; int i, update_cnt = 0; char *tag, *val; int taglen, vallen; job_desc_msg_t job_msg; slurm_init_job_desc_msg (&job_msg); /* set current user, needed e.g., for AllowGroups checks */ job_msg.user_id = getuid(); for (i=0; i<argc; i++) { tag = argv[i]; val = strchr(argv[i], '='); if (val) { taglen = val - argv[i]; val++; vallen = strlen(val); } else if (strncasecmp(tag, "Nice", MAX(strlen(tag), 2)) == 0){ /* "Nice" is the only tag that might not have an equal sign, so it is handled specially. */ job_msg.nice = NICE_OFFSET + 100; update_cnt++; continue; } else { exit_code = 1; fprintf (stderr, "Invalid input: %s\n", argv[i]); fprintf (stderr, "Request aborted\n"); return -1; } if (strncasecmp(tag, "JobId", MAX(taglen, 3)) == 0) { job_msg.job_id = slurm_xlate_job_id(val); if (job_msg.job_id == 0) { error ("Invalid JobId value: %s", val); exit_code = 1; return 0; } } else if (strncasecmp(tag, "Comment", MAX(taglen, 3)) == 0) { job_msg.comment = val; update_cnt++; } else if (strncasecmp(tag, "TimeLimit", MAX(taglen, 5)) == 0) { bool incr, decr; uint32_t job_current_time, time_limit; incr = (val[0] == '+'); decr = (val[0] == '-'); if (incr || decr) val++; time_limit = time_str2mins(val); if ((time_limit < 0) && (time_limit != INFINITE)) { error("Invalid TimeLimit value"); exit_code = 1; return 0; } if (incr || decr) { job_current_time = _get_job_time(job_msg. job_id); if (job_current_time == NO_VAL) { exit_code = 1; return 0; } if (incr) { time_limit += job_current_time; } else if (time_limit > job_current_time) { error("TimeLimit decrement larger than" " current time limit (%u > %u)", time_limit, job_current_time); exit_code = 1; return 0; } else { time_limit = job_current_time - time_limit; } } job_msg.time_limit = time_limit; update_cnt++; } else if (strncasecmp(tag, "TimeMin", MAX(taglen, 5)) == 0) { int time_min = time_str2mins(val); if ((time_min < 0) && (time_min != INFINITE)) { error("Invalid TimeMin value"); exit_code = 1; return 0; } job_msg.time_min = time_min; update_cnt++; } else if (strncasecmp(tag, "Priority", MAX(taglen, 2)) == 0) { if (parse_uint32(val, &job_msg.priority)) { error ("Invalid Priority value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (strncasecmp(tag, "Nice", MAX(taglen, 2)) == 0) { int nice; nice = strtoll(val, (char **) NULL, 10); if (abs(nice) > NICE_OFFSET) { error("Invalid nice value, must be between " "-%d and %d", NICE_OFFSET, NICE_OFFSET); exit_code = 1; return 0; } job_msg.nice = NICE_OFFSET + nice; update_cnt++; } else if (strncasecmp(tag, "NumCPUs", MAX(taglen, 6)) == 0) { int min_cpus, max_cpus=0; if (!get_resource_arg_range(val, "NumCPUs", &min_cpus, &max_cpus, false) || (min_cpus <= 0) || (max_cpus && (max_cpus < min_cpus))) { error ("Invalid NumCPUs value: %s", val); exit_code = 1; return 0; } job_msg.min_cpus = min_cpus; if (max_cpus) job_msg.max_cpus = max_cpus; update_cnt++; } /* ReqProcs was removed in SLURM version 2.1 */ else if (strncasecmp(tag, "ReqProcs", MAX(taglen, 8)) == 0) { if (parse_uint32(val, &job_msg.num_tasks)) { error ("Invalid ReqProcs value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (strncasecmp(tag, "Requeue", MAX(taglen, 4)) == 0) { if (parse_uint16(val, &job_msg.requeue)) { error ("Invalid Requeue value: %s", val); exit_code = 1; return 0; } update_cnt++; } /* ReqNodes was replaced by NumNodes in SLURM version 2.1 */ else if ((strncasecmp(tag, "ReqNodes", MAX(taglen, 8)) == 0) || (strncasecmp(tag, "NumNodes", MAX(taglen, 8)) == 0)) { int min_nodes, max_nodes, rc; if (strcmp(val, "0") == 0) { job_msg.min_nodes = 0; } else if (strcasecmp(val, "ALL") == 0) { job_msg.min_nodes = INFINITE; } else { min_nodes = (int) job_msg.min_nodes; max_nodes = (int) job_msg.max_nodes; rc = get_resource_arg_range( val, "requested node count", &min_nodes, &max_nodes, false); if (!rc) return rc; job_msg.min_nodes = (uint32_t) min_nodes; job_msg.max_nodes = (uint32_t) max_nodes; } update_size = true; update_cnt++; } else if (strncasecmp(tag, "ReqSockets", MAX(taglen, 4)) == 0) { if (parse_uint16(val, &job_msg.sockets_per_node)) { error ("Invalid ReqSockets value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (strncasecmp(tag, "ReqCores", MAX(taglen, 4)) == 0) { if (parse_uint16(val, &job_msg.cores_per_socket)) { error ("Invalid ReqCores value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (strncasecmp(tag, "TasksPerNode", MAX(taglen, 2))==0) { if (parse_uint16(val, &job_msg.ntasks_per_node)) { error ("Invalid TasksPerNode value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (strncasecmp(tag, "ReqThreads", MAX(taglen, 4)) == 0) { if (parse_uint16(val, &job_msg.threads_per_core)) { error ("Invalid ReqThreads value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (strncasecmp(tag, "MinCPUsNode", MAX(taglen, 4)) == 0) { if (parse_uint16(val, &job_msg.pn_min_cpus)) { error ("Invalid MinCPUsNode value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (strncasecmp(tag, "MinMemoryNode", MAX(taglen, 10)) == 0) { if (parse_uint32(val, &job_msg.pn_min_memory)) { error ("Invalid MinMemoryNode value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (strncasecmp(tag, "MinMemoryCPU", MAX(taglen, 10)) == 0) { if (parse_uint32(val, &job_msg.pn_min_memory)) { error ("Invalid MinMemoryCPU value: %s", val); exit_code = 1; return 0; } job_msg.pn_min_memory |= MEM_PER_CPU; update_cnt++; } else if (strncasecmp(tag, "MinTmpDiskNode", MAX(taglen, 5)) == 0) { if (parse_uint32(val, &job_msg.pn_min_tmp_disk)) { error ("Invalid MinTmpDiskNode value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (strncasecmp(tag, "Partition", MAX(taglen, 2)) == 0) { job_msg.partition = val; update_cnt++; } else if (strncasecmp(tag, "QOS", MAX(taglen, 2)) == 0) { job_msg.qos = val; update_cnt++; } else if (strncasecmp(tag, "ReservationName", MAX(taglen, 3)) == 0) { job_msg.reservation = val; update_cnt++; } else if (strncasecmp(tag, "Name", MAX(taglen, 2)) == 0) { job_msg.name = val; update_cnt++; } else if (strncasecmp(tag, "WCKey", MAX(taglen, 1)) == 0) { job_msg.wckey = val; update_cnt++; } else if (strncasecmp(tag, "StdOut", MAX(taglen, 6)) == 0) { job_msg.std_out = val; update_cnt++; } else if (strncasecmp(tag, "Switches", MAX(taglen, 5)) == 0) { char *sep_char; job_msg.req_switch = (uint32_t) strtol(val, &sep_char, 10); update_cnt++; if (sep_char && sep_char[0] == '@') { job_msg.wait4switch = time_str2mins(sep_char+1) * 60; } } else if (strncasecmp(tag, "wait-for-switch", MAX(taglen, 5)) == 0) { if (parse_uint32(val, &job_msg.wait4switch)) { error ("Invalid wait-for-switch value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (strncasecmp(tag, "Shared", MAX(taglen, 2)) == 0) { if (strncasecmp(val, "YES", MAX(vallen, 1)) == 0) job_msg.shared = 1; else if (strncasecmp(val, "NO", MAX(vallen, 1)) == 0) job_msg.shared = 0; else if (parse_uint16(val, &job_msg.shared)) { error ("Invalid wait-for-switch value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (strncasecmp(tag, "Contiguous", MAX(taglen, 3)) == 0) { if (strncasecmp(val, "YES", MAX(vallen, 1)) == 0) job_msg.contiguous = 1; else if (strncasecmp(val, "NO", MAX(vallen, 1)) == 0) job_msg.contiguous = 0; else if (parse_uint16(val, &job_msg.contiguous)) { error ("Invalid Contiguous value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (strncasecmp(tag, "CoreSpec", MAX(taglen, 4)) == 0) { if (parse_uint16(val, &job_msg.core_spec)) { error ("Invalid CoreSpec value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (strncasecmp(tag, "ExcNodeList", MAX(taglen, 3)) == 0){ job_msg.exc_nodes = val; update_cnt++; } else if (!strncasecmp(tag, "NodeList", MAX(taglen, 8)) || !strncasecmp(tag, "ReqNodeList", MAX(taglen, 8))) { job_msg.req_nodes = val; update_size = true; update_cnt++; } else if (strncasecmp(tag, "Features", MAX(taglen, 1)) == 0) { job_msg.features = val; update_cnt++; } else if (strncasecmp(tag, "Gres", MAX(taglen, 2)) == 0) { if (!strcasecmp(val, "help") || !strcasecmp(val, "list")) { print_gres_help(); } else { job_msg.gres = val; update_cnt++; } } else if (strncasecmp(tag, "Account", MAX(taglen, 1)) == 0) { job_msg.account = val; update_cnt++; } else if (strncasecmp(tag, "Dependency", MAX(taglen, 1)) == 0) { job_msg.dependency = val; update_cnt++; } else if (strncasecmp(tag, "Geometry", MAX(taglen, 2)) == 0) { char* token, *delimiter = ",x", *next_ptr; int j, rc = 0; int dims = slurmdb_setup_cluster_dims(); uint16_t geo[dims]; char* geometry_tmp = xstrdup(val); char* original_ptr = geometry_tmp; token = strtok_r(geometry_tmp, delimiter, &next_ptr); for (j=0; j<dims; j++) { if (token == NULL) { error("insufficient dimensions in " "Geometry"); rc = -1; break; } geo[j] = (uint16_t) atoi(token); if (geo[j] <= 0) { error("invalid --geometry argument"); rc = -1; break; } geometry_tmp = next_ptr; token = strtok_r(geometry_tmp, delimiter, &next_ptr); } if (token != NULL) { error("too many dimensions in Geometry"); rc = -1; } if (original_ptr) xfree(original_ptr); if (rc != 0) exit_code = 1; else { for (j=0; j<dims; j++) job_msg.geometry[j] = geo[j]; update_cnt++; } } else if (strncasecmp(tag, "Rotate", MAX(taglen, 2)) == 0) { if (strncasecmp(val, "YES", MAX(vallen, 1)) == 0) job_msg.rotate = 1; else if (strncasecmp(val, "NO", MAX(vallen, 1)) == 0) job_msg.rotate = 0; else if (parse_uint16(val, &job_msg.rotate)) { error ("Invalid wait-for-switch value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (strncasecmp(tag, "Conn-Type", MAX(taglen, 2)) == 0) { verify_conn_type(val, job_msg.conn_type); if (job_msg.conn_type[0] != (uint16_t)NO_VAL) update_cnt++; } else if (strncasecmp(tag, "Licenses", MAX(taglen, 1)) == 0) { job_msg.licenses = val; update_cnt++; } else if (!strncasecmp(tag, "EligibleTime", MAX(taglen, 2)) || !strncasecmp(tag, "StartTime", MAX(taglen, 2))) { if ((job_msg.begin_time = parse_time(val, 0))) { if (job_msg.begin_time < time(NULL)) job_msg.begin_time = time(NULL); update_cnt++; } } else if (!strncasecmp(tag, "EndTime", MAX(taglen, 2))) { job_msg.end_time = parse_time(val, 0); update_cnt++; } else { exit_code = 1; fprintf (stderr, "Update of this parameter is not " "supported: %s\n", argv[i]); fprintf (stderr, "Request aborted\n"); return 0; } } if (update_cnt == 0) { exit_code = 1; fprintf (stderr, "No changes specified\n"); return 0; } if (slurm_update_job(&job_msg)) return slurm_get_errno (); if (update_size) _update_job_size(job_msg.job_id); return SLURM_SUCCESS; }
/** * HTTP async callback, invoked when all the headers have been read. * * @return TRUE if we can continue with the request. */ static gboolean soap_header_ind(http_async_t *ha, header_t *header, int code, const char *message) { soap_rpc_t *sr = http_async_get_opaque(ha); const char *buf; soap_rpc_check(sr); g_assert(ha == sr->ha); if (GNET_PROPERTY(soap_debug) > 2) { g_debug("SOAP \"%s\" at \"%s\": got HTTP %d %s", sr->action, sr->url, code, message); } /* * Grab local socket address if they are interested. */ if (sr->options & SOAP_RPC_O_LOCAL_ADDR) sr->got_local_addr = http_async_get_local_addr(ha, &sr->local_addr); /* * If we sent a non-mandatory request and get a 405 "Method not allowed" * error, retry with M-POST. Likewise, a 510 "Not extended" reply is an * invitation to use the HTTP Extension Framework (RFC 2774). */ if ( (405 == code || 510 == code) && !sr->mandatory && !sr->retry && (sr->options & SOAP_RPC_O_MAN_RETRY) ) { if (GNET_PROPERTY(soap_debug) > 1) { g_message("SOAP \"%s\" at \"%s\": will be retrying with M-POST", sr->action, sr->url); } sr->retry = TRUE; /* Signal we should retry */ http_async_cancel(ha); return FALSE; } /* * If we sent a mandatory request, there needs to be an "Ext:" header * in the reply to show that the mandatory request was understood as such. */ if (sr->mandatory && 200 == code) { const char *ext = header_get(header, "Ext"); if (NULL == ext) { if (GNET_PROPERTY(soap_debug)) { g_warning("SOAP \"%s\" at \"%s\": M-POST not understood", sr->action, sr->url); } http_async_error(ha, HTTP_ASYNC_MAN_FAILURE); return FALSE; } } /* * Save the HTTP headers and code to be able to analyze the reply payload. * * Since the option HTTP_O_READ_REPLY is used, we'll get the reply data * from the server even if the status code is not 200 and we need to be * able to differentiate between a success report and an error. */ sr->header = header_refcnt_inc(header); sr->http_code = code; /* * See whether they advertise a Content-Length, which may not be the * case if chunked transfer encoding is used for the reply. In that * case, we shall dynamically adjust the reception buffer size. */ buf = header_get(header, "Content-Length"); if (buf != NULL) { guint32 len; int error; len = parse_uint32(buf, NULL, 10, &error); if (error) { if (GNET_PROPERTY(soap_debug)) { g_warning("SOAP \"%s\" at \"%s\": " "cannot parse Content-Length header: " "value is \"%s\", error is %s", sr->action, sr->url, buf, g_strerror(error)); } http_async_error(ha, HTTP_ASYNC_BAD_HEADER); return FALSE; } if (len > sr->maxlen) { http_async_error(ha, HTTP_ASYNC_DATA2BIG); return FALSE; } sr->content_len = len; } /* * Allocate data buffer: either they advertised content length, or 1/16th * of the maximum data length we accept to grab from the server. */ sr->reply_size = (buf != NULL) ? sr->content_len : (sr->maxlen >> 4); sr->reply_data = halloc(sr->reply_size); return TRUE; /* OK, go on */ }
char *parse_uint32_nb(char *s, unsigned char nb[4]) { unsigned n; if (!(s = parse_uint32(s, &n))) return NULL; PACK32(nb, n); return s; }
int http_read_response(http_t *ctx) { char buf[BUFFERSIZE]; char *p, *endptr; uint32_t code; ssize_t ret, size; int error; RUNTIME_ASSERT(ctx); RUNTIME_ASSERT(ctx->state == HTTP_STATE_REQUEST); ret = fifo_findchar(ctx->input, '\n', sizeof buf); if (ret < 0) { return 0; } if ((size_t) ret >= sizeof buf) { http_log(ctx, "HTTP response line is too long"); return -1; } size = ret + 1; ret = fifo_read(ctx->input, buf, size); RUNTIME_ASSERT(ret > 0 && (size_t) ret <= sizeof buf); ret--; RUNTIME_ASSERT(buf[ret] == '\n'); while (ret >= 0 && isspace((unsigned char) buf[ret])) buf[ret--] = '\0'; http_log(ctx, "buf=\"%s\"", buf); p = http_parse_version(ctx, buf); if (!p) { http_log(ctx, "Not a HTTP reply: %s", buf); return -1; } if (!isspace((unsigned char) *p)) { http_log(ctx, "Missing space after HTTP/x.y: %s", buf); return -1; } p = skip_spaces(p); if (!isdigit((unsigned char) *p)) { http_log(ctx, "Invalid HTTP status code: %s", buf); return -1; } code = parse_uint32(p, &endptr, 10, &error); if (*endptr != '\0' && !isspace((unsigned char) *endptr)) { http_log(ctx, "Invalid HTTP status code: %s", buf); return -1; } if (code < 100 || code > 999) { http_log(ctx, "HTTP status code is out-of-range: %s", buf); return -1; } /* Don't care about the rest of the line */ ctx->status_code = code; ctx->state = HTTP_STATE_HEADERS; return 0; }
/** * Loads the whitelist into memory. */ static void G_COLD whitelist_retrieve(void) { char line[1024]; FILE *f; filestat_t st; unsigned linenum = 0; file_path_t fp[1]; whitelist_generation++; file_path_set(fp, settings_config_dir(), whitelist_file); f = file_config_open_read_norename("Host Whitelist", fp, N_ITEMS(fp)); if (!f) return; if (fstat(fileno(f), &st)) { g_warning("%s(): fstat() failed: %m", G_STRFUNC); fclose(f); return; } while (fgets(line, sizeof line, f)) { pslist_t *sl_addr, *sl; const char *endptr, *start; host_addr_t addr; uint16 port; uint8 bits; bool item_ok; bool use_tls; char *hname; linenum++; if (!file_line_chomp_tail(line, sizeof line, NULL)) { g_warning("%s(): line %u too long, aborting", G_STRFUNC, linenum); break; } if (file_line_is_skipable(line)) continue; sl_addr = NULL; addr = zero_host_addr; endptr = NULL; hname = NULL; endptr = is_strprefix(line, "tls:"); if (endptr) { use_tls = TRUE; start = endptr; } else { use_tls = FALSE; start = line; } port = 0; if (string_to_host_addr_port(start, &endptr, &addr, &port)) { sl_addr = name_to_host_addr(host_addr_to_string(addr), settings_dns_net()); } else if (string_to_host_or_addr(start, &endptr, &addr)) { uchar c = *endptr; switch (c) { case '\0': case ':': case '/': break; default: if (!is_ascii_space(c)) endptr = NULL; } if (!endptr) { g_warning("%s(): line %d: " "expected a hostname or IP address \"%s\"", G_STRFUNC, linenum, line); continue; } /* Terminate the string for name_to_host_addr() */ hname = h_strndup(start, endptr - start); } else { g_warning("%s(): line %d: expected hostname or IP address \"%s\"", G_STRFUNC, linenum, line); continue; } g_assert(sl_addr != NULL || hname != NULL); g_assert(NULL != endptr); bits = 0; item_ok = TRUE; /* * When an explicit address is given (no hostname) and with no * port, one can suffix the address with bits to indicate a CIDR * range of whitelisted addresses. */ if (0 == port) { /* Ignore trailing items separated by a space */ while ('\0' != *endptr && !is_ascii_space(*endptr)) { uchar c = *endptr++; if (':' == c) { int error; uint32 v; if (0 != port) { g_warning("%s(): line %d: multiple colons after host", G_STRFUNC, linenum); item_ok = FALSE; break; } v = parse_uint32(endptr, &endptr, 10, &error); port = (error || v > 0xffff) ? 0 : v; if (0 == port) { g_warning("%s(): line %d: " "invalid port value after host", G_STRFUNC, linenum); item_ok = FALSE; break; } } else if ('/' == c) { const char *ep; uint32 mask; if (0 != bits) { g_warning("%s(): line %d: " "multiple slashes after host", G_STRFUNC, linenum); item_ok = FALSE; break; } if (string_to_ip_strict(endptr, &mask, &ep)) { if (!host_addr_is_ipv4(addr)) { g_warning("%s(): line %d: " "IPv4 netmask after non-IPv4 address", G_STRFUNC, linenum); item_ok = FALSE; break; } endptr = ep; if (0 == (bits = netmask_to_cidr(mask))) { g_warning("%s(): line %d: " "IPv4 netmask after non-IPv4 address", G_STRFUNC, linenum); item_ok = FALSE; break; } } else { int error; uint32 v; v = parse_uint32(endptr, &endptr, 10, &error); if ( error || 0 == v || (v > 32 && host_addr_is_ipv4(addr)) || (v > 128 && host_addr_is_ipv6(addr)) ) { g_warning("%s(): line %d: " "invalid numeric netmask after host", G_STRFUNC, linenum); item_ok = FALSE; break; } bits = v; } } else { g_warning("%s(): line %d: " "unexpected character after host", G_STRFUNC, linenum); item_ok = FALSE; break; } } } if (item_ok) { struct whitelist *item; if (hname) { item = whitelist_hostname_create(use_tls, hname, port); whitelist_dns_resolve(item, FALSE); } else { PSLIST_FOREACH(sl_addr, sl) { host_addr_t *aptr = sl->data; g_assert(aptr != NULL); item = whitelist_addr_create(use_tls, *aptr, port, bits); whitelist_add(item); } } } else {
/* * scontrol_update_job - update the slurm job configuration per the supplied * arguments * IN argc - count of arguments * IN argv - list of arguments * RET 0 if no slurm error, errno otherwise. parsing error prints * error message and returns 0 */ extern int scontrol_update_job(int argc, char **argv) { bool update_size = false; int i, update_cnt = 0, rc = SLURM_SUCCESS, rc2; char *tag, *val; int taglen, vallen; job_desc_msg_t job_msg; job_array_resp_msg_t *resp = NULL; uint32_t job_uid = NO_VAL; slurm_init_job_desc_msg (&job_msg); for (i = 0; i < argc; i++) { char *add_info = NULL; tag = argv[i]; val = strchr(argv[i], '='); if (val) { taglen = val - argv[i]; if ((taglen > 0) && ((val[-1] == '+') || (val[-1] == '-'))) { add_info = val - 1; taglen--; } val++; vallen = strlen(val); } else if (xstrncasecmp(tag, "Nice", MAX(strlen(tag), 2)) == 0){ /* "Nice" is the only tag that might not have an equal sign, so it is handled specially. */ job_msg.nice = NICE_OFFSET + 100; update_cnt++; continue; } else if (!val && argv[i + 1]) { tag = argv[i]; taglen = strlen(tag); val = argv[++i]; vallen = strlen(val); } else { exit_code = 1; fprintf (stderr, "Invalid input: %s\n", argv[i]); fprintf (stderr, "Request aborted\n"); return -1; } if (xstrncasecmp(tag, "JobId", MAX(taglen, 3)) == 0) { job_msg.job_id_str = val; } else if (xstrncasecmp(tag, "AdminComment", MAX(taglen, 3)) == 0) { if (add_info) { if (add_info[0] == '-') { error("Invalid syntax, AdminComment can not be subtracted from."); exit_code = 1; return 0; } job_msg.admin_comment = add_info; /* * Mark as unset so we know we handled this * correctly as there is a check later to make * sure we know we got a +-. */ add_info = NULL; } else job_msg.admin_comment = val; update_cnt++; } else if (xstrncasecmp(tag, "ArrayTaskThrottle", MAX(taglen, 10)) == 0) { int throttle; throttle = strtoll(val, (char **) NULL, 10); if (throttle < 0) { error("Invalid ArrayTaskThrottle value"); exit_code = 1; return 0; } job_msg.array_inx = val; update_cnt++; } else if (xstrncasecmp(tag, "Comment", MAX(taglen, 3)) == 0) { job_msg.comment = val; update_cnt++; } else if (xstrncasecmp(tag, "Clusters", MAX(taglen, 8)) == 0) { job_msg.clusters = val; update_cnt++; } else if (xstrncasecmp(tag, "ClusterFeatures", MAX(taglen, 8)) == 0) { job_msg.cluster_features = val; update_cnt++; } else if (xstrncasecmp(tag, "DelayBoot", MAX(taglen, 5)) == 0) { int time_sec = time_str2secs(val); if (time_sec == NO_VAL) { error("Invalid DelayBoot value"); exit_code = 1; return 0; } job_msg.delay_boot = time_sec; update_cnt++; } else if (xstrncasecmp(tag, "TimeLimit", MAX(taglen, 5)) == 0) { uint32_t job_current_time, time_limit; if (val && ((val[0] == '+') || (val[0] == '-'))) { if (add_info) { error("Invalid syntax, variations of +=- are not accepted."); exit_code = 1; return 0; } add_info = val; val++; } time_limit = time_str2mins(val); if (time_limit == NO_VAL) { error("Invalid TimeLimit value"); exit_code = 1; return 0; } if (add_info) { if (!job_msg.job_id_str) { error("JobId must precede TimeLimit " "increment or decrement"); exit_code = 1; return 0; } job_current_time = _get_job_time(job_msg. job_id_str); if (job_current_time == NO_VAL) { exit_code = 1; return 0; } if (add_info[0] == '+') { time_limit += job_current_time; } else if (time_limit > job_current_time) { error("TimeLimit decrement larger than" " current time limit (%u > %u)", time_limit, job_current_time); exit_code = 1; return 0; } else { time_limit = job_current_time - time_limit; } /* * Mark as unset so we know we handled this * correctly as there is a check later to make * sure we know we got a +-. */ add_info = NULL; } job_msg.time_limit = time_limit; update_cnt++; } else if (xstrncasecmp(tag, "TimeMin", MAX(taglen, 5)) == 0) { int time_min = time_str2mins(val); if ((time_min < 0) && (time_min != INFINITE)) { error("Invalid TimeMin value"); exit_code = 1; return 0; } job_msg.time_min = time_min; update_cnt++; } else if (xstrncasecmp(tag, "Priority", MAX(taglen, 2)) == 0) { if (parse_uint32(val, &job_msg.priority)) { error ("Invalid Priority value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (xstrncasecmp(tag, "Nice", MAX(taglen, 2)) == 0) { long long tmp_nice; tmp_nice = strtoll(val, (char **)NULL, 10); if (llabs(tmp_nice) > (NICE_OFFSET - 3)) { error("Nice value out of range (+/- %u). Value " "ignored", NICE_OFFSET - 3); exit_code = 1; return 0; } job_msg.nice = NICE_OFFSET + tmp_nice; update_cnt++; } else if (!xstrncasecmp(tag, "CPUsPerTask", MAX(taglen, 9))) { if (parse_uint16(val, &job_msg.cpus_per_task)) { error("Invalid CPUsPerTask value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (!xstrncasecmp(tag, "CpusPerTres", MAX(taglen, 9))) { job_msg.cpus_per_tres = val; update_cnt++; } else if (xstrncasecmp(tag, "NumCPUs", MAX(taglen, 6)) == 0) { int min_cpus, max_cpus=0; if (!get_resource_arg_range(val, "NumCPUs", &min_cpus, &max_cpus, false) || (min_cpus <= 0) || (max_cpus && (max_cpus < min_cpus))) { error ("Invalid NumCPUs value: %s", val); exit_code = 1; return 0; } job_msg.min_cpus = min_cpus; if (max_cpus) job_msg.max_cpus = max_cpus; update_cnt++; } /* ReqProcs was removed in Slurm version 2.1 */ else if ((xstrncasecmp(tag, "NumTasks", MAX(taglen, 8)) == 0) || (xstrncasecmp(tag, "ReqProcs", MAX(taglen, 8)) == 0)) { if (parse_uint32(val, &job_msg.num_tasks)) { error ("Invalid NumTasks value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (xstrncasecmp(tag, "Requeue", MAX(taglen, 4)) == 0) { if (parse_uint16(val, &job_msg.requeue)) { error ("Invalid Requeue value: %s", val); exit_code = 1; return 0; } update_cnt++; } /* ReqNodes was replaced by NumNodes in Slurm version 2.1 */ else if ((xstrncasecmp(tag, "ReqNodes", MAX(taglen, 8)) == 0) || (xstrncasecmp(tag, "NumNodes", MAX(taglen, 8)) == 0)) { int min_nodes, max_nodes, rc; if (xstrcmp(val, "0") == 0) { job_msg.min_nodes = 0; } else if (xstrcasecmp(val, "ALL") == 0) { job_msg.min_nodes = INFINITE; } else { min_nodes = (int) job_msg.min_nodes; max_nodes = (int) job_msg.max_nodes; rc = get_resource_arg_range( val, "requested node count", &min_nodes, &max_nodes, false); if (!rc) return rc; job_msg.min_nodes = (uint32_t) min_nodes; job_msg.max_nodes = (uint32_t) max_nodes; } update_size = true; update_cnt++; } else if (xstrncasecmp(tag, "ReqSockets", MAX(taglen, 4)) == 0) { if (parse_uint16(val, &job_msg.sockets_per_node)) { error ("Invalid ReqSockets value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (xstrncasecmp(tag, "ReqCores", MAX(taglen, 4)) == 0) { if (parse_uint16(val, &job_msg.cores_per_socket)) { error ("Invalid ReqCores value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (xstrncasecmp(tag, "TasksPerNode", MAX(taglen, 2))==0) { if (parse_uint16(val, &job_msg.ntasks_per_node)) { error ("Invalid TasksPerNode value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (xstrncasecmp(tag, "ReqThreads", MAX(taglen, 4)) == 0) { if (parse_uint16(val, &job_msg.threads_per_core)) { error ("Invalid ReqThreads value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (xstrncasecmp(tag, "MinCPUsNode", MAX(taglen, 4)) == 0) { if (parse_uint16(val, &job_msg.pn_min_cpus)) { error ("Invalid MinCPUsNode value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (xstrncasecmp(tag, "MinMemoryNode", MAX(taglen, 10)) == 0) { if (parse_uint64(val, &job_msg.pn_min_memory)) { error ("Invalid MinMemoryNode value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (xstrncasecmp(tag, "MinMemoryCPU", MAX(taglen, 10)) == 0) { if (parse_uint64(val, &job_msg.pn_min_memory)) { error ("Invalid MinMemoryCPU value: %s", val); exit_code = 1; return 0; } job_msg.pn_min_memory |= MEM_PER_CPU; update_cnt++; } else if (xstrncasecmp(tag, "MinTmpDiskNode", MAX(taglen, 5)) == 0) { if (parse_uint32(val, &job_msg.pn_min_tmp_disk)) { error ("Invalid MinTmpDiskNode value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (xstrncasecmp(tag, "Partition", MAX(taglen, 2)) == 0) { job_msg.partition = val; update_cnt++; } else if (xstrncasecmp(tag, "QOS", MAX(taglen, 2)) == 0) { job_msg.qos = val; update_cnt++; } else if (xstrncasecmp(tag, "ReservationName", MAX(taglen, 3)) == 0) { job_msg.reservation = val; update_cnt++; } else if (!xstrncasecmp(tag, "Name", MAX(taglen, 2)) || !xstrncasecmp(tag, "JobName", MAX(taglen, 4))) { job_msg.name = val; update_cnt++; } else if (xstrncasecmp(tag, "WCKey", MAX(taglen, 1)) == 0) { job_msg.wckey = val; update_cnt++; } else if (xstrncasecmp(tag, "StdOut", MAX(taglen, 6)) == 0) { job_msg.std_out = val; update_cnt++; } else if (xstrncasecmp(tag, "Switches", MAX(taglen, 5)) == 0) { char *sep_char; job_msg.req_switch = (uint32_t) strtol(val, &sep_char, 10); update_cnt++; if (sep_char && sep_char[0] == '@') { job_msg.wait4switch = time_str2mins(sep_char+1) * 60; } } else if (xstrncasecmp(tag, "wait-for-switch", MAX(taglen, 5)) == 0) { if (parse_uint32(val, &job_msg.wait4switch)) { error ("Invalid wait-for-switch value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (!xstrncasecmp(tag, "OverSubscribe", MAX(taglen, 2)) || !xstrncasecmp(tag, "Shared", MAX(taglen, 2))) { if (xstrncasecmp(val, "YES", MAX(vallen, 1)) == 0) job_msg.shared = 1; else if (xstrncasecmp(val, "NO", MAX(vallen, 1)) == 0) job_msg.shared = 0; else if (parse_uint16(val, &job_msg.shared)) { error("Invalid OverSubscribe value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (xstrncasecmp(tag, "Contiguous", MAX(taglen, 3)) == 0) { if (xstrncasecmp(val, "YES", MAX(vallen, 1)) == 0) job_msg.contiguous = 1; else if (xstrncasecmp(val, "NO", MAX(vallen, 1)) == 0) job_msg.contiguous = 0; else if (parse_uint16(val, &job_msg.contiguous)) { error ("Invalid Contiguous value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (xstrncasecmp(tag, "CoreSpec", MAX(taglen, 4)) == 0) { if (!xstrcmp(val, "-1") || !xstrcmp(val, "*")) job_msg.core_spec = INFINITE16; else if (parse_uint16(val, &job_msg.core_spec)) { error ("Invalid CoreSpec value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (!xstrncasecmp(tag, "MemPerTres", MAX(taglen, 5))) { job_msg.mem_per_tres = val; update_cnt++; } else if (xstrncasecmp(tag, "ThreadSpec", MAX(taglen, 4)) == 0) { if (!xstrcmp(val, "-1") || !xstrcmp(val, "*")) job_msg.core_spec = INFINITE16; else if (parse_uint16(val, &job_msg.core_spec)) { error ("Invalid ThreadSpec value: %s", val); exit_code = 1; return 0; } else job_msg.core_spec |= CORE_SPEC_THREAD; update_cnt++; } else if (!xstrncasecmp(tag, "TresBind", MAX(taglen, 5))) { job_msg.tres_bind = val; update_cnt++; } else if (!xstrncasecmp(tag, "TresFreq", MAX(taglen, 5))) { job_msg.tres_freq = val; update_cnt++; } else if (!xstrncasecmp(tag, "TresPerJob", MAX(taglen, 8))) { job_msg.tres_per_job = val; update_cnt++; } else if (!xstrncasecmp(tag, "TresPerNode", MAX(taglen, 8))) { /* "gres" replaced by "tres_per_node" in v18.08 */ if (job_msg.tres_per_node) xstrfmtcat(job_msg.tres_per_node, ",%s", val); else job_msg.tres_per_node = xstrdup(val); update_cnt++; } else if (!xstrncasecmp(tag, "TresPerSocket", MAX(taglen, 8))) { job_msg.tres_per_socket = val; update_cnt++; } else if (!xstrncasecmp(tag, "TresPerTask", MAX(taglen, 8))) { job_msg.tres_per_task = val; update_cnt++; } else if (xstrncasecmp(tag, "ExcNodeList", MAX(taglen, 3)) == 0){ job_msg.exc_nodes = val; update_cnt++; } else if (!xstrncasecmp(tag, "NodeList", MAX(taglen, 8)) || !xstrncasecmp(tag, "ReqNodeList", MAX(taglen, 8))) { job_msg.req_nodes = val; update_size = true; update_cnt++; } else if (xstrncasecmp(tag, "Features", MAX(taglen, 1)) == 0) { job_msg.features = val; update_cnt++; } else if (xstrncasecmp(tag, "Gres", MAX(taglen, 2)) == 0) { /* "gres" replaced by "tres_per_node" in v18.08 */ if (!xstrcasecmp(val, "help") || !xstrcasecmp(val, "list")) { print_gres_help(); } else if (job_msg.tres_per_node) { xstrfmtcat(job_msg.tres_per_node, ",%s", val); } else { job_msg.tres_per_node = xstrdup(val); update_cnt++; } } else if (xstrncasecmp(tag, "Account", MAX(taglen, 1)) == 0) { job_msg.account = val; update_cnt++; } else if (xstrncasecmp(tag, "BurstBuffer", MAX(taglen, 1)) == 0) { job_msg.burst_buffer = val; update_cnt++; } else if (xstrncasecmp(tag, "Dependency", MAX(taglen, 1)) == 0) { job_msg.dependency = val; update_cnt++; } else if (xstrncasecmp(tag, "Licenses", MAX(taglen, 1)) == 0) { job_msg.licenses = val; update_cnt++; } else if (!xstrncasecmp(tag, "EligibleTime", MAX(taglen, 2)) || !xstrncasecmp(tag, "StartTime", MAX(taglen, 2))) { if ((job_msg.begin_time = parse_time(val, 0))) { if (job_msg.begin_time < time(NULL)) job_msg.begin_time = time(NULL); update_cnt++; } } else if (!xstrncasecmp(tag, "EndTime", MAX(taglen, 2))) { job_msg.end_time = parse_time(val, 0); update_cnt++; } else if (!xstrncasecmp(tag, "Reboot", MAX(taglen, 3))) { if (xstrncasecmp(val, "YES", MAX(vallen, 1)) == 0) job_msg.reboot = 1; else if (xstrncasecmp(val, "NO", MAX(vallen, 1)) == 0) job_msg.reboot = 0; else if (parse_uint16(val, &job_msg.reboot)) { error ("Invalid reboot value: %s", val); exit_code = 1; return 0; } update_cnt++; } else if (!xstrncasecmp(tag, "UserID", MAX(taglen, 3))) { uid_t user_id = 0; if (uid_from_string(val, &user_id) < 0) { exit_code = 1; fprintf (stderr, "Invalid UserID: %s\n", val); fprintf (stderr, "Request aborted\n"); return 0; } job_uid = (uint32_t) user_id; } else if (!xstrncasecmp(tag, "Deadline", MAX(taglen, 3))) { if ((job_msg.deadline = parse_time(val, 0))) { update_cnt++; } } else { exit_code = 1; fprintf (stderr, "Update of this parameter is not " "supported: %s\n", argv[i]); fprintf (stderr, "Request aborted\n"); return 0; } if (add_info) { error("Option %s does not accept [+|-]= syntax", tag); exit_code = 1; return 0; } } if (update_cnt == 0) { exit_code = 1; fprintf (stderr, "No changes specified\n"); return 0; } /* If specified, override uid with effective uid provided by * -u <uid> or --uid=<uid> */ if (euid != NO_VAL) job_msg.user_id = euid; if (!job_msg.job_id_str && job_msg.name) { /* Translate name to job ID string */ job_msg.job_id_str = _job_name2id(job_msg.name, job_uid); if (!job_msg.job_id_str) { exit_code = 1; return 0; } } if (!job_msg.job_id_str) { error("No job ID specified"); exit_code = 1; return 0; } if (update_size && !_is_single_job(job_msg.job_id_str)) { exit_code = 1; return 0; } if (_is_job_id(job_msg.job_id_str)) { job_msg.job_id_str = _next_job_id(); while (job_msg.job_id_str) { rc2 = slurm_update_job2(&job_msg, &resp); if (update_size && (rc2 == SLURM_SUCCESS)) { /* See check above for one job ID */ job_msg.job_id = slurm_atoul(job_msg.job_id_str); _update_job_size(job_msg.job_id); } if (rc2 != SLURM_SUCCESS) { rc2 = slurm_get_errno(); rc = MAX(rc, rc2); exit_code = 1; if (quiet_flag != 1) { fprintf(stderr, "%s for job %s\n", slurm_strerror(slurm_get_errno()), job_msg.job_id_str); } } else if (resp) { for (i = 0; i < resp->job_array_count; i++) { if ((resp->error_code[i] == SLURM_SUCCESS) && (resp->job_array_count == 1)) continue; exit_code = 1; if (quiet_flag == 1) continue; fprintf(stderr, "%s: %s\n", resp->job_array_id[i], slurm_strerror(resp-> error_code[i])); } slurm_free_job_array_resp(resp); resp = NULL; } job_msg.job_id_str = _next_job_id(); } } else if (job_msg.job_id_str) { exit_code = 1; rc = ESLURM_INVALID_JOB_ID; slurm_seterrno(rc); if (quiet_flag != 1) { fprintf(stderr, "%s for job %s\n", slurm_strerror(rc), job_msg.job_id_str); } } return rc; }
extern int scontrol_parse_part_options (int argc, char *argv[], int *update_cnt_ptr, update_part_msg_t *part_msg_ptr) { int i, min, max; char *tag, *val; int taglen, vallen; if (!update_cnt_ptr) { error("scontrol_parse_part_options internal error, " "update_cnt_ptr == NULL"); exit_code = 1; return -1; } if (!part_msg_ptr) { error("scontrol_parse_part_options internal error, " "part_msg_ptr == NULL"); exit_code = 1; return -1; } for (i=0; i<argc; i++) { tag = argv[i]; val = strchr(argv[i], '='); if (val) { taglen = val - argv[i]; val++; vallen = strlen(val); } else { exit_code = 1; error("Invalid input: %s Request aborted", argv[i]); return -1; } if (strncasecmp(tag, "PartitionName", MAX(taglen, 2)) == 0) { part_msg_ptr->name = val; (*update_cnt_ptr)++; } else if (strncasecmp(tag, "MaxTime", MAX(taglen, 4)) == 0) { int max_time = time_str2mins(val); if ((max_time < 0) && (max_time != INFINITE)) { exit_code = 1; error("Invalid input %s", argv[i]); return -1; } part_msg_ptr->max_time = max_time; (*update_cnt_ptr)++; } else if (strncasecmp(tag, "DefaultTime", MAX(taglen, 8)) == 0){ int default_time = time_str2mins(val); if ((default_time < 0) && (default_time != INFINITE)) { exit_code = 1; error("Invalid input %s", argv[i]); return -1; } part_msg_ptr->default_time = default_time; (*update_cnt_ptr)++; } else if (strncasecmp(tag, "MaxCPUsPerNode", MAX(taglen, 4)) == 0) { if ((xstrcasecmp(val,"UNLIMITED") == 0) || (xstrcasecmp(val,"INFINITE") == 0)) { part_msg_ptr->max_cpus_per_node = (uint32_t) INFINITE; } else if (parse_uint32(val, &part_msg_ptr-> max_cpus_per_node)) { error("Invalid MaxCPUsPerNode value: %s", val); return -1; } (*update_cnt_ptr)++; } else if (strncasecmp(tag, "MaxNodes", MAX(taglen, 4)) == 0) { if ((xstrcasecmp(val,"UNLIMITED") == 0) || (xstrcasecmp(val,"INFINITE") == 0)) part_msg_ptr->max_nodes = (uint32_t) INFINITE; else { min = 1; get_resource_arg_range(val, "MaxNodes", &min, &max, true); part_msg_ptr->max_nodes = min; } (*update_cnt_ptr)++; } else if (strncasecmp(tag, "MinNodes", MAX(taglen, 2)) == 0) { min = 1; verify_node_count(val, &min, &max); part_msg_ptr->min_nodes = min; (*update_cnt_ptr)++; } else if (strncasecmp(tag, "Default", MAX(taglen, 7)) == 0) { if (strncasecmp(val, "NO", MAX(vallen, 1)) == 0) part_msg_ptr->flags |= PART_FLAG_DEFAULT_CLR; else if (strncasecmp(val, "YES", MAX(vallen, 1)) == 0) part_msg_ptr->flags |= PART_FLAG_DEFAULT; else { exit_code = 1; error("Invalid input: %s", argv[i]); error("Acceptable Default values " "are YES and NO"); return -1; } (*update_cnt_ptr)++; } else if (!strncasecmp(tag, "DisableRootJobs", MAX(taglen, 1))) { if (strncasecmp(val, "NO", MAX(vallen, 1)) == 0) part_msg_ptr->flags |= PART_FLAG_NO_ROOT_CLR; else if (strncasecmp(val, "YES", MAX(vallen, 1)) == 0) part_msg_ptr->flags |= PART_FLAG_NO_ROOT; else { exit_code = 1; error("Invalid input: %s", argv[i]); error("Acceptable DisableRootJobs values " "are YES and NO"); return -1; } (*update_cnt_ptr)++; } else if (!strncasecmp(tag, "ExclusiveUser", MAX(taglen, 1))) { if (strncasecmp(val, "NO", MAX(vallen, 1)) == 0) part_msg_ptr->flags |= PART_FLAG_EXC_USER_CLR; else if (strncasecmp(val, "YES", MAX(vallen, 1)) == 0) part_msg_ptr->flags |= PART_FLAG_EXCLUSIVE_USER; else { exit_code = 1; error("Invalid input: %s", argv[i]); error("Acceptable ExclusiveUser values " "are YES and NO"); return -1; } (*update_cnt_ptr)++; } else if (strncasecmp(tag, "Hidden", MAX(taglen, 1)) == 0) { if (strncasecmp(val, "NO", MAX(vallen, 1)) == 0) part_msg_ptr->flags |= PART_FLAG_HIDDEN_CLR; else if (strncasecmp(val, "YES", MAX(vallen, 1)) == 0) part_msg_ptr->flags |= PART_FLAG_HIDDEN; else { exit_code = 1; error("Invalid input: %s", argv[i]); error("Acceptable Hidden values " "are YES and NO"); return -1; } (*update_cnt_ptr)++; } else if (strncasecmp(tag, "LLN", MAX(taglen, 1)) == 0) { if (strncasecmp(val, "NO", MAX(vallen, 1)) == 0) part_msg_ptr->flags |= PART_FLAG_LLN_CLR; else if (strncasecmp(val, "YES", MAX(vallen, 1)) == 0) part_msg_ptr->flags |= PART_FLAG_LLN; else { exit_code = 1; error("Invalid input: %s", argv[i]); error("Acceptable LLN values " "are YES and NO"); return -1; } (*update_cnt_ptr)++; } else if (strncasecmp(tag, "RootOnly", MAX(taglen, 3)) == 0) { if (strncasecmp(val, "NO", MAX(vallen, 1)) == 0) part_msg_ptr->flags |= PART_FLAG_ROOT_ONLY_CLR; else if (strncasecmp(val, "YES", MAX(vallen, 1)) == 0) part_msg_ptr->flags |= PART_FLAG_ROOT_ONLY; else { exit_code = 1; error("Invalid input: %s", argv[i]); error("Acceptable RootOnly values " "are YES and NO"); return -1; } (*update_cnt_ptr)++; } else if (strncasecmp(tag, "ReqResv", MAX(taglen, 3)) == 0) { if (strncasecmp(val, "NO", MAX(vallen, 1)) == 0) part_msg_ptr->flags |= PART_FLAG_REQ_RESV_CLR; else if (strncasecmp(val, "YES", MAX(vallen, 1)) == 0) part_msg_ptr->flags |= PART_FLAG_REQ_RESV; else { exit_code = 1; error("Invalid input: %s", argv[i]); error("Acceptable ReqResv values " "are YES and NO"); return -1; } (*update_cnt_ptr)++; } else if (strncasecmp(tag, "Shared", MAX(taglen, 2)) == 0) { char *colon_pos = strchr(val, ':'); if (colon_pos) { *colon_pos = '\0'; vallen = strlen(val); } if (strncasecmp(val, "NO", MAX(vallen, 1)) == 0) { part_msg_ptr->max_share = 1; } else if (strncasecmp(val, "EXCLUSIVE", MAX(vallen, 1)) == 0) { part_msg_ptr->max_share = 0; } else if (strncasecmp(val, "YES", MAX(vallen, 1)) == 0) { if (colon_pos) { part_msg_ptr->max_share = (uint16_t) strtol(colon_pos+1, (char **) NULL, 10); } else { part_msg_ptr->max_share = (uint16_t) 4; } } else if (strncasecmp(val, "FORCE", MAX(vallen, 1)) == 0) { if (colon_pos) { part_msg_ptr->max_share = (uint16_t) strtol(colon_pos+1, (char **) NULL, 10) | SHARED_FORCE; } else { part_msg_ptr->max_share = (uint16_t) 4 |SHARED_FORCE; } } else { exit_code = 1; error("Invalid input: %s", argv[i]); error("Acceptable Shared values are " "NO, EXCLUSIVE, YES:#, and FORCE:#"); return -1; } (*update_cnt_ptr)++; } else if (strncasecmp(tag, "PreemptMode", MAX(taglen, 3)) == 0) { uint16_t new_mode = preempt_mode_num(val); if (new_mode != (uint16_t) NO_VAL) part_msg_ptr->preempt_mode = new_mode; else { error("Invalid input: %s", argv[i]); return -1; } (*update_cnt_ptr)++; } else if (!strncasecmp(tag, "Priority", MAX(taglen, 3))) { if (parse_uint16(val, &part_msg_ptr->priority_tier)) { error("Invalid Priority value: %s", val); return -1; } part_msg_ptr->priority_job_factor = part_msg_ptr->priority_tier; (*update_cnt_ptr)++; } else if (!strncasecmp(tag,"PriorityJobFactor",MAX(taglen, 3))) { if (parse_uint16(val, &part_msg_ptr->priority_job_factor)) { error("Invalid PriorityJobFactor value: %s", val); return -1; } (*update_cnt_ptr)++; } else if (!strncasecmp(tag, "PriorityTier", MAX(taglen, 3))) { if (parse_uint16(val, &part_msg_ptr->priority_tier)) { error("Invalid PriorityTier value: %s", val); return -1; } (*update_cnt_ptr)++; } else if (strncasecmp(tag, "State", MAX(taglen, 2)) == 0) { if (strncasecmp(val, "INACTIVE", MAX(vallen, 1)) == 0) part_msg_ptr->state_up = PARTITION_INACTIVE; else if (strncasecmp(val, "DOWN", MAX(vallen, 1)) == 0) part_msg_ptr->state_up = PARTITION_DOWN; else if (strncasecmp(val, "UP", MAX(vallen, 1)) == 0) part_msg_ptr->state_up = PARTITION_UP; else if (strncasecmp(val, "DRAIN", MAX(vallen, 1)) == 0) part_msg_ptr->state_up = PARTITION_DRAIN; else { exit_code = 1; error("Invalid input: %s", argv[i]); error("Acceptable State values " "are UP, DOWN, DRAIN and INACTIVE"); return -1; } (*update_cnt_ptr)++; } else if (!strncasecmp(tag, "Nodes", MAX(taglen, 1))) { part_msg_ptr->nodes = val; (*update_cnt_ptr)++; } else if (!strncasecmp(tag, "AllowGroups", MAX(taglen, 6))) { part_msg_ptr->allow_groups = val; (*update_cnt_ptr)++; } else if (!strncasecmp(tag, "AllowAccounts", MAX(taglen, 6))) { part_msg_ptr->allow_accounts = val; (*update_cnt_ptr)++; } else if (!strncasecmp(tag, "AllowQos", MAX(taglen, 6))) { part_msg_ptr->allow_qos = val; (*update_cnt_ptr)++; } else if (!strncasecmp(tag, "DenyAccounts", MAX(taglen, 5))) { part_msg_ptr->deny_accounts = val; (*update_cnt_ptr)++; } else if (!strncasecmp(tag, "DenyQos", MAX(taglen, 5))) { part_msg_ptr->deny_qos = val; (*update_cnt_ptr)++; } else if (!strncasecmp(tag, "AllocNodes", MAX(taglen, 6))) { part_msg_ptr->allow_alloc_nodes = val; (*update_cnt_ptr)++; } else if (!strncasecmp(tag, "Alternate", MAX(taglen, 3))) { part_msg_ptr->alternate = val; (*update_cnt_ptr)++; } else if (!strncasecmp(tag, "GraceTime", MAX(taglen, 5))) { if (parse_uint32(val, &part_msg_ptr->grace_time)) { error ("Invalid GraceTime value: %s", val); return -1; } (*update_cnt_ptr)++; } else if (!strncasecmp(tag, "DefMemPerCPU", MAX(taglen, 10))) { if (parse_uint32(val, &part_msg_ptr->def_mem_per_cpu)) { error ("Invalid DefMemPerCPU value: %s", val); return -1; } part_msg_ptr->def_mem_per_cpu |= MEM_PER_CPU; (*update_cnt_ptr)++; } else if (!strncasecmp(tag, "DefMemPerNode", MAX(taglen, 10))) { if (parse_uint32(val, &part_msg_ptr->def_mem_per_cpu)) { error ("Invalid DefMemPerNode value: %s", val); return -1; } (*update_cnt_ptr)++; } else if (!strncasecmp(tag, "MaxMemPerCPU", MAX(taglen, 10))) { if (parse_uint32(val, &part_msg_ptr->max_mem_per_cpu)) { error ("Invalid MaxMemPerCPU value: %s", val); return -1; } part_msg_ptr->max_mem_per_cpu |= MEM_PER_CPU; (*update_cnt_ptr)++; } else if (!strncasecmp(tag, "MaxMemPerNode", MAX(taglen, 10))) { if (parse_uint32(val, &part_msg_ptr->max_mem_per_cpu)) { error ("Invalid MaxMemPerNode value: %s", val); return -1; } (*update_cnt_ptr)++; } else if (!strncasecmp(tag, "QoS", MAX(taglen, 3))) { part_msg_ptr->qos_char = val; (*update_cnt_ptr)++; } else { exit_code = 1; error("Update of this parameter is not " "supported: %s\n", argv[i]); error("Request aborted"); return -1; } } return 0; }
/** * Extract information from SOAP fault tree. * * @param fault the XML <Fault> tree * @param code where UPnP error code is written, if non-NULL * @param error where address of UPnP error string is written, if non-NULL * * @attention * The error string is pointing in the XML tree and will become invalid as * soon as the tree is freed so it needs to be duplicated if it must persist. * * @return TRUE if OK, FALSE on error. */ static gboolean upnp_ctrl_extract_fault(xnode_t *fault, int *code, const char **error) { xnode_t *fcode, *fstring, *detail, *uerror; const char *parse_error = NULL; g_assert(fault != NULL); /* * The SOAP specification for the <faultcode> element are very bad. * Indeed, the content is a string bearing the *prefix* of the SOAP * namespace, which is completely arbitrary and not accessible at this * level since all nodes are normalized with their namespace, the prefix * string being irrelevant once parsing is done. And namespace have no * meaning in element *content*. * * Sure, we know we force the "s" prefix for SOAP, and most UPnP stacks * are going to use that prefix as well, but matching the <faultcode> * content to look for "s:Client" or "s:MustUnderstand" is just plain * wrong, and a blatant encapsulation violation. * * So instead we look backwards in the string to find the first ':' and * consider the tail part of the string, totally ignoring the prefix. * That's a lousy parsing, but in practice it's going to work and should * be safe since there's little choice anyway according to the SOAP * specifications (meaning they could have just as well ignored the * prefix in this string and just mandate "Client" or "MustUnderstand"). * * Also note that <faultcode>, <faultstring> and <detail> elements are * architected without any SOAP namespace. That's surprising. */ fcode = xnode_tree_find_depth(fault, 1, node_named_as, deconstify_gchar(SOAP_FAULT_CODE)); if (NULL == fcode) { parse_error = "cannot find <faultcode>"; goto error; } else { const char *value; const char *name; value = xnode_first_text(fcode); if (NULL == value) { parse_error = "<faultcode> does not contain text"; goto error; } /* * We're only handling "Client" errors. */ name = strrchr(value, ':'); if (NULL == name) { parse_error = "no ':' in fault code name"; goto error; } name++; if (0 != strcmp(name, SOAP_CLIENT_FAULT)) { parse_error = "not a Client fault"; goto error; } } /* * Here is a sample fault tree from the UPnP 1.0 architecture: * * <s:Fault> * <faultcode>s:Client</faultcode> * <faultstring>UPnPError</faultstring> * <detail> * <UPnpError xmlns="urn:schemas-upnp-org:control-1-0"> * <errorCode>error code</errorCode> * <errorDescription>error string</errorDescription> * </UPnPError> * </detail> * <s:Fault> * * Note that the UPnP tags are in the "urn:schemas-upnp-org:control-1-0" * namespace. */ fstring = xnode_tree_find_depth(fault, 1, node_named_as, deconstify_gchar(SOAP_FAULT_STRING)); if (NULL == fstring) { parse_error = "no <faultstring> found"; goto error; } else { const char *value; value = xnode_first_text(fstring); if (NULL == value) { parse_error = "<faultstring> does not contain text"; goto error; } if (0 != strcmp(value, SOAP_UPNP_ERROR)) { parse_error = "<faultstring> is not an UPnP error"; goto error; } } detail = xnode_tree_find_depth(fault, 1, node_named_as, deconstify_gchar(SOAP_FAULT_DETAIL)); if (NULL == detail) { parse_error = "no <detail> found"; goto error; } /* * First child must be a <UPnpError> tag. */ uerror = xnode_first_child(detail); if (xnode_is_element_named(uerror, UPNP_NS_ERROR, SOAP_UPNP_ERROR)) { xnode_t *xn; if (code != NULL) { const char *value; int err; xn = xnode_tree_find_depth(uerror, 1, node_named_as, deconstify_gchar(UPNP_ERROR_CODE)); if (NULL == xn) { parse_error = "no <errorCode> found"; goto error; } value = xnode_first_text(xn); if (NULL == value) { parse_error = "<errorCode> doest not contain text"; goto error; } *code = parse_uint32(value, NULL, 10, &err); if (err) { parse_error = "cannot parse <errorCode> value"; goto error; } } if (error != NULL) { xn = xnode_tree_find_depth(uerror, 1, node_named_as, deconstify_gchar(UPNP_ERROR_DESC)); *error = (NULL == xn) ? NULL : xnode_first_text(xn); } } else { parse_error = "no <UPnPError> found"; goto error; } return TRUE; error: if (GNET_PROPERTY(upnp_debug)) g_warning("UPNP fault parsing error: %s", EMPTY_STRING(parse_error)); return FALSE; }
/* * scontrol_parse_res_options parse options for creating or updating a reservation * IN argc - count of arguments * IN argv - list of arguments * IN msg - a string to append to any error message * OUT resv_msg_ptr - struct holding reservation parameters * OUT free_user_str - bool indicating that resv_msg_ptr->users should be freed * OUT free_acct_str - bool indicating that resv_msg_ptr->accounts should be * freed * RET 0 on success, -1 on err and prints message */ extern int scontrol_parse_res_options(int argc, char *argv[], const char *msg, resv_desc_msg_t *resv_msg_ptr, int *free_user_str, int *free_acct_str, int *free_tres_license, int *free_tres_bb, int *free_tres_corecnt, int *free_tres_nodecnt) { int i; int duration = -3; /* -1 == INFINITE, -2 == error, -3 == not set */ *free_user_str = 0; *free_acct_str = 0; *free_tres_license = 0; *free_tres_bb = 0; *free_tres_corecnt = 0; *free_tres_nodecnt = 0; for (i=0; i<argc; i++) { char *tag = argv[i]; int taglen = 0; char plus_minus = '\0'; char *val = strchr(argv[i], '='); taglen = val - argv[i]; if (!val && strncasecmp(argv[i], "res", 3) == 0) { continue; } else if (!val || taglen == 0) { exit_code = 1; error("Unknown parameter %s. %s", argv[i], msg); return SLURM_ERROR; } if (val[-1] == '+' || val[-1] == '-') { plus_minus = val[-1]; taglen--; } val++; if (strncasecmp(tag, "ReservationName", MAX(taglen, 1)) == 0) { resv_msg_ptr->name = val; } else if (strncasecmp(tag, "Accounts", MAX(taglen, 1)) == 0) { if (plus_minus) { resv_msg_ptr->accounts = _process_plus_minus(plus_minus, val); *free_acct_str = 1; } else { resv_msg_ptr->accounts = val; } } else if (strncasecmp(tag, "BurstBuffer", MAX(taglen, 2)) == 0) { resv_msg_ptr->burst_buffer = val; } else if (strncasecmp(tag, "StartTime", MAX(taglen, 1)) == 0) { time_t t = parse_time(val, 0); if (errno == ESLURM_INVALID_TIME_VALUE) { exit_code = 1; error("Invalid start time %s. %s", argv[i], msg); return SLURM_ERROR; } resv_msg_ptr->start_time = t; } else if (strncasecmp(tag, "EndTime", MAX(taglen, 1)) == 0) { time_t t = parse_time(val, 0); if (errno == ESLURM_INVALID_TIME_VALUE) { exit_code = 1; error("Invalid end time %s. %s", argv[i],msg); return SLURM_ERROR; } resv_msg_ptr->end_time = t; } else if (strncasecmp(tag, "Duration", MAX(taglen, 1)) == 0) { /* -1 == INFINITE, -2 == error, -3 == not set */ duration = time_str2mins(val); if (duration < 0 && duration != INFINITE) { exit_code = 1; error("Invalid duration %s. %s", argv[i],msg); return SLURM_ERROR; } resv_msg_ptr->duration = (uint32_t)duration; } else if (strncasecmp(tag, "Flags", MAX(taglen, 2)) == 0) { uint32_t f; if (plus_minus) { char *tmp = _process_plus_minus(plus_minus, val); f = parse_resv_flags(tmp, msg); xfree(tmp); } else { f = parse_resv_flags(val, msg); } if (f == 0xffffffff) { return SLURM_ERROR; } else { resv_msg_ptr->flags = f; } } else if (strncasecmp(tag, "NodeCnt", MAX(taglen,5)) == 0 || strncasecmp(tag, "NodeCount", MAX(taglen,5)) == 0) { if (_parse_resv_node_cnt(resv_msg_ptr, val, false) == SLURM_ERROR) return SLURM_ERROR; } else if (strncasecmp(tag, "CoreCnt", MAX(taglen,5)) == 0 || strncasecmp(tag, "CoreCount", MAX(taglen,5)) == 0 || strncasecmp(tag, "CPUCnt", MAX(taglen,5)) == 0 || strncasecmp(tag, "CPUCount", MAX(taglen,5)) == 0) { if (_parse_resv_core_cnt(resv_msg_ptr, val, false) == SLURM_ERROR) return SLURM_ERROR; } else if (strncasecmp(tag, "Nodes", MAX(taglen, 5)) == 0) { resv_msg_ptr->node_list = val; } else if (strncasecmp(tag, "Features", MAX(taglen, 2)) == 0) { resv_msg_ptr->features = val; } else if (strncasecmp(tag, "Licenses", MAX(taglen, 2)) == 0) { resv_msg_ptr->licenses = val; } else if (strncasecmp(tag, "PartitionName", MAX(taglen, 1)) == 0) { resv_msg_ptr->partition = val; } else if (strncasecmp(tag, "TRES", MAX(taglen, 1)) == 0) { if (_parse_resv_tres(val, resv_msg_ptr, free_tres_license, free_tres_bb, free_tres_corecnt, free_tres_nodecnt) == SLURM_ERROR) return SLURM_ERROR; } else if (strncasecmp(tag, "Users", MAX(taglen, 1)) == 0) { if (plus_minus) { resv_msg_ptr->users = _process_plus_minus(plus_minus, val); *free_user_str = 1; } else { resv_msg_ptr->users = val; } } else if (strncasecmp(tag, "Watts", MAX(taglen, 1)) == 0) { if (parse_uint32(val, &(resv_msg_ptr->resv_watts))) { error("Invalid Watts value: %s", val); return SLURM_ERROR; } } else if (strncasecmp(tag, "res", 3) == 0) { continue; } else { exit_code = 1; error("Unknown parameter %s. %s", argv[i], msg); return SLURM_ERROR; } } return SLURM_SUCCESS; }
void pgut_setopt(pgut_option *opt, const char *optarg, pgut_optsrc src) { const char *message; if (opt == NULL) { fprintf(stderr, "Try \"%s --help\" for more information.\n", PROGRAM_NAME); exit(EINVAL); } if (opt->source > src) { /* high prior value has been set already. */ return; } else if (src >= SOURCE_CMDLINE && opt->source >= src) { /* duplicated option in command line */ message = "specified only once"; } else { /* can be overwritten if non-command line source */ opt->source = src; switch (opt->type) { case 'b': case 'B': if (optarg == NULL) { *((bool *) opt->var) = (opt->type == 'b'); return; } else if (parse_bool(optarg, (bool *) opt->var)) { return; } message = "a boolean"; break; case 'f': ((pgut_optfn) opt->var)(opt, optarg); return; case 'i': if (parse_int32(optarg, opt->var)) return; message = "a 32bit signed integer"; break; case 'u': if (parse_uint32(optarg, opt->var)) return; message = "a 32bit unsigned integer"; break; case 'I': if (parse_int64(optarg, opt->var)) return; message = "a 64bit signed integer"; break; case 'U': if (parse_uint64(optarg, opt->var)) return; message = "a 64bit unsigned integer"; break; case 's': if (opt->source != SOURCE_DEFAULT) free(*(char **) opt->var); *(char **) opt->var = pgut_strdup(optarg); return; case 't': if (parse_time(optarg, opt->var)) return; message = "a time"; break; case 'y': case 'Y': if (optarg == NULL) { *(YesNo *) opt->var = (opt->type == 'y' ? YES : NO); return; } else { bool value; if (parse_bool(optarg, &value)) { *(YesNo *) opt->var = (value ? YES : NO); return; } } message = "a boolean"; break; default: ereport(ERROR, (errcode(EINVAL), errmsg("invalid option type: %c", opt->type))); return; /* keep compiler quiet */ } } if (isprint(opt->sname)) ereport(ERROR, (errcode(EINVAL), errmsg("option -%c, --%s should be %s: '%s'", opt->sname, opt->lname, message, optarg))); else ereport(ERROR, (errcode(EINVAL), errmsg("option --%s should be %s: '%s'", opt->lname, message, optarg))); }
FLAC__bool parse_option(int option_index, const char *option_argument, CommandLineOptions *options) { const char *opt = long_options_[option_index].name; Operation *op; Argument *arg; FLAC__bool ok = true; if(0 == strcmp(opt, "preserve-modtime")) { options->preserve_modtime = true; } else if(0 == strcmp(opt, "with-filename")) { options->prefix_with_filename = true; } else if(0 == strcmp(opt, "no-filename")) { options->prefix_with_filename = false; } else if(0 == strcmp(opt, "no-utf8-convert")) { options->utf8_convert = false; } else if(0 == strcmp(opt, "dont-use-padding")) { options->use_padding = false; } else if(0 == strcmp(opt, "no-cued-seekpoints")) { options->cued_seekpoints = false; } else if(0 == strcmp(opt, "show-md5sum")) { (void) append_shorthand_operation(options, OP__SHOW_MD5SUM); } else if(0 == strcmp(opt, "show-min-blocksize")) { (void) append_shorthand_operation(options, OP__SHOW_MIN_BLOCKSIZE); } else if(0 == strcmp(opt, "show-max-blocksize")) { (void) append_shorthand_operation(options, OP__SHOW_MAX_BLOCKSIZE); } else if(0 == strcmp(opt, "show-min-framesize")) { (void) append_shorthand_operation(options, OP__SHOW_MIN_FRAMESIZE); } else if(0 == strcmp(opt, "show-max-framesize")) { (void) append_shorthand_operation(options, OP__SHOW_MAX_FRAMESIZE); } else if(0 == strcmp(opt, "show-sample-rate")) { (void) append_shorthand_operation(options, OP__SHOW_SAMPLE_RATE); } else if(0 == strcmp(opt, "show-channels")) { (void) append_shorthand_operation(options, OP__SHOW_CHANNELS); } else if(0 == strcmp(opt, "show-bps")) { (void) append_shorthand_operation(options, OP__SHOW_BPS); } else if(0 == strcmp(opt, "show-total-samples")) { (void) append_shorthand_operation(options, OP__SHOW_TOTAL_SAMPLES); } else if(0 == strcmp(opt, "set-md5sum")) { op = append_shorthand_operation(options, OP__SET_MD5SUM); FLAC__ASSERT(0 != option_argument); if(!parse_md5(option_argument, op->argument.streaminfo_md5.value)) { flac_fprintf(stderr, "ERROR (--%s): bad MD5 sum\n", opt); ok = false; } else undocumented_warning(opt); } else if(0 == strcmp(opt, "set-min-blocksize")) { op = append_shorthand_operation(options, OP__SET_MIN_BLOCKSIZE); if(!parse_uint32(option_argument, &(op->argument.streaminfo_uint32.value)) || op->argument.streaminfo_uint32.value < FLAC__MIN_BLOCK_SIZE || op->argument.streaminfo_uint32.value > FLAC__MAX_BLOCK_SIZE) { flac_fprintf(stderr, "ERROR (--%s): value must be >= %u and <= %u\n", opt, FLAC__MIN_BLOCK_SIZE, FLAC__MAX_BLOCK_SIZE); ok = false; } else undocumented_warning(opt); } else if(0 == strcmp(opt, "set-max-blocksize")) { op = append_shorthand_operation(options, OP__SET_MAX_BLOCKSIZE); if(!parse_uint32(option_argument, &(op->argument.streaminfo_uint32.value)) || op->argument.streaminfo_uint32.value < FLAC__MIN_BLOCK_SIZE || op->argument.streaminfo_uint32.value > FLAC__MAX_BLOCK_SIZE) { flac_fprintf(stderr, "ERROR (--%s): value must be >= %u and <= %u\n", opt, FLAC__MIN_BLOCK_SIZE, FLAC__MAX_BLOCK_SIZE); ok = false; } else undocumented_warning(opt); } else if(0 == strcmp(opt, "set-min-framesize")) { op = append_shorthand_operation(options, OP__SET_MIN_FRAMESIZE); if(!parse_uint32(option_argument, &(op->argument.streaminfo_uint32.value)) || op->argument.streaminfo_uint32.value >= (1u<<FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN)) { flac_fprintf(stderr, "ERROR (--%s): value must be a %u-bit unsigned integer\n", opt, FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN); ok = false; } else undocumented_warning(opt); } else if(0 == strcmp(opt, "set-max-framesize")) { op = append_shorthand_operation(options, OP__SET_MAX_FRAMESIZE); if(!parse_uint32(option_argument, &(op->argument.streaminfo_uint32.value)) || op->argument.streaminfo_uint32.value >= (1u<<FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN)) { flac_fprintf(stderr, "ERROR (--%s): value must be a %u-bit unsigned integer\n", opt, FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN); ok = false; } else undocumented_warning(opt); } else if(0 == strcmp(opt, "set-sample-rate")) { op = append_shorthand_operation(options, OP__SET_SAMPLE_RATE); if(!parse_uint32(option_argument, &(op->argument.streaminfo_uint32.value)) || !FLAC__format_sample_rate_is_valid(op->argument.streaminfo_uint32.value)) { flac_fprintf(stderr, "ERROR (--%s): invalid sample rate\n", opt); ok = false; } else undocumented_warning(opt); } else if(0 == strcmp(opt, "set-channels")) { op = append_shorthand_operation(options, OP__SET_CHANNELS); if(!parse_uint32(option_argument, &(op->argument.streaminfo_uint32.value)) || op->argument.streaminfo_uint32.value > FLAC__MAX_CHANNELS) { flac_fprintf(stderr, "ERROR (--%s): value must be > 0 and <= %u\n", opt, FLAC__MAX_CHANNELS); ok = false; } else undocumented_warning(opt); } else if(0 == strcmp(opt, "set-bps")) { op = append_shorthand_operation(options, OP__SET_BPS); if(!parse_uint32(option_argument, &(op->argument.streaminfo_uint32.value)) || op->argument.streaminfo_uint32.value < FLAC__MIN_BITS_PER_SAMPLE || op->argument.streaminfo_uint32.value > FLAC__MAX_BITS_PER_SAMPLE) { flac_fprintf(stderr, "ERROR (--%s): value must be >= %u and <= %u\n", opt, FLAC__MIN_BITS_PER_SAMPLE, FLAC__MAX_BITS_PER_SAMPLE); ok = false; } else undocumented_warning(opt); } else if(0 == strcmp(opt, "set-total-samples")) { op = append_shorthand_operation(options, OP__SET_TOTAL_SAMPLES); if(!parse_uint64(option_argument, &(op->argument.streaminfo_uint64.value)) || op->argument.streaminfo_uint64.value >= (((FLAC__uint64)1)<<FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN)) { flac_fprintf(stderr, "ERROR (--%s): value must be a %u-bit unsigned integer\n", opt, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN); ok = false; } else undocumented_warning(opt); } else if(0 == strcmp(opt, "show-vendor-tag")) { (void) append_shorthand_operation(options, OP__SHOW_VC_VENDOR); } else if(0 == strcmp(opt, "show-tag")) { const char *violation; op = append_shorthand_operation(options, OP__SHOW_VC_FIELD); FLAC__ASSERT(0 != option_argument); if(!parse_vorbis_comment_field_name(option_argument, &(op->argument.vc_field_name.value), &violation)) { FLAC__ASSERT(0 != violation); flac_fprintf(stderr, "ERROR (--%s): malformed vorbis comment field name \"%s\",\n %s\n", opt, option_argument, violation); ok = false; } } else if(0 == strcmp(opt, "remove-all-tags")) { (void) append_shorthand_operation(options, OP__REMOVE_VC_ALL); } else if(0 == strcmp(opt, "remove-tag")) { const char *violation; op = append_shorthand_operation(options, OP__REMOVE_VC_FIELD); FLAC__ASSERT(0 != option_argument); if(!parse_vorbis_comment_field_name(option_argument, &(op->argument.vc_field_name.value), &violation)) { FLAC__ASSERT(0 != violation); flac_fprintf(stderr, "ERROR (--%s): malformed vorbis comment field name \"%s\",\n %s\n", opt, option_argument, violation); ok = false; } } else if(0 == strcmp(opt, "remove-first-tag")) { const char *violation; op = append_shorthand_operation(options, OP__REMOVE_VC_FIRSTFIELD); FLAC__ASSERT(0 != option_argument); if(!parse_vorbis_comment_field_name(option_argument, &(op->argument.vc_field_name.value), &violation)) { FLAC__ASSERT(0 != violation); flac_fprintf(stderr, "ERROR (--%s): malformed vorbis comment field name \"%s\",\n %s\n", opt, option_argument, violation); ok = false; } } else if(0 == strcmp(opt, "set-tag")) { const char *violation; op = append_shorthand_operation(options, OP__SET_VC_FIELD); FLAC__ASSERT(0 != option_argument); op->argument.vc_field.field_value_from_file = false; if(!parse_vorbis_comment_field(option_argument, &(op->argument.vc_field.field), &(op->argument.vc_field.field_name), &(op->argument.vc_field.field_value), &(op->argument.vc_field.field_value_length), &violation)) { FLAC__ASSERT(0 != violation); flac_fprintf(stderr, "ERROR (--%s): malformed vorbis comment field \"%s\",\n %s\n", opt, option_argument, violation); ok = false; } } else if(0 == strcmp(opt, "set-tag-from-file")) { const char *violation; op = append_shorthand_operation(options, OP__SET_VC_FIELD); FLAC__ASSERT(0 != option_argument); op->argument.vc_field.field_value_from_file = true; if(!parse_vorbis_comment_field(option_argument, &(op->argument.vc_field.field), &(op->argument.vc_field.field_name), &(op->argument.vc_field.field_value), &(op->argument.vc_field.field_value_length), &violation)) { FLAC__ASSERT(0 != violation); flac_fprintf(stderr, "ERROR (--%s): malformed vorbis comment field \"%s\",\n %s\n", opt, option_argument, violation); ok = false; } } else if(0 == strcmp(opt, "import-tags-from")) { op = append_shorthand_operation(options, OP__IMPORT_VC_FROM); FLAC__ASSERT(0 != option_argument); if(!parse_string(option_argument, &(op->argument.filename.value))) { flac_fprintf(stderr, "ERROR (--%s): missing filename\n", opt); ok = false; } } else if(0 == strcmp(opt, "export-tags-to")) { op = append_shorthand_operation(options, OP__EXPORT_VC_TO); FLAC__ASSERT(0 != option_argument); if(!parse_string(option_argument, &(op->argument.filename.value))) { flac_fprintf(stderr, "ERROR (--%s): missing filename\n", opt); ok = false; } } else if(0 == strcmp(opt, "import-cuesheet-from")) { if(0 != find_shorthand_operation(options, OP__IMPORT_CUESHEET_FROM)) { flac_fprintf(stderr, "ERROR (--%s): may be specified only once\n", opt); ok = false; } op = append_shorthand_operation(options, OP__IMPORT_CUESHEET_FROM); FLAC__ASSERT(0 != option_argument); if(!parse_string(option_argument, &(op->argument.import_cuesheet_from.filename))) { flac_fprintf(stderr, "ERROR (--%s): missing filename\n", opt); ok = false; } } else if(0 == strcmp(opt, "export-cuesheet-to")) { op = append_shorthand_operation(options, OP__EXPORT_CUESHEET_TO); FLAC__ASSERT(0 != option_argument); if(!parse_string(option_argument, &(op->argument.filename.value))) { flac_fprintf(stderr, "ERROR (--%s): missing filename\n", opt); ok = false; } } else if(0 == strcmp(opt, "import-picture-from")) { op = append_shorthand_operation(options, OP__IMPORT_PICTURE_FROM); FLAC__ASSERT(0 != option_argument); if(!parse_string(option_argument, &(op->argument.specification.value))) { flac_fprintf(stderr, "ERROR (--%s): missing specification\n", opt); ok = false; } } else if(0 == strcmp(opt, "export-picture-to")) { arg = find_argument(options, ARG__BLOCK_NUMBER); op = append_shorthand_operation(options, OP__EXPORT_PICTURE_TO); FLAC__ASSERT(0 != option_argument); if(!parse_string(option_argument, &(op->argument.export_picture_to.filename))) { flac_fprintf(stderr, "ERROR (--%s): missing filename\n", opt); ok = false; } op->argument.export_picture_to.block_number_link = arg? &(arg->value.block_number) : 0; } else if(0 == strcmp(opt, "add-seekpoint")) { const char *violation; char *spec; FLAC__ASSERT(0 != option_argument); if(!parse_add_seekpoint(option_argument, &spec, &violation)) { FLAC__ASSERT(0 != violation); flac_fprintf(stderr, "ERROR (--%s): malformed seekpoint specification \"%s\",\n %s\n", opt, option_argument, violation); ok = false; } else { op = find_shorthand_operation(options, OP__ADD_SEEKPOINT); if(0 == op) op = append_shorthand_operation(options, OP__ADD_SEEKPOINT); local_strcat(&(op->argument.add_seekpoint.specification), spec); local_strcat(&(op->argument.add_seekpoint.specification), ";"); free(spec); } } else if(0 == strcmp(opt, "add-replay-gain")) { (void) append_shorthand_operation(options, OP__ADD_REPLAY_GAIN); } else if(0 == strcmp(opt, "remove-replay-gain")) { const FLAC__byte * const tags[5] = { GRABBAG__REPLAYGAIN_TAG_REFERENCE_LOUDNESS, GRABBAG__REPLAYGAIN_TAG_TITLE_GAIN, GRABBAG__REPLAYGAIN_TAG_TITLE_PEAK, GRABBAG__REPLAYGAIN_TAG_ALBUM_GAIN, GRABBAG__REPLAYGAIN_TAG_ALBUM_PEAK }; size_t i; for(i = 0; i < sizeof(tags)/sizeof(tags[0]); i++) { op = append_shorthand_operation(options, OP__REMOVE_VC_FIELD); op->argument.vc_field_name.value = local_strdup((const char *)tags[i]); } } else if(0 == strcmp(opt, "add-padding")) { op = append_shorthand_operation(options, OP__ADD_PADDING); FLAC__ASSERT(0 != option_argument); if(!parse_add_padding(option_argument, &(op->argument.add_padding.length))) { flac_fprintf(stderr, "ERROR (--%s): illegal length \"%s\", length must be >= 0 and < 2^%u\n", opt, option_argument, FLAC__STREAM_METADATA_LENGTH_LEN); ok = false; } } else if(0 == strcmp(opt, "help")) { options->show_long_help = true; } else if(0 == strcmp(opt, "version")) { options->show_version = true; } else if(0 == strcmp(opt, "list")) { (void) append_major_operation(options, OP__LIST); } else if(0 == strcmp(opt, "append")) { (void) append_major_operation(options, OP__APPEND); } else if(0 == strcmp(opt, "remove")) { (void) append_major_operation(options, OP__REMOVE); } else if(0 == strcmp(opt, "remove-all")) { (void) append_major_operation(options, OP__REMOVE_ALL); } else if(0 == strcmp(opt, "merge-padding")) { (void) append_major_operation(options, OP__MERGE_PADDING); } else if(0 == strcmp(opt, "sort-padding")) { (void) append_major_operation(options, OP__SORT_PADDING); } else if(0 == strcmp(opt, "block-number")) { arg = append_argument(options, ARG__BLOCK_NUMBER); FLAC__ASSERT(0 != option_argument); if(!parse_block_number(option_argument, &(arg->value.block_number))) { flac_fprintf(stderr, "ERROR: malformed block number specification \"%s\"\n", option_argument); ok = false; } } else if(0 == strcmp(opt, "block-type")) { arg = append_argument(options, ARG__BLOCK_TYPE); FLAC__ASSERT(0 != option_argument); if(!parse_block_type(option_argument, &(arg->value.block_type))) { flac_fprintf(stderr, "ERROR (--%s): malformed block type specification \"%s\"\n", opt, option_argument); ok = false; } options->args.checks.has_block_type = true; } else if(0 == strcmp(opt, "except-block-type")) { arg = append_argument(options, ARG__EXCEPT_BLOCK_TYPE); FLAC__ASSERT(0 != option_argument); if(!parse_block_type(option_argument, &(arg->value.block_type))) { flac_fprintf(stderr, "ERROR (--%s): malformed block type specification \"%s\"\n", opt, option_argument); ok = false; } options->args.checks.has_except_block_type = true; } else if(0 == strcmp(opt, "data-format")) { arg = append_argument(options, ARG__DATA_FORMAT); FLAC__ASSERT(0 != option_argument); if(!parse_data_format(option_argument, &(arg->value.data_format))) { flac_fprintf(stderr, "ERROR (--%s): illegal data format \"%s\"\n", opt, option_argument); ok = false; } } else if(0 == strcmp(opt, "application-data-format")) { FLAC__ASSERT(0 != option_argument); if(!parse_application_data_format(option_argument, &(options->application_data_format_is_hexdump))) { flac_fprintf(stderr, "ERROR (--%s): illegal application data format \"%s\"\n", opt, option_argument); ok = false; } } else if(0 == strcmp(opt, "from-file")) { arg = append_argument(options, ARG__FROM_FILE); FLAC__ASSERT(0 != option_argument); arg->value.from_file.file_name = local_strdup(option_argument); } else { FLAC__ASSERT(0); } return ok; }
static int parse_option(struct dhcpcd_ctx *ctx, const char *ifname, struct if_options *ifo, int opt, const char *arg, struct dhcp_opt **ldop, struct dhcp_opt **edop) { int i, l, t; unsigned int u; char *p = NULL, *fp, *np, **nconf; ssize_t s; struct in_addr addr, addr2; in_addr_t *naddr; struct rt *rt; const struct dhcp_opt *d; uint8_t *request, *require, *no; struct dhcp_opt **dop, *ndop; size_t *dop_len, dl; struct vivco *vivco; struct token *token; #ifdef INET6 size_t sl; struct if_ia *ia; uint8_t iaid[4]; struct if_sla *sla, *slap; #endif dop = NULL; dop_len = NULL; #ifdef INET6 i = 0; #endif switch(opt) { case 'f': /* FALLTHROUGH */ case 'g': /* FALLTHROUGH */ case 'n': /* FALLTHROUGH */ case 'x': /* FALLTHROUGH */ case 'T': /* FALLTHROUGH */ case 'U': /* FALLTHROUGH */ case 'V': /* We need to handle non interface options */ break; case 'b': ifo->options |= DHCPCD_BACKGROUND; break; case 'c': free(ifo->script); ifo->script = strdup(arg); if (ifo->script == NULL) syslog(LOG_ERR, "%s: %m", __func__); break; case 'd': ifo->options |= DHCPCD_DEBUG; break; case 'e': add_environ(ifo, arg, 1); break; case 'h': if (!arg) { ifo->options |= DHCPCD_HOSTNAME; break; } s = parse_string(ifo->hostname, HOSTNAME_MAX_LEN, arg); if (s == -1) { syslog(LOG_ERR, "hostname: %m"); return -1; } if (s != 0 && ifo->hostname[0] == '.') { syslog(LOG_ERR, "hostname cannot begin with ."); return -1; } ifo->hostname[s] = '\0'; if (ifo->hostname[0] == '\0') ifo->options &= ~DHCPCD_HOSTNAME; else ifo->options |= DHCPCD_HOSTNAME; break; case 'i': if (arg) s = parse_string((char *)ifo->vendorclassid + 1, VENDORCLASSID_MAX_LEN, arg); else s = 0; if (s == -1) { syslog(LOG_ERR, "vendorclassid: %m"); return -1; } *ifo->vendorclassid = (uint8_t)s; break; case 'k': ifo->options |= DHCPCD_RELEASE; break; case 'l': if (*arg == '-') { syslog(LOG_ERR, "leasetime must be a positive value"); return -1; } errno = 0; ifo->leasetime = (uint32_t)strtoul(arg, NULL, 0); if (errno == EINVAL || errno == ERANGE) { syslog(LOG_ERR, "`%s' out of range", arg); return -1; } break; case 'm': ifo->metric = atoint(arg); if (ifo->metric < 0) { syslog(LOG_ERR, "metric must be a positive value"); return -1; } break; case 'o': arg = set_option_space(ctx, arg, &d, &dl, ifo, &request, &require, &no); if (make_option_mask(d, dl, request, arg, 1) != 0) { syslog(LOG_ERR, "unknown option `%s'", arg); return -1; } break; case 'p': ifo->options |= DHCPCD_PERSISTENT; break; case 'q': ifo->options |= DHCPCD_QUIET; break; case 'r': if (parse_addr(&ifo->req_addr, NULL, arg) != 0) return -1; ifo->options |= DHCPCD_REQUEST; ifo->req_mask.s_addr = 0; break; case 's': if (ifo->options & DHCPCD_IPV6 && !(ifo->options & DHCPCD_IPV4)) { ifo->options |= DHCPCD_INFORM; break; } if (arg && *arg != '\0') { if (parse_addr(&ifo->req_addr, &ifo->req_mask, arg) != 0) return -1; } else { ifo->req_addr.s_addr = 0; ifo->req_mask.s_addr = 0; } ifo->options |= DHCPCD_INFORM | DHCPCD_PERSISTENT; ifo->options &= ~(DHCPCD_ARP | DHCPCD_STATIC); break; case 't': ifo->timeout = atoint(arg); if (ifo->timeout < 0) { syslog(LOG_ERR, "timeout must be a positive value"); return -1; } break; case 'u': s = USERCLASS_MAX_LEN - ifo->userclass[0] - 1; s = parse_string((char *)ifo->userclass + ifo->userclass[0] + 2, s, arg); if (s == -1) { syslog(LOG_ERR, "userclass: %m"); return -1; } if (s != 0) { ifo->userclass[ifo->userclass[0] + 1] = s; ifo->userclass[0] += s + 1; } break; case 'v': p = strchr(arg, ','); if (!p || !p[1]) { syslog(LOG_ERR, "invalid vendor format: %s", arg); return -1; } /* If vendor starts with , then it is not encapsulated */ if (p == arg) { arg++; s = parse_string((char *)ifo->vendor + 1, VENDOR_MAX_LEN, arg); if (s == -1) { syslog(LOG_ERR, "vendor: %m"); return -1; } ifo->vendor[0] = (uint8_t)s; ifo->options |= DHCPCD_VENDORRAW; break; } /* Encapsulated vendor options */ if (ifo->options & DHCPCD_VENDORRAW) { ifo->options &= ~DHCPCD_VENDORRAW; ifo->vendor[0] = 0; } /* No need to strip the comma */ i = atoint(arg); if (i < 1 || i > 254) { syslog(LOG_ERR, "vendor option should be between" " 1 and 254 inclusive"); return -1; } arg = p + 1; s = VENDOR_MAX_LEN - ifo->vendor[0] - 2; if (inet_aton(arg, &addr) == 1) { if (s < 6) { s = -1; errno = ENOBUFS; } else { memcpy(ifo->vendor + ifo->vendor[0] + 3, &addr.s_addr, sizeof(addr.s_addr)); s = sizeof(addr.s_addr); } } else { s = parse_string((char *)ifo->vendor + ifo->vendor[0] + 3, s, arg); } if (s == -1) { syslog(LOG_ERR, "vendor: %m"); return -1; } if (s != 0) { ifo->vendor[ifo->vendor[0] + 1] = i; ifo->vendor[ifo->vendor[0] + 2] = s; ifo->vendor[0] += s + 2; } break; case 'w': ifo->options |= DHCPCD_WAITIP; if (arg != NULL && arg[0] != '\0') { if (arg[0] == '4' || arg[1] == '4') ifo->options |= DHCPCD_WAITIP4; if (arg[0] == '6' || arg[1] == '6') ifo->options |= DHCPCD_WAITIP6; } break; case 'y': ifo->reboot = atoint(arg); if (ifo->reboot < 0) { syslog(LOG_ERR, "reboot must be a positive value"); return -1; } break; case 'z': if (ifname == NULL) ctx->ifav = splitv(&ctx->ifac, ctx->ifav, arg); break; case 'A': ifo->options &= ~DHCPCD_ARP; /* IPv4LL requires ARP */ ifo->options &= ~DHCPCD_IPV4LL; break; case 'B': ifo->options &= ~DHCPCD_DAEMONISE; break; case 'C': /* Commas to spaces for shell */ while ((p = strchr(arg, ','))) *p = ' '; s = strlen("skip_hooks=") + strlen(arg) + 1; p = malloc(sizeof(char) * s); if (p == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } snprintf(p, s, "skip_hooks=%s", arg); add_environ(ifo, p, 0); free(p); break; case 'D': ifo->options |= DHCPCD_CLIENTID | DHCPCD_DUID; break; case 'E': ifo->options |= DHCPCD_LASTLEASE; break; case 'F': if (!arg) { ifo->fqdn = FQDN_BOTH; break; } if (strcmp(arg, "none") == 0) ifo->fqdn = FQDN_NONE; else if (strcmp(arg, "ptr") == 0) ifo->fqdn = FQDN_PTR; else if (strcmp(arg, "both") == 0) ifo->fqdn = FQDN_BOTH; else if (strcmp(arg, "disable") == 0) ifo->fqdn = FQDN_DISABLE; else { syslog(LOG_ERR, "invalid value `%s' for FQDN", arg); return -1; } break; case 'G': ifo->options &= ~DHCPCD_GATEWAY; break; case 'H': ifo->options |= DHCPCD_XID_HWADDR; break; case 'I': /* Strings have a type of 0 */; ifo->clientid[1] = 0; if (arg) s = parse_string_hwaddr((char *)ifo->clientid + 1, CLIENTID_MAX_LEN, arg, 1); else s = 0; if (s == -1) { syslog(LOG_ERR, "clientid: %m"); return -1; } ifo->options |= DHCPCD_CLIENTID; ifo->clientid[0] = (uint8_t)s; break; case 'J': ifo->options |= DHCPCD_BROADCAST; break; case 'K': ifo->options &= ~DHCPCD_LINK; break; case 'L': ifo->options &= ~DHCPCD_IPV4LL; break; case 'M': ifo->options |= DHCPCD_MASTER; break; case 'O': arg = set_option_space(ctx, arg, &d, &dl, ifo, &request, &require, &no); if (make_option_mask(d, dl, request, arg, -1) != 0 || make_option_mask(d, dl, require, arg, -1) != 0 || make_option_mask(d, dl, no, arg, 1) != 0) { syslog(LOG_ERR, "unknown option `%s'", arg); return -1; } break; case 'Q': arg = set_option_space(ctx, arg, &d, &dl, ifo, &request, &require, &no); if (make_option_mask(d, dl, require, arg, 1) != 0 || make_option_mask(d, dl, request, arg, 1) != 0) { syslog(LOG_ERR, "unknown option `%s'", arg); return -1; } break; case 'S': p = strchr(arg, '='); if (p == NULL) { syslog(LOG_ERR, "static assignment required"); return -1; } p++; if (strncmp(arg, "ip_address=", strlen("ip_address=")) == 0) { if (parse_addr(&ifo->req_addr, ifo->req_mask.s_addr == 0 ? &ifo->req_mask : NULL, p) != 0) return -1; ifo->options |= DHCPCD_STATIC; ifo->options &= ~DHCPCD_INFORM; } else if (strncmp(arg, "subnet_mask=", strlen("subnet_mask=")) == 0) { if (parse_addr(&ifo->req_mask, NULL, p) != 0) return -1; } else if (strncmp(arg, "routes=", strlen("routes=")) == 0 || strncmp(arg, "static_routes=", strlen("static_routes=")) == 0 || strncmp(arg, "classless_static_routes=", strlen("classless_static_routes=")) == 0 || strncmp(arg, "ms_classless_static_routes=", strlen("ms_classless_static_routes=")) == 0) { fp = np = strwhite(p); if (np == NULL) { syslog(LOG_ERR, "all routes need a gateway"); return -1; } *np++ = '\0'; np = strskipwhite(np); if (ifo->routes == NULL) { ifo->routes = malloc(sizeof(*ifo->routes)); if (ifo->routes == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } TAILQ_INIT(ifo->routes); } rt = malloc(sizeof(*rt)); if (rt == NULL) { syslog(LOG_ERR, "%s: %m", __func__); *fp = ' '; return -1; } if (parse_addr(&rt->dest, &rt->net, p) == -1 || parse_addr(&rt->gate, NULL, np) == -1) { free(rt); *fp = ' '; return -1; } TAILQ_INSERT_TAIL(ifo->routes, rt, next); *fp = ' '; } else if (strncmp(arg, "routers=", strlen("routers=")) == 0) { if (ifo->routes == NULL) { ifo->routes = malloc(sizeof(*ifo->routes)); if (ifo->routes == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } TAILQ_INIT(ifo->routes); } rt = malloc(sizeof(*rt)); if (rt == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } rt->dest.s_addr = INADDR_ANY; rt->net.s_addr = INADDR_ANY; if (parse_addr(&rt->gate, NULL, p) == -1) { free(rt); return -1; } TAILQ_INSERT_TAIL(ifo->routes, rt, next); } else { s = 0; if (ifo->config != NULL) { while (ifo->config[s] != NULL) { if (strncmp(ifo->config[s], arg, p - arg) == 0) { p = strdup(arg); if (p == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } free(ifo->config[s]); ifo->config[s] = p; return 1; } s++; } } p = strdup(arg); if (p == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } nconf = realloc(ifo->config, sizeof(char *) * (s + 2)); if (nconf == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } ifo->config = nconf; ifo->config[s] = p; ifo->config[s + 1] = NULL; } break; case 'W': if (parse_addr(&addr, &addr2, arg) != 0) return -1; if (strchr(arg, '/') == NULL) addr2.s_addr = INADDR_BROADCAST; naddr = realloc(ifo->whitelist, sizeof(in_addr_t) * (ifo->whitelist_len + 2)); if (naddr == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } ifo->whitelist = naddr; ifo->whitelist[ifo->whitelist_len++] = addr.s_addr; ifo->whitelist[ifo->whitelist_len++] = addr2.s_addr; break; case 'X': if (parse_addr(&addr, &addr2, arg) != 0) return -1; if (strchr(arg, '/') == NULL) addr2.s_addr = INADDR_BROADCAST; naddr = realloc(ifo->blacklist, sizeof(in_addr_t) * (ifo->blacklist_len + 2)); if (naddr == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } ifo->blacklist = naddr; ifo->blacklist[ifo->blacklist_len++] = addr.s_addr; ifo->blacklist[ifo->blacklist_len++] = addr2.s_addr; break; case 'Z': if (ifname == NULL) ctx->ifdv = splitv(&ctx->ifdc, ctx->ifdv, arg); break; case '4': ifo->options &= ~DHCPCD_IPV6; ifo->options |= DHCPCD_IPV4; break; case '6': ifo->options &= ~DHCPCD_IPV4; ifo->options |= DHCPCD_IPV6; break; case O_NOIPV4: ifo->options &= ~DHCPCD_IPV4; break; case O_NOIPV6: ifo->options &= ~DHCPCD_IPV6; break; #ifdef INET case O_ARPING: while (arg && *arg != '\0') { fp = strwhite(arg); if (fp) *fp++ = '\0'; if (parse_addr(&addr, NULL, arg) != 0) return -1; naddr = realloc(ifo->arping, sizeof(in_addr_t) * (ifo->arping_len + 1)); if (naddr == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } ifo->arping = naddr; ifo->arping[ifo->arping_len++] = addr.s_addr; arg = strskipwhite(fp); } break; case O_DESTINATION: if (make_option_mask(ctx->dhcp_opts, ctx->dhcp_opts_len, ifo->dstmask, arg, 2) != 0) { if (errno == EINVAL) syslog(LOG_ERR, "option `%s' does not take" " an IPv4 address", arg); else syslog(LOG_ERR, "unknown option `%s'", arg); return -1; } break; case O_FALLBACK: free(ifo->fallback); ifo->fallback = strdup(arg); if (ifo->fallback == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } break; #endif case O_IAID: if (ifname == NULL) { syslog(LOG_ERR, "IAID must belong in an interface block"); return -1; } if (parse_iaid(ifo->iaid, arg, sizeof(ifo->iaid)) == -1) return -1; ifo->options |= DHCPCD_IAID; break; case O_IPV6RS: ifo->options |= DHCPCD_IPV6RS; break; case O_NOIPV6RS: ifo->options &= ~DHCPCD_IPV6RS; break; case O_IPV6RA_FORK: ifo->options &= ~DHCPCD_IPV6RA_REQRDNSS; break; case O_IPV6RA_OWN: ifo->options |= DHCPCD_IPV6RA_OWN; break; case O_IPV6RA_OWN_D: ifo->options |= DHCPCD_IPV6RA_OWN_DEFAULT; break; case O_NOALIAS: ifo->options |= DHCPCD_NOALIAS; break; #ifdef INET6 case O_IA_NA: i = D6_OPTION_IA_NA; /* FALLTHROUGH */ case O_IA_TA: if (i == 0) i = D6_OPTION_IA_TA; /* FALLTHROUGH */ case O_IA_PD: if (i == 0) { if (ifname == NULL) { syslog(LOG_ERR, "IA PD must belong in an interface block"); return -1; } i = D6_OPTION_IA_PD; } if (arg != NULL && ifname == NULL) { syslog(LOG_ERR, "IA with IAID must belong in an interface block"); return -1; } ifo->options |= DHCPCD_IA_FORCED; if (ifo->ia_type != 0 && ifo->ia_type != i) { syslog(LOG_ERR, "cannot specify a different IA type"); return -1; } ifo->ia_type = i; if (arg == NULL) break; fp = strwhite(arg); if (fp) *fp++ = '\0'; if (parse_iaid(iaid, arg, sizeof(iaid)) == -1) return -1; ia = NULL; for (sl = 0; sl < ifo->ia_len; sl++) { if (ifo->ia[sl].iaid[0] == iaid[0] && ifo->ia[sl].iaid[1] == iaid[1] && ifo->ia[sl].iaid[2] == iaid[2] && ifo->ia[sl].iaid[3] == iaid[3]) { ia = &ifo->ia[sl]; break; } } if (ia == NULL) { ia = realloc(ifo->ia, sizeof(*ifo->ia) * (ifo->ia_len + 1)); if (ia == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } ifo->ia = ia; ia = &ifo->ia[ifo->ia_len++]; ia->iaid[0] = iaid[0]; ia->iaid[1] = iaid[1]; ia->iaid[2] = iaid[2]; ia->iaid[3] = iaid[3]; ia->sla = NULL; ia->sla_len = 0; } if (ifo->ia_type != D6_OPTION_IA_PD) break; for (p = fp; p; p = fp) { fp = strwhite(p); if (fp) { *fp++ = '\0'; fp = strskipwhite(fp); } sla = realloc(ia->sla, sizeof(*ia->sla) * (ia->sla_len + 1)); if (sla == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } ia->sla = sla; sla = &ia->sla[ia->sla_len++]; np = strchr(p, '/'); if (np) *np++ = '\0'; if (strcmp(ifname, p) == 0) { syslog(LOG_ERR, "%s: cannot assign IA_PD to itself", ifname); return -1; } if (strlcpy(sla->ifname, p, sizeof(sla->ifname)) >= sizeof(sla->ifname)) { syslog(LOG_ERR, "%s: interface name too long", arg); return -1; } p = np; if (p) { np = strchr(p, '/'); if (np) *np++ = '\0'; if (*p == '\0') sla->sla_set = 0; else { errno = 0; sla->sla = atoint(p); sla->sla_set = 1; if (errno) return -1; } if (np) { sla->prefix_len = atoint(np); if (sla->prefix_len < 0 || sla->prefix_len > 128) return -1; } else sla->prefix_len = 64; } else { sla->sla_set = 0; /* Sanity - check there are no more * unspecified SLA's */ for (sl = 0; sl < ia->sla_len - 1; sl++) { slap = &ia->sla[sl]; if (slap->sla_set == 0 && strcmp(slap->ifname, sla->ifname) == 0) { syslog(LOG_WARNING, "%s: cannot specify the " "same interface twice with " "an automatic SLA", sla->ifname); ia->sla_len--; break; } } } } #endif break; case O_HOSTNAME_SHORT: ifo->options |= DHCPCD_HOSTNAME | DHCPCD_HOSTNAME_SHORT; break; case O_DEV: #ifdef PLUGIN_DEV if (ctx->dev_load) free(ctx->dev_load); ctx->dev_load = strdup(arg); #endif break; case O_NODEV: ifo->options &= ~DHCPCD_DEV; break; case O_DEFINE: dop = &ifo->dhcp_override; dop_len = &ifo->dhcp_override_len; /* FALLTHROUGH */ case O_DEFINE6: if (dop == NULL) { dop = &ifo->dhcp6_override; dop_len = &ifo->dhcp6_override_len; } /* FALLTHROUGH */ case O_VENDOPT: if (dop == NULL) { dop = &ifo->vivso_override; dop_len = &ifo->vivso_override_len; } *edop = *ldop = NULL; /* FALLTHROUGH */ case O_EMBED: if (dop == NULL) { if (*edop) { dop = &(*edop)->embopts; dop_len = &(*edop)->embopts_len; } else if (ldop) { dop = &(*ldop)->embopts; dop_len = &(*ldop)->embopts_len; } else { syslog(LOG_ERR, "embed must be after a define or encap"); return -1; } } /* FALLTHROUGH */ case O_ENCAP: if (dop == NULL) { if (*ldop == NULL) { syslog(LOG_ERR, "encap must be after a define"); return -1; } dop = &(*ldop)->encopts; dop_len = &(*ldop)->encopts_len; } /* Shared code for define, define6, embed and encap */ /* code */ if (opt == O_EMBED) /* Embedded options don't have codes */ u = 0; else { fp = strwhite(arg); if (fp == NULL) { syslog(LOG_ERR, "invalid syntax: %s", arg); return -1; } *fp++ = '\0'; errno = 0; u = strtoul(arg, &np, 0); if (u > UINT32_MAX || errno != 0 || *np != '\0') { syslog(LOG_ERR, "invalid code: %s", arg); return -1; } arg = strskipwhite(fp); if (arg == NULL) { syslog(LOG_ERR, "invalid syntax"); return -1; } } /* type */ fp = strwhite(arg); if (fp) *fp++ = '\0'; np = strchr(arg, ':'); /* length */ if (np) { *np++ = '\0'; if ((l = atoint(np)) == -1) return -1; } else l = 0; t = 0; if (strcasecmp(arg, "request") == 0) { t |= REQUEST; arg = strskipwhite(fp); fp = strwhite(arg); if (fp == NULL) { syslog(LOG_ERR, "incomplete request type"); return -1; } *fp++ = '\0'; } else if (strcasecmp(arg, "norequest") == 0) { t |= NOREQ; arg = strskipwhite(fp); fp = strwhite(arg); if (fp == NULL) { syslog(LOG_ERR, "incomplete request type"); return -1; } *fp++ = '\0'; } if (strcasecmp(arg, "index") == 0) { t |= INDEX; arg = strskipwhite(fp); fp = strwhite(arg); if (fp == NULL) { syslog(LOG_ERR, "incomplete index type"); return -1; } *fp++ = '\0'; } if (strcasecmp(arg, "array") == 0) { t |= ARRAY; arg = strskipwhite(fp); fp = strwhite(arg); if (fp == NULL) { syslog(LOG_ERR, "incomplete array type"); return -1; } *fp++ = '\0'; } if (strcasecmp(arg, "ipaddress") == 0) t |= ADDRIPV4; else if (strcasecmp(arg, "ip6address") == 0) t |= ADDRIPV6; else if (strcasecmp(arg, "string") == 0) t |= STRING; else if (strcasecmp(arg, "byte") == 0) t |= UINT8; else if (strcasecmp(arg, "uint16") == 0) t |= UINT16; else if (strcasecmp(arg, "int16") == 0) t |= SINT16; else if (strcasecmp(arg, "uint32") == 0) t |= UINT32; else if (strcasecmp(arg, "int32") == 0) t |= SINT32; else if (strcasecmp(arg, "flag") == 0) t |= FLAG; else if (strcasecmp(arg, "domain") == 0) t |= STRING | RFC3397; else if (strcasecmp(arg, "binhex") == 0) t |= BINHEX; else if (strcasecmp(arg, "embed") == 0) t |= EMBED; else if (strcasecmp(arg, "encap") == 0) t |= ENCAP; else if (strcasecmp(arg, "rfc3361") ==0) t |= STRING | RFC3361; else if (strcasecmp(arg, "rfc3442") ==0) t |= STRING | RFC3442; else if (strcasecmp(arg, "rfc5969") == 0) t |= STRING | RFC5969; else if (strcasecmp(arg, "option") == 0) t |= OPTION; else { syslog(LOG_ERR, "unknown type: %s", arg); return -1; } if (l && !(t & (STRING | BINHEX))) { syslog(LOG_WARNING, "ignoring length for type `%s'", arg); l = 0; } if (t & ARRAY && t & (STRING | BINHEX)) { syslog(LOG_WARNING, "ignoring array for strings"); t &= ~ARRAY; } /* variable */ if (!fp) { if (!(t & OPTION)) { syslog(LOG_ERR, "type %s requires a variable name", arg); return -1; } np = NULL; } else { arg = strskipwhite(fp); fp = strwhite(arg); if (fp) *fp++ = '\0'; np = strdup(arg); if (np == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } } if (opt != O_EMBED) { for (dl = 0, ndop = *dop; dl < *dop_len; dl++, ndop++) { /* type 0 seems freshly malloced struct * for us to use */ if (ndop->option == u || ndop->type == 0) break; } if (dl == *dop_len) ndop = NULL; } else ndop = NULL; if (ndop == NULL) { if ((ndop = realloc(*dop, sizeof(**dop) * ((*dop_len) + 1))) == NULL) { syslog(LOG_ERR, "%s: %m", __func__); free(np); return -1; } *dop = ndop; ndop = &(*dop)[(*dop_len)++]; ndop->embopts = NULL; ndop->embopts_len = 0; ndop->encopts = NULL; ndop->encopts_len = 0; } else free_dhcp_opt_embenc(ndop); ndop->option = u; /* could have been 0 */ ndop->type = t; ndop->len = l; ndop->var = np; /* Save the define for embed and encap options */ if (opt == O_DEFINE || opt == O_DEFINE6 || opt == O_VENDOPT) *ldop = ndop; else if (opt == O_ENCAP) *edop = ndop; break; case O_VENDCLASS: fp = strwhite(arg); if (fp) *fp++ = '\0'; errno = 0; u = strtoul(arg, &np, 0); if (u > UINT32_MAX || errno != 0 || *np != '\0') { syslog(LOG_ERR, "invalid code: %s", arg); return -1; } if (fp) { s = parse_string(NULL, 0, fp); if (s == -1) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } if (s + (sizeof(uint16_t) * 2) > UINT16_MAX) { syslog(LOG_ERR, "vendor class is too big"); return -1; } np = malloc(s); if (np == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } parse_string(np, s, fp); } else { s = 0; np = NULL; } vivco = realloc(ifo->vivco, sizeof(*ifo->vivco) * (ifo->vivco_len + 1)); if (vivco == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } ifo->vivco = vivco; ifo->vivco_en = u; vivco = &ifo->vivco[ifo->vivco_len++]; vivco->len = s; vivco->data = (uint8_t *)np; break; case O_AUTHPROTOCOL: fp = strwhite(arg); if (fp) *fp++ = '\0'; if (strcasecmp(arg, "token") == 0) ifo->auth.protocol = AUTH_PROTO_TOKEN; else if (strcasecmp(arg, "delayed") == 0) ifo->auth.protocol = AUTH_PROTO_DELAYED; else if (strcasecmp(arg, "delayedrealm") == 0) ifo->auth.protocol = AUTH_PROTO_DELAYEDREALM; else { syslog(LOG_ERR, "%s: unsupported protocol", arg); return -1; } arg = strskipwhite(fp); fp = strwhite(arg); if (arg == NULL) { ifo->auth.options |= DHCPCD_AUTH_SEND; ifo->auth.algorithm = AUTH_ALG_HMAC_MD5; ifo->auth.rdm = AUTH_RDM_MONOTONIC; break; } if (fp) *fp++ = '\0'; if (strcasecmp(arg, "hmacmd5") == 0 || strcasecmp(arg, "hmac-md5") == 0) ifo->auth.algorithm = AUTH_ALG_HMAC_MD5; else { syslog(LOG_ERR, "%s: unsupported algorithm", arg); return 1; } arg = fp; if (arg == NULL) { ifo->auth.options |= DHCPCD_AUTH_SEND; ifo->auth.rdm = AUTH_RDM_MONOTONIC; break; } if (strcasecmp(arg, "monocounter") == 0) { ifo->auth.rdm = AUTH_RDM_MONOTONIC; ifo->auth.options |= DHCPCD_AUTH_RDM_COUNTER; } else if (strcasecmp(arg, "monotonic") ==0 || strcasecmp(arg, "monotime") == 0) ifo->auth.rdm = AUTH_RDM_MONOTONIC; else { syslog(LOG_ERR, "%s: unsupported RDM", arg); return -1; } ifo->auth.options |= DHCPCD_AUTH_SEND; break; case O_AUTHTOKEN: fp = strwhite(arg); if (fp == NULL) { syslog(LOG_ERR, "authtoken requires a realm"); return -1; } *fp++ = '\0'; token = malloc(sizeof(*token)); if (token == NULL) { syslog(LOG_ERR, "%s: %m", __func__); return -1; } if (parse_uint32(&token->secretid, arg) == -1) { syslog(LOG_ERR, "%s: not a number", arg); free(token); return -1; } arg = fp; fp = strend(arg); if (fp == NULL) { syslog(LOG_ERR, "authtoken requies an a key"); free(token); return -1; } *fp++ = '\0'; token->realm_len = parse_string(NULL, 0, arg); if (token->realm_len) { token->realm = malloc(token->realm_len); if (token->realm == NULL) { free(token); syslog(LOG_ERR, "%s: %m", __func__); return -1; } parse_string((char *)token->realm, token->realm_len, arg); } arg = fp; fp = strend(arg); if (fp == NULL) { syslog(LOG_ERR, "authtoken requies an an expiry date"); free(token->realm); free(token); return -1; } *fp++ = '\0'; if (*arg == '"') { arg++; np = strchr(arg, '"'); if (np) *np = '\0'; } if (strcmp(arg, "0") == 0 || strcasecmp(arg, "forever") == 0) token->expire =0; else { struct tm tm; memset(&tm, 0, sizeof(tm)); if (strptime(arg, "%Y-%m-%d %H:%M", &tm) == NULL) { syslog(LOG_ERR, "%s: invalid date time", arg); free(token->realm); free(token); return -1; } if ((token->expire = mktime(&tm)) == (time_t)-1) { syslog(LOG_ERR, "%s: mktime: %m", __func__); free(token->realm); free(token); return -1; } } arg = fp; token->key_len = parse_string(NULL, 0, arg); if (token->key_len == 0) { syslog(LOG_ERR, "authtoken needs a key"); free(token->realm); free(token); return -1; } token->key = malloc(token->key_len); parse_string((char *)token->key, token->key_len, arg); TAILQ_INSERT_TAIL(&ifo->auth.tokens, token, next); break; case O_AUTHNOTREQUIRED: ifo->auth.options &= ~DHCPCD_AUTH_REQUIRE; break; case O_NODHCP: ifo->options &= ~DHCPCD_DHCP; break; case O_NODHCP6: ifo->options &= ~DHCPCD_DHCP6; break; default: return 0; } return 1; }
static guestfs_int_isoinfo * parse_isoinfo (char **lines) { guestfs_int_isoinfo *ret; size_t i; ret = calloc (1, sizeof *ret); if (ret == NULL) { reply_with_perror ("calloc"); return NULL; } /* Default each int field in the struct to -1. */ ret->iso_volume_space_size = (uint32_t) -1; ret->iso_volume_set_size = (uint32_t) -1; ret->iso_volume_sequence_number = (uint32_t) -1; ret->iso_logical_block_size = (uint32_t) -1; ret->iso_volume_creation_t = -1; ret->iso_volume_modification_t = -1; ret->iso_volume_expiration_t = -1; ret->iso_volume_effective_t = -1; for (i = 0; lines[i] != NULL; ++i) { if (STRPREFIX (lines[i], "System id: ")) { ret->iso_system_id = strdup (&lines[i][11]); if (ret->iso_system_id == NULL) goto error; } else if (STRPREFIX (lines[i], "Volume id: ")) { ret->iso_volume_id = strdup (&lines[i][11]); if (ret->iso_volume_id == NULL) goto error; } else if (STRPREFIX (lines[i], "Volume set id: ")) { ret->iso_volume_set_id = strdup (&lines[i][15]); if (ret->iso_volume_set_id == NULL) goto error; } else if (STRPREFIX (lines[i], "Publisher id: ")) { ret->iso_publisher_id = strdup (&lines[i][14]); if (ret->iso_publisher_id == NULL) goto error; } else if (STRPREFIX (lines[i], "Data preparer id: ")) { ret->iso_data_preparer_id = strdup (&lines[i][18]); if (ret->iso_data_preparer_id == NULL) goto error; } else if (STRPREFIX (lines[i], "Application id: ")) { ret->iso_application_id = strdup (&lines[i][16]); if (ret->iso_application_id == NULL) goto error; } else if (STRPREFIX (lines[i], "Copyright File id: ")) { ret->iso_copyright_file_id = strdup (&lines[i][19]); if (ret->iso_copyright_file_id == NULL) goto error; } else if (STRPREFIX (lines[i], "Abstract File id: ")) { ret->iso_abstract_file_id = strdup (&lines[i][18]); if (ret->iso_abstract_file_id == NULL) goto error; } else if (STRPREFIX (lines[i], "Bibliographic File id: ")) { ret->iso_bibliographic_file_id = strdup (&lines[i][23]); if (ret->iso_bibliographic_file_id == NULL) goto error; } else if (STRPREFIX (lines[i], "Volume size is: ")) { if (parse_uint32 (&ret->iso_volume_space_size, &lines[i][16]) == -1) goto error; } else if (STRPREFIX (lines[i], "Volume set size is: ")) { if (parse_uint32 (&ret->iso_volume_set_size, &lines[i][20]) == -1) goto error; } else if (STRPREFIX (lines[i], "Volume set sequence number is: ")) { if (parse_uint32 (&ret->iso_volume_sequence_number, &lines[i][31]) == -1) goto error; } else if (STRPREFIX (lines[i], "Logical block size is: ")) { if (parse_uint32 (&ret->iso_logical_block_size, &lines[i][23]) == -1) goto error; } else if (STRPREFIX (lines[i], "Creation Date: ")) { if (parse_time_t (&ret->iso_volume_creation_t, &lines[i][19]) == -1) goto error; } else if (STRPREFIX (lines[i], "Modification Date: ")) { if (parse_time_t (&ret->iso_volume_modification_t, &lines[i][19]) == -1) goto error; } else if (STRPREFIX (lines[i], "Expiration Date: ")) { if (parse_time_t (&ret->iso_volume_expiration_t, &lines[i][19]) == -1) goto error; } else if (STRPREFIX (lines[i], "Effective Date: ")) { if (parse_time_t (&ret->iso_volume_effective_t, &lines[i][19]) == -1) goto error; } } /* Any string fields which were not set above will be NULL. However * we cannot return NULL fields in structs, so we convert these to * empty strings here. */ if (ret->iso_system_id == NULL) { ret->iso_system_id = strdup (""); if (ret->iso_system_id == NULL) goto error; } if (ret->iso_volume_id == NULL) { ret->iso_volume_id = strdup (""); if (ret->iso_volume_id == NULL) goto error; } if (ret->iso_volume_set_id == NULL) { ret->iso_volume_set_id = strdup (""); if (ret->iso_volume_set_id == NULL) goto error; } if (ret->iso_publisher_id == NULL) { ret->iso_publisher_id = strdup (""); if (ret->iso_publisher_id == NULL) goto error; } if (ret->iso_data_preparer_id == NULL) { ret->iso_data_preparer_id = strdup (""); if (ret->iso_data_preparer_id == NULL) goto error; } if (ret->iso_application_id == NULL) { ret->iso_application_id = strdup (""); if (ret->iso_application_id == NULL) goto error; } if (ret->iso_copyright_file_id == NULL) { ret->iso_copyright_file_id = strdup (""); if (ret->iso_copyright_file_id == NULL) goto error; } if (ret->iso_abstract_file_id == NULL) { ret->iso_abstract_file_id = strdup (""); if (ret->iso_abstract_file_id == NULL) goto error; } if (ret->iso_bibliographic_file_id == NULL) { ret->iso_bibliographic_file_id = strdup (""); if (ret->iso_bibliographic_file_id == NULL) goto error; } return ret; error: free (ret->iso_system_id); free (ret->iso_volume_id); free (ret->iso_volume_set_id); free (ret->iso_publisher_id); free (ret->iso_data_preparer_id); free (ret->iso_application_id); free (ret->iso_copyright_file_id); free (ret->iso_abstract_file_id); free (ret->iso_bibliographic_file_id); free (ret); return NULL; }
/** * HTTP request parsing */ uint8_t* ICACHE_FLASH_ATTR http_request_parse( http_request_object_type* request, uint8_t* data ) { http_header_scheme_type scheme; char empty[ 1 ] = "\0", host[ 5 ] = "Host", content_length[ 15 ] = "Content-Length", header_sec_ws_key[ 18 ] = "Sec-WebSocket-Key"; uint8_t* mark, *store, *end; uint16_t length; if( request->location == NULL ) { request->location = ( url_object_type* ) os_malloc( sizeof( url_object_type ) ); url_initialize( request->location, URL_PROTOCOL_NONE, ( uint8_t* ) empty, 0, ( uint8_t* ) empty, ( uint8_t* ) empty ); } data = http_request_parse_method_line( request, data ); scheme = http_request_path_get_scheme( request->location->path ); request->content_length = 0; request->headers = NULL; request->location->hostname = NULL; request->location->host_ip = 0x00000000; request->scheme = scheme; while( ( *data != '\0' ) && (( *data ) != '\r' && ( *( data + 1 ) != '\n' )) ) { mark = http_header_field_parse_name( data, ( uint8_t* ) empty, 1 ); if( ( *mark ) == ':' ) { ( *mark ) = '\0'; if( http_header_field_check_scheme( data, scheme ) ) { length = http_header_field_value_length( mark + 1 ); store = ( uint8_t* ) os_malloc( length + 1 ); end = http_header_field_parse_value( mark + 1, store, 0 ); if( strcmp( content_length, ( char* ) data ) == 0 ) { parse_uint32( &( request->content_length ), store ); } else if( strcmp( host, ( char* ) data ) == 0 ) { request->location->hostname = store; } else { request->headers = http_header_field_add( request->headers, data, store ); os_free( store ); } data = end; } else { data = http_header_field_parse_value( mark + 1, ( uint8_t* ) empty, 1 ); } ( *mark ) = ':'; } else break; } if(( *data ) == '\r' && ( *( data + 1 ) == '\n' )) { data += 2; if( request->content_length > 0 ) url_parse_query( request->location, data, ( int16_t ) request->content_length ); request->content = (( *data ) == '\0' ) ? NULL : data; } else request->content = data; if( scheme == ( HTTP_REQUEST_SCHEME | WS_REQUEST_SCHEME ) ) { if( http_header_field_get( request->headers, ( uint8_t* ) header_sec_ws_key ) != NULL ) request->location->protocol = URL_PROTOCOL_WS; else request->location->protocol = URL_PROTOCOL_HTTP; } else if( scheme == WS_REQUEST_SCHEME ) request->location->protocol = URL_PROTOCOL_WS; else request->location->protocol = URL_PROTOCOL_HTTP; return data; }