int hvm_save(struct domain *d, hvm_domain_context_t *h) { char *c; struct hvm_save_header hdr; struct hvm_save_end end; hvm_save_handler handler; uint16_t i; hdr.magic = HVM_FILE_MAGIC; hdr.version = HVM_FILE_VERSION; /* Save xen changeset */ c = strrchr(xen_changeset(), ':'); if ( c ) hdr.changeset = simple_strtoll(c, NULL, 16); else hdr.changeset = -1ULL; /* Unknown */ arch_hvm_save(d, &hdr); if ( hvm_save_entry(HEADER, 0, h, &hdr) != 0 ) { gdprintk(XENLOG_ERR, "HVM save: failed to write header\n"); return -EFAULT; } /* Save all available kinds of state */ for ( i = 0; i <= HVM_SAVE_CODE_MAX; i++ ) { handler = hvm_sr_handlers[i].save; if ( handler != NULL ) { gdprintk(XENLOG_INFO, "HVM save: %s\n", hvm_sr_handlers[i].name); if ( handler(d, h) != 0 ) { gdprintk(XENLOG_ERR, "HVM save: failed to save type %"PRIu16"\n", i); return -EFAULT; } } } /* Save an end-of-file marker */ if ( hvm_save_entry(END, 0, h, &end) != 0 ) { /* Run out of data */ gdprintk(XENLOG_ERR, "HVM save: no room for end marker.\n"); return -EFAULT; } /* Save macros should not have let us overrun */ ASSERT(h->cur <= h->size); return 0; }
void __init cmdline_parse(const char *cmdline) { char opt[100], *optval, *optkey, *q; const char *p = cmdline; struct kernel_param *param; int bool_assert; if ( cmdline == NULL ) return; safe_strcpy(saved_cmdline, cmdline); for ( ; ; ) { /* Skip whitespace. */ while ( *p == ' ' ) p++; if ( *p == '\0' ) break; /* Grab the next whitespace-delimited option. */ q = optkey = opt; while ( (*p != ' ') && (*p != '\0') ) { if ( (q-opt) < (sizeof(opt)-1) ) /* avoid overflow */ *q++ = *p; p++; } *q = '\0'; /* Search for value part of a key=value option. */ optval = strchr(opt, '='); if ( optval != NULL ) { *optval++ = '\0'; /* nul-terminate the option value */ q = strpbrk(opt, "([{<"); } else { optval = q; /* default option value is empty string */ q = NULL; } /* Boolean parameters can be inverted with 'no-' prefix. */ bool_assert = !!strncmp("no-", optkey, 3); if ( !bool_assert ) optkey += 3; for ( param = &__setup_start; param < &__setup_end; param++ ) { if ( strcmp(param->name, optkey) ) { if ( param->type == OPT_CUSTOM && q && strlen(param->name) == q + 1 - opt && !strncmp(param->name, opt, q + 1 - opt) ) { optval[-1] = '='; ((void (*)(const char *))param->var)(q); optval[-1] = '\0'; } continue; } switch ( param->type ) { case OPT_STR: strlcpy(param->var, optval, param->len); break; case OPT_UINT: assign_integer_param( param, simple_strtoll(optval, NULL, 0)); break; case OPT_BOOL: case OPT_INVBOOL: if ( !parse_bool(optval) ) bool_assert = !bool_assert; assign_integer_param( param, (param->type == OPT_BOOL) == bool_assert); break; case OPT_SIZE: assign_integer_param( param, parse_size_and_unit(optval, NULL)); break; case OPT_CUSTOM: if ( !bool_assert ) { if ( *optval ) break; safe_strcpy(opt, "no"); optval = opt; } ((void (*)(const char *))param->var)(optval); break; default: BUG(); break; } } } }
/** * vsscanf - Unformat a buffer into a list of arguments * @buf: input buffer * @fmt: format of buffer * @args: arguments */ int vsscanf(const char * buf, const char * fmt, va_list args) { const char *str = buf; char *next; int num = 0; int qualifier; int base; int field_width = -1; int is_sign = 0; while(*fmt && *str) { /* skip any white space in format */ /* white space in format matchs any amount of * white space, including none, in the input. */ if (isspace(*fmt)) { while (isspace(*fmt)) ++fmt; while (isspace(*str)) ++str; } /* anything that is not a conversion must match exactly */ if (*fmt != '%' && *fmt) { if (*fmt++ != *str++) break; continue; } if (!*fmt) break; ++fmt; /* skip this conversion. * advance both strings to next white space */ if (*fmt == '*') { while (!isspace(*fmt) && *fmt) fmt++; while (!isspace(*str) && *str) str++; continue; } /* get field width */ if (isdigit(*fmt)) field_width = skip_atoi(&fmt); /* get conversion qualifier */ qualifier = -1; if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'Z') { qualifier = *fmt; fmt++; } base = 10; is_sign = 0; if (!*fmt || !*str) break; switch(*fmt++) { case 'c': { char *s = (char *) va_arg(args,char*); if (field_width == -1) field_width = 1; do { *s++ = *str++; } while(field_width-- > 0 && *str); num++; } continue; case 's': { char *s = (char *) va_arg(args, char *); if(field_width == -1) field_width = INT_MAX; /* first, skip leading white space in buffer */ while (isspace(*str)) str++; /* now copy until next white space */ while (*str && !isspace(*str) && field_width--) { *s++ = *str++; } *s = '\0'; num++; } continue; case 'n': /* return number of characters read so far */ { int *i = (int *)va_arg(args,int*); *i = str - buf; } continue; case 'o': base = 8; break; case 'x': case 'X': base = 16; break; case 'd': case 'i': is_sign = 1; case 'u': break; case '%': /* looking for '%' in str */ if (*str++ != '%') return num; continue; default: /* invalid format; stop here */ return num; } /* have some sort of integer conversion. * first, skip white space in buffer. */ while (isspace(*str)) str++; if (!*str || !isdigit(*str)) break; switch(qualifier) { case 'h': if (is_sign) { short *s = (short *) va_arg(args,short *); *s = (short) simple_strtol(str,&next,base); } else { unsigned short *s = (unsigned short *) va_arg(args, unsigned short *); *s = (unsigned short) simple_strtoul(str, &next, base); } break; case 'l': if (is_sign) { long *l = (long *) va_arg(args,long *); *l = simple_strtol(str,&next,base); } else { unsigned long *l = (unsigned long*) va_arg(args,unsigned long*); *l = simple_strtoul(str,&next,base); } break; case 'L': if (is_sign) { long long *l = (long long*) va_arg(args,long long *); *l = simple_strtoll(str,&next,base); } else {
static ssize_t env_proc_write(struct file *file, const char __user *buf, size_t size, loff_t *ppos) { char *buffer = NULL; int ret,i,v_index=0; buffer = (char *)kmalloc(size,GFP_KERNEL); if(buffer==NULL){ ret = -ENOMEM; printk("[env_proc_write]alloc buffer fail\n"); goto fail_malloc; } memset(buffer,0x00,size); if(copy_from_user(buffer,buf,size)){ ret = -EFAULT; goto end; } /*parse buffer into name and value*/ for(i=0;i<size;i++){ if(buffer[i] == '='){ v_index = i+1; buffer[i] = '\0'; buffer[size-1] = '\0'; break; } } if(i==size){ printk("write fail, buffer:%s\n",buffer); ret = -EFAULT; goto end; }else{ printk("[env_proc_write]name :%s,value:%s\n",buffer,buffer+v_index); } if(!strcmp(buffer,DATA_FREE_SIZE_TH_NAME)){ #ifdef LIMIT_SDCARD_SIZE struct kstatfs stat; long long data_free_size = 0; char *value = buffer+v_index; long long value_new = 0; int mum = 1; char value_buf[20] = {0}; struct file *fp=NULL; char tmp_buff[20]; for(i=0;i<strlen(value);i++){ if(value[i] == 'M' || value[i] == 'm'){ mum = 1024*1024; break; }else if(value[i] == 'K' || value[i] == 'k'){ mum = 1024; break; }else{ value_buf[i] = value[i]; } } value_new =(long long)simple_strtoll(value_buf,NULL,10)*mum; fp = filp_open("/data",O_RDONLY, 0777); if (IS_ERR(fp)) { printk("open data fail\n"); ret = -EFAULT; goto end; } vfs_statfs(&fp->f_path, &stat); data_free_size = stat.f_bfree * stat.f_bsize; filp_close(fp, NULL); if(value_new >= data_free_size){ printk("new value %llx more than data free size %llx, setting fail\n",value_new,data_free_size); ret = -EFAULT; goto end; } sprintf(tmp_buff,"%lld",value_new); ret = set_env(buffer,tmp_buff); #else printk("[env_proc_write]it don't support limit sdcard size\n"); ret = -EFAULT; goto end; #endif }else{ ret = set_env(buffer,buffer+v_index); } /**/ end: kfree(buffer); fail_malloc: if(ret) return ret; else return size; }
void __init video_init(void) { int node, depth; u32 address_cells, size_cells; struct lfb_prop lfbp; unsigned char *lfb; paddr_t hdlcd_start, hdlcd_size; paddr_t framebuffer_start, framebuffer_size; const struct fdt_property *prop; const u32 *cell; const char *mode_string; char _mode_string[16]; int bytes_per_pixel = 4; struct color_masks *c = NULL; struct modeline *videomode = NULL; int i; if ( find_compatible_node("arm,hdlcd", &node, &depth, &address_cells, &size_cells) <= 0 ) return; prop = fdt_get_property(device_tree_flattened, node, "reg", NULL); if ( !prop ) return; cell = (const u32 *)prop->data; device_tree_get_reg(&cell, address_cells, size_cells, &hdlcd_start, &hdlcd_size); prop = fdt_get_property(device_tree_flattened, node, "framebuffer", NULL); if ( !prop ) return; cell = (const u32 *)prop->data; device_tree_get_reg(&cell, address_cells, size_cells, &framebuffer_start, &framebuffer_size); if ( !hdlcd_start ) { printk(KERN_ERR "HDLCD address missing from device tree, disabling driver\n"); return; } if ( !hdlcd_start || !framebuffer_start ) { printk(KERN_ERR "HDLCD: framebuffer address missing from device tree, disabling driver\n"); return; } mode_string = fdt_getprop(device_tree_flattened, node, "mode", NULL); if ( !mode_string ) { get_color_masks("32", &c); memcpy(_mode_string, "1280x1024@60", strlen("1280x1024@60") + 1); bytes_per_pixel = 4; } else if ( strlen(mode_string) < strlen("800x600@60") || strlen(mode_string) > sizeof(_mode_string) - 1 ) { printk(KERN_ERR "HDLCD: invalid modeline=%s\n", mode_string); return; } else { char *s = strchr(mode_string, '-'); if ( !s ) { printk(KERN_INFO "HDLCD: bpp not found in modeline %s, assume 32 bpp\n", mode_string); get_color_masks("32", &c); memcpy(_mode_string, mode_string, strlen(mode_string) + 1); bytes_per_pixel = 4; } else { if ( strlen(s) < 6 ) { printk(KERN_ERR "HDLCD: invalid mode %s\n", mode_string); return; } s++; if ( get_color_masks(s, &c) < 0 ) { printk(KERN_WARNING "HDLCD: unsupported bpp %s\n", s); return; } bytes_per_pixel = simple_strtoll(s, NULL, 10) / 8; } i = s - mode_string - 1; memcpy(_mode_string, mode_string, i); memcpy(_mode_string + i, mode_string + i + 3, 4); } for ( i = 0; i < ARRAY_SIZE(videomodes); i++ ) { if ( !strcmp(_mode_string, videomodes[i].mode) ) { videomode = &videomodes[i]; break; } } if ( !videomode ) { printk(KERN_WARNING "HDLCD: unsupported videomode %s\n", _mode_string); return; } if ( framebuffer_size < bytes_per_pixel * videomode->xres * videomode->yres ) { printk(KERN_ERR "HDLCD: the framebuffer is too small, disabling the HDLCD driver\n"); return; } printk(KERN_INFO "Initializing HDLCD driver\n"); lfb = ioremap_wc(framebuffer_start, framebuffer_size); if ( !lfb ) { printk(KERN_ERR "Couldn't map the framebuffer\n"); return; } memset(lfb, 0x00, bytes_per_pixel * videomode->xres * videomode->yres); /* uses FIXMAP_MISC */ set_pixclock(videomode->pixclock); set_fixmap(FIXMAP_MISC, hdlcd_start >> PAGE_SHIFT, DEV_SHARED); HDLCD[HDLCD_COMMAND] = 0; HDLCD[HDLCD_LINELENGTH] = videomode->xres * bytes_per_pixel; HDLCD[HDLCD_LINECOUNT] = videomode->yres - 1; HDLCD[HDLCD_LINEPITCH] = videomode->xres * bytes_per_pixel; HDLCD[HDLCD_PF] = ((bytes_per_pixel - 1) << 3); HDLCD[HDLCD_INTMASK] = 0; HDLCD[HDLCD_FBBASE] = framebuffer_start; HDLCD[HDLCD_BUS] = 0xf00 | (1 << 4); HDLCD[HDLCD_VBACK] = videomode->vback - 1; HDLCD[HDLCD_VSYNC] = videomode->vsync - 1; HDLCD[HDLCD_VDATA] = videomode->yres - 1; HDLCD[HDLCD_VFRONT] = videomode->vfront - 1; HDLCD[HDLCD_HBACK] = videomode->hback - 1; HDLCD[HDLCD_HSYNC] = videomode->hsync - 1; HDLCD[HDLCD_HDATA] = videomode->xres - 1; HDLCD[HDLCD_HFRONT] = videomode->hfront - 1; HDLCD[HDLCD_POLARITIES] = (1 << 2) | (1 << 3); HDLCD[HDLCD_RED] = (c->red_size << 8) | c->red_shift; HDLCD[HDLCD_GREEN] = (c->green_size << 8) | c->green_shift; HDLCD[HDLCD_BLUE] = (c->blue_size << 8) | c->blue_shift; HDLCD[HDLCD_COMMAND] = 1; clear_fixmap(FIXMAP_MISC); lfbp.pixel_on = (((1 << c->red_size) - 1) << c->red_shift) | (((1 << c->green_size) - 1) << c->green_shift) | (((1 << c->blue_size) - 1) << c->blue_shift); lfbp.lfb = lfb; lfbp.font = &font_vga_8x16; lfbp.bits_per_pixel = bytes_per_pixel*8; lfbp.bytes_per_line = bytes_per_pixel*videomode->xres; lfbp.width = videomode->xres; lfbp.height = videomode->yres; lfbp.flush = hdlcd_flush; lfbp.text_columns = videomode->xres / 8; lfbp.text_rows = videomode->yres / 16; if ( lfb_init(&lfbp) < 0 ) return; video_puts = lfb_scroll_puts; }
static void process_options(int argc, char * const argv[]) { int error = 0; for (;;) { int option_index = 0; static const char *short_options = "bs:f:l:opqnNca"; static const struct option long_options[] = { {"help", no_argument, 0, 0}, {"version", no_argument, 0, 0}, {"forcebinary", no_argument, 0, 'a'}, {"canonicalprint", no_argument, 0, 'c'}, {"file", required_argument, 0, 'f'}, {"prettyprint", no_argument, 0, 'p'}, {"omitoob", no_argument, 0, 'o'}, {"omitbad", no_argument, 0, 'b'}, {"startaddress", required_argument, 0, 's'}, {"length", required_argument, 0, 'l'}, {"noecc", no_argument, 0, 'n'}, {"noskipbad", no_argument, 0, 'N'}, {"quiet", no_argument, 0, 'q'}, {0, 0, 0, 0}, }; int c = getopt_long(argc, argv, short_options, long_options, &option_index); if (c == EOF) { break; } switch (c) { case 0: switch (option_index) { case 0: display_help(); break; case 1: display_version(); break; } break; case 'b': omitbad = true; break; case 's': start_addr = simple_strtoll(optarg, &error); break; case 'f': if (!(dumpfile = strdup(optarg))) { perror("stddup"); exit(EXIT_FAILURE); } break; case 'l': length = simple_strtoll(optarg, &error); break; case 'o': omitoob = true; break; case 'a': forcebinary = true; break; case 'c': canonical = true; case 'p': pretty_print = true; break; case 'q': quiet = true; break; case 'n': noecc = true; break; case 'N': noskipbad = true; break; case '?': error++; break; } } if (start_addr < 0) errmsg_die("Can't specify negative offset with option -s: %lld", start_addr); if (length < 0) errmsg_die("Can't specify negative length with option -l: %lld", length); if (quiet && pretty_print) { fprintf(stderr, "The quiet and pretty print options are mutually-\n" "exclusive. Choose one or the other.\n"); exit(EXIT_FAILURE); } if (forcebinary && pretty_print) { fprintf(stderr, "The forcebinary and pretty print options are\n" "mutually-exclusive. Choose one or the " "other.\n"); exit(EXIT_FAILURE); } if ((argc - optind) != 1 || error) display_help(); mtddev = argv[optind]; }
static void process_options(int argc, char * const argv[]) { int error = 0; mtdoffset = 0; for (;;) { int option_index = 0; static const char short_options[] = "hb:mnNoOpqs:a"; static const struct option long_options[] = { /* Order of these args with val==0 matters; see option_index. */ {"version", no_argument, 0, 0}, {"input-skip", required_argument, 0, 0}, {"input-size", required_argument, 0, 0}, {"help", no_argument, 0, 'h'}, {"blockalign", required_argument, 0, 'b'}, {"markbad", no_argument, 0, 'm'}, {"noecc", no_argument, 0, 'n'}, {"noskipbad", no_argument, 0, 'N'}, {"oob", no_argument, 0, 'o'}, {"onlyoob", no_argument, 0, 'O'}, {"pad", no_argument, 0, 'p'}, {"quiet", no_argument, 0, 'q'}, {"start", required_argument, 0, 's'}, {"autoplace", no_argument, 0, 'a'}, {0, 0, 0, 0}, }; int c = getopt_long(argc, argv, short_options, long_options, &option_index); if (c == EOF) break; switch (c) { case 0: switch (option_index) { case 0: /* --version */ display_version(); break; case 1: /* --input-skip */ inputskip = simple_strtoll(optarg, &error); break; case 2: /* --input-size */ inputsize = simple_strtoll(optarg, &error); break; } break; case 'q': quiet = true; break; case 'n': noecc = true; break; case 'N': noskipbad = true; break; case 'm': markbad = true; break; case 'o': writeoob = true; break; case 'O': writeoob = true; onlyoob = true; break; case 'p': pad = true; break; case 's': mtdoffset = simple_strtoll(optarg, &error); break; case 'b': blockalign = atoi(optarg); break; case 'a': autoplace = true; break; case 'h': display_help(EXIT_SUCCESS); break; case '?': error++; break; } } if (mtdoffset < 0) errmsg_die("Can't specify negative device offset with option" " -s: %lld", mtdoffset); if (blockalign < 0) errmsg_die("Can't specify negative blockalign with option -b:" " %d", blockalign); if (autoplace && noecc) errmsg_die("Autoplacement and no-ECC are mutually exclusive"); if (!onlyoob && (pad && writeoob)) errmsg_die("Can't pad when oob data is present"); argc -= optind; argv += optind; /* * There must be at least the MTD device node positional * argument remaining and, optionally, the input file. */ if (argc < 1 || argc > 2 || error) display_help(EXIT_FAILURE); mtd_device = argv[0]; /* * Standard input may be specified either explictly as "-" or * implicity by simply omitting the second of the two * positional arguments. */ img = ((argc == 2) ? argv[1] : standard_input); }
int hvm_load(struct domain *d, hvm_domain_context_t *h) { char *c; uint64_t cset; struct hvm_save_header hdr; struct hvm_save_descriptor *desc; hvm_load_handler handler; struct vcpu *v; /* Read the save header, which must be first */ if ( hvm_load_entry(HEADER, h, &hdr) != 0 ) return -1; if ( arch_hvm_load(d, &hdr) ) return -1; c = strrchr(xen_changeset(), ':'); if ( hdr.changeset == -1ULL ) gdprintk(XENLOG_WARNING, "HVM restore: Xen changeset was not saved.\n"); else if ( c == NULL ) gdprintk(XENLOG_WARNING, "HVM restore: Xen changeset is not available.\n"); else { cset = simple_strtoll(c, NULL, 16); if ( hdr.changeset != cset ) gdprintk(XENLOG_WARNING, "HVM restore: saved Xen changeset (%#"PRIx64 ") does not match host (%#"PRIx64").\n", hdr.changeset, cset); } /* Down all the vcpus: we only re-enable the ones that had state saved. */ for_each_vcpu(d, v) if ( test_and_set_bit(_VPF_down, &v->pause_flags) ) vcpu_sleep_nosync(v); for ( ; ; ) { if ( h->size - h->cur < sizeof(struct hvm_save_descriptor) ) { /* Run out of data */ gdprintk(XENLOG_ERR, "HVM restore: save did not end with a null entry\n"); return -1; } /* Read the typecode of the next entry and check for the end-marker */ desc = (struct hvm_save_descriptor *)(&h->data[h->cur]); if ( desc->typecode == 0 ) return 0; /* Find the handler for this entry */ if ( (desc->typecode > HVM_SAVE_CODE_MAX) || ((handler = hvm_sr_handlers[desc->typecode].load) == NULL) ) { gdprintk(XENLOG_ERR, "HVM restore: unknown entry typecode %u\n", desc->typecode); return -1; } /* Load the entry */ gdprintk(XENLOG_INFO, "HVM restore: %s %"PRIu16"\n", hvm_sr_handlers[desc->typecode].name, desc->instance); if ( handler(d, h) != 0 ) { gdprintk(XENLOG_ERR, "HVM restore: failed to load entry %u/%u\n", desc->typecode, desc->instance); return -1; } } /* Not reached */ }
static void process_options(int argc, char * const argv[]) { int error = 0; for (;;) { int option_index = 0; static const char *short_options = "ab:fjmnNopqrs:y"; static const struct option long_options[] = { {"help", no_argument, 0, 0}, {"version", no_argument, 0, 0}, {"autoplace", no_argument, 0, 'a'}, {"blockalign", required_argument, 0, 'b'}, {"forcelegacy", no_argument, 0, 'f'}, {"jffs2", no_argument, 0, 'j'}, {"markbad", no_argument, 0, 'm'}, {"noecc", no_argument, 0, 'n'}, {"noskipbad", no_argument, 0, 'N'}, {"oob", no_argument, 0, 'o'}, {"pad", no_argument, 0, 'p'}, {"quiet", no_argument, 0, 'q'}, {"raw", no_argument, 0, 'r'}, {"start", required_argument, 0, 's'}, {"yaffs", no_argument, 0, 'y'}, {0, 0, 0, 0}, }; int c = getopt_long(argc, argv, short_options, long_options, &option_index); if (c == EOF) { break; } switch (c) { case 0: switch (option_index) { case 0: display_help(); break; case 1: display_version(); break; } break; case 'q': quiet = true; break; case 'a': autoplace = true; break; case 'j': forcejffs2 = true; break; case 'y': forceyaffs = true; break; case 'f': forcelegacy = true; break; case 'n': noecc = true; break; case 'N': noskipbad = true; break; case 'm': markbad = true; break; case 'o': writeoob = true; break; case 'p': pad = true; break; case 'r': rawoob = true; writeoob = true; break; case 's': mtdoffset = simple_strtoll(optarg, &error); break; case 'b': blockalign = atoi(optarg); break; case '?': error++; break; } } if (mtdoffset < 0) errmsg_die("Can't specify negative device offset with option" " -s: %lld", mtdoffset); if (blockalign < 0) errmsg_die("Can't specify negative blockalign with option -b:" " %d", blockalign); argc -= optind; argv += optind; /* * There must be at least the MTD device node positional * argument remaining and, optionally, the input file. */ if (argc < 1 || argc > 2 || error) display_help(); mtd_device = argv[0]; /* * Standard input may be specified either explictly as "-" or * implicity by simply omitting the second of the two * positional arguments. */ img = ((argc == 2) ? argv[1] : standard_input); }
static void process_options(int argc, char * const argv[]) { int error = 0; for (;;) { int option_index = 0; static const char short_options[] = "hV"; static const struct option long_options[] = { {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}, }; int c = getopt_long(argc, argv, short_options, long_options, &option_index); if (c == EOF) { break; } switch (c) { case 'V': display_version(); break; case 'h': display_help(EXIT_SUCCESS); break; case '?': error++; break; } } if ((argc - optind) < 3 || error) display_help(EXIT_FAILURE); const char *s_command = argv[optind++]; mtddev = argv[optind++]; if (strcmp(s_command, "del") == 0 && (argc - optind) == 1) { const char *s_part_no = argv[optind++]; long tmp = simple_strtol(s_part_no, &error); if (tmp < 0) errmsg_die("Can't specify negative partition number: %ld", tmp); if (tmp > INT_MAX) errmsg_die("Partition number exceeds INT_MAX: %ld", tmp); part_no = tmp; command = COMMAND_DEL; } else if (strcmp(s_command, "add") == 0 && (argc - optind) == 3) { const char *s_start; const char *s_length; part_name = argv[optind++]; s_start = argv[optind++]; s_length = argv[optind++]; if (strlen(part_name) >= BLKPG_DEVNAMELTH) errmsg_die("Partition name (%s) should be less than %d characters", part_name, BLKPG_DEVNAMELTH); start_addr = simple_strtoll(s_start, &error); if (start_addr < 0) errmsg_die("Can't specify negative start offset: %lld", start_addr); length = simple_strtoll(s_length, &error); if (length < 0) errmsg_die("Can't specify negative length: %lld", length); command = COMMAND_ADD; } else display_help(EXIT_FAILURE); if (error) display_help(EXIT_FAILURE); }