Esempio n. 1
0
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);
}
Esempio n. 2
0
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;
}
Esempio n. 3
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;
}
Esempio n. 4
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);
}
Esempio n. 5
0
File: fcgi.C Progetto: kmeaw/phantom
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;
}
Esempio n. 6
0
/**
 * 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);
}
Esempio n. 7
0
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);
}
Esempio n. 8
0
/*
 * 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;
}
Esempio n. 9
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;
}
Esempio n. 10
0
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();
}
Esempio n. 11
0
File: main.cpp Progetto: CCJY/coliru
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;
}
Esempio n. 12
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;
}
Esempio n. 13
0
/**
 * 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;
}
Esempio n. 14
0
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);
}
Esempio n. 15
0
/**
 * 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;
}
Esempio n. 16
0
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;
}
Esempio n. 17
0
/*
 * 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;
}
Esempio n. 18
0
/**
 * 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 */
}
Esempio n. 19
0
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;
}
Esempio n. 20
0
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;
}
Esempio n. 21
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 {
Esempio n. 22
0
/*
 * 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;
}
Esempio n. 23
0
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;
}
Esempio n. 24
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;
}
Esempio n. 25
0
/*
 * 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;
}
Esempio n. 26
0
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)));
}
Esempio n. 27
0
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;
}
Esempio n. 28
0
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;
}
Esempio n. 29
0
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;
}
Esempio n. 30
0
/**
 * 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;
}