/** * Open and parse the first line of a given file as the ASCII representation * of an unsigned 64-bit integer. * * @param path file path * @param missing whether file may be missing (to shut up warnings) * @param errptr if non-NULL, filled with error number (0 means OK) * * @return the value we parsed on the first line, 0 otherwise. * * @note * The ``errptr'' parameter needs to be used to distinguish between * a file containing "0" and a file which could not be parsed correctly. */ guint64 filehead_uint64(const char *path, gboolean missing, int *errptr) { int fd; guint64 value; char data[FILEHEAD_LINE_MAXLEN + 1]; ssize_t r; int error; fd = missing ? file_open_missing(path, O_RDONLY) : file_open(path, O_RDONLY, 0); if (-1 == fd) goto error; r = read(fd, data, sizeof data - 1); /* reserve one byte for NUL */ if ((ssize_t) -1 == r) goto error_close; g_assert(r >= 0 && UNSIGNED(r) < sizeof data); fd_close(&fd); data[r] = '\0'; value = parse_uint64(data, NULL, 10, &error); if (error) { errno = error; goto error; } if (errptr != NULL) *errptr = 0; return value; error_close: fd_close(&fd); error: if (errptr != NULL) *errptr = errno; return 0; }
static int http_handle_content_length_header(http_t *ctx, const char *name, char *value) { uint64_t u; int error; char *ep; RUNTIME_ASSERT(ctx); RUNTIME_ASSERT(name); RUNTIME_ASSERT(value); u = parse_uint64(value, &ep, 10, &error); if (error || '\0' != *ep) { http_set_status(ctx, 400, "Bad Request (Bad Content-Length)"); return -1; } ctx->content_length = u; return 0; }
/* Parses a sample count as either a number of samples or a duration in seconds. * Must be called after decimation parameters have been read from server. */ static bool parse_samples(const char **string, uint64_t *result) { bool ok = parse_uint64(string, result); if (ok) { double duration = (double) *result; // In case it's a duration after all bool seconds = **string == '.'; if (seconds) { long nsec; ok = parse_nanoseconds(string, &nsec) && parse_char(string, 's'); duration += 1e-9 * (double) nsec; } else seconds = read_char(string, 's'); if (ok && seconds) *result = (uint64_t) round( duration * sample_frequency / get_decimation()); } return ok && TEST_OK_(*result > 0, "Zero sample count"); }
/** * Reads data from the http context buffer (decodes it if the transfer- * encoding isn't "identity") and transfers up to ``buflen'' bytes into * ``buf''. The http context MUST be in state HTTP_STATE_BODY. * * @returns (ssize_t) -1 on failure and sets errno. If errno is set to EAGAIN * further data may be available later. * * If there's a transfer-encoding * error, errno will be set to EIO. If (-1) is returned and errno * has any other value than EAGAIN, the function MUST NOT be called * again. */ ssize_t http_read_body(http_t *ctx, char *buf, ssize_t buflen) { ssize_t ret = 0, count = 0; uint64_t left; RUNTIME_ASSERT(ctx != NULL); RUNTIME_ASSERT(buf != NULL); RUNTIME_ASSERT(buflen >= 0); RUNTIME_ASSERT(ctx->sane); RUNTIME_ASSERT(ctx->state == HTTP_STATE_BODY); switch (ctx->encoding) { case HTTP_TRANSFER_ENCODING_IDENTITY: RUNTIME_ASSERT(ctx->content_length >= ctx->received); left = ctx->content_length - ctx->received; if (left == 0) { return 0; } RUNTIME_ASSERT(left > 0); ret = fifo_read(ctx->input, buf, MIN(left, (size_t) buflen)); if (ret > 0) { ctx->received += ret; } else if (ret == 0) { errno = EAGAIN; return -1; } count = ret; break; case HTTP_TRANSFER_ENCODING_CHUNKED: while (!ctx->last_chunk && buflen > 0) { RUNTIME_ASSERT(ctx->content_length >= ctx->received); left = ctx->chunk_size - ctx->chunk_received; if (left > 0) { ret = fifo_read(ctx->input, buf, MIN(left, (size_t) buflen)); if (ret > 0) { RUNTIME_ASSERT(ret <= buflen); ctx->chunk_received += ret; ctx->received += ret; buf += ret; buflen -= ret; count += ret; } else { if (ret == 0 && count == 0) { errno = EAGAIN; return -1; } return count; } } else { char chunk_intro[1024]; ssize_t pos, size; uint64_t v; char *endptr; int error; /* If this isn't the first chunk, wait for trailing <CR><LF> */ if (ctx->chunk_size > 0) { pos = fifo_findchar(ctx->input, '\n', sizeof chunk_intro); if (pos == (ssize_t) -1) { if (count > 0) return count; errno = EAGAIN; return -1; } RUNTIME_ASSERT(pos >= 0 && (size_t) pos < sizeof chunk_intro); size = fifo_read(ctx->input, chunk_intro, pos + 1); RUNTIME_ASSERT(size == pos + 1); RUNTIME_ASSERT(chunk_intro[pos] == '\n'); chunk_intro[pos] = '\0'; } RUNTIME_ASSERT(ctx->chunk_received == ctx->chunk_size); /* Mark the previous chunk as completely handled */ ctx->chunk_sum_received += ctx->chunk_size; ctx->chunk_size = 0; ctx->chunk_received = 0; /* Determine the size of the next chunk */ pos = fifo_findchar(ctx->input, '\n', sizeof chunk_intro); if (pos == (ssize_t) -1) { if (count > 0) return count; errno = EAGAIN; return -1; } RUNTIME_ASSERT(pos >= 0 && (size_t) pos < sizeof chunk_intro); size = fifo_read(ctx->input, chunk_intro, pos + 1); RUNTIME_ASSERT(size == pos + 1); RUNTIME_ASSERT(chunk_intro[pos] == '\n'); chunk_intro[pos] = '\0'; /* Read the chunk header and determine its size (hex value) */ v = parse_uint64(chunk_intro, &endptr, 16, &error); if ( (!v && error) || (*endptr != '\0' && !isspace((unsigned char) *endptr)) ) { errno = EIO; ctx->sane = false; return -1; } if (v == 0) { /* Only the last chunk has a zero length */ #if 1 http_log(ctx, "Last chunk reached"); #endif ctx->last_chunk = true; return count > 0 ? count : 0; } #if 0 http_log(ctx, "chunk_size=%" PRIu64, v); #endif ctx->chunk_size = v; } } break; default: RUNTIME_ASSERT(0); } return count; }
/** * Parses the payload of a HTTP "Range" header. * * A range with an "open end", is indicated by "end == (uint64_t) -1". * * @param s a NUL-terminated string containing the payload of a Ranger header. * @return 0 on failure, otherwise the amount of byte ranges in the header. */ size_t http_parse_range(const char *s, struct byte_range_set **set_ptr) { char *ep; int error; size_t n = 0; RUNTIME_ASSERT(s); if (set_ptr) *set_ptr = NULL; s = skip_spaces(s); s = skip_prefix(s, "bytes="); if (!s) { DBUG("Expected \"bytes=\""); goto failure; } while ('\0' != *s) { uint64_t start, end; s = skip_spaces(s); if (',' == *s) { s++; continue; } if ('-' == *s) { start = (uint64_t) -1; s++; if (!isdigit((unsigned char) *s)) { DBUG("Neither start nor end given"); goto failure; } } else { start = parse_uint64(s, &ep, 10, &error); if (error || (uint64_t) -1 == start) { DBUG("Invalid range start"); goto failure; } if ('-' != *ep) { DBUG("Expected '-'"); goto failure; } s = ++ep; } if (!isdigit((unsigned char) *s)) { end = (uint64_t) -1; } else { end = parse_uint64(s, &ep, 10, &error); if (error || (uint64_t) -1 == end) { DBUG("Invalid range end"); goto failure; } s = ep; } if ((uint64_t) -1 != start && start > end) { DBUG("range start is beyond range end"); goto failure; } s = skip_spaces(s); if (',' == *s) { s++; } else if ('\0' != *s) { DBUG("bad character after byte range"); goto failure; } n++; if (set_ptr) { struct byte_range_set *set = *set_ptr; if (!set) { const size_t min_num = 8; set = malloc(min_num * sizeof set->ranges + sizeof *set); if (!set) { CRIT("malloc() failed"); goto failure; } set->n = 0; set->size = min_num; *set_ptr = set; } RUNTIME_ASSERT(*set_ptr); RUNTIME_ASSERT(set); if (set->n >= set->size) { void *p; set->size = 0 == set->size ? 8 : 2 * set->size; p = realloc(set, set->size * sizeof *set); if (!p) { CRIT("realloc() failed"); goto failure; } *set_ptr = set = p; } set->ranges[set->n].start = start; set->ranges[set->n].end = end; set->n++; } } return n; failure: DO_FREE(*set_ptr); return -1; }
/* Typical crazy output from the xfs_info command: * * meta-data=/dev/sda1 isize=256 agcount=4, agsize=6392 blks * = sectsz=512 attr=2 * data = bsize=4096 blocks=25568, imaxpct=25 * = sunit=0 swidth=0 blks * naming =version 2 bsize=4096 ascii-ci=0 * log =internal bsize=4096 blocks=1200, version=2 * = sectsz=512 sunit=0 blks, lazy-count=1 * realtime =none extsz=4096 blocks=0, rtextents=0 * * We may need to revisit this parsing code if the output changes * in future. */ static guestfs_int_xfsinfo * parse_xfs_info (char **lines) { guestfs_int_xfsinfo *ret; char *buf = NULL, *p; size_t i; ret = malloc (sizeof *ret); if (ret == NULL) { reply_with_error ("malloc"); return NULL; } /* Initialize fields to NULL or -1 so the caller can tell which fields * were updated in the code below. */ ret->xfs_mntpoint = NULL; ret->xfs_inodesize = -1; ret->xfs_agcount = -1; ret->xfs_agsize = -1; ret->xfs_sectsize = -1; ret->xfs_attr = -1; ret->xfs_blocksize = -1; ret->xfs_datablocks = -1; ret->xfs_imaxpct = -1; ret->xfs_sunit = -1; ret->xfs_swidth = -1; ret->xfs_dirversion = -1; ret->xfs_dirblocksize = -1; ret->xfs_cimode = -1; ret->xfs_logname = NULL; ret->xfs_logblocksize = -1; ret->xfs_logblocks = -1; ret->xfs_logversion = -1; ret->xfs_logsectsize = -1; ret->xfs_logsunit = -1; ret->xfs_lazycount = -1; ret->xfs_rtname = NULL; ret->xfs_rtextsize = -1; ret->xfs_rtblocks = -1; ret->xfs_rtextents = -1; for (i = 0; lines[i] != NULL; ++i) { if ((p = strstr (lines[i], "meta-data="))) { ret->xfs_mntpoint = split_strdup (p + 10); if (ret->xfs_mntpoint == NULL) goto error; } if ((p = strstr (lines[i], "isize="))) { buf = split_strdup (p + 6); if (buf == NULL) goto error; if (parse_uint32 (&ret->xfs_inodesize, buf) == -1) goto error; free (buf); } if ((p = strstr (lines[i], "agcount="))) { buf = split_strdup (p + 8); if (buf == NULL) goto error; if (parse_uint32 (&ret->xfs_agcount, buf) == -1) goto error; free (buf); } if ((p = strstr (lines[i], "agsize="))) { buf = split_strdup (p + 7); if (buf == NULL) goto error; if (parse_uint32 (&ret->xfs_agsize, buf) == -1) goto error; free (buf); } if ((p = strstr (lines[i], "sectsz="))) { buf = split_strdup (p + 7); if (buf == NULL) goto error; if (i == 1) { if (parse_uint32 (&ret->xfs_sectsize, buf) == -1) goto error; free (buf); } else if (i == 6) { if (parse_uint32 (&ret->xfs_logsectsize, buf) == -1) goto error; free (buf); } else goto error; } if ((p = strstr (lines[i], "attr="))) { buf = split_strdup (p + 5); if (buf == NULL) goto error; if (parse_uint32 (&ret->xfs_attr, buf) == -1) goto error; free (buf); } if ((p = strstr (lines[i], "bsize="))) { buf = split_strdup (p + 6); if (buf == NULL) goto error; if (i == 2) { if (parse_uint32 (&ret->xfs_blocksize, buf) == -1) goto error; free (buf); } else if (i == 4) { if (parse_uint32 (&ret->xfs_dirblocksize, buf) == -1) goto error; free (buf); } else if (i == 5) { if (parse_uint32 (&ret->xfs_logblocksize, buf) == -1) goto error; free (buf); } else goto error; } if ((p = strstr (lines[i], "blocks="))) { buf = split_strdup (p + 7); if (buf == NULL) goto error; if (i == 2) { if (parse_uint64 (&ret->xfs_datablocks, buf) == -1) goto error; free (buf); } else if (i == 5) { if (parse_uint32 (&ret->xfs_logblocks, buf) == -1) goto error; free (buf); } else if (i == 7) { if (parse_uint64 (&ret->xfs_rtblocks, buf) == -1) goto error; free (buf); } else goto error; } if ((p = strstr (lines[i], "imaxpct="))) { buf = split_strdup (p + 8); if (buf == NULL) goto error; if (parse_uint32 (&ret->xfs_imaxpct, buf) == -1) goto error; free (buf); } if ((p = strstr (lines[i], "sunit="))) { buf = split_strdup (p + 6); if (buf == NULL) goto error; if (i == 3) { if (parse_uint32 (&ret->xfs_sunit, buf) == -1) goto error; free (buf); } else if (i == 6) { if (parse_uint32 (&ret->xfs_logsunit, buf) == -1) goto error; free (buf); } else goto error; } if ((p = strstr (lines[i], "swidth="))) { buf = split_strdup (p + 7); if (buf == NULL) goto error; if (parse_uint32 (&ret->xfs_swidth, buf) == -1) goto error; free (buf); } if ((p = strstr (lines[i], "naming =version "))) { buf = split_strdup (p + 18); if (buf == NULL) goto error; if (parse_uint32 (&ret->xfs_dirversion, buf) == -1) goto error; free (buf); } if ((p = strstr (lines[i], "ascii-ci="))) { buf = split_strdup (p + 9); if (buf == NULL) goto error; if (parse_uint32 (&ret->xfs_cimode, buf) == -1) goto error; free (buf); } if ((p = strstr (lines[i], "log ="))) { ret->xfs_logname = split_strdup (p + 10); if (ret->xfs_logname == NULL) goto error; } if ((p = strstr (lines[i], "version="))) { buf = split_strdup (p + 8); if (buf == NULL) goto error; if (parse_uint32 (&ret->xfs_logversion, buf) == -1) goto error; free (buf); } if ((p = strstr (lines[i], "lazy-count="))) { buf = split_strdup (p + 11); if (buf == NULL) goto error; if (parse_uint32 (&ret->xfs_lazycount, buf) == -1) goto error; free (buf); } if ((p = strstr (lines[i], "realtime ="))) { ret->xfs_rtname = split_strdup (p + 10); if (ret->xfs_rtname == NULL) goto error; } if ((p = strstr (lines[i], "rtextents="))) { buf = split_strdup (p + 10); if (buf == NULL) goto error; if (parse_uint64 (&ret->xfs_rtextents, buf) == -1) goto error; free (buf); } } if (ret->xfs_mntpoint == NULL) { ret->xfs_mntpoint = strdup (""); if (ret->xfs_mntpoint == NULL) goto error; } if (ret->xfs_logname == NULL) { ret->xfs_logname = strdup (""); if (ret->xfs_logname == NULL) goto error; } if (ret->xfs_rtname == NULL) { ret->xfs_rtname = strdup (""); if (ret->xfs_rtname == NULL) goto error; } return ret; error: free (buf); free (ret->xfs_mntpoint); free (ret->xfs_logname); free (ret->xfs_rtname); free (ret); return NULL; }
/** * Load spam database from the supplied FILE. * * The current file format is as follows: * * # Comment * SHA1 <SHA-1> * ADDED <date> * END * * @returns the amount of entries loaded or -1 on failure. */ static G_GNUC_COLD gulong spam_load(FILE *f) { static const struct spam_item zero_item; struct spam_item item; char line[1024]; guint line_no = 0; bit_array_t tag_used[BIT_ARRAY_SIZE(NUM_SPAM_TAGS)]; gulong item_count = 0; g_assert(f); /* Reset state */ item = zero_item; bit_array_init(tag_used, NUM_SPAM_TAGS); while (fgets(line, sizeof line, f)) { const char *tag_name, *value; char *sp, *nl; spam_tag_t tag; line_no++; nl = strchr(line, '\n'); if (!nl) { /* * If the line is too long or unterminated the file is either * corrupt or was manually edited without respecting the * exact format. If we continued, we would read from the * middle of a line which could be the filename or ID. */ g_warning("spam_load(): " "line too long or missing newline in line %u", line_no); break; } *nl = '\0'; /* Skip comments and empty lines */ if (*line == '#' || *line == '\0') continue; sp = strchr(line, ' '); if (sp) { *sp = '\0'; value = &sp[1]; } else { value = strchr(line, '\0'); } tag_name = line; tag = spam_string_to_tag(tag_name); g_assert(UNSIGNED(tag) < UNSIGNED(NUM_SPAM_TAGS)); if (SPAM_TAG_UNKNOWN != tag && !bit_array_flip(tag_used, tag)) { g_warning("spam_load(): duplicate tag \"%s\" in entry in line %u", tag_name, line_no); continue; } switch (tag) { case SPAM_TAG_ADDED: { time_t t; t = date2time(value, tm_time()); if ((time_t) -1 == t) { item.damaged = TRUE; } } break; case SPAM_TAG_SHA1: { if (strlen(value) != SHA1_BASE32_SIZE) { item.damaged = TRUE; g_warning("spam_load(): SHA-1 has wrong length."); } else { const struct sha1 *raw; raw = base32_sha1(value); if (raw) item.sha1 = *raw; else item.damaged = TRUE; } } break; case SPAM_TAG_NAME: { if ('\0' == value[0]) { item.damaged = TRUE; g_warning("spam_load(): Missing filename pattern."); } else if (!utf8_is_valid_string(value)) { item.damaged = TRUE; g_warning("spam_load(): Filename pattern is not UTF-8."); } else { item.name = h_strdup(value); } } break; case SPAM_TAG_SIZE: { const char *endptr; guint64 u; int error; u = parse_uint64(value, &endptr, 10, &error); if (error) { item.damaged = TRUE; g_warning("spam_load(): Cannot parse SIZE: %s", value); } else { item.min_size = u; item.max_size = u; if ('-' == endptr[0]) { u = parse_uint64(&endptr[1], &endptr, 10, &error); if (error) { item.damaged = TRUE; g_warning("spam_load(): Cannot parse SIZE: %s", value); } if (u < item.min_size) { item.damaged = TRUE; g_warning("spam_load(): " "Maximum size below minimum size"); } else { item.max_size = u; } } } } break; case SPAM_TAG_END: if ( !bit_array_get(tag_used, SPAM_TAG_SHA1) && !bit_array_get(tag_used, SPAM_TAG_NAME) ) { g_warning("spam_load(): missing SHA1 or NAME tag"); item.damaged = TRUE; } if (!bit_array_get(tag_used, SPAM_TAG_ADDED)) { g_warning("spam_load(): missing ADDED tag"); item.damaged = TRUE; } item.done = TRUE; break; case SPAM_TAG_UNKNOWN: /* Ignore */ break; case NUM_SPAM_TAGS: g_assert_not_reached(); break; } if (item.done && !item.damaged) { if (bit_array_get(tag_used, SPAM_TAG_SHA1)) { spam_sha1_add(&item.sha1); item_count++; } if (bit_array_get(tag_used, SPAM_TAG_NAME)) { if (!bit_array_get(tag_used, SPAM_TAG_SIZE)) { item.min_size = 0; item.max_size = MAX_INT_VAL(filesize_t); } if ( spam_add_name_and_size(item.name, item.min_size, item.max_size) ) { item.damaged = TRUE; } else { item_count++; } } } if (item.damaged) { g_warning("Damaged spam entry in line %u: " "tag_name=\"%s\", value=\"%s\"", line_no, tag_name, value); } if (item.done) { /* Reset state */ HFREE_NULL(item.name); item = zero_item; bit_array_clear_range(tag_used, 0, NUM_SPAM_TAGS - 1U); } } spam_sha1_sync(); return item_count; }
int options_parse(int argc, const char** argv, options_t* options) { uint64_t val; int i; /* Initialize options to default values. */ options->nconnections = DEFAULT_CONNECTIONS; options->nthreads = DEFAULT_THREADS; options->receive = DEFAULT_RECEIVE; options->number_thread_loops = DEFAULT_LOOPS; options->number_connection_loops = DEFAULT_LOOPS; options->client_sends_first = CLIENT_SENDS_FIRST; options->set_read_write_event = SET_READ_WRITE_EVENT; options->nprocessors = 0; files_init(&options->files); /* Last parameter is not an option. */ argc--; i = 1; while (i < argc) { if (strcasecmp(argv[i], "--connections") == 0) { /* Last parameter? */ if (i + 1 == argc) { files_free(&options->files); return -1; } if (parse_uint64(argv[i + 1], MIN_CONNECTIONS, MAX_CONNECTIONS, &val) < 0) { files_free(&options->files); return -1; } options->nconnections = (unsigned) val; i += 2; } else if (strcasecmp(argv[i], "--threads") == 0) { /* Last parameter? */ if (i + 1 == argc) { files_free(&options->files); return -1; } if (parse_uint64(argv[i + 1], MIN_THREADS, MAX_THREADS, &val) < 0) { files_free(&options->files); return -1; } options->nthreads = (unsigned) val; i += 2; } else if (strcasecmp(argv[i], "--receive") == 0) { /* Last parameter? */ if (i + 1 == argc) { files_free(&options->files); return -1; } if (parse_uint64(argv[i + 1], MIN_RECEIVE, MAX_RECEIVE, &val) < 0) { files_free(&options->files); return -1; } options->receive = (unsigned) val; i += 2; } else if (strcasecmp(argv[i], "--thread-loops") == 0) { /* Last parameter? */ if (i + 1 == argc) { files_free(&options->files); return -1; } if (parse_uint64(argv[i + 1], MIN_LOOPS, MAX_LOOPS, &options->number_thread_loops) < 0) { files_free(&options->files); return -1; } i += 2; } else if (strcasecmp(argv[i], "--connection-loops") == 0) { /* Last parameter? */ if (i + 1 == argc) { files_free(&options->files); return -1; } if (parse_uint64(argv[i + 1], MIN_LOOPS, MAX_LOOPS, &options->number_connection_loops) < 0) { files_free(&options->files); return -1; } i += 2; } else if (strcasecmp(argv[i], "--client-sends-first") == 0) { options->client_sends_first = 1; i++; } else if (strcasecmp(argv[i], "--server-sends-first") == 0) { options->client_sends_first = 0; i++; } else if (strcasecmp(argv[i], "--set-read-write-event") == 0) { options->set_read_write_event = 1; i++; } else if (strcasecmp(argv[i], "--do-not-set-read-write-event") == 0) { options->set_read_write_event = 0; i++; } else if (strcasecmp(argv[i], "--processors") == 0) { /* Last parameter? */ if (i + 1 == argc) { files_free(&options->files); return -1; } if (parse_processors(argv[i + 1], options->processors, &options->nprocessors) < 0) { files_free(&options->files); return -1; } i += 2; } else if (strcasecmp(argv[i], "--file") == 0) { /* Last parameter? */ if (i + 1 == argc) { files_free(&options->files); return -1; } if (files_add(&options->files, argv[i + 1]) < 0) { files_free(&options->files); return -1; } i += 2; } else { files_free(&options->files); return -1; } } /* If no files have been specified... */ if (options->files.used == 0) { if (files_add_dummy(&options->files) < 0) { files_free(&options->files); return -1; } } options->nthreads = MIN(options->nthreads, options->nconnections); if (options->receive == 0) { options->client_sends_first = 1; } return 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; }
/* Processes the current directive. * If the encoder returns an error, a message including current file and * line number together with the pt error string is printed on stderr. * * Returns 0 on success; a negative enum errcode otherwise. * Returns -err_internal if @p or @e is the NULL pointer. * Returns -err_parse_missing_directive if there was a pt directive marker, * but no directive. * Returns -stop_process if the .exp directive was encountered. * Returns -err_pt_lib if the pt encoder returned an error. * Returns -err_parse if a general parsing error was encountered. * Returns -err_parse_unknown_directive if there was an unknown pt directive. */ static int p_process(struct parser *p, struct pt_encoder *e) { int bytes_written; int errcode; char *directive, *payload, *pt_label_name, *tmp; struct pt_directive *pd; struct pt_packet packet; if (bug_on(!p)) return -err_internal; if (bug_on(!e)) return -err_internal; pd = p->pd; if (!pd) return -err_internal; directive = pd->name; payload = pd->payload; pt_label_name = NULL; bytes_written = 0; errcode = 0; /* find a label name. */ tmp = strchr(directive, ':'); if (tmp) { uint64_t x; pt_label_name = directive; directive = tmp+1; *tmp = '\0'; /* ignore whitespace between label and directive. */ while (isspace(*directive)) directive += 1; /* if we can lookup a yasm label with the same name, the * current pt directive label is invalid. */ errcode = yasm_lookup_label(p->y, &x, pt_label_name); if (errcode == 0) errcode = -err_label_not_unique; if (errcode != -err_no_label) return yasm_print_err(p->y, "label lookup", errcode); /* if we can lookup a pt directive label with the same * name, the current pt directive label is invalid. */ errcode = l_lookup(p->pt_labels, &x, pt_label_name); if (errcode == 0) errcode = -err_label_not_unique; if (errcode != -err_no_label) return yasm_print_err(p->y, "label lookup", -err_label_not_unique); } /* now try to match the directive string and call the * corresponding function that parses the payload and emits an * according packet. */ if (strcmp(directive, "") == 0) return yasm_print_err(p->y, "invalid syntax", -err_parse_missing_directive); else if (strcmp(directive, ".exp") == 0) { /* this is the end of processing pt directives, so we * add a p_last label to the pt directive labels. */ errcode = l_append(p->pt_labels, "eos", p->pt_bytes_written); if (errcode < 0) return yasm_print_err(p->y, "append label", errcode); return -stop_process; } if (strcmp(directive, "psb") == 0) { errcode = parse_empty(payload); if (errcode < 0) { yasm_print_err(p->y, "psb: parsing failed", errcode); goto error; } packet.type = ppt_psb; } else if (strcmp(directive, "psbend") == 0) { errcode = parse_empty(payload); if (errcode < 0) { yasm_print_err(p->y, "psbend: parsing failed", errcode); goto error; } packet.type = ppt_psbend; } else if (strcmp(directive, "pad") == 0) { errcode = parse_empty(payload); if (errcode < 0) { yasm_print_err(p->y, "pad: parsing failed", errcode); goto error; } packet.type = ppt_pad; } else if (strcmp(directive, "ovf") == 0) { errcode = parse_empty(payload); if (errcode < 0) { yasm_print_err(p->y, "ovf: parsing failed", errcode); goto error; } packet.type = ppt_ovf; } else if (strcmp(directive, "tnt") == 0) { errcode = parse_tnt(&packet.payload.tnt.payload, &packet.payload.tnt.bit_size, payload); if (errcode < 0) { yasm_print_err(p->y, "tnt: parsing failed", errcode); goto error; } packet.type = ppt_tnt_8; } else if (strcmp(directive, "tnt64") == 0) { errcode = parse_tnt(&packet.payload.tnt.payload, &packet.payload.tnt.bit_size, payload); if (errcode < 0) { yasm_print_err(p->y, "tnt64: parsing failed", errcode); goto error; } packet.type = ppt_tnt_64; } else if (strcmp(directive, "tip") == 0) { errcode = parse_ip(p, &packet.payload.ip.ip, &packet.payload.ip.ipc, payload); if (errcode < 0) { yasm_print_err(p->y, "tip: parsing failed", errcode); goto error; } packet.type = ppt_tip; } else if (strcmp(directive, "tip.pge") == 0) { errcode = parse_ip(p, &packet.payload.ip.ip, &packet.payload.ip.ipc, payload); if (errcode < 0) { yasm_print_err(p->y, "tip.pge: parsing failed", errcode); goto error; } packet.type = ppt_tip_pge; } else if (strcmp(directive, "tip.pgd") == 0) { errcode = parse_ip(p, &packet.payload.ip.ip, &packet.payload.ip.ipc, payload); if (errcode < 0) { yasm_print_err(p->y, "tip.pgd: parsing failed", errcode); goto error; } packet.type = ppt_tip_pgd; } else if (strcmp(directive, "fup") == 0) { errcode = parse_ip(p, &packet.payload.ip.ip, &packet.payload.ip.ipc, payload); if (errcode < 0) { yasm_print_err(p->y, "fup: parsing failed", errcode); goto error; } packet.type = ppt_fup; } else if (strcmp(directive, "mode.exec") == 0) { if (strcmp(payload, "16bit") == 0) { packet.payload.mode.bits.exec.csl = 0; packet.payload.mode.bits.exec.csd = 0; } else if (strcmp(payload, "64bit") == 0) { packet.payload.mode.bits.exec.csl = 1; packet.payload.mode.bits.exec.csd = 0; } else if (strcmp(payload, "32bit") == 0) { packet.payload.mode.bits.exec.csl = 0; packet.payload.mode.bits.exec.csd = 1; } else { errcode = yasm_print_err(p->y, "mode.exec: argument must be one of \"16bit\", \"64bit\" or \"32bit\"", -err_parse); goto error; } packet.payload.mode.leaf = pt_mol_exec; packet.type = ppt_mode; } else if (strcmp(directive, "mode.tsx") == 0) { if (strcmp(payload, "begin") == 0) { packet.payload.mode.bits.tsx.intx = 1; packet.payload.mode.bits.tsx.abrt = 0; } else if (strcmp(payload, "abort") == 0) { packet.payload.mode.bits.tsx.intx = 0; packet.payload.mode.bits.tsx.abrt = 1; } else if (strcmp(payload, "commit") == 0) { packet.payload.mode.bits.tsx.intx = 0; packet.payload.mode.bits.tsx.abrt = 0; } else { errcode = yasm_print_err(p->y, "mode.tsx: argument must be one of \"begin\", \"abort\" or \"commit\"", -err_parse); goto error; } packet.payload.mode.leaf = pt_mol_tsx; packet.type = ppt_mode; } else if (strcmp(directive, "pip") == 0) { errcode = parse_uint64(&packet.payload.pip.cr3, payload); if (errcode < 0) { yasm_print_err(p->y, "pip: parsing failed", errcode); goto error; } packet.type = ppt_pip; } else if (strcmp(directive, "tsc") == 0) { errcode = parse_uint64(&packet.payload.tsc.tsc, payload); if (errcode < 0) { yasm_print_err(p->y, "tsc: parsing failed", errcode); goto error; } packet.type = ppt_tsc; } else if (strcmp(directive, "cbr") == 0) { errcode = parse_uint8(&packet.payload.cbr.ratio, payload); if (errcode < 0) { yasm_print_err(p->y, "cbr: parsing cbr failed", errcode); goto error; } packet.type = ppt_cbr; } else { errcode = yasm_print_err(p->y, "invalid syntax", -err_parse_unknown_directive); goto error; } bytes_written = pt_enc_next(e, &packet); if (bytes_written < 0) { const char *errstr, *format; char *msg; size_t n; errstr = pt_errstr(pt_errcode(bytes_written)); format = "encoder error in directive %s (status %s)"; /* the length of format includes the "%s" (-2) * characters, we add errstr (+-0) and then we need * space for a terminating null-byte (+1). */ n = strlen(format)-4 + strlen(directive) + strlen(errstr) + 1; msg = malloc(n); if (!msg) errcode = yasm_print_err(p->y, "encoder error not enough memory to show error code", -err_pt_lib); else { sprintf(msg, format, directive, errstr); errcode = yasm_print_err(p->y, msg, -err_pt_lib); free(msg); } } else { if (pt_label_name) { errcode = l_append(p->pt_labels, pt_label_name, p->pt_bytes_written); if (errcode < 0) goto error; } p->pt_bytes_written += bytes_written; } error: if (errcode < 0) bytes_written = errcode; return bytes_written; }
/* Typical crazy output from the xfs_info command: * * meta-data=/dev/sda1 isize=256 agcount=4, agsize=6392 blks * = sectsz=512 attr=2 *[ = crc=0 ] * data = bsize=4096 blocks=25568, imaxpct=25 * = sunit=0 swidth=0 blks * naming =version 2 bsize=4096 ascii-ci=0 * log =internal bsize=4096 blocks=1200, version=2 * = sectsz=512 sunit=0 blks, lazy-count=1 * realtime =none extsz=4096 blocks=0, rtextents=0 * * [...] line only appears in Fedora >= 21 * * We may need to revisit this parsing code if the output changes * in future. */ static guestfs_int_xfsinfo * parse_xfs_info (char **lines) { guestfs_int_xfsinfo *ret; CLEANUP_FREE char *section = NULL; /* first column, eg "meta-data", "data" */ char *p; size_t i; ret = malloc (sizeof *ret); if (ret == NULL) { reply_with_error ("malloc"); return NULL; } /* Initialize fields to NULL or -1 so the caller can tell which fields * were updated in the code below. */ ret->xfs_mntpoint = NULL; ret->xfs_inodesize = -1; ret->xfs_agcount = -1; ret->xfs_agsize = -1; ret->xfs_sectsize = -1; ret->xfs_attr = -1; ret->xfs_blocksize = -1; ret->xfs_datablocks = -1; ret->xfs_imaxpct = -1; ret->xfs_sunit = -1; ret->xfs_swidth = -1; ret->xfs_dirversion = -1; ret->xfs_dirblocksize = -1; ret->xfs_cimode = -1; ret->xfs_logname = NULL; ret->xfs_logblocksize = -1; ret->xfs_logblocks = -1; ret->xfs_logversion = -1; ret->xfs_logsectsize = -1; ret->xfs_logsunit = -1; ret->xfs_lazycount = -1; ret->xfs_rtname = NULL; ret->xfs_rtextsize = -1; ret->xfs_rtblocks = -1; ret->xfs_rtextents = -1; for (i = 0; lines[i] != NULL; ++i) { if (verbose) fprintf (stderr, "xfs_info: lines[%zu] = \'%s\'\n", i, lines[i]); if (c_isalpha (lines[i][0])) { free (section); section = split_strdup (lines[i]); if (!section) goto error; if (verbose) fprintf (stderr, "xfs_info: new section %s\n", section); } if ((p = strstr (lines[i], "meta-data="))) { ret->xfs_mntpoint = split_strdup (p + 10); if (ret->xfs_mntpoint == NULL) goto error; } if ((p = strstr (lines[i], "isize="))) { CLEANUP_FREE char *buf = split_strdup (p + 6); if (buf == NULL) goto error; if (parse_uint32 (&ret->xfs_inodesize, buf) == -1) goto error; } if ((p = strstr (lines[i], "agcount="))) { CLEANUP_FREE char *buf = split_strdup (p + 8); if (buf == NULL) goto error; if (parse_uint32 (&ret->xfs_agcount, buf) == -1) goto error; } if ((p = strstr (lines[i], "agsize="))) { CLEANUP_FREE char *buf = split_strdup (p + 7); if (buf == NULL) goto error; if (parse_uint32 (&ret->xfs_agsize, buf) == -1) goto error; } if ((p = strstr (lines[i], "sectsz="))) { if (section) { CLEANUP_FREE char *buf = split_strdup (p + 7); if (buf == NULL) goto error; if (STREQ (section, "meta-data")) { if (parse_uint32 (&ret->xfs_sectsize, buf) == -1) goto error; } else if (STREQ (section, "log")) { if (parse_uint32 (&ret->xfs_logsectsize, buf) == -1) goto error; } } } if ((p = strstr (lines[i], "attr="))) { CLEANUP_FREE char *buf = split_strdup (p + 5); if (buf == NULL) goto error; if (parse_uint32 (&ret->xfs_attr, buf) == -1) goto error; } if ((p = strstr (lines[i], "bsize="))) { if (section) { CLEANUP_FREE char *buf = split_strdup (p + 6); if (buf == NULL) goto error; if (STREQ (section, "data")) { if (parse_uint32 (&ret->xfs_blocksize, buf) == -1) goto error; } else if (STREQ (section, "naming")) { if (parse_uint32 (&ret->xfs_dirblocksize, buf) == -1) goto error; } else if (STREQ (section, "log")) { if (parse_uint32 (&ret->xfs_logblocksize, buf) == -1) goto error; } } } if ((p = strstr (lines[i], "blocks="))) { if (section) { CLEANUP_FREE char *buf = split_strdup (p + 7); if (buf == NULL) goto error; if (STREQ (section, "data")) { if (parse_uint64 (&ret->xfs_datablocks, buf) == -1) goto error; } else if (STREQ (section, "log")) { if (parse_uint32 (&ret->xfs_logblocks, buf) == -1) goto error; } else if (STREQ (section, "realtime")) { if (parse_uint64 (&ret->xfs_rtblocks, buf) == -1) goto error; } } } if ((p = strstr (lines[i], "imaxpct="))) { CLEANUP_FREE char *buf = split_strdup (p + 8); if (buf == NULL) goto error; if (parse_uint32 (&ret->xfs_imaxpct, buf) == -1) goto error; } if ((p = strstr (lines[i], "sunit="))) { if (section) { CLEANUP_FREE char *buf = split_strdup (p + 6); if (buf == NULL) goto error; if (STREQ (section, "data")) { if (parse_uint32 (&ret->xfs_sunit, buf) == -1) goto error; } else if (STREQ (section, "log")) { if (parse_uint32 (&ret->xfs_logsunit, buf) == -1) goto error; } } } if ((p = strstr (lines[i], "swidth="))) { CLEANUP_FREE char *buf = split_strdup (p + 7); if (buf == NULL) goto error; if (parse_uint32 (&ret->xfs_swidth, buf) == -1) goto error; } if ((p = strstr (lines[i], "naming =version "))) { CLEANUP_FREE char *buf = split_strdup (p + 18); if (buf == NULL) goto error; if (parse_uint32 (&ret->xfs_dirversion, buf) == -1) goto error; } if ((p = strstr (lines[i], "ascii-ci="))) { CLEANUP_FREE char *buf = split_strdup (p + 9); if (buf == NULL) goto error; if (parse_uint32 (&ret->xfs_cimode, buf) == -1) goto error; } if ((p = strstr (lines[i], "log ="))) { ret->xfs_logname = split_strdup (p + 10); if (ret->xfs_logname == NULL) goto error; } if ((p = strstr (lines[i], "version="))) { CLEANUP_FREE char *buf = split_strdup (p + 8); if (buf == NULL) goto error; if (parse_uint32 (&ret->xfs_logversion, buf) == -1) goto error; } if ((p = strstr (lines[i], "lazy-count="))) { CLEANUP_FREE char *buf = split_strdup (p + 11); if (buf == NULL) goto error; if (parse_uint32 (&ret->xfs_lazycount, buf) == -1) goto error; } if ((p = strstr (lines[i], "realtime ="))) { ret->xfs_rtname = split_strdup (p + 10); if (ret->xfs_rtname == NULL) goto error; } if ((p = strstr (lines[i], "rtextents="))) { CLEANUP_FREE char *buf = split_strdup (p + 10); if (buf == NULL) goto error; if (parse_uint64 (&ret->xfs_rtextents, buf) == -1) goto error; } } if (ret->xfs_mntpoint == NULL) { ret->xfs_mntpoint = strdup (""); if (ret->xfs_mntpoint == NULL) goto error; } if (ret->xfs_logname == NULL) { ret->xfs_logname = strdup (""); if (ret->xfs_logname == NULL) goto error; } if (ret->xfs_rtname == NULL) { ret->xfs_rtname = strdup (""); if (ret->xfs_rtname == NULL) goto error; } return ret; error: free (ret->xfs_mntpoint); free (ret->xfs_logname); free (ret->xfs_rtname); free (ret); return NULL; }
int options_parse(int argc, const char** argv, options_t* options) { uint64_t val; int i; /* Initialize options to default values. */ options->number_messages_per_receive = DEFAULT_MESSAGES_PER_RECEIVE; options->nthreads = DEFAULT_THREADS; #ifdef SO_REUSEPORT options->single_receiver_socket = SINGLE_RECEIVER_SOCKET; #else options->single_receiver_socket = 1; #endif options->nprocessors = 0; /* Last parameter is not an option. */ argc--; i = 1; while (i < argc) { if (strcasecmp(argv[i], "--messages-per-receive") == 0) { /* Last parameter? */ if (i + 1 == argc) { return -1; } if (parse_uint64(argv[i + 1], MIN_MESSAGES_PER_RECEIVE, MAX_MESSAGES_PER_RECEIVE, &val) < 0) { return -1; } options->number_messages_per_receive = (unsigned) val; i += 2; } else if (strcasecmp(argv[i], "--threads") == 0) { /* Last parameter? */ if (i + 1 == argc) { return -1; } if (parse_uint64(argv[i + 1], MIN_THREADS, MAX_THREADS, &val) < 0) { return -1; } options->nthreads = (unsigned) val; i += 2; #ifdef SO_REUSEPORT } else if (strcasecmp(argv[i], "--single-receiver-socket") == 0) { options->single_receiver_socket = 1; i++; } else if (strcasecmp(argv[i], "--one-receiver-socket-per-thread") == 0) { options->single_receiver_socket = 0; i++; #endif /* SO_REUSEPORT */ } else if (strcasecmp(argv[i], "--processors") == 0) { /* Last parameter? */ if (i + 1 == argc) { return -1; } if (parse_processors(argv[i + 1], options->processors, &options->nprocessors) < 0) { return -1; } i += 2; } else { return -1; } } return 0; }
/* parses a 4-touple of the form {x, y, z, w} * where x, y, z, w are numbers */ static boolean parse_immediate_data(struct translate_ctx *ctx, unsigned type, union tgsi_immediate_data *values) { unsigned i; int ret; eat_opt_white( &ctx->cur ); if (*ctx->cur != '{') { report_error( ctx, "Expected `{'" ); return FALSE; } ctx->cur++; for (i = 0; i < 4; i++) { eat_opt_white( &ctx->cur ); if (i > 0) { if (*ctx->cur != ',') { report_error( ctx, "Expected `,'" ); return FALSE; } ctx->cur++; eat_opt_white( &ctx->cur ); } switch (type) { case TGSI_IMM_FLOAT64: ret = parse_double(&ctx->cur, &values[i].Uint, &values[i+1].Uint); i++; break; case TGSI_IMM_INT64: ret = parse_int64(&ctx->cur, &values[i].Uint, &values[i+1].Uint); i++; break; case TGSI_IMM_UINT64: ret = parse_uint64(&ctx->cur, &values[i].Uint, &values[i+1].Uint); i++; break; case TGSI_IMM_FLOAT32: ret = parse_float(&ctx->cur, &values[i].Float); break; case TGSI_IMM_UINT32: ret = parse_uint(&ctx->cur, &values[i].Uint); break; case TGSI_IMM_INT32: ret = parse_int(&ctx->cur, &values[i].Int); break; default: assert(0); ret = FALSE; break; } if (!ret) { report_error( ctx, "Expected immediate constant" ); return FALSE; } } eat_opt_white( &ctx->cur ); if (*ctx->cur != '}') { report_error( ctx, "Expected `}'" ); return FALSE; } ctx->cur++; return TRUE; }
static int key_value_parse_line_with_key(struct key_value_specification *k, char *line, void *base_address[]) { char *valuestr; int rc, len, klen; klen = strlen(k->key); len = strlen(line); if (len < klen + 1) return 1; if (strncmp(line, k->key, klen) != 0) return 1; if (line[klen] != ':') return 1; /* Skip leading spaces */ klen = klen + 1; while (line[klen] == ' ') klen++; /* At this point, we have a match on the key */ valuestr = &line[klen]; switch (k->type) { case KVS_STRING: rc = parse_string(valuestr, k, base_address); break; case KVS_INT64: rc = parse_int64(valuestr, k, base_address); break; case KVS_INT32: rc = parse_int32(valuestr, k, base_address); break; case KVS_INT16: rc = parse_int16(valuestr, k, base_address); break; case KVS_INT8: rc = parse_int8(valuestr, k, base_address); break; case KVS_UINT64: rc = parse_uint64(valuestr, k, base_address); break; case KVS_UINT32: rc = parse_uint32(valuestr, k, base_address); break; case KVS_UINT16: rc = parse_uint16(valuestr, k, base_address); break; case KVS_UINT8: rc = parse_uint8(valuestr, k, base_address); break; case KVS_DOUBLE: rc = parse_double(valuestr, k, base_address); break; case KVS_FLOAT: rc = parse_float(valuestr, k, base_address); break; default: fprintf(stderr, "%s:%d: unknown key type '%c' for key '%s'\n", __func__, __LINE__, k->type, k->key); rc = -1; break; } return rc; }
G_GNUC_COLD void upload_stats_load_history(void) { FILE *upload_stats_file; file_path_t fp; char line[FILENAME_MAX + 64]; guint lineno = 0; gcu_upload_stats_gui_freeze(); file_path_set(&fp, settings_config_dir(), ul_stats_file); /* open file for reading */ upload_stats_file = file_config_open_read(ul_stats_what, &fp, 1); if (upload_stats_file == NULL) goto done; /* parse, insert names into ul_stats_clist */ while (fgets(line, sizeof(line), upload_stats_file)) { static const struct ul_stats zero_item; struct ul_stats item; struct sha1 sha1_buf; const char *p; size_t i; lineno++; if (line[0] == '#' || line[0] == '\n') continue; p = strchr(line, '\t'); if (NULL == p) goto corrupted; line[p - line] = '\0'; /* line is now the URL-escaped file name */ p++; /* URL-unescape in-place */ if (!url_unescape(line, TRUE)) goto corrupted; item = zero_item; item.pathname = line; for (i = 0; i < 8; i++) { guint64 v; int error; const char *endptr; p = skip_ascii_spaces(p); /* SVN versions up to 15322 had only 6 fields in the history */ if (5 == i && '\0' == *p) break; switch (i) { case 7: /* We have a SHA1 or '*' if none known */ if ('*' != *p) { size_t len = clamp_strlen(p, SHA1_BASE32_SIZE); error = !parse_base32_sha1(p, len, &sha1_buf); item.sha1 = error ? NULL : &sha1_buf; } else { error = FALSE; } p = skip_ascii_non_spaces(p); v = 0; break; default: v = parse_uint64(p, &endptr, 10, &error); p = deconstify_gchar(endptr); } if (error || !is_ascii_space(*endptr)) goto corrupted; switch (i) { case 0: item.size = v; break; case 1: item.attempts = v; break; case 2: item.complete = v; break; case 3: item.bytes_sent |= ((guint64) (guint32) v) << 32; break; case 4: item.bytes_sent |= (guint32) v; break; case 5: item.rtime = MIN(v + (time_t) 0, TIME_T_MAX + (guint64) 0); case 6: item.dtime = MIN(v + (time_t) 0, TIME_T_MAX + (guint64) 0); case 7: break; /* Already stored above */ default: g_assert_not_reached(); goto corrupted; } } /* * We store the filenames UTF-8 encoded but the file might have been * edited or corrupted. */ if (is_absolute_path(item.pathname)) { item.filename = lazy_filename_to_utf8_normalized( filepath_basename(item.pathname), UNI_NORM_NFC); } else { item.filename = lazy_unknown_to_utf8_normalized( filepath_basename(item.pathname), UNI_NORM_NFC, NULL); } if (upload_stats_find(NULL, item.pathname, item.size)) { g_warning("upload_stats_load_history():" " Ignoring line %u due to duplicate file.", lineno); } else if (upload_stats_find(item.sha1, item.pathname, item.size)) { g_warning("upload_stats_load_history():" " Ignoring line %u due to duplicate file.", lineno); } else { upload_stats_add(item.pathname, item.size, item.filename, item.attempts, item.complete, item.bytes_sent, item.rtime, item.dtime, item.sha1); } continue; corrupted: g_warning("upload statistics file corrupted at line %u.", lineno); } /* close file */ fclose(upload_stats_file); done: gcu_upload_stats_gui_thaw(); return; }
/** * This function is used to read the disk cache into memory. * * It must be passed one line from the cache (ending with '\n'). It * performs all the syntactic processing to extract the fields from * the line and calls add_volatile_cache_entry() to append the record * to the in-memory cache. */ static G_GNUC_COLD void parse_and_append_cache_entry(char *line) { const char *p, *end; /* pointers to scan the line */ int c, error; filesize_t size; time_t mtime; struct sha1 sha1; struct tth tth; bool has_tth; /* Skip comments and blank lines */ if (file_line_is_skipable(line)) return; /* Scan until file size */ p = line; while ((c = *p) != '\0' && c != '\t') { p++; } if (urn_get_bitprint(line, p - line, &sha1, &tth)) { has_tth = TRUE; } else if (urn_get_sha1(line, &sha1)) { has_tth = FALSE; } else { const char *sha1_digest_ascii; has_tth = FALSE; sha1_digest_ascii = line; /* SHA1 digest is the first field. */ if ( *p != '\t' || (p - sha1_digest_ascii) != SHA1_BASE32_SIZE || SHA1_RAW_SIZE != base32_decode(sha1.data, sizeof sha1.data, sha1_digest_ascii, SHA1_BASE32_SIZE) ) { goto failure; } } p++; /* Skip \t */ /* p is now supposed to point to the beginning of the file size */ size = parse_uint64(p, &end, 10, &error); if (error || *end != '\t') { goto failure; } p = ++end; /* * p is now supposed to point to the beginning of the file last * modification time. */ mtime = parse_uint64(p, &end, 10, &error); if (error || *end != '\t') { goto failure; } p = ++end; /* p is now supposed to point to the file name */ if (strchr(p, '\t') != NULL) goto failure; add_volatile_cache_entry(p, size, mtime, &sha1, has_tth ? &tth : NULL, FALSE); return; failure: g_warning("malformed line in SHA1 cache file: %s", line); }
static void integer_number(void) { uint64_t number = parse_uint64(parser.previous.start, parser.previous.length); emit_constant(INT_VAL((int64_t)number)); }
template_t * template_load(const char *filename) { struct template_chunk *chunk; FILE *f; char *buf = NULL, *q; size_t buf_len, line; template_t *tpl = NULL; int c; char entity[128], *e = NULL; RUNTIME_ASSERT(filename != NULL); f = safer_fopen(filename, SAFER_FOPEN_RD); if (!f) { WARN("could not open \"%s\": %s", filename, compat_strerror(errno)); goto failure; } tpl = calloc(1, sizeof *tpl); if (!tpl) { CRIT("Out of memory"); goto failure; } tpl->chunks = NULL; buf_len = 4096; buf = calloc(1, buf_len); if (!buf) { CRIT("Out of memory"); goto failure; } for (line = 1; /* NOTHING */; line++) { char *p; p = fgets(buf, buf_len, f); if (!p) { if (!ferror(f)) break; CRIT("fgets() failed: %s", compat_strerror(errno)); goto failure; } q = strchr(buf, '\n'); if (!q) { CRIT("Line too long or unterminated: \"%s\"", buf); goto failure; } while (isspace((unsigned char) *q)) { *q = '\0'; if (q == buf) break; q--; } if (q == buf && *q == '\0') break; if (line == 1 && 0 == strncmp(buf, "HTTP/", sizeof "HTTP/" - 1)) { uint64_t code; char *endptr; int error; struct http_response hres; size_t size; snode_t *sn; p = strchr(buf, ' '); if (!p) { WARN("Invalid HTTP response: \"%s\"", buf); goto failure; } p = skip_spaces(p); code = parse_uint64(p, &endptr, 10, &error); if (code < 100 || code > 999) { WARN("Invalid HTTP result code: \"%s\"", buf); goto failure; } p = skip_spaces(endptr); hres.code = code; size = sizeof hres.msg; append_string(hres.msg, &size, p); RUNTIME_ASSERT(hres.msg == (char *) &hres); chunk = template_raw_chunk_new(chunk_http_response, (char *) &hres, sizeof hres); if (NULL == (sn = snode_new(chunk))) { CRIT("snode_new() failed"); goto failure; } tpl->chunks = snode_prepend(tpl->chunks, sn); } else { size_t len; snode_t *sn; if (!isalpha((unsigned char) buf[0]) || NULL == strchr(buf, ':')) { WARN("Invalid HTTP header: \"%s\"", buf); goto failure; } for (p = buf; (c = (unsigned char) *p) != ':'; ++p) if (!isalpha(c) && c != '-') { WARN("Invalid character HTTP in header name: \"%s\"", buf); goto failure; } len = strlen(buf) + 1; chunk = template_raw_chunk_new(chunk_http_header, buf, len); if (NULL == (sn = snode_new(chunk))) { CRIT("snode_new() failed"); goto failure; } tpl->chunks = snode_prepend(tpl->chunks, sn); } } if (feof(f)) { tpl->chunks = snode_reverse(tpl->chunks); return tpl; } q = buf; e = NULL; for (;;) { c = fgetc(f); if (c == EOF) { if (!ferror(f)) break; CRIT("fgetc() failed: %s", compat_strerror(errno)); goto failure; } if ((size_t) (q - buf) >= buf_len) { char *n; buf_len += 4096; n = realloc(buf, buf_len); if (!n) { CRIT("Out of memory"); goto failure; } q = &n[q - buf]; buf = n; } *q++ = c; if (c == ';' && e != NULL) { RUNTIME_ASSERT(e >= entity && e < &entity[sizeof entity]); *e = '\0'; chunk = template_chunk_new(entity); if (chunk) { struct template_chunk *data; size_t data_len; snode_t *sn; data_len = (q - buf) - strlen(entity) - 2; RUNTIME_ASSERT(data_len <= INT_MAX); if (data_len > 0) { data = template_raw_chunk_new(chunk_data, buf, data_len); if (NULL == (sn = snode_new(data))) { CRIT("snode_new() failed"); goto failure; } tpl->chunks = snode_prepend(tpl->chunks, sn); buf_len = 4096; buf = calloc(1, buf_len); if (!buf) { CRIT("Out of memory"); goto failure; } } q = buf; if (NULL == (sn = snode_new(chunk))) { CRIT("snode_new() failed"); goto failure; } tpl->chunks = snode_prepend(tpl->chunks, sn); } e = NULL; } if (e) { bool b = isalnum(c) || c == '.' || c == '_'; if (b && e < &entity[sizeof entity - 1]) { *e++ = c; } else { e = NULL; } } if (c == '&') { e = entity; } } fclose(f); f = NULL; if (q != buf) { snode_t *sn; chunk = template_raw_chunk_new(chunk_data, buf, q - buf); if (NULL == (sn = snode_new(chunk))) { CRIT("snode_new() failed"); goto failure; } tpl->chunks = snode_prepend(tpl->chunks, sn); } DO_FREE(buf); tpl->chunks = snode_reverse(tpl->chunks); #if 0 { size_t n = 0; snode_t *sn = tpl->chunks; while (sn) { struct gwc_data_chunk *data = sn->ptr; DBUG("data->type=%d; data->buf=%p; data->size=%d", (int) data->type, data->buf, (int) data->size); sn = sn->next; n += data->size; } DBUG("n=%d", (int) n); } #endif return tpl; failure: CRIT("Loading data template from \"%s\" failed.", filename); if (f) { fclose(f); f = NULL; } DO_FREE(buf); if (tpl) { while (tpl->chunks != NULL) { snode_t *sn = tpl->chunks->next; DO_FREE(tpl->chunks); tpl->chunks = sn; } DO_FREE(tpl); } return NULL; }
/* reads, corrects and parses the verity table, validates parameters, and if `f->flags' does not have `FEC_VERITY_DISABLE' set, calls `verify_tree' to load and validate the hash tree */ static int parse_table(fec_handle *f, uint64_t offset, uint32_t size, bool useecc) { check(f); check(size >= VERITY_MIN_TABLE_SIZE); check(size <= VERITY_MAX_TABLE_SIZE); debug("offset = %" PRIu64 ", size = %u", offset, size); verity_info *v = &f->verity; std::unique_ptr<char[]> table(new (std::nothrow) char[size + 1]); if (!table) { errno = ENOMEM; return -1; } if (!useecc) { if (!raw_pread(f, table.get(), size, offset)) { error("failed to read verity table: %s", strerror(errno)); return -1; } } else if (fec_pread(f, table.get(), size, offset) != (ssize_t)size) { error("failed to ecc read verity table: %s", strerror(errno)); return -1; } table[size] = '\0'; debug("verity table: '%s'", table.get()); int i = 0; std::unique_ptr<uint8_t[]> salt; uint8_t root[SHA256_DIGEST_LENGTH]; auto tokens = android::base::Split(table.get(), " "); for (const auto& token : tokens) { switch (i++) { case 0: /* version */ if (token != stringify(VERITY_TABLE_VERSION)) { error("unsupported verity table version: %s", token.c_str()); return -1; } break; case 3: /* data_block_size */ case 4: /* hash_block_size */ /* assume 4 KiB block sizes for everything */ if (token != stringify(FEC_BLOCKSIZE)) { error("unsupported verity block size: %s", token.c_str()); return -1; } break; case 5: /* num_data_blocks */ if (parse_uint64(token.c_str(), f->data_size / FEC_BLOCKSIZE, &v->data_blocks) == -1) { error("invalid number of verity data blocks: %s", token.c_str()); return -1; } break; case 6: /* hash_start_block */ if (parse_uint64(token.c_str(), f->data_size / FEC_BLOCKSIZE, &v->hash_start) == -1) { error("invalid verity hash start block: %s", token.c_str()); return -1; } v->hash_start *= FEC_BLOCKSIZE; break; case 7: /* algorithm */ if (token != "sha256") { error("unsupported verity hash algorithm: %s", token.c_str()); return -1; } break; case 8: /* digest */ if (parse_hex(root, sizeof(root), token.c_str()) == -1) { error("invalid verity root hash: %s", token.c_str()); return -1; } break; case 9: /* salt */ v->salt_size = token.size(); check(v->salt_size % 2 == 0); v->salt_size /= 2; salt.reset(new (std::nothrow) uint8_t[v->salt_size]); if (!salt) { errno = ENOMEM; return -1; } if (parse_hex(salt.get(), v->salt_size, token.c_str()) == -1) { error("invalid verity salt: %s", token.c_str()); return -1; } break; default: break; } } if (i < VERITY_TABLE_ARGS) { error("not enough arguments in verity table: %d; expected at least " stringify(VERITY_TABLE_ARGS), i); return -1; } check(v->hash_start < f->data_size); if (v->metadata_start < v->hash_start) { check(v->data_blocks == v->metadata_start / FEC_BLOCKSIZE); } else { check(v->data_blocks == v->hash_start / FEC_BLOCKSIZE); } if (v->salt) { delete[] v->salt; v->salt = NULL; } v->salt = salt.release(); if (v->table) { delete[] v->table; v->table = NULL; } v->table = table.release(); if (!(f->flags & FEC_VERITY_DISABLE)) { if (verify_tree(f, root) == -1) { return -1; } check(v->hash); uint8_t zero_block[FEC_BLOCKSIZE]; memset(zero_block, 0, FEC_BLOCKSIZE); if (verity_hash(f, zero_block, v->zero_hash) == -1) { error("failed to hash"); return -1; } } return 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, "OverSubscribe", MAX(taglen, 5)) || !strncasecmp(tag, "Shared", MAX(taglen, 2))) { 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 OverSubscribe values are " "NO, EXCLUSIVE, YES:#, and FORCE:#"); return -1; } (*update_cnt_ptr)++; } else if (strncasecmp(tag, "OverTimeLimit", MAX(taglen, 5)) == 0) { if ((xstrcasecmp(val,"UNLIMITED") == 0) || (xstrcasecmp(val,"INFINITE") == 0)) { part_msg_ptr->over_time_limit = (uint16_t) INFINITE; } else if (parse_uint16(val, &part_msg_ptr-> over_time_limit)) { error("Invalid OverTimeLimit value: %s", val); 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_uint64(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_uint64(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_uint64(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_uint64(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; }
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))); }
static void hub_handle_command(char *buf, uint32_t len) { char *hub_my_nick; /* XXX */ hub_my_nick = main_to_hub_string(my_nick); if (len >= 6 && strncmp(buf, "$Lock ", 6) == 0) { char *key; if (!check_state(buf, (DCUserState) DC_HUB_LOCK)) goto hub_handle_command_cleanup; key = (char*) memmem(buf+6, len-6, " Pk=", 4); if (key == NULL) { warn(_("Invalid $Lock message: Missing Pk value\n")); key = buf+len; } key = decode_lock(buf+6, key-buf-6, DC_CLIENT_BASE_KEY); if (strleftcmp("EXTENDEDPROTOCOL", buf+6) == 0) { if (!hub_putf("$Supports TTHSearch NoGetINFO NoHello|")) { free(key); goto hub_handle_command_cleanup; } } if (!hub_putf("$Key %s|", key)) { free(key); goto hub_handle_command_cleanup; } free(key); if (!hub_putf("$ValidateNick %s|", hub_my_nick)) goto hub_handle_command_cleanup; hub_state = DC_HUB_HELLO; } else if (len >= 10 && strncmp(buf, "$Supports ", 10) == 0) { char *p0, *p1; hub_extensions = 0; for (p0 = buf+10; (p1 = strchr(p0, ' ')) != NULL; p0 = p1+1) { *p1 = '\0'; parse_hub_extension(p0); } if (*p0 != '\0') parse_hub_extension(p0); } else if (strcmp(buf, "$GetPass") == 0) { if (my_password == NULL) { screen_putf(_("Hub requires password.\n")); hub_disconnect(); goto hub_handle_command_cleanup; } screen_putf(_("Sending password to hub.\n")); if (!hub_putf("$MyPass %s|", my_password)) goto hub_handle_command_cleanup; } else if (strcmp(buf, "$BadPass") == 0) { warn(_("Password not accepted.\n")); hub_disconnect(); } else if (strcmp(buf, "$LogedIn") == 0) { screen_putf(_("You have received operator status.\n")); } else if (len >= 9 && strncmp(buf, "$HubName ", 9) == 0) { free(hub_name); hub_name = hub_to_main_string(buf + 9); screen_putf(_("Hub name is %s.\n"), quotearg(hub_name)); } else if (strcmp(buf, "$GetNetInfo") == 0) { hub_putf("$NetInfo %d$1$%c|", my_ul_slots, is_active ? 'A' : 'P'); } else if (strcmp(buf, "$ValidateDenide") == 0) { if (!check_state(buf, (DCUserState) DC_HUB_HELLO)) goto hub_handle_command_cleanup; /* DC++ disconnects immediately if this is received. * But shouldn't we give the client a chance to change the nick? * Also what happens if we receive this when correctly logged in? */ warn(_("Hub did not accept nick. Nick may be in use.\n")); hub_disconnect(); } else if (len >= 7 && strncmp(buf, "$Hello ", 7) == 0) { DCUserInfo *ui; char *conv_nick; conv_nick = hub_to_main_string(buf + 7); if (hub_state == DC_HUB_HELLO) { if (strcmp(buf+7, hub_my_nick) == 0) { screen_putf(_("Nick accepted. You are now logged in.\n")); } else { /* This probably won't happen, but better safe... */ free(my_nick); my_nick = xstrdup(conv_nick); free(hub_my_nick); hub_my_nick = xstrdup(buf + 7); screen_putf(_("Nick accepted but modified to %s. You are now logged in.\n"), quotearg(my_nick)); } ui = user_info_new(conv_nick); ui->info_quered = true; /* Hub is sending this automaticly */ hmap_put(hub_users, ui->nick, ui); free (conv_nick); if (!hub_putf("$Version 1,0091|")) goto hub_handle_command_cleanup; if (!hub_putf("$GetNickList|")) goto hub_handle_command_cleanup; if (!send_my_info()) goto hub_handle_command_cleanup; hub_state = DC_HUB_LOGGED_IN; } else { flag_putf(DC_DF_JOIN_PART, _("User %s logged in.\n"), quotearg(conv_nick)); ui = user_info_new(conv_nick); hmap_put(hub_users, ui->nick, ui); free (conv_nick); if ((hub_extensions & HUB_EXT_NOGETINFO) == 0) { if (!hub_putf("$GetINFO %s %s|", buf+7, hub_my_nick)) goto hub_handle_command_cleanup; ui->info_quered = true; } } } else if (len >= 8 && strncmp(buf, "$MyINFO ", 8) == 0) { DCUserInfo *ui; char *token; uint32_t len; char* conv_buf; char *work_buf; buf += 8; work_buf = conv_buf = hub_to_main_string(buf); token = strsep(&work_buf, " "); if (strcmp(token, "$ALL") != 0) { warn(_("Invalid $MyINFO message: Missing $ALL parameter, ignoring\n")); free(conv_buf); goto hub_handle_command_cleanup; } token = strsep(&work_buf, " "); if (token == NULL) { warn(_("Invalid $MyINFO message: Missing nick parameter, ignoring\n")); free(conv_buf); goto hub_handle_command_cleanup; } ui = (DCUserInfo*) hmap_get(hub_users, token); if (ui == NULL) { /* * if the full buf has not been converted from hub to local charset, * we should try to convert nick only */ /* char *conv_nick = hub_to_main_string(token); if ((ui = hmap_get(hub_users, conv_nick)) == NULL) { */ ui = user_info_new(token); ui->info_quered = true; hmap_put(hub_users, ui->nick, ui); /* } free(conv_nick); */ } token = strsep(&work_buf, "$"); if (token == NULL) { warn(_("Invalid $MyINFO message: Missing description parameter, ignoring\n")); free(conv_buf); goto hub_handle_command_cleanup; } free(ui->description); ui->description = xstrdup(token); token = strsep(&work_buf, "$"); if (token == NULL) { warn(_("Invalid $MyINFO message: Missing description separator, ignoring\n")); free(conv_buf); goto hub_handle_command_cleanup; } token = strsep(&work_buf, "$"); if (token == NULL) { warn(_("Invalid $MyINFO message: Missing connection speed, ignoring\n")); free(conv_buf); goto hub_handle_command_cleanup; } len = strlen(token); free(ui->speed); if (len == 0) { ui->speed = xstrdup(""); ui->level = 0; /* XXX: or 1? acceptable level? */ } else { ui->speed = xstrndup(token, len-1); ui->level = token[len-1]; } token = strsep(&work_buf, "$"); if (token == NULL) { warn(_("Invalid $MyINFO message: Missing e-mail address, ignoring\n")); free(conv_buf); goto hub_handle_command_cleanup; } free(ui->email); ui->email = xstrdup(token); token = strsep(&work_buf, "$"); if (token == NULL) { warn(_("Invalid $MyINFO message: Missing share size, ignoring\n")); free(conv_buf); goto hub_handle_command_cleanup; } if (!parse_uint64(token, &ui->share_size)) { warn(_("Invalid $MyINFO message: Invalid share size, ignoring\n")); free(conv_buf); goto hub_handle_command_cleanup; } if (ui->active_state == DC_ACTIVE_RECEIVED_PASSIVE || ui->active_state == DC_ACTIVE_KNOWN_ACTIVE) ui->active_state = DC_ACTIVE_UNKNOWN; /* XXX: Now that user's active_state may have changed, try queue again? */ free(conv_buf); } else if (strcmp(buf, "$HubIsFull") == 0) { warn(_("Hub is full.\n")); /* DC++ does not disconnect immediately. So I guess we won't either. */ /* Maybe we should be expecting an "hub follow" message? */ /* hub_disconnect(); */ } else if (len >= 3 && (buf[0] == '<' || strncmp(buf, " * ", 3) == 0)) { char *head; char *tail; char *msg; bool first = true; /* int scrwidth; size_t firstlen; size_t otherlen; screen_get_size(NULL, &scrwidth); firstlen = scrwidth - strlen(_("Public:")); otherlen = scrwidth - strlen(_(" | ")); */ msg = prepare_chat_string_for_display(buf); for (head = msg; (tail = strchr(head, '\n')) != NULL; head = tail+1) { /*PtrV *wrapped;*/ if (tail[-1] == '\r') /* end > buf here, buf[0] == '<' or ' ' */ tail[-1] = '\0'; else tail[0] = '\0'; /*wrapped = wordwrap(quotearg(buf), first ? firstlen : otherlen, otherlen); for (c = 0; c < wrapped->cur; c++) flag_putf(DC_DF_PUBLIC_CHAT, first ? _("Public: %s\n") : _(" | %s\n"), ); ptrv_foreach(wrapped, free); ptrv_free(wrapped);*/ flag_putf(DC_DF_PUBLIC_CHAT, first ? _("Public: %s\n") : _(" | %s\n"), quotearg(head)); first = false; } flag_putf(DC_DF_PUBLIC_CHAT, first ? _("Public: %s\n") : _(" | %s\n"), quotearg(head)); free(msg); } else if (len >= 5 && strncmp(buf, "$To: ", 5) == 0) { char *msg; char *tail; char *frm; char *head; bool first = true; msg = strchr(buf+5, '$'); if (msg == NULL) { warn(_("Invalid $To message: Missing text separator, ignoring\n")); goto hub_handle_command_cleanup; } *msg = '\0'; msg++; /* FIXME: WTF is this? Remove multiple "From: "? Why!? */ frm = buf+5; while ((tail = strstr(msg, "From: ")) != NULL && tail < msg) frm = tail+6; msg = prepare_chat_string_for_display(msg); frm = prepare_chat_string_for_display(frm); for (head = msg; (tail = strchr(head, '\n')) != NULL; head = tail+1) { if (tail[-1] == '\r') /* tail > buf here because head[0] == '<' or ' ' */ tail[-1] = '\0'; else tail[0] = '\0'; if (first) { screen_putf(_("Private: [%s] %s\n"), quotearg_n(0, frm), quotearg_n(1, head)); first = false; } else { screen_putf(_(" | %s\n"), quotearg(head)); } } if (first) { screen_putf(_("Private: [%s] %s\n"), quotearg_n(0, frm), quotearg_n(1, head)); } else { screen_putf(_(" | %s\n"), quotearg(head)); } free(msg); free(frm); } else if (len >= 13 && strncmp(buf, "$ConnectToMe ", 13) == 0) { struct sockaddr_in addr; buf += 13; if (strsep(&buf, " ") == NULL) { warn(_("Invalid $ConnectToMe message: Missing or invalid nick\n")); goto hub_handle_command_cleanup; } if (!parse_ip_and_port(buf, &addr, 0)) { warn(_("Invalid $ConnectToMe message: Invalid address specification.\n")); goto hub_handle_command_cleanup; } flag_putf(DC_DF_CONNECTIONS, _("Connecting to user on %s\n"), sockaddr_in_str(&addr)); user_connection_new(&addr, -1); } else if (len >= 16 && strncmp(buf, "$RevConnectToMe ", 16) == 0) { char *nick; char *local_nick; DCUserInfo *ui; nick = strtok(buf+16, " "); if (nick == NULL) { warn(_("Invalid $RevConnectToMe message: Missing nick parameter\n")); goto hub_handle_command_cleanup; } if (strcmp(nick, hub_my_nick) == 0) { warn(_("Invalid $RevConnectToMe message: Remote nick is our nick\n")); goto hub_handle_command_cleanup; } local_nick = hub_to_main_string(nick); ui = (DCUserInfo*) hmap_get(hub_users, local_nick); if (ui == NULL) { warn(_("Invalid $RevConnectToMe message: Unknown user %s, ignoring\n"), quotearg(local_nick)); free(local_nick); goto hub_handle_command_cleanup; } free(local_nick); if (ui->conn_count >= DC_USER_MAX_CONN) { warn(_("No more connections to user %s allowed.\n"), quotearg(ui->nick)); goto hub_handle_command_cleanup; } if (!is_active) { if (ui->active_state == DC_ACTIVE_SENT_PASSIVE) { warn(_("User %s is also passive. Cannot establish connection.\n"), quotearg(ui->nick)); /* We could set this to DC_ACTIVE_UNKNOWN too. This would mean * we would keep sending RevConnectToMe next time the download * queue is modified or some timer expired and told us to retry * download. The remote would then send back RevConnectToMe * and this would happen again. This way we would try again - * maybe remote has become active since last time we checked? * But no - DC++ only replies with RevConnectToMe to our first * RevConnectToMe. After that it ignores them all. */ ui->active_state = DC_ACTIVE_RECEIVED_PASSIVE; if (hmap_remove(pending_userinfo, ui->nick) != NULL) ui->refcount--; goto hub_handle_command_cleanup; } if (ui->active_state != DC_ACTIVE_RECEIVED_PASSIVE) { /* Inform remote that we are also passive. */ if (!hub_putf("$RevConnectToMe %s %s|", hub_my_nick, nick)) goto hub_handle_command_cleanup; } } ui->active_state = DC_ACTIVE_RECEIVED_PASSIVE; if (!hub_connect_user(ui)) goto hub_handle_command_cleanup; } else if ( (len >= 10 && strncmp(buf, "$NickList ", 10) == 0) || (len >= 8 && strncmp(buf, "$OpList ", 8) == 0) ) { char *nick; char *end; int oplist; char *conv_nick; if ( strncmp(buf, "$NickList ", 10) == 0) { nick = buf + 10; oplist = 0; } else { nick = buf + 8; oplist = 1; } for (; (end = strstr(nick, "$$")) != NULL; nick = end+2) { DCUserInfo *ui; *end = '\0'; conv_nick = hub_to_main_string(nick); ui = (DCUserInfo*) hmap_get(hub_users, conv_nick); if (ui == NULL) { ui = user_info_new(conv_nick); hmap_put(hub_users, ui->nick, ui); } free(conv_nick); if (!ui->info_quered && (hub_extensions & HUB_EXT_NOGETINFO) == 0) { if (!hub_putf("$GetINFO %s %s|", nick, hub_my_nick)) { goto hub_handle_command_cleanup; } ui->info_quered = true; } if (oplist) ui->is_operator = true; } } else if (len >= 6 && strncmp(buf, "$Quit ", 6) == 0) { DCUserInfo *ui; char *conv_nick = hub_to_main_string(buf+6); // I don't want these messages. //flag_putf(DC_DF_JOIN_PART, "User %s quits.\n", quotearg(conv_nick)); ui = (DCUserInfo*) hmap_remove(hub_users, conv_nick); if (ui == NULL) { /* Some hubs print quit messages for users that never joined, * so print this as debug only. */ flag_putf(DC_DF_DEBUG, _("Invalid $Quit message: Unknown user %s.\n"), quotearg(conv_nick)); } else user_info_free(ui); free(conv_nick); } else if (len >= 8 && strncmp(buf, "$Search ", 8) == 0) { char *source; int parse_result = 0; DCSearchSelection sel; sel.patterns = NULL; buf += 8; source = strsep(&buf, " "); if (source == NULL) { warn(_("Invalid $Search message: Missing source specification.\n")); goto hub_handle_command_cleanup; } /* charset handling is in parse_search_selection */ parse_result = parse_search_selection(buf, &sel); if (parse_result != 1) { if (sel.patterns != NULL) { int i = 0; for (i = 0; i < sel.patterncount; i++) { search_string_free(sel.patterns+i); } free(sel.patterns); } if (parse_result == 0) warn(_("Invalid $Search message: %s: Invalid search specification.\n"), buf); goto hub_handle_command_cleanup; } if (strncmp(source, "Hub:", 4) == 0) { DCUserInfo *ui; char *conv_nick = hub_to_main_string(source+4); ui = (DCUserInfo*) hmap_get(hub_users, conv_nick); if (ui == NULL) { warn(_("Invalid $Search message: Unknown user %s.\n"), quotearg(conv_nick)); if (sel.patterns != NULL) { int i = 0; for (i = 0; i < sel.patterncount; i++) { search_string_free(sel.patterns+i); } free(sel.patterns); } free(conv_nick); goto hub_handle_command_cleanup; } free(conv_nick); if (strcmp(ui->nick, my_nick) == 0) { if (sel.patterns != NULL) { int i = 0; for (i = 0; i < sel.patterncount; i++) { search_string_free(sel.patterns+i); } free(sel.patterns); } goto hub_handle_command_cleanup; } perform_inbound_search(&sel, ui, NULL); if (sel.patterns != NULL) { int i = 0; for (i = 0; i < sel.patterncount; i++) { search_string_free(sel.patterns+i); } free(sel.patterns); } } else { struct sockaddr_in addr; if (!parse_ip_and_port(source, &addr, DC_CLIENT_UDP_PORT)) { warn(_("Invalid $Search message: Invalid address specification.\n")); if (sel.patterns != NULL) { int i = 0; for (i = 0; i < sel.patterncount; i++) { search_string_free(sel.patterns+i); } free(sel.patterns); } goto hub_handle_command_cleanup; } if (local_addr.sin_addr.s_addr == addr.sin_addr.s_addr && listen_port == ntohs(addr.sin_port)) { if (sel.patterns != NULL) { int i = 0; for (i = 0; i < sel.patterncount; i++) { search_string_free(sel.patterns+i); } free(sel.patterns); } goto hub_handle_command_cleanup; } perform_inbound_search(&sel, NULL, &addr); if (sel.patterns != NULL) { int i = 0; for (i = 0; i < sel.patterncount; i++) { search_string_free(sel.patterns+i); } free(sel.patterns); } } } else if (len >= 4 && strncmp(buf, "$SR ", 4) == 0) { handle_search_result(buf, len); } else if (len == 0) { /* Ignore empty commands. */ } hub_handle_command_cleanup: free(hub_my_nick); }
FLAC__bool parse_option(int option_index, const char *option_argument, CommandLineOptions *options) { const char *opt = long_options_[option_index].name; Operation *op; Argument *arg; FLAC__bool ok = true; if(0 == strcmp(opt, "preserve-modtime")) { options->preserve_modtime = true; } else if(0 == strcmp(opt, "with-filename")) { options->prefix_with_filename = true; } else if(0 == strcmp(opt, "no-filename")) { options->prefix_with_filename = false; } else if(0 == strcmp(opt, "no-utf8-convert")) { options->utf8_convert = false; } else if(0 == strcmp(opt, "dont-use-padding")) { options->use_padding = false; } else if(0 == strcmp(opt, "no-cued-seekpoints")) { options->cued_seekpoints = false; } else if(0 == strcmp(opt, "show-md5sum")) { (void) append_shorthand_operation(options, OP__SHOW_MD5SUM); } else if(0 == strcmp(opt, "show-min-blocksize")) { (void) append_shorthand_operation(options, OP__SHOW_MIN_BLOCKSIZE); } else if(0 == strcmp(opt, "show-max-blocksize")) { (void) append_shorthand_operation(options, OP__SHOW_MAX_BLOCKSIZE); } else if(0 == strcmp(opt, "show-min-framesize")) { (void) append_shorthand_operation(options, OP__SHOW_MIN_FRAMESIZE); } else if(0 == strcmp(opt, "show-max-framesize")) { (void) append_shorthand_operation(options, OP__SHOW_MAX_FRAMESIZE); } else if(0 == strcmp(opt, "show-sample-rate")) { (void) append_shorthand_operation(options, OP__SHOW_SAMPLE_RATE); } else if(0 == strcmp(opt, "show-channels")) { (void) append_shorthand_operation(options, OP__SHOW_CHANNELS); } else if(0 == strcmp(opt, "show-bps")) { (void) append_shorthand_operation(options, OP__SHOW_BPS); } else if(0 == strcmp(opt, "show-total-samples")) { (void) append_shorthand_operation(options, OP__SHOW_TOTAL_SAMPLES); } else if(0 == strcmp(opt, "set-md5sum")) { op = append_shorthand_operation(options, OP__SET_MD5SUM); FLAC__ASSERT(0 != option_argument); if(!parse_md5(option_argument, op->argument.streaminfo_md5.value)) { flac_fprintf(stderr, "ERROR (--%s): bad MD5 sum\n", opt); ok = false; } else undocumented_warning(opt); } else if(0 == strcmp(opt, "set-min-blocksize")) { op = append_shorthand_operation(options, OP__SET_MIN_BLOCKSIZE); if(!parse_uint32(option_argument, &(op->argument.streaminfo_uint32.value)) || op->argument.streaminfo_uint32.value < FLAC__MIN_BLOCK_SIZE || op->argument.streaminfo_uint32.value > FLAC__MAX_BLOCK_SIZE) { flac_fprintf(stderr, "ERROR (--%s): value must be >= %u and <= %u\n", opt, FLAC__MIN_BLOCK_SIZE, FLAC__MAX_BLOCK_SIZE); ok = false; } else undocumented_warning(opt); } else if(0 == strcmp(opt, "set-max-blocksize")) { op = append_shorthand_operation(options, OP__SET_MAX_BLOCKSIZE); if(!parse_uint32(option_argument, &(op->argument.streaminfo_uint32.value)) || op->argument.streaminfo_uint32.value < FLAC__MIN_BLOCK_SIZE || op->argument.streaminfo_uint32.value > FLAC__MAX_BLOCK_SIZE) { flac_fprintf(stderr, "ERROR (--%s): value must be >= %u and <= %u\n", opt, FLAC__MIN_BLOCK_SIZE, FLAC__MAX_BLOCK_SIZE); ok = false; } else undocumented_warning(opt); } else if(0 == strcmp(opt, "set-min-framesize")) { op = append_shorthand_operation(options, OP__SET_MIN_FRAMESIZE); if(!parse_uint32(option_argument, &(op->argument.streaminfo_uint32.value)) || op->argument.streaminfo_uint32.value >= (1u<<FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN)) { flac_fprintf(stderr, "ERROR (--%s): value must be a %u-bit unsigned integer\n", opt, FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN); ok = false; } else undocumented_warning(opt); } else if(0 == strcmp(opt, "set-max-framesize")) { op = append_shorthand_operation(options, OP__SET_MAX_FRAMESIZE); if(!parse_uint32(option_argument, &(op->argument.streaminfo_uint32.value)) || op->argument.streaminfo_uint32.value >= (1u<<FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN)) { flac_fprintf(stderr, "ERROR (--%s): value must be a %u-bit unsigned integer\n", opt, FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN); ok = false; } else undocumented_warning(opt); } else if(0 == strcmp(opt, "set-sample-rate")) { op = append_shorthand_operation(options, OP__SET_SAMPLE_RATE); if(!parse_uint32(option_argument, &(op->argument.streaminfo_uint32.value)) || !FLAC__format_sample_rate_is_valid(op->argument.streaminfo_uint32.value)) { flac_fprintf(stderr, "ERROR (--%s): invalid sample rate\n", opt); ok = false; } else undocumented_warning(opt); } else if(0 == strcmp(opt, "set-channels")) { op = append_shorthand_operation(options, OP__SET_CHANNELS); if(!parse_uint32(option_argument, &(op->argument.streaminfo_uint32.value)) || op->argument.streaminfo_uint32.value > FLAC__MAX_CHANNELS) { flac_fprintf(stderr, "ERROR (--%s): value must be > 0 and <= %u\n", opt, FLAC__MAX_CHANNELS); ok = false; } else undocumented_warning(opt); } else if(0 == strcmp(opt, "set-bps")) { op = append_shorthand_operation(options, OP__SET_BPS); if(!parse_uint32(option_argument, &(op->argument.streaminfo_uint32.value)) || op->argument.streaminfo_uint32.value < FLAC__MIN_BITS_PER_SAMPLE || op->argument.streaminfo_uint32.value > FLAC__MAX_BITS_PER_SAMPLE) { flac_fprintf(stderr, "ERROR (--%s): value must be >= %u and <= %u\n", opt, FLAC__MIN_BITS_PER_SAMPLE, FLAC__MAX_BITS_PER_SAMPLE); ok = false; } else undocumented_warning(opt); } else if(0 == strcmp(opt, "set-total-samples")) { op = append_shorthand_operation(options, OP__SET_TOTAL_SAMPLES); if(!parse_uint64(option_argument, &(op->argument.streaminfo_uint64.value)) || op->argument.streaminfo_uint64.value >= (((FLAC__uint64)1)<<FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN)) { flac_fprintf(stderr, "ERROR (--%s): value must be a %u-bit unsigned integer\n", opt, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN); ok = false; } else undocumented_warning(opt); } else if(0 == strcmp(opt, "show-vendor-tag")) { (void) append_shorthand_operation(options, OP__SHOW_VC_VENDOR); } else if(0 == strcmp(opt, "show-tag")) { const char *violation; op = append_shorthand_operation(options, OP__SHOW_VC_FIELD); FLAC__ASSERT(0 != option_argument); if(!parse_vorbis_comment_field_name(option_argument, &(op->argument.vc_field_name.value), &violation)) { FLAC__ASSERT(0 != violation); flac_fprintf(stderr, "ERROR (--%s): malformed vorbis comment field name \"%s\",\n %s\n", opt, option_argument, violation); ok = false; } } else if(0 == strcmp(opt, "remove-all-tags")) { (void) append_shorthand_operation(options, OP__REMOVE_VC_ALL); } else if(0 == strcmp(opt, "remove-tag")) { const char *violation; op = append_shorthand_operation(options, OP__REMOVE_VC_FIELD); FLAC__ASSERT(0 != option_argument); if(!parse_vorbis_comment_field_name(option_argument, &(op->argument.vc_field_name.value), &violation)) { FLAC__ASSERT(0 != violation); flac_fprintf(stderr, "ERROR (--%s): malformed vorbis comment field name \"%s\",\n %s\n", opt, option_argument, violation); ok = false; } } else if(0 == strcmp(opt, "remove-first-tag")) { const char *violation; op = append_shorthand_operation(options, OP__REMOVE_VC_FIRSTFIELD); FLAC__ASSERT(0 != option_argument); if(!parse_vorbis_comment_field_name(option_argument, &(op->argument.vc_field_name.value), &violation)) { FLAC__ASSERT(0 != violation); flac_fprintf(stderr, "ERROR (--%s): malformed vorbis comment field name \"%s\",\n %s\n", opt, option_argument, violation); ok = false; } } else if(0 == strcmp(opt, "set-tag")) { const char *violation; op = append_shorthand_operation(options, OP__SET_VC_FIELD); FLAC__ASSERT(0 != option_argument); op->argument.vc_field.field_value_from_file = false; if(!parse_vorbis_comment_field(option_argument, &(op->argument.vc_field.field), &(op->argument.vc_field.field_name), &(op->argument.vc_field.field_value), &(op->argument.vc_field.field_value_length), &violation)) { FLAC__ASSERT(0 != violation); flac_fprintf(stderr, "ERROR (--%s): malformed vorbis comment field \"%s\",\n %s\n", opt, option_argument, violation); ok = false; } } else if(0 == strcmp(opt, "set-tag-from-file")) { const char *violation; op = append_shorthand_operation(options, OP__SET_VC_FIELD); FLAC__ASSERT(0 != option_argument); op->argument.vc_field.field_value_from_file = true; if(!parse_vorbis_comment_field(option_argument, &(op->argument.vc_field.field), &(op->argument.vc_field.field_name), &(op->argument.vc_field.field_value), &(op->argument.vc_field.field_value_length), &violation)) { FLAC__ASSERT(0 != violation); flac_fprintf(stderr, "ERROR (--%s): malformed vorbis comment field \"%s\",\n %s\n", opt, option_argument, violation); ok = false; } } else if(0 == strcmp(opt, "import-tags-from")) { op = append_shorthand_operation(options, OP__IMPORT_VC_FROM); FLAC__ASSERT(0 != option_argument); if(!parse_string(option_argument, &(op->argument.filename.value))) { flac_fprintf(stderr, "ERROR (--%s): missing filename\n", opt); ok = false; } } else if(0 == strcmp(opt, "export-tags-to")) { op = append_shorthand_operation(options, OP__EXPORT_VC_TO); FLAC__ASSERT(0 != option_argument); if(!parse_string(option_argument, &(op->argument.filename.value))) { flac_fprintf(stderr, "ERROR (--%s): missing filename\n", opt); ok = false; } } else if(0 == strcmp(opt, "import-cuesheet-from")) { if(0 != find_shorthand_operation(options, OP__IMPORT_CUESHEET_FROM)) { flac_fprintf(stderr, "ERROR (--%s): may be specified only once\n", opt); ok = false; } op = append_shorthand_operation(options, OP__IMPORT_CUESHEET_FROM); FLAC__ASSERT(0 != option_argument); if(!parse_string(option_argument, &(op->argument.import_cuesheet_from.filename))) { flac_fprintf(stderr, "ERROR (--%s): missing filename\n", opt); ok = false; } } else if(0 == strcmp(opt, "export-cuesheet-to")) { op = append_shorthand_operation(options, OP__EXPORT_CUESHEET_TO); FLAC__ASSERT(0 != option_argument); if(!parse_string(option_argument, &(op->argument.filename.value))) { flac_fprintf(stderr, "ERROR (--%s): missing filename\n", opt); ok = false; } } else if(0 == strcmp(opt, "import-picture-from")) { op = append_shorthand_operation(options, OP__IMPORT_PICTURE_FROM); FLAC__ASSERT(0 != option_argument); if(!parse_string(option_argument, &(op->argument.specification.value))) { flac_fprintf(stderr, "ERROR (--%s): missing specification\n", opt); ok = false; } } else if(0 == strcmp(opt, "export-picture-to")) { arg = find_argument(options, ARG__BLOCK_NUMBER); op = append_shorthand_operation(options, OP__EXPORT_PICTURE_TO); FLAC__ASSERT(0 != option_argument); if(!parse_string(option_argument, &(op->argument.export_picture_to.filename))) { flac_fprintf(stderr, "ERROR (--%s): missing filename\n", opt); ok = false; } op->argument.export_picture_to.block_number_link = arg? &(arg->value.block_number) : 0; } else if(0 == strcmp(opt, "add-seekpoint")) { const char *violation; char *spec; FLAC__ASSERT(0 != option_argument); if(!parse_add_seekpoint(option_argument, &spec, &violation)) { FLAC__ASSERT(0 != violation); flac_fprintf(stderr, "ERROR (--%s): malformed seekpoint specification \"%s\",\n %s\n", opt, option_argument, violation); ok = false; } else { op = find_shorthand_operation(options, OP__ADD_SEEKPOINT); if(0 == op) op = append_shorthand_operation(options, OP__ADD_SEEKPOINT); local_strcat(&(op->argument.add_seekpoint.specification), spec); local_strcat(&(op->argument.add_seekpoint.specification), ";"); free(spec); } } else if(0 == strcmp(opt, "add-replay-gain")) { (void) append_shorthand_operation(options, OP__ADD_REPLAY_GAIN); } else if(0 == strcmp(opt, "remove-replay-gain")) { const FLAC__byte * const tags[5] = { GRABBAG__REPLAYGAIN_TAG_REFERENCE_LOUDNESS, GRABBAG__REPLAYGAIN_TAG_TITLE_GAIN, GRABBAG__REPLAYGAIN_TAG_TITLE_PEAK, GRABBAG__REPLAYGAIN_TAG_ALBUM_GAIN, GRABBAG__REPLAYGAIN_TAG_ALBUM_PEAK }; size_t i; for(i = 0; i < sizeof(tags)/sizeof(tags[0]); i++) { op = append_shorthand_operation(options, OP__REMOVE_VC_FIELD); op->argument.vc_field_name.value = local_strdup((const char *)tags[i]); } } else if(0 == strcmp(opt, "add-padding")) { op = append_shorthand_operation(options, OP__ADD_PADDING); FLAC__ASSERT(0 != option_argument); if(!parse_add_padding(option_argument, &(op->argument.add_padding.length))) { flac_fprintf(stderr, "ERROR (--%s): illegal length \"%s\", length must be >= 0 and < 2^%u\n", opt, option_argument, FLAC__STREAM_METADATA_LENGTH_LEN); ok = false; } } else if(0 == strcmp(opt, "help")) { options->show_long_help = true; } else if(0 == strcmp(opt, "version")) { options->show_version = true; } else if(0 == strcmp(opt, "list")) { (void) append_major_operation(options, OP__LIST); } else if(0 == strcmp(opt, "append")) { (void) append_major_operation(options, OP__APPEND); } else if(0 == strcmp(opt, "remove")) { (void) append_major_operation(options, OP__REMOVE); } else if(0 == strcmp(opt, "remove-all")) { (void) append_major_operation(options, OP__REMOVE_ALL); } else if(0 == strcmp(opt, "merge-padding")) { (void) append_major_operation(options, OP__MERGE_PADDING); } else if(0 == strcmp(opt, "sort-padding")) { (void) append_major_operation(options, OP__SORT_PADDING); } else if(0 == strcmp(opt, "block-number")) { arg = append_argument(options, ARG__BLOCK_NUMBER); FLAC__ASSERT(0 != option_argument); if(!parse_block_number(option_argument, &(arg->value.block_number))) { flac_fprintf(stderr, "ERROR: malformed block number specification \"%s\"\n", option_argument); ok = false; } } else if(0 == strcmp(opt, "block-type")) { arg = append_argument(options, ARG__BLOCK_TYPE); FLAC__ASSERT(0 != option_argument); if(!parse_block_type(option_argument, &(arg->value.block_type))) { flac_fprintf(stderr, "ERROR (--%s): malformed block type specification \"%s\"\n", opt, option_argument); ok = false; } options->args.checks.has_block_type = true; } else if(0 == strcmp(opt, "except-block-type")) { arg = append_argument(options, ARG__EXCEPT_BLOCK_TYPE); FLAC__ASSERT(0 != option_argument); if(!parse_block_type(option_argument, &(arg->value.block_type))) { flac_fprintf(stderr, "ERROR (--%s): malformed block type specification \"%s\"\n", opt, option_argument); ok = false; } options->args.checks.has_except_block_type = true; } else if(0 == strcmp(opt, "data-format")) { arg = append_argument(options, ARG__DATA_FORMAT); FLAC__ASSERT(0 != option_argument); if(!parse_data_format(option_argument, &(arg->value.data_format))) { flac_fprintf(stderr, "ERROR (--%s): illegal data format \"%s\"\n", opt, option_argument); ok = false; } } else if(0 == strcmp(opt, "application-data-format")) { FLAC__ASSERT(0 != option_argument); if(!parse_application_data_format(option_argument, &(options->application_data_format_is_hexdump))) { flac_fprintf(stderr, "ERROR (--%s): illegal application data format \"%s\"\n", opt, option_argument); ok = false; } } else if(0 == strcmp(opt, "from-file")) { arg = append_argument(options, ARG__FROM_FILE); FLAC__ASSERT(0 != option_argument); arg->value.from_file.file_name = local_strdup(option_argument); } else { FLAC__ASSERT(0); } return ok; }
static void magnet_handle_key(struct magnet_resource *res, const char *name, const char *value) { char *to_free = NULL; g_return_if_fail(res); g_return_if_fail(name); g_return_if_fail(value); if (!utf8_is_valid_string(value)) { const char *encoding; char *result; g_message("MAGNET URI key \"%s\" is not UTF-8 encoded", name); if (MAGNET_KEY_DISPLAY_NAME != magnet_key_get(name)) return; result = unknown_to_utf8(value, &encoding); if (result != value) { to_free = result; } value = result; g_message("assuming MAGNET URI key \"%s\" is %s encoded", name, encoding); } switch (magnet_key_get(name)) { case MAGNET_KEY_DISPLAY_NAME: if (!res->display_name) { magnet_set_display_name(res, value); } break; case MAGNET_KEY_ALTERNATE_SOURCE: case MAGNET_KEY_EXACT_SOURCE: { struct magnet_source *ms; const char *error; ms = magnet_parse_exact_source(value, &error); if (ms) { if (!res->sha1 && ms->sha1) { res->sha1 = atom_sha1_get(ms->sha1); } if (!ms->sha1 || sha1_eq(res->sha1, ms->sha1)) { res->sources = g_slist_prepend(res->sources, ms); } else { magnet_source_free(&ms); } } else { g_message("could not parse source \"%s\" in MAGNET URI: %s", value, NULL_STRING(error)); } } break; case MAGNET_KEY_EXACT_TOPIC: if (!magnet_set_exact_topic(res, value)) { g_message("MAGNET URI contained unsupported exact topic \"%s\"", value); } break; case MAGNET_KEY_KEYWORD_TOPIC: magnet_add_search(res, value); break; case MAGNET_KEY_EXACT_LENGTH: { int error; uint64 u; u = parse_uint64(value, NULL, 10, &error); if (!error) { magnet_set_filesize(res, u); } } break; case MAGNET_KEY_PARQ_ID: magnet_set_parq_id(res, value); break; case MAGNET_KEY_VENDOR: magnet_set_vendor(res, value); break; case MAGNET_KEY_GUID: magnet_set_guid(res, value); break; case MAGNET_KEY_DHT: { int error; uint8 u; u = parse_uint8(value, NULL, 10, &error); if (!error) { magnet_set_dht(res, u); } } break; case MAGNET_KEY_NONE: g_message("unhandled parameter in MAGNET URI: \"%s\"", name); break; case NUM_MAGNET_KEYS: g_assert_not_reached(); } G_FREE_NULL(to_free); }