Exemple #1
0
/* Try to parse a hunk range specification from the string RANGE.
 * Return parsed information in *START and *LENGTH, and return TRUE
 * if the range parsed correctly. Note: This function may modify the
 * input value RANGE. */
static svn_boolean_t
parse_range(svn_linenum_t *start, svn_linenum_t *length, char *range)
{
  char *comma;

  if (*range == 0)
    return FALSE;

  comma = strstr(range, ",");
  if (comma)
    {
      if (strlen(comma + 1) > 0)
        {
          /* Try to parse the length. */
          if (! parse_offset(length, comma + 1))
            return FALSE;

          /* Snip off the end of the string,
           * so we can comfortably parse the line
           * number the hunk starts at. */
          *comma = '\0';
        }
       else
         /* A comma but no length? */
         return FALSE;
    }
  else
    {
      *length = 1;
    }

  /* Try to parse the line number the hunk starts at. */
  return parse_offset(start, range);
}
Exemple #2
0
static void node_memverify(xml_data_node *node)
{
	xml_attribute_node *attr_node;
	const char *s1;
	const char *s2;
	const char *s3;
	int region;
	void *new_buffer;
	mess_pile pile;

	/* <memverify> - verifies that a range of memory contains specific data */
	attr_node = xml_get_attribute(node, "start");
	s1 = attr_node ? attr_node->value : NULL;
	if (!s1)
	{
		error_missingattribute("start");
		return;
	}

	attr_node = xml_get_attribute(node, "end");
	s2 = attr_node ? attr_node->value : NULL;
	if (!s2)
		s2 = "0";

	attr_node = xml_get_attribute(node, "region");
	s3 = attr_node ? attr_node->value : NULL;

	memset(&new_command, 0, sizeof(new_command));
	new_command.command_type = MESSTEST_COMMAND_VERIFY_MEMORY;
	new_command.u.verify_args.start = parse_offset(s1);
	new_command.u.verify_args.end = parse_offset(s2);

	if (s3)
	{
		region = memory_region_from_string(s3);
		if (region == REGION_INVALID)
			error_invalidmemregion(s3);
		new_command.u.verify_args.mem_region = region;
	}

	pile_init(&pile);
	messtest_get_data(node, &pile);
	new_buffer = pool_malloc(&command_pool, pile_size(&pile));
	memcpy(new_buffer, pile_getptr(&pile), pile_size(&pile));
	new_command.u.verify_args.verify_data = new_buffer;
	new_command.u.verify_args.verify_data_size = pile_size(&pile);
	pile_delete(&pile);

	if (!append_command())
	{
		error_outofmemory();
		return;
	}
}
Exemple #3
0
static GObexApparam *parse_folder_filters(GObexApparam *apparam,
							DBusMessageIter *iter)
{
	DBusMessageIter array;

	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
		return NULL;

	dbus_message_iter_recurse(iter, &array);

	while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
		const char *key;
		DBusMessageIter value, entry;

		dbus_message_iter_recurse(&array, &entry);
		dbus_message_iter_get_basic(&entry, &key);

		dbus_message_iter_next(&entry);
		dbus_message_iter_recurse(&entry, &value);

		if (strcasecmp(key, "Offset") == 0) {
			if (parse_offset(apparam, &value) == NULL)
				return NULL;
		} else if (strcasecmp(key, "MaxCount") == 0) {
			if (parse_max_count(apparam, &value) == NULL)
				return NULL;
		}

		dbus_message_iter_next(&array);
	}

	return apparam;
}
Exemple #4
0
TSAPI struct tslib_module_info *mod_init(struct tsdev *dev, const char *params)
{

	struct tslib_offset *off;
	
	struct stat sbuf;
	int offset_fd;
	char offsetbuf[200];
	int bytes,ret;
	char *offsetfile=NULL;
	char *defaultoffsetfile = "/etc/pointeroffset";

	char *fifofile=NULL;
	char *defaultfifofile = "/var/tmp/offsetpipe";


    off = malloc(sizeof(struct tslib_offset));
	if (off == NULL) {
		return NULL;
	}

	off->module.ops = &offset_ops;
    off->x_offset = 0;
    off->y_offset = 0;

    off->fifo_fd = 0;
    off->sample_count = 0;
    
	/*
	 * Check calibration file
	 */
	//fprintf(stderr, "Loading offsetfile\n");
     
	if( (offsetfile = getenv("TSLIB_OFFSETFILE")) == NULL) offsetfile = defaultoffsetfile;
	if(stat(offsetfile,&sbuf)==0) {
		offset_fd = open(offsetfile,O_RDONLY);
		bytes = read(offset_fd,offsetbuf,sbuf.st_size);
        //fprintf(stderr, "Loaded %d bytes from offsetfile\n", bytes);
        parse_offset(off, offsetbuf, bytes);
		close(offset_fd);
	}
    
	if( (fifofile = getenv("TSLIB_OFFSETFIFO")) == NULL) fifofile = defaultfifofile;
    //fprintf(stderr, "making fifo file\n");
    ret = mknod(fifofile, S_IFIFO | 0660, 0);
    if (ret == 0 || (ret == -1 && errno == EEXIST)) {
        off->fifo_fd = open(fifofile, O_RDONLY|O_NONBLOCK|O_NDELAY);
    }

	return &off->module;
}
Exemple #5
0
static void simread(const char *const *action) {
  const char *processid = action[0];
  const char *file_name = action[2];
  const char *index = action[4];
  const char *position_str =action[5];
  const char *size_str = action[6];
  msg_file_t file = NULL;
  sg_size_t size = parse_size(size_str);
  sg_offset_t position= parse_offset(position_str);
  double clock = MSG_get_clock();       /* this "call" is free thanks to inlining */
  file = get_file_descriptor(file_name,index);
  ACT_DEBUG("Entering Read: %s (size: %llu)", NAME, size);
  MSG_file_seek(file,position,SEEK_SET);
  MSG_file_read(file, size);
  log_action(action, MSG_get_clock() - clock);
  XBT_INFO("read  worker %s%s is done",processid,index);
}
Exemple #6
0
int command_add(args_t * args)
{
	assert(args != NULL);

	/* ========================= */

	int add(args_t * args, off_t poffset)
	{
		int rc = 0;

		off_t offset = 0;
		size_t size = 0;
		uint32_t flags = 0;

		rc = parse_offset(args->offset, &offset);
		if (rc < 0)
			return rc;
		rc = parse_size(args->size, &size);
		if (rc < 0)
			return rc;
		rc = parse_size(args->flags, &flags);
		if (rc < 0)
			return rc;

		ffs_type_t type = FFS_TYPE_DATA;
		if (args->logical == f_LOGICAL)
			type = FFS_TYPE_LOGICAL;

		const char * target = args->target;
		int debug = args->debug;

		RAII(FILE *, file, fopen_generic(target, "r+", debug), fclose);
		RAII(ffs_t *, ffs,  __ffs_fopen(file, poffset), __ffs_fclose);

		rc = __ffs_entry_add(ffs, args->name, offset, size,
				     type, flags);
		if (rc < 0)
			return rc;

		if (args->verbose == f_VERBOSE)
			printf("%llx: %s: add partition at offset '%llx' size "
			       "'%x' type '%d' flags '%x'\n", poffset,
				args->name, offset, size, type, flags);

		return rc;
	}
Exemple #7
0
int
parse_munge(int *argc_p, char ***argv_p,struct tc_pedit_sel *sel)
{
	struct tc_pedit_key tkey;
	int argc = *argc_p;
	char **argv = *argv_p;
	int res = -1;

	if (argc <= 0)
		return -1;

	memset(&tkey, 0, sizeof(tkey));

	if (matches(*argv, "offset") == 0) {
		NEXT_ARG();
		res = parse_offset(&argc, &argv,sel,&tkey);
		goto done;
	} else {
		char k[16];
		struct m_pedit_util *p = NULL;

		strncpy(k, *argv, sizeof (k) - 1);

		if (argc > 0 ) {
			p = get_pedit_kind(k);
			if (NULL == p)
				goto bad_val;
			res = p->parse_peopt(&argc, &argv, sel,&tkey);
			if (res < 0) {
				fprintf(stderr,"bad pedit parsing\n");
				goto bad_val;
			}
			goto done;
		}
	}

bad_val:
	return -1;

done:

	*argc_p = argc;
	*argv_p = argv;
	return res;
}
static void simread(const char *const *action) {
  const char *processid = action[0];
  const char *file_name = action[2];
  const char *index = action[4];
  const char *position_str =action[5];
  const char *size_str = action[6];
  msg_file_t file = NULL;
  sg_size_t size = parse_size(size_str);
  sg_offset_t position= parse_offset(position_str);
  double clock = MSG_get_clock();       /* this "call" is free thanks to inlining */
  
  if(position<2880 && (position+size)<2880)
  {
  file = get_file_descriptor("fast",file_name,index);
  ACT_DEBUG("Entering Read: %s (size: %llu)", NAME, size);
  MSG_file_seek(file,position,SEEK_SET);
  MSG_file_read(file, size);
  }
  else if(position<2880 && (position+size)>2880)
  {
  //read the Head part
  file = get_file_descriptor("fast",file_name,index);
  ACT_DEBUG("Entering Read: %s (size: %llu)", NAME, size);
  MSG_file_seek(file,position,SEEK_SET);
  MSG_file_read(file, (2880-position));
  //read the data part
  file = get_file_descriptor("slow",file_name,index);
  ACT_DEBUG("Entering Read: %s (size: %llu)", NAME, size);
  MSG_file_seek(file,2880,SEEK_SET);
  MSG_file_read(file, size-(2880-position));
  }
  else
  {
  XBT_INFO("3 position is  %llu ,size is %llu",position,size);
  file = get_file_descriptor("slow",file_name,index);
  ACT_DEBUG("Entering Read: %s (size: %llu)", NAME, size);
  MSG_file_seek(file,position,SEEK_SET);
  MSG_file_read(file, size);
  }
  
  log_action(action, MSG_get_clock() - clock);
  XBT_INFO("read  worker %s%s is done",processid,index);
}
Exemple #9
0
static int
offset_read(struct tslib_module_info *info, struct ts_sample *samp, int nr)
{
	struct tslib_offset *off = (struct tslib_offset *)info;
	struct ts_sample cur;
	int ret;
    int bytes_read;
    int count;
	int xtemp,ytemp;
    char buffer[512];

    //fprintf(stderr, "Reading %d samples\n", nr);
    if (off->sample_count > 50) {
        off->sample_count = 0;
        // check the fifo.  it's in nonblocking - so we can read as much as we want
        // it will just give back what it had in the buffer
        bytes_read = read(off->fifo_fd, buffer, 512);
        if (bytes_read > 0) {
            parse_offset(off, buffer, bytes_read);
        }
    }
    //fprintf(stderr, "past fifo check\n");
    
    ret = info->next->ops->read(info->next, samp, nr);
	if (ret >= 0) {
		int nr;

		for (nr = 0; nr < ret; nr++, samp++) {
            samp->x += off->x_offset;
            samp->y += off->y_offset;
            #ifdef DEBUG
                fprintf(stderr, "------> adjusted:  %d\t%d\n", samp->x, samp->y);
            #endif
            off->sample_count++;
        }
    }
	
	return ret;
}
Exemple #10
0
int
main(int argc, char **argv)
{
    INUM_T inum;
    int ch;
    char *cp, *dash;
    char *fstype = NULL;
    FS_INFO *fs;
    int32_t sec_skew = 0;
    char *imgtype = NULL;
    IMG_INFO *img;
    SSIZE_T imgoff = 0;


    /* When > 0 this is the number of blocks to print, used for -b arg */
    DADDR_T numblock = 0;

    progname = argv[0];
    setlocale(LC_ALL, "");


    while ((ch = getopt(argc, argv, "b:f:i:o:s:vVz:")) > 0) {
	switch (ch) {
	case '?':
	default:
	    fprintf(stderr, "Invalid argument: %s\n", argv[optind]);
	    usage();
	case 'b':
	    numblock = strtoull(optarg, &cp, 0);
	    if (*cp || cp == optarg || numblock < 1) {
		fprintf(stderr,
		    "invalid argument: block count must be positive: %s\n",
		    optarg);
		usage();
	    }
	    break;
	case 'f':
	    fstype = optarg;
	    break;
	case 'i':
	    imgtype = optarg;
	    break;

	case 'o':
	    if ((imgoff = parse_offset(optarg)) == -1) {
		tsk_error_print(stderr);
		exit(1);
	    }
	    break;

	case 's':
	    sec_skew = atoi(optarg);
	    break;

	case 'v':
	    verbose++;
	    break;

	case 'V':
	    print_version(stdout);
	    exit(0);
	case 'z':
	    {
		char envstr[32];
		snprintf(envstr, 32, "TZ=%s", optarg);
		if (0 != putenv(envstr)) {
		    fprintf(stderr, "error setting environment");
		    exit(1);
		}

		tzset();
	    }
	    break;

	}
    }

    /* We need at least two more argument */
    if (optind + 1 >= argc) {
	fprintf(stderr, "Missing image name and/or address\n");
	usage();
    }

    /* if we are given the inode in the inode-type-id form, then ignore
     * the other stuff w/out giving an error 
     *
     * This will make scripting easier
     */
    if ((dash = strchr(argv[argc - 1], '-')) != NULL) {
	*dash = '\0';
    }

    inum = strtoull(argv[argc - 1], &cp, 0);
    if (*cp || cp == argv[argc - 1]) {
	fprintf(stderr, "bad inode number: %s", argv[argc - 1]);
	usage();
    }

    /*
     * Open the file system.
     */
    if ((img =
	    img_open(imgtype, argc - optind - 1,
		(const char **) &argv[optind])) == NULL) {
	tsk_error_print(stderr);
	exit(1);
    }

    if ((fs = fs_open(img, imgoff, fstype)) == NULL) {
	tsk_error_print(stderr);
	if (tsk_errno == TSK_ERR_FS_UNSUPTYPE)
	    fs_print_types(stderr);
	img->close(img);
	exit(1);
    }

    if (inum > fs->last_inum) {
	fprintf(stderr,
	    "Metadata address is too large for image (%" PRIuINUM ")\n",
	    fs->last_inum);
	fs->close(fs);
	img->close(img);
	exit(1);
    }

    if (inum < fs->first_inum) {
	fprintf(stderr,
	    "Metadata address is too small for image (%" PRIuINUM ")\n",
	    fs->first_inum);
	fs->close(fs);
	img->close(img);
	exit(1);
    }

    if (fs->istat(fs, stdout, inum, numblock, sec_skew)) {
	tsk_error_print(stderr);
	fs->close(fs);
	img->close(img);
	exit(1);
    }

    fs->close(fs);
    img->close(img);
    exit(0);
}
Exemple #11
0
static GObexApparam *parse_message_filters(GObexApparam *apparam,
							DBusMessageIter *iter)
{
	DBusMessageIter array;

	DBG("");

	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
		return NULL;

	dbus_message_iter_recurse(iter, &array);

	while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
		const char *key;
		DBusMessageIter value, entry;

		dbus_message_iter_recurse(&array, &entry);
		dbus_message_iter_get_basic(&entry, &key);

		dbus_message_iter_next(&entry);
		dbus_message_iter_recurse(&entry, &value);

		if (strcasecmp(key, "Offset") == 0) {
			if (parse_offset(apparam, &value) == NULL)
				return NULL;
		} else if (strcasecmp(key, "MaxCount") == 0) {
			if (parse_max_count(apparam, &value) == NULL)
				return NULL;
		} else if (strcasecmp(key, "SubjectLength") == 0) {
			if (parse_subject_length(apparam, &value) == NULL)
				return NULL;
		} else if (strcasecmp(key, "Fields") == 0) {
			if (parse_fields(apparam, &value) == NULL)
				return NULL;
		} else if (strcasecmp(key, "Types") == 0) {
			if (parse_filter_type(apparam, &value) == NULL)
				return NULL;
		} else if (strcasecmp(key, "PeriodBegin") == 0) {
			if (parse_period_begin(apparam, &value) == NULL)
				return NULL;
		} else if (strcasecmp(key, "PeriodEnd") == 0) {
			if (parse_period_end(apparam, &value) == NULL)
				return NULL;
		} else if (strcasecmp(key, "Read") == 0) {
			if (parse_filter_read(apparam, &value) == NULL)
				return NULL;
		} else if (strcasecmp(key, "Recipient") == 0) {
			if (parse_filter_recipient(apparam, &value) == NULL)
				return NULL;
		} else if (strcasecmp(key, "Sender") == 0) {
			if (parse_filter_sender(apparam, &value) == NULL)
				return NULL;
		} else if (strcasecmp(key, "Priority") == 0) {
			if (parse_filter_priority(apparam, &value) == NULL)
				return NULL;
		}

		dbus_message_iter_next(&array);
	}

	return apparam;
}
Exemple #12
0
int
main(int argc, char **argv)
{
    FS_INFO *fs = NULL;
    DADDR_T addr = 0;
    char *fstype = NULL;
    DADDR_T read_num_units;	/* Number of data units */
    int usize = 0;		/* Length of each data unit */
    int ch;
    char format = 0, *cp, *imgtype = NULL;
    IMG_INFO *img;
    extern int optind;
    SSIZE_T imgoff = 0;

    progname = argv[0];
    setlocale(LC_ALL, "");

    while ((ch = getopt(argc, argv, "af:hi:o:su:vVw")) > 0) {
	switch (ch) {
	case 'a':
	    format |= DCAT_ASCII;
	    break;
	case 'f':
	    fstype = optarg;
	    if (strcmp(fstype, DLS_TYPE) == 0)
		fstype = RAW_STR;

	    break;
	case 'h':
	    format |= DCAT_HEX;
	    break;
	case 'i':
	    imgtype = optarg;
	    break;
	case 'o':
	    if ((imgoff = parse_offset(optarg)) == -1) {
		tsk_error_print(stderr);
		exit(1);
	    }
	    break;
	case 's':
	    format |= DCAT_STAT;
	    break;
	case 'u':
	    usize = strtoul(optarg, &cp, 0);
	    if (*cp || cp == optarg) {
		fprintf(stderr, "Invalid block size: %s\n", optarg);
		usage();
	    }
	    break;
	case 'v':
	    verbose++;
	    break;
	case 'V':
	    print_version(stdout);
	    exit(0);
	    break;
	case 'w':
	    format |= DCAT_HTML;
	    break;
	case '?':
	default:
	    fprintf(stderr, "Invalid argument: %s\n", argv[optind]);
	    usage();
	}
    }

    if (format & DCAT_STAT) {
	if (optind == argc)
	    usage();

	if (format & (DCAT_HTML | DCAT_ASCII | DCAT_HEX)) {
	    fprintf(stderr, "NOTE: Additional flags will be ignored\n");
	}
    }
    /* We need at least two more arguments */
    else if (optind + 1 >= argc) {
	fprintf(stderr, "Missing image name and/or address\n");
	usage();
    }

    if ((format & DCAT_ASCII) && (format & DCAT_HEX)) {
	fprintf(stderr, "Ascii and Hex flags can not be used together\n");
	usage();
    }

    /* We need to figure out if there is a length argument... */
    /* Check out the second argument from the end */

    /* default number of units is 1 */
    read_num_units = 1;

    /* Get the block address */
    if (format & DCAT_STAT) {
	if ((img =
		img_open(imgtype, argc - optind,
		    (const char **) &argv[optind])) == NULL) {
	    tsk_error_print(stderr);
	    exit(1);
	}

    }
    else {
	addr = strtoull(argv[argc - 2], &cp, 0);
	if (*cp || cp == argv[argc - 2]) {

	    /* Not a number, so it is the image name and we do not have a length */
	    addr = strtoull(argv[argc - 1], &cp, 0);
	    if (*cp || cp == argv[argc - 1]) {
		fprintf(stderr, "Invalid block address: %s\n",
		    argv[argc - 1]);
		usage();
	    }

	    if ((img =
		    img_open(imgtype, argc - optind - 1,
			(const char **) &argv[optind])) == NULL) {
		tsk_error_print(stderr);
		exit(1);
	    }

	}
	else {
	    /* We got a number, so take the length as well while we are at it */
	    read_num_units = strtoull(argv[argc - 1], &cp, 0);
	    if (*cp || cp == argv[argc - 1]) {
		fprintf(stderr, "Invalid size: %s\n", argv[argc - 1]);
		usage();
	    }
	    else if (read_num_units <= 0) {
		fprintf(stderr, "Invalid size: %" PRIuDADDR "\n",
		    read_num_units);
		usage();
	    }

	    if ((img =
		    img_open(imgtype, argc - optind - 2,
			(const char **) &argv[optind])) == NULL) {

		tsk_error_print(stderr);
		exit(1);
	    }

	}
    }

    /* open the file */
    if ((fs = fs_open(img, imgoff, fstype)) == NULL) {
	tsk_error_print(stderr);
	if (tsk_errno == TSK_ERR_FS_UNSUPTYPE)
	    fs_print_types(stderr);
	img->close(img);
	exit(1);
    }



    /* Set the default size if given */
    if ((usize != 0) &&
	(((fs->ftype & FSMASK) == RAWFS_TYPE) ||
	    ((fs->ftype & FSMASK) == SWAPFS_TYPE))) {

	DADDR_T sectors;
	int orig_dsize, new_dsize;

	if (usize % 512) {
	    fprintf(stderr,
		"New data unit size not a multiple of 512 (%d)\n", usize);
	    usage();
	}

	/* We need to do some math to update the block_count value */

	/* Get the original number of sectors */
	orig_dsize = fs->block_size / 512;
	sectors = fs->block_count * orig_dsize;

	/* Convert that to the new size */
	new_dsize = usize / 512;
	fs->block_count = sectors / new_dsize;
	if (sectors % new_dsize)
	    fs->block_count++;
	fs->last_block = fs->block_count - 1;

	fs->block_size = usize;
    }

    if (addr > fs->last_block) {
	fprintf(stderr,
	    "Data unit address too large for image (%" PRIuDADDR ")\n",
	    fs->last_block);
	fs->close(fs);
	img->close(img);
	exit(1);
    }
    if (addr < fs->first_block) {
	fprintf(stderr,
	    "Data unit address too small for image (%" PRIuDADDR ")\n",
	    fs->first_block);
	fs->close(fs);
	img->close(img);
	exit(1);
    }

    if (fs_dcat(fs, format, addr, read_num_units)) {
	tsk_error_print(stderr);
	fs->close(fs);
	img->close(img);
	exit(1);
    }

    fs->close(fs);
    img->close(img);

    exit(0);
}
Exemple #13
0
static int u32_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n)
{
	struct {
		struct tc_u32_sel sel;
		struct tc_u32_key keys[128];
	} sel;
	struct tcmsg *t = NLMSG_DATA(n);
	struct rtattr *tail;
	int sel_ok = 0;
	int sample_ok = 0;
	__u32 htid = 0;
	__u32 order = 0;

	memset(&sel, 0, sizeof(sel));

	if (handle && get_u32_handle(&t->tcm_handle, handle)) {
		fprintf(stderr, "Illegal filter ID\n");
		return -1;
	}

	if (argc == 0)
		return 0;

	tail = (struct rtattr*)(((void*)n)+NLMSG_ALIGN(n->nlmsg_len));
	addattr_l(n, 4096, TCA_OPTIONS, NULL, 0);

	while (argc > 0) {
		if (matches(*argv, "match") == 0) {
			NEXT_ARG();
			if (parse_selector(&argc, &argv, &sel.sel)) {
				fprintf(stderr, "Illegal \"match\"\n");
				return -1;
			}
			sel_ok++;
			continue;
		} else if (matches(*argv, "offset") == 0) {
			NEXT_ARG();
			if (parse_offset(&argc, &argv, &sel.sel)) {
				fprintf(stderr, "Illegal \"offset\"\n");
				return -1;
			}
			continue;
		} else if (matches(*argv, "hashkey") == 0) {
			NEXT_ARG();
			if (parse_hashkey(&argc, &argv, &sel.sel)) {
				fprintf(stderr, "Illegal \"hashkey\"\n");
				return -1;
			}
			continue;
		} else if (matches(*argv, "classid") == 0 ||
			   strcmp(*argv, "flowid") == 0) {
			unsigned handle;
			NEXT_ARG();
			if (get_tc_classid(&handle, *argv)) {
				fprintf(stderr, "Illegal \"classid\"\n");
				return -1;
			}
			addattr_l(n, 4096, TCA_U32_CLASSID, &handle, 4);
			sel.sel.flags |= TC_U32_TERMINAL;
		} else if (matches(*argv, "divisor") == 0) {
			unsigned divisor;
			NEXT_ARG();
			if (get_unsigned(&divisor, *argv, 0) || divisor == 0 ||
			    divisor > 0x100) {
				fprintf(stderr, "Illegal \"divisor\"\n");
				return -1;
			}
			addattr_l(n, 4096, TCA_U32_DIVISOR, &divisor, 4);
		} else if (matches(*argv, "order") == 0) {
			NEXT_ARG();
			if (get_u32(&order, *argv, 0)) {
				fprintf(stderr, "Illegal \"order\"\n");
				return -1;
			}
		} else if (strcmp(*argv, "link") == 0) {
			unsigned handle;
			NEXT_ARG();
			if (get_u32_handle(&handle, *argv)) {
				fprintf(stderr, "Illegal \"link\"\n");
				return -1;
			}
			if (handle && TC_U32_NODE(handle)) {
				fprintf(stderr, "\"link\" must be a hash table.\n");
				return -1;
			}
			addattr_l(n, 4096, TCA_U32_LINK, &handle, 4);
		} else if (strcmp(*argv, "ht") == 0) {
			unsigned handle;
			NEXT_ARG();
			if (get_u32_handle(&handle, *argv)) {
				fprintf(stderr, "Illegal \"ht\"\n");
				return -1;
			}
			if (handle && TC_U32_NODE(handle)) {
				fprintf(stderr, "\"ht\" must be a hash table.\n");
				return -1;
			}
			if (sample_ok)
				htid = (htid&0xFF000)|(handle&0xFFF00000);
			else
				htid = (handle&0xFFFFF000);
		} else if (strcmp(*argv, "sample") == 0) {
			__u32 hash;
			struct {
				struct tc_u32_sel sel;
				struct tc_u32_key keys[4];
			} sel2;
			NEXT_ARG();
			if (parse_selector(&argc, &argv, &sel2.sel)) {
				fprintf(stderr, "Illegal \"sample\"\n");
				return -1;
			}
			if (sel2.sel.nkeys != 1) {
				fprintf(stderr, "\"sample\" must contain exactly ONE key.\n");
				return -1;
			}
			hash = sel2.sel.keys[0].val&sel2.sel.keys[0].mask;
			hash ^= hash>>16;
			hash ^= hash>>8;
			htid = ((hash<<12)&0xFF000)|(htid&0xFFF00000);
			sample_ok = 1;
			continue;
#ifdef TC_CONFIG_ALL
		} else if (matches(*argv, "police") == 0) {
Exemple #14
0
int main(int argc,char *argv[]){
  int toc_bias=0;
  int toc_offset=0;
  int sample_offset=0;
  int force_cdrom_endian=-1;
  int force_cdrom_sectors=-1;
  int force_cdrom_overlap=-1;
  char *force_cdrom_device=NULL;
  char *force_generic_device=NULL;
  char *force_cooked_device=NULL;
  int force_cdrom_speed=0;
  int max_retries=20;
  char *span=NULL;
  int output_type=1; /* 0=raw, 1=wav, 2=aifc */
  int output_endian=0; /* -1=host, 0=little, 1=big */
  int query_only=0;
  int batch=0,i;
  int run_cache_test=0;

  char *logfile_name=NULL;
  char *reportfile_name=NULL;
  int logfile_open=0;
  int reportfile_open=0;

  /* full paranoia, but allow skipping */
  int paranoia_mode=PARANOIA_MODE_FULL^PARANOIA_MODE_NEVERSKIP; 

  char *info_file=NULL;
  int out;

  int search=0;
  int c,long_option_index;

  atexit(cleanup);

  while((c=getopt_long(argc,argv,optstring,options,&long_option_index))!=EOF){
    switch(c){
    case 'B':
      batch=1;
      break;
    case 'c':
      force_cdrom_endian=0;
      break;
    case 'C':
      force_cdrom_endian=1;
      break;
    case 'n':
      force_cdrom_sectors=atoi(optarg);
      break;
    case 'o':
      force_cdrom_overlap=atoi(optarg);
      break;
    case 'd':
      if(force_cdrom_device)free(force_cdrom_device);
      force_cdrom_device=copystring(optarg);
      break;
    case 'g':
      if(force_cooked_device){
	report("-g option incompatable with -k\n");
	exit(1);
      }
      force_cooked_device=NULL;
      if(force_generic_device)free(force_generic_device);
      force_generic_device=copystring(optarg);
      break;
    case 'k':
      if(force_generic_device || force_cdrom_device){
	report("-k option incompatable with -d and -g\n");
	exit(1);
      }
      if(force_cooked_device)free(force_cooked_device);
      force_cooked_device=copystring(optarg);
      break;
    case 'S':
      force_cdrom_speed=atoi(optarg);
      break;
    case 'p':
      output_type=0;
      output_endian=-1;
      break;
    case 'r':
      output_type=0;
      output_endian=0;
      break;
    case 'R':
      output_type=0;
      output_endian=1;
      break;
    case 'w':
      output_type=1;
      output_endian=0;
      break;
    case 'a':
      output_type=2;
      output_endian=1;
      break;
    case 'f':
      output_type=3;
      output_endian=1;
      break;
    case 'v':
      verbose=CDDA_MESSAGE_PRINTIT;
      quiet=0;
      break;
    case 's':
      search=1;
      break;
    case 'q':
      verbose=CDDA_MESSAGE_FORGETIT;
      quiet=1;
      break;
    case 'e':
      callscript=1;
      fprintf(stderr,"Sending all callbacks to stderr for wrapper script\n");
      break;
    case 'V':
      fprintf(stderr,VERSION);
      fprintf(stderr,"\n");
      exit(0);
      break;
    case 'Q':
      query_only=1;
      break;
    case 'h':
      usage(stdout);
      exit(0);
    case 'Z':
      paranoia_mode=PARANOIA_MODE_DISABLE; 
      break;
    case 'A':
      run_cache_test=1;
      query_only=1;
      reportfile_open=1;
      verbose=CDDA_MESSAGE_PRINTIT;
      break;
    case 'z':
      if (optarg) {
        max_retries = atoi (optarg);
        paranoia_mode&=~PARANOIA_MODE_NEVERSKIP;
      } else {
        paranoia_mode|=PARANOIA_MODE_NEVERSKIP;
      }
      break;
    case 'Y':
      paranoia_mode|=PARANOIA_MODE_OVERLAP; /* cdda2wav style overlap 
						check only */
      paranoia_mode&=~PARANOIA_MODE_VERIFY;
      break;
    case 'X':
      /*paranoia_mode&=~(PARANOIA_MODE_SCRATCH|PARANOIA_MODE_REPAIR);*/
      abort_on_skip=1;
      break;
    case 'W':
      paranoia_mode&=~PARANOIA_MODE_REPAIR;
      break;
    case 'F':
      paranoia_mode&=~(PARANOIA_MODE_FRAGMENT);
      break;
    case 'i':
      if(info_file)free(info_file);
      info_file=copystring(info_file);
      break;
    case 'T':
      toc_bias=-1;
      break;
    case 't':
      toc_offset=atoi(optarg);
      break;
    case 'l':
      if(logfile_name)free(logfile_name);
      logfile_name=NULL;
      if(optarg)
	logfile_name=strdup(optarg);
      logfile_open=1;
      break;
    case 'L':
      if(reportfile_name)free(reportfile_name);
      reportfile_name=NULL;
      if(optarg)
	reportfile_name=strdup(optarg);
      reportfile_open=1;
      break;
    case 'O':
      sample_offset=atoi(optarg);
      break;
    default:
      usage(stderr);
      exit(1);
    }
  }

  if(logfile_open){
    if(logfile_name==NULL)
      logfile_name=strdup("cdparanoia.log");
    if(!strcmp(logfile_name,"-")){
      logfile=stdout;
      logfile_open=0;
    }else{
      logfile=fopen(logfile_name,"w");
      if(logfile==NULL){
	report("Cannot open log summary file %s: %s",logfile_name,
	       strerror(errno));
	exit(1);
      }
    }
  }
  if(reportfile_open){
    if(reportfile_name==NULL)
      reportfile_name=strdup("cdparanoia.log");
    if(!strcmp(reportfile_name,"-")){
      reportfile=stdout;
      reportfile_open=0;
    }else{
      if(logfile_name && !strcmp(reportfile_name,logfile_name)){
	reportfile=logfile;
	reportfile_open=0;
      }else{
	reportfile=fopen(reportfile_name,"w");
	if(reportfile==NULL){
	  report("Cannot open debug log file %s: %s",reportfile_name,
		 strerror(errno));
	  exit(1);
	}
      }
    }
  }
    
  if(logfile){
    /* log command line and version */
    int i;
    for (i = 0; i < argc; i++) 
      fprintf(logfile,"%s ",argv[i]);
    fprintf(logfile,"\n");

    if(reportfile!=logfile){
      fprintf(logfile,VERSION);
      fprintf(logfile,"\n");
      fprintf(logfile,"Using cdda library version: %s\n",cdda_version());
      fprintf(logfile,"Using paranoia library version: %s\n",paranoia_version());
    }
    fflush(logfile);
  }

  if(reportfile && reportfile!=logfile){
    /* log command line */
    int i;
    for (i = 0; i < argc; i++) 
      fprintf(reportfile,"%s ",argv[i]);
    fprintf(reportfile,"\n");
    fflush(reportfile);
  }

  if(optind>=argc && !query_only){
    if(batch)
      span=NULL;
    else{
      /* D'oh.  No span. Fetch me a brain, Igor. */
      usage(stderr);
      exit(1);
    }
  }else
    span=copystring(argv[optind]);

  report(VERSION);
  if(verbose){
    report("Using cdda library version: %s",cdda_version());
    report("Using paranoia library version: %s",paranoia_version());
  }

  /* Query the cdrom/disc; we may need to override some settings */

  if(force_cooked_device){
    d=cdda_identify_cooked(force_cooked_device,verbose,NULL);
  }else if(force_generic_device)
    d=cdda_identify_scsi(force_generic_device,force_cdrom_device,verbose,NULL);
  else
    if(force_cdrom_device)
      d=cdda_identify(force_cdrom_device,verbose,NULL);
    else
      if(search)
	d=cdda_find_a_cdrom(verbose,NULL);
      else{
	/* does the /dev/cdrom link exist? */
	struct stat s;
	if(lstat("/dev/cdrom",&s)){
	  /* no link.  Search anyway */
	  d=cdda_find_a_cdrom(verbose,NULL);
	}else{
	  d=cdda_identify("/dev/cdrom",verbose,NULL);
	  if(d==NULL  && !verbose){
	    verbose=1;
	    report("\n/dev/cdrom exists but isn't accessible.  By default,\n"
		   "cdparanoia stops searching for an accessible drive here.\n"
		   "Consider using -sv to force a more complete autosense\n"
		   "of the machine.\n\nMore information about /dev/cdrom:");

	    d=cdda_identify("/dev/cdrom",CDDA_MESSAGE_PRINTIT,NULL);
	    report("\n");
	    exit(1);
	  }else
	    report(" ");
	}
      }

  if(!d){
    if(!verbose)
      report("\nUnable to open cdrom drive; -v will give more information.");
    exit(1);
  }
  
  if(verbose)
    cdda_verbose_set(d,CDDA_MESSAGE_PRINTIT,CDDA_MESSAGE_PRINTIT);
  else
    cdda_verbose_set(d,CDDA_MESSAGE_PRINTIT,CDDA_MESSAGE_FORGETIT);

  /* possibly force hand on endianness of drive, sector request size */
  if(force_cdrom_endian!=-1){
    d->bigendianp=force_cdrom_endian;
    switch(force_cdrom_endian){
    case 0:
      report("Forcing CDROM sense to little-endian; ignoring preset and autosense");
      break;
    case 1:
      report("Forcing CDROM sense to big-endian; ignoring preset and autosense");
      break;
    }
  }
  if(force_cdrom_sectors!=-1){
    if(force_cdrom_sectors<0 || force_cdrom_sectors>100){
      report("Default sector read size must be 1<= n <= 100\n");
      cdda_close(d);
      d=NULL;
      exit(1);
    }
    report("Forcing default to read %d sectors; "
	   "ignoring preset and autosense",force_cdrom_sectors);
    d->nsectors=force_cdrom_sectors;
    d->bigbuff=force_cdrom_sectors*CD_FRAMESIZE_RAW;
  }
  if(force_cdrom_overlap!=-1){
    if(force_cdrom_overlap<0 || force_cdrom_overlap>75){
      report("Search overlap sectors must be 0<= n <=75\n");
      cdda_close(d);
      d=NULL;
      exit(1);
    }
    report("Forcing search overlap to %d sectors; "
	   "ignoring autosense",force_cdrom_overlap);
  }

  switch(cdda_open(d)){
  case -2:case -3:case -4:case -5:
    report("\nUnable to open disc.  Is there an audio CD in the drive?");
    exit(1);
  case -6:
    report("\ncdparanoia could not find a way to read audio from this drive.");
    exit(1);
  case 0:
    break;
  default:
    report("\nUnable to open disc.");
    exit(1);
  }

  if(force_cdrom_speed==0)force_cdrom_speed=-1;
  if(force_cdrom_speed!=-1){
    report("\nAttempting to set speed to %dx... ",force_cdrom_speed);
  }else{
    if(verbose)
      report("\nAttempting to set cdrom to full speed... ");
  }

  if(cdda_speed_set(d,force_cdrom_speed)){
    if(verbose || force_cdrom_speed!=-1)
      report("\tCDROM speed set FAILED. Continuing anyway...");
  }else{
    if(verbose)
      report("\tdrive returned OK.");
  }
  
  if(run_cache_test){
    int warn=analyze_cache(d, stderr, reportfile, force_cdrom_speed);
    
    if(warn==0){
      reportC("\nDrive tests OK with Paranoia.\n\n");
      return 0;
    }

    if(warn==1)
      reportC("\nWARNING! PARANOIA MAY NOT BE TRUSTWORTHY WITH THIS DRIVE!\n"
	      "\nThe Paranoia library may not model this CDROM drive's cache"
	      "\ncorrectly according to this analysis run. Analysis is not"
	      "\nalways accurate (it can be fooled by machine load or random"
	      "\nkernel latencies), but if a failed result happens more often"
	      "\nthan one time in twenty on an unloaded machine, please mail"
	      "\nthe %s file produced by this failed analysis to"
	      "\[email protected] to assist developers in extending"
	      "\nParanoia to handle this CDROM properly.\n\n",reportfile_name);
    return 1;
  }


  /* Dump the TOC */
  if(query_only || verbose)display_toc(d);
  if(query_only)exit(0);

  /* bias the disc.  A hack.  Of course. */
  /* we may need to read before or past user area; this is never
     default, and we do it because the [allegedly informed] user told
     us to */
  if(sample_offset){
    toc_offset+=sample_offset/588;
    sample_offset%=588;
    if(sample_offset<0){
      sample_offset+=588;
      toc_offset--;
    }
  }

  if(toc_bias){
    toc_offset=-cdda_track_firstsector(d,1);
  }
  for(i=0;i<d->tracks+1;i++)
    d->disc_toc[i].dwStartSector+=toc_offset;


  if(d->nsectors==1){
    report("WARNING: The autosensed/selected sectors per read value is\n"
	   "         one sector, making it very unlikely Paranoia can \n"
	   "         work.\n\n"
	   "         Attempting to continue...\n\n");
  }

  /* parse the span, set up begin and end sectors */

  {
    long first_sector;
    long last_sector;
    long batch_first;
    long batch_last;
    int batch_track;

    if(span){
      /* look for the hyphen */ 
      char *span2=strchr(span,'-');
      if(strrchr(span,'-')!=span2){
	report("Error parsing span argument");
	cdda_close(d);
	d=NULL;
	exit(1);
      }
      
      if(span2!=NULL){
	*span2='\0';
	span2++;
      }
      
      first_sector=parse_offset(d,span,-1);
      if(first_sector==-1)
	last_sector=parse_offset(d,span2,cdda_disc_firstsector(d));
      else
	last_sector=parse_offset(d,span2,first_sector);
      
      if(first_sector==-1){
	if(last_sector==-1){
	  report("Error parsing span argument");
	  cdda_close(d);
	  d=NULL;
	  exit(1);
	}else{
	  first_sector=cdda_disc_firstsector(d);
	}
      }else{
	if(last_sector==-1){
	  if(span2){ /* There was a hyphen */
	    last_sector=cdda_disc_lastsector(d);
	  }else{
	    last_sector=
	      cdda_track_lastsector(d,cdda_sector_gettrack(d,first_sector));
	  }
	}
      }
    }else{
      first_sector=cdda_disc_firstsector(d);
      last_sector=cdda_disc_lastsector(d);
    }

    {
      int track1=cdda_sector_gettrack(d,first_sector);
      int track2=cdda_sector_gettrack(d,last_sector);
      long off1=first_sector-cdda_track_firstsector(d,track1);
      long off2=last_sector-cdda_track_firstsector(d,track2);
      int i;

      for(i=track1;i<=track2;i++)
	if(!cdda_track_audiop(d,i)){
	  report("Selected span contains non audio tracks.  Aborting.\n\n");
	  exit(1);
	}

      report("Ripping from sector %7ld (track %2d [%d:%02d.%02d])\n"
	     "\t  to sector %7ld (track %2d [%d:%02d.%02d])\n",first_sector,
	     track1,(int)(off1/(60*75)),(int)((off1/75)%60),(int)(off1%75),
	     last_sector,
	     track2,(int)(off2/(60*75)),(int)((off2/75)%60),(int)(off2%75));
      
    }

    {
      long cursor;
      int16_t offset_buffer[1176];
      int offset_buffer_used=0;
      int offset_skip=sample_offset*4;

      p=paranoia_init(d);
      paranoia_modeset(p,paranoia_mode);
      if(force_cdrom_overlap!=-1)paranoia_overlapset(p,force_cdrom_overlap);

      if(verbose)
        cdda_verbose_set(d,CDDA_MESSAGE_LOGIT,CDDA_MESSAGE_LOGIT);
      else
        cdda_verbose_set(d,CDDA_MESSAGE_FORGETIT,CDDA_MESSAGE_FORGETIT);

      paranoia_seek(p,cursor=first_sector,SEEK_SET);      

      /* this is probably a good idea in general */
      seteuid(getuid());
      setegid(getgid());

      /* we'll need to be able to read one sector past user data if we
	 have a sample offset in order to pick up the last bytes.  We
	 need to set the disc length forward here so that the libs are
	 willing to read past, assuming that works on the hardware, of
	 course */
      if(sample_offset)
	d->disc_toc[d->tracks].dwStartSector++;

      while(cursor<=last_sector){
	char outfile_name[256];
	if(batch){
	  batch_first=cursor;
	  batch_last=
	    cdda_track_lastsector(d,batch_track=
				  cdda_sector_gettrack(d,cursor));
	  if(batch_last>last_sector)batch_last=last_sector;
	}else{
	  batch_first=first_sector;
	  batch_last=last_sector;
	  batch_track=-1;
	}
	
	callbegin=batch_first;
	callend=batch_last;
	
	/* argv[optind] is the span, argv[optind+1] (if exists) is outfile */
	
	if(optind+1<argc){
	  if(!strcmp(argv[optind+1],"-")){
	    out=dup(fileno(stdout));
	    if(batch)report("Are you sure you wanted 'batch' "
			    "(-B) output with stdout?");
	    report("outputting to stdout\n");
	    if(logfile){
	      fprintf(logfile,"outputting to stdout\n");
	      fflush(logfile);
	    }
	    outfile_name[0]='\0';
	  }else{
	    char path[256];

	    char *post=strrchr(argv[optind+1],'/');
	    int pos=(post?post-argv[optind+1]+1:0);
	    char *file=argv[optind+1]+pos;
	    
	    path[0]='\0';

	    if(pos)
	      strncat(path,argv[optind+1],pos>256?256:pos);

	    if(batch)
	      snprintf(outfile_name,246,"%strack%02d.%s",path,batch_track,file);
	    else
	      snprintf(outfile_name,246,"%s%s",path,file);

	    if(file[0]=='\0'){
	      switch(output_type){
	      case 0: /* raw */
		strcat(outfile_name,"cdda.raw");
		break;
	      case 1:
		strcat(outfile_name,"cdda.wav");
		break;
	      case 2:
		strcat(outfile_name,"cdda.aifc");
		break;
	      case 3:
		strcat(outfile_name,"cdda.aiff");
		break;
	      }
	    }
	    
	    out=open(outfile_name,O_RDWR|O_CREAT|O_TRUNC,0666);
	    if(out==-1){
	      report("Cannot open specified output file %s: %s",outfile_name,
		      strerror(errno));
	      cdda_close(d);
	      d=NULL;
	      exit(1);
	    }
	    report("outputting to %s\n",outfile_name);
	    if(logfile){
	      fprintf(logfile,"outputting to %s\n",outfile_name);
	      fflush(logfile);
	    }
	  }
	}else{
	  /* default */
	  if(batch)
	    sprintf(outfile_name,"track%02d.",batch_track);
	  else
	    outfile_name[0]='\0';
	  
	  switch(output_type){
	  case 0: /* raw */
	    strcat(outfile_name,"cdda.raw");
	    break;
	  case 1:
	    strcat(outfile_name,"cdda.wav");
	    break;
	  case 2:
	    strcat(outfile_name,"cdda.aifc");
	    break;
	  case 3:
	    strcat(outfile_name,"cdda.aiff");
	    break;
	  }
	  
	  out=open(outfile_name,O_RDWR|O_CREAT|O_TRUNC,0666);
	  if(out==-1){
	    report("Cannot open default output file %s: %s",outfile_name,
		    strerror(errno));
	    cdda_close(d);
	    d=NULL;
	    exit(1);
	  }
	  report("outputting to %s\n",outfile_name);
	  if(logfile){
	    fprintf(logfile,"outputting to %s\n",outfile_name);
	    fflush(logfile);
	  }
	}
	
	switch(output_type){
	case 0: /* raw */
	  break;
	case 1: /* wav */
	  WriteWav(out,(batch_last-batch_first+1)*CD_FRAMESIZE_RAW);
	  break;
	case 2: /* aifc */
	  WriteAifc(out,(batch_last-batch_first+1)*CD_FRAMESIZE_RAW);
	  break;
	case 3: /* aiff */
	  WriteAiff(out,(batch_last-batch_first+1)*CD_FRAMESIZE_RAW);
	  break;
	}
	
	/* Off we go! */

	if(offset_buffer_used){
	  /* partial sector from previous batch read */
	  cursor++;
	  if(buffering_write(out,
			     ((char *)offset_buffer)+offset_buffer_used,
			     CD_FRAMESIZE_RAW-offset_buffer_used)){
	    report("Error writing output: %s",strerror(errno));
	    exit(1);
	  }
	}
	
	skipped_flag=0;
	while(cursor<=batch_last){
	  /* read a sector */
	  int16_t *readbuf=paranoia_read_limited(p,callback,max_retries);
	  char *err=cdda_errors(d);
	  char *mes=cdda_messages(d);

	  if(mes || err)
	    fprintf(stderr,"\r                               "
		    "                                           \r%s%s\n",
		    mes?mes:"",err?err:"");
	  
	  if(err)free(err);
	  if(mes)free(mes);
	  if(readbuf==NULL){
	    if(errno==EBADF || errno==ENOMEDIUM){
	      report("\nparanoia_read: CDROM drive unavailable, bailing.\n");
	      exit(1);
	    }
	    skipped_flag=1;
	    report("\nparanoia_read: Unrecoverable error, bailing.\n");
	    break;
	  }
	  if(skipped_flag && abort_on_skip){
	    cursor=batch_last+1;
	    break;
	  }

	  skipped_flag=0;
	  cursor++;
	  
	  if(output_endian!=bigendianp()){
	    int i;
	    for(i=0;i<CD_FRAMESIZE_RAW/2;i++)readbuf[i]=swap16(readbuf[i]);
	  }
	  
	  callback(cursor*(CD_FRAMEWORDS)-1,-2);

	  if(buffering_write(out,((char *)readbuf)+offset_skip,
			     CD_FRAMESIZE_RAW-offset_skip)){
	    report("Error writing output: %s",strerror(errno));
	    exit(1);
	  }
	  offset_skip=0;
	  
	  if(output_endian!=bigendianp()){
	    int i;
	    for(i=0;i<CD_FRAMESIZE_RAW/2;i++)readbuf[i]=swap16(readbuf[i]);
	  }

	  /* One last bit of silliness to deal with sample offsets */
	  if(sample_offset && cursor>batch_last){
	    int i;
	    /* read a sector and output the partial offset.  Save the
               rest for the next batch iteration */
	    readbuf=paranoia_read_limited(p,callback,max_retries);
	    err=cdda_errors(d);mes=cdda_messages(d);

	    if(mes || err)
	      fprintf(stderr,"\r                               "
		      "                                           \r%s%s\n",
		      mes?mes:"",err?err:"");
	  
	    if(err)free(err);if(mes)free(mes);
	    if(readbuf==NULL){
	      skipped_flag=1;
	      report("\nparanoia_read: Unrecoverable error reading through "
		     "sample_offset shift\n\tat end of track, bailing.\n");
	      break;
	    }
	    if(skipped_flag && abort_on_skip)break;
	    skipped_flag=0;
	    /* do not move the cursor */
	  
	    if(output_endian!=bigendianp())
	      for(i=0;i<CD_FRAMESIZE_RAW/2;i++)
		offset_buffer[i]=swap16(readbuf[i]);
	    else
	      memcpy(offset_buffer,readbuf,CD_FRAMESIZE_RAW);
	    offset_buffer_used=sample_offset*4;
	  
	    callback(cursor*(CD_FRAMEWORDS),-2);

	    if(buffering_write(out,(char *)offset_buffer,
			       offset_buffer_used)){
	      report("Error writing output: %s",strerror(errno));
	      exit(1);
	    }
	  }
	}
	callback(cursor*(CD_FRAMESIZE_RAW/2)-1,-1);
	buffering_close(out);
	if(skipped_flag){
	  /* remove the file */
	  report("\nRemoving aborted file: %s",outfile_name);
	  unlink(outfile_name);
	  /* make the cursor correct if we have another track */
	  if(batch_track!=-1){
	    batch_track++;
	    cursor=cdda_track_firstsector(d,batch_track);
	    paranoia_seek(p,cursor,SEEK_SET);      
	    offset_skip=sample_offset*4;
	    offset_buffer_used=0;
	  }
	}
	report("\n");
      }

      paranoia_free(p);
      p=NULL;
    }
  }

  report("Done.\n\n");
  
  cdda_close(d);
  d=NULL;
  if(logfile_open)
    fclose(logfile);
  if(reportfile_open)
    fclose(reportfile);
  return 0;
}
Exemple #15
0
int main(int argc, char **argv)
{
	struct extract_options options = { NULL, ".", 0, SIZE_MAX, 0, (SIZE_MAX>>1), DEFAULT_FORMATS, 0, 0 };
	int i = 0, opt = 0;
	size_t failures = 0;
	size_t sumnumfiles = 0;
	size_t numfiles = 0;
	size_t size = 0;
	size_t sumsize = 0;

	while ((opt = getopt_long(argc, argv, "f:o:hqm:x:n:i:s", long_options, NULL)) != -1)
	{
		switch (opt)
		{
			case 'f':
				if (!parse_formats(optarg, &options.formats))
					return 255;
				else if (options.formats == 0)
				{
					fprintf(stderr, "error: No formats specified.\n"SEE_HELP);
					return 255;
				}
				break;

			case 'o':
				options.outdir = optarg;
				break;

			case 'h':
				return usage(argc, argv);

			case 'q':
				options.quiet = 1;
				break;

			case 'x':
			case 'm':
			case 'n':
				if (!parse_size(optarg, &size))
				{
					perror(optarg);
					fprintf(stderr, SEE_HELP);
					return 255;
				}

				if (opt == 'm')
					options.minsize = size;
				else if (opt == 'x')
					options.maxsize = size;
				else
					options.length  = size;
				break;

			case 'i':
				if (!parse_offset(optarg, &(options.offset)))
				{
					perror(optarg);
					fprintf(stderr, SEE_HELP);
					return 255;
				}
				break;

			case 's':
				options.simulate = 1;
				break;

			default:
				fprintf(stderr, SEE_HELP);
				return 255;
		}
	}

	if (optind >= argc)
	{
		fprintf(stderr, "error: Not enough arguments.\n"SEE_HELP);
		return 1;
	}

	if (options.length == 0)
	{
		if (!options.quiet)
			printf("Nothing to extract for 0-length range.\n");
		return 0;
	}

	for (i = optind; i < argc; ++ i)
	{
		options.filepath = argv[i];
		numfiles = 0;
		size = 0;
		if (extract(&options, &numfiles, &size))
		{
			sumnumfiles += numfiles;
			sumsize += size;
		}
		else {
			fprintf(stderr, "Error processing file: %s\n", options.filepath);
			failures += 1;
		}
	}

	double sz = 0;
	const char *sz_unit = format_size(sumsize, &sz);
	if (sumnumfiles == 1)
		printf("Extracted 1 file of %g %s size.\n", sz, sz_unit);
	else
		printf("Extracted %"PRIzu" files of %g %s size.\n", sumnumfiles, sz, sz_unit);

	if (failures > 0)
	{
		fprintf(stderr, "%"PRIzu" error(s) during extraction.\n", failures);
		return 1;
	}
	return 0;
}
Exemple #16
0
bool_t tz_parse (unsigned char *str, struct tz_t *tz)
{
	unsigned char *s;

	memset (tz, 0, sizeof (*tz));

	if (! str || *str == 0) {
		tz->name_std[0] = tz->name_dst[0] = 'G';
		tz->name_std[1] = tz->name_dst[1] = 'M';
		tz->name_std[2] = tz->name_dst[2] = 'T';
		goto ok;
	}

	/* LY: scan for STD name. */
	for (s = str; *s >= 'A' && *s <= 'Z'; )
		s++;
	if (s != str + 3)
		goto ballout;
	tz->name_std[0] = str[0];
	tz->name_std[1] = str[1];
	tz->name_std[2] = str[2];

	/* LY: parse STD offset. */
	str = parse_offset (s, &tz->offset_std);
	if (! str)
		goto ballout;

	if (*str == 0) {
		/* LY: there is no DST. */
		tz->name_dst[0] = tz->name_std[0];
		tz->name_dst[1] = tz->name_std[1];
		tz->name_dst[2] = tz->name_std[2];
		tz->offset_dst = tz->offset_std;
		goto ok;
	}

	/* LY: scan for DST name. */
	for (s = str; *s >= 'A' && *s <= 'Z'; )
		s++;
	if (s == str + 3) {
		tz->name_dst[0] = str[0];
		tz->name_dst[1] = str[1];
		tz->name_dst[2] = str[2];

		/* LY: parse DST offset. */
		str = parse_offset (s, &tz->offset_dst);
		if (! str)
			goto ballout;
	} else if (s != str)
		goto ballout;

	/* LY: start = 2am of last week sunday of March. */
	tz->start.month = 3;
	tz->start.week = 5;
	tz->start.day = 0;
	tz->start.seconds = 3600 * 2;
	if (*str == ',') {
		str = parse_rule (str + 1, &tz->start);
		if (! str)
			goto ballout;
	}

	/* LY: end = 3am of last week sunday of October. */
	tz->end.month = 10;
	tz->end.week = 5;
	tz->end.day = 0;
	tz->end.seconds = 3600 * 3;
	if (*str == ',') {
		str = parse_rule (str + 1, &tz->end);
		if (! str)
			goto ballout;
	}

	if (*str != 0)
		goto ballout;

ok:
	return 1;

ballout:
	return 0;
}
Exemple #17
0
int
main(int argc, char **argv)
{
    MM_INFO *mm;
    char *mmtype = NULL;
    int ch;
    SSIZE_T imgoff = 0;
    char *imgtype = NULL;
    IMG_INFO *img;

    progname = argv[0];

    while ((ch = getopt(argc, argv, "i:o:t:vV")) > 0) {
	switch (ch) {
	case 'i':
	    imgtype = optarg;
	    break;

	case 'o':
	    if ((imgoff = parse_offset(optarg)) == -1) {
		tsk_error_print(stderr);
		exit(1);
	    }

	    break;
	case 't':
	    mmtype = optarg;
	    break;
	case 'v':
	    verbose++;
	    break;
	case 'V':
	    print_version(stdout);
	    exit(0);
	case '?':
	default:
	    fprintf(stderr, "Unknown argument\n");
	    usage();
	}
    }

    /* We need at least one more argument */
    if (optind >= argc) {
	fprintf(stderr, "Missing image name\n");
	usage();
    }

    /* open the image */
    if ((img =
	    img_open(imgtype, argc - optind,
		(const char **) &argv[optind])) == NULL) {
	tsk_error_print(stderr);
	exit(1);
    }


    /* process the partition tables */
    if ((mm = mm_open(img, imgoff, mmtype)) == NULL) {
	tsk_error_print(stderr);
	if (tsk_errno == TSK_ERR_MM_UNSUPTYPE)
	    mm_print_types(stderr);

	exit(1);
    }

    print_stats(mm);

    mm->close(mm);
    img->close(img);
    exit(0);
}
Exemple #18
0
void parse_options(int argc, char **argv)
{
    int opt;

    if (argc < 2) {
        usage();
        exit(1);
    }

    while ((opt = getopt(argc, argv, "hvkALRDCWBqi:w:s:S:c:o:p:P:")) != -1) {
        switch (opt) {
        case 'h':
            usage();
            exit(0);
        case 'v':
            version();
            exit(0);
        case 'L':
            randomize = 0;
            default_size = 1<<18;
            break;
        case 'R':
            interval = 0;
            deadline = 3000000;
            temp_wsize = 1<<26;
            quiet = 1;
            break;
        case 'D':
            direct = 1;
            break;
        case 'C':
            cached = 1;
            break;
        case 'A':
            async = 1;
            break;
        case 'W':
            write_test++;
            break;
        case 'i':
            interval = parse_time(optarg);
            break;
        case 'w':
            deadline = parse_time(optarg);
            break;
        case 's':
            size = parse_size(optarg);
            break;
        case 'S':
            wsize = parse_offset(optarg);
            break;
        case 'o':
            offset = parse_offset(optarg);
            break;
        case 'p':
            period_request = parse_int(optarg);
            break;
        case 'P':
            period_time = parse_time(optarg);
            break;
        case 'q':
            quiet = 1;
            break;
        case 'B':
            quiet = 1;
            batch_mode = 1;
            break;
        case 'c':
            stop_at_request = parse_int(optarg);
            break;
        case 'k':
            keep_file = 1;
            break;
        case '?':
            usage();
            exit(1);
        }
    }

    if (optind > argc-1)
        errx(1, "no destination specified");
    if (optind < argc-1)
        errx(1, "more than one destination specified");
    path = argv[optind];
}
Exemple #19
0
static int
parse_label(struct sun_disklabel *sl, const char *file)
{
	char offset[32];
	char size[32];
	char flag[32];
	char tag[32];
	char buf[128];
	char text[128];
	char volname[SUN_VOLNAME_LEN + 1];
	struct sun_disklabel sl1;
	char *bp;
	const char *what;
	uint8_t part;
	FILE *fp;
	int line;
	int rv;
	int wantvtoc;
	unsigned alt, cyl, hd, nr, sec;

	line = wantvtoc = 0;
	if ((fp = fopen(file, "r")) == NULL)
		err(1, "fopen");
	sl1 = *sl;
	bzero(&sl1.sl_part, sizeof(sl1.sl_part));
	while (fgets(buf, sizeof(buf), fp) != NULL) {
		/*
		 * In order to recognize a partition entry, we search
		 * for lines starting with a single letter followed by
		 * a colon as their first non-white characters.  We
		 * silently ignore any other lines, so any comment etc.
		 * lines in the label template will be ignored.
		 *
		 * XXX We should probably also recognize the geometry
		 * fields on top, and allow changing the geometry
		 * emulated by this disk.
		 */
		for (bp = buf; isspace(*bp); bp++)
			;
		if (strncmp(bp, "text:", strlen("text:")) == 0) {
			bp += strlen("text:");
			rv = sscanf(bp,
			    " %s cyl %u alt %u hd %u sec %u",
			    text, &cyl, &alt, &hd, &sec);
			if (rv != 5) {
				warnx("%s, line %d: text label does not "
				    "contain required fields",
				    file, line + 1);
				fclose(fp);
				return (1);
			}
			if (alt != 2) {
				warnx("%s, line %d: # alt must be equal 2",
				    file, line + 1);
				fclose(fp);
				return (1);
			}
			if (cyl == 0 || cyl > USHRT_MAX) {
				what = "cyl";
				nr = cyl;
			unreasonable:
				warnx("%s, line %d: # %s %d unreasonable",
				    file, line + 1, what, nr);
				fclose(fp);
				return (1);
			}
			if (hd == 0 || hd > USHRT_MAX) {
				what = "hd";
				nr = hd;
				goto unreasonable;
			}
			if (sec == 0 || sec > USHRT_MAX) {
				what = "sec";
				nr = sec;
				goto unreasonable;
			}
			if (mediasize == 0)
				warnx("unit size unknown, no sector count "
				    "check could be done");
			else if ((uintmax_t)(cyl + alt) * sec * hd >
				 (uintmax_t)mediasize / sectorsize) {
				warnx("%s, line %d: sector count %ju exceeds "
				    "unit size %ju",
				    file, line + 1,
				    (uintmax_t)(cyl + alt) * sec * hd,
				    (uintmax_t)mediasize / sectorsize);
				fclose(fp);
				return (1);
			}
			sl1.sl_pcylinders = cyl + alt;
			sl1.sl_ncylinders = cyl;
			sl1.sl_acylinders = alt;
			sl1.sl_nsectors = sec;
			sl1.sl_ntracks = hd;
			memset(sl1.sl_text, 0, sizeof(sl1.sl_text));
			snprintf(sl1.sl_text, sizeof(sl1.sl_text),
			    "%s cyl %u alt %u hd %u sec %u",
			    text, cyl, alt, hd, sec);
			continue;
		}
		if (strncmp(bp, "volume name:", strlen("volume name:")) == 0) {
			wantvtoc = 1; /* Volume name requires VTOC. */
			bp += strlen("volume name:");
#if SUN_VOLNAME_LEN != 8
# error "scanf field width does not match SUN_VOLNAME_LEN"
#endif
			/*
			 * We set the field length to one more than
			 * SUN_VOLNAME_LEN to allow detecting an
			 * overflow.
			 */
			memset(volname, 0, sizeof volname);
			rv = sscanf(bp, " %9[^\n]", volname);
			if (rv != 1) {
				/* Clear the volume name. */
				memset(sl1.sl_vtoc_volname, 0,
				    SUN_VOLNAME_LEN);
			} else {
				memcpy(sl1.sl_vtoc_volname, volname,
				    SUN_VOLNAME_LEN);
				if (volname[SUN_VOLNAME_LEN] != '\0')
					warnx(
"%s, line %d: volume name longer than %d characters, truncating",
					    file, line + 1, SUN_VOLNAME_LEN);
			}
			continue;
		}
		if (strlen(bp) < 2 || bp[1] != ':') {
			line++;
			continue;
		}
		rv = sscanf(bp, "%c: %30s %30s %30s %30s",
		    &part, size, offset, tag, flag);
		if (rv < 3) {
		syntaxerr:
			warnx("%s: syntax error on line %d",
			    file, line + 1);
			fclose(fp);
			return (1);
		}
		if (parse_size(&sl1, part - 'a', size) ||
		    parse_offset(&sl1, part - 'a', offset))
			goto syntaxerr;
		if (rv > 3) {
			wantvtoc = 1;
			if (rv == 5 && parse_flag(&sl1, part - 'a', flag))
				goto syntaxerr;
			if (parse_tag(&sl1, part - 'a', tag))
				goto syntaxerr;
		}
		line++;
	}
	fclose(fp);
	if (wantvtoc) {
		sl1.sl_vtoc_sane = SUN_VTOC_SANE;
		sl1.sl_vtoc_vers = SUN_VTOC_VERSION;
		sl1.sl_vtoc_nparts = SUN_NPART;
	} else {
		sl1.sl_vtoc_sane = 0;
		sl1.sl_vtoc_vers = 0;
		sl1.sl_vtoc_nparts = 0;
		bzero(&sl1.sl_vtoc_map, sizeof(sl1.sl_vtoc_map));
	}
	*sl = sl1;
	return (check_label(sl));
}
int
main(int argc,char *argv[])
{
  int   toc_bias             =  0;
  int   force_cdrom_endian   = -1;
  int   output_type          =  1; /* 0=raw, 1=wav, 2=aifc */
  int   output_endian        =  0; /* -1=host, 0=little, 1=big */
  int   query_only           =  0;
  int   batch                =  0;
  int   run_cache_test       =  0;
  long int force_cdrom_overlap  = -1;
  long int force_cdrom_sectors  = -1;
  long int force_cdrom_speed    =  0;
  long int force_overread       =  0;
  long int sample_offset        =  0;
  long int test_flags           =  0;
  long int toc_offset           =  0;
  long int max_retries          = 20;

  char *logfile_name=NULL;
  char *reportfile_name=NULL;

  /* full paranoia, but allow skipping */
  int paranoia_mode=PARANOIA_MODE_FULL^PARANOIA_MODE_NEVERSKIP;

  int out;

  int c,long_option_index;

  atexit(cleanup);

  while((c=getopt_long(argc,argv,optstring,options,&long_option_index))!=EOF){
    switch(c){
    case 'a':
      output_type=2;
      output_endian=1;
      break;
    case 'B':
      batch=1;
      break;
    case 'c':
      force_cdrom_endian=0;
      break;
    case 'C':
      force_cdrom_endian=1;
      break;
    case 'e':
      callscript=1;
      fprintf(stderr,
              "Sending all callback output to stderr for wrapper script\n");
      break;
    case 'f':
      output_type=3;
      output_endian=1;
      break;
    case 'F':
      paranoia_mode&=~(PARANOIA_MODE_FRAGMENT);
      break;
    case 'g':
    case 'k':
    case 'd':
      if (force_cdrom_device) {
        fprintf(stderr,
                "Multiple cdrom devices given. Previous device %s ignored\n",
                force_cdrom_device);
        free(force_cdrom_device);
      }
      force_cdrom_device=strdup(optarg);
      break;
    case 'h':
      usage(stdout);
      exit(0);
    case 'l':
      if(logfile_name)free(logfile_name);
      logfile_name=NULL;
      if(optarg)
	logfile_name=strdup(optarg);
      logfile_open=1;
      break;
    case 'L':
      if(reportfile_name)free(reportfile_name);
      reportfile_name=NULL;
      if(optarg)
	reportfile_name=strdup(optarg);
      reportfile_open=1;
      break;
    case 'm':
      {
        long int mmc_timeout_sec;
        if (get_int_arg(c, &mmc_timeout_sec)) {
          mmc_timeout_ms = 1000*mmc_timeout_sec;
        }
      }
      break;
    case 'n':
      get_int_arg(c, &force_cdrom_sectors);
      break;
    case 'o':
      get_int_arg(c, &force_cdrom_overlap);
      break;
    case 'O':
      get_int_arg(c, &sample_offset);
      break;
    case 'p':
      output_type=0;
      output_endian=-1;
      break;
    case 'r':
      output_type=0;
      output_endian=0;
      break;
    case 'q':
      verbose=CDDA_MESSAGE_FORGETIT;
      quiet=1;
      break;
    case 'Q':
      query_only=1;
      break;
    case 'R':
      output_type=0;
      output_endian=1;
      break;
    case 'S':
      get_int_arg(c, &force_cdrom_speed);
      break;
    case 't':
      get_int_arg(c, &toc_offset);
      break;
    case 'T':
      toc_bias=-1;
      break;
    case 'v':
      verbose=CDDA_MESSAGE_PRINTIT;
      quiet=0;
      break;
    case 'V':
      fprintf(stderr,PARANOIA_VERSION);
      fprintf(stderr,"\n");
      exit(0);
      break;
    case 'w':
      output_type=1;
      output_endian=0;
      break;
    case 'W':
      paranoia_mode&=~PARANOIA_MODE_REPAIR;
      break;
    case 'x':
      get_int_arg(c, &test_flags);
      break;
    case 'X':
      /*paranoia_mode&=~(PARANOIA_MODE_SCRATCH|PARANOIA_MODE_REPAIR);*/
      abort_on_skip=1;
      break;
    case 'Y':
      paranoia_mode|=PARANOIA_MODE_OVERLAP; /* cdda2wav style overlap
                                                check only */
      paranoia_mode&=~PARANOIA_MODE_VERIFY;
      break;
    case 'Z':
      paranoia_mode=PARANOIA_MODE_DISABLE;
      break;
    case 'A':
      run_cache_test=1;
      query_only=1;
      reportfile_open=1;
      verbose=CDDA_MESSAGE_PRINTIT;
      break;
    case 'z':
      if (optarg) {
        get_int_arg(c, &max_retries);
        paranoia_mode&=~PARANOIA_MODE_NEVERSKIP;
      } else {
        paranoia_mode|=PARANOIA_MODE_NEVERSKIP;
      }
      break;
    case 'E':
      force_overread=1;
      break;
    default:
      usage(stderr);
      exit(1);
    }
  }

  if(logfile_open){
    if(logfile_name==NULL)
      logfile_name=strdup("cdparanoia.log");
    if(!strcmp(logfile_name,"-")){
      logfile=stdout;
      logfile_open=0;
    }else{
      logfile=fopen(logfile_name,"w");
      if(logfile==NULL){
	report("Cannot open log summary file %s: %s",logfile_name,
	       strerror(errno));
	exit(1);
      }
    }
  }
  if(reportfile_open){
    if(reportfile_name==NULL)
      reportfile_name=strdup("cdparanoia.log");
    if(!strcmp(reportfile_name,"-")){
      reportfile=stdout;
      reportfile_open=0;
    }else{
      if(logfile_name && !strcmp(reportfile_name,logfile_name)){
	reportfile=logfile;
	reportfile_open=0;
      }else{
	reportfile=fopen(reportfile_name,"w");
	if(reportfile==NULL){
	  report("Cannot open debug log file %s: %s",reportfile_name,
		 strerror(errno));
	  exit(1);
	}
      }
    }
  }

  if(logfile){
    /* log command line and version */
    int i;
    for (i = 0; i < argc; i++)
      fprintf(logfile,"%s ",argv[i]);
    fprintf(logfile,"\n");

    if(reportfile!=logfile){
      fprintf(logfile,VERSION);
      fprintf(logfile,"\n");
      fprintf(logfile,"Using cdda library version: %s\n",cdda_version());
      fprintf(logfile,"Using paranoia library version: %s\n",paranoia_version());
    }
    fflush(logfile);
  }

  if(reportfile && reportfile!=logfile){
    /* log command line */
    int i;
    for (i = 0; i < argc; i++)
      fprintf(reportfile,"%s ",argv[i]);
    fprintf(reportfile,"\n");
    fflush(reportfile);
  }

  if(optind>=argc && !query_only){
    if(batch)
      span=NULL;
    else{
      /* D'oh.  No span. Fetch me a brain, Igor. */
      usage(stderr);
      exit(1);
    }
  }else
    if (argv[optind]) span=strdup(argv[optind]);

  report(PARANOIA_VERSION);
  if(verbose){
    report("Using cdda library version: %s",cdda_version());
    report("Using paranoia library version: %s",paranoia_version());
  }

  /* Query the cdrom/disc; we may need to override some settings */

  if(force_cdrom_device)
    d=cdda_identify(force_cdrom_device,verbose,NULL);
  else {
    driver_id_t driver_id;
    char **ppsz_cd_drives = cdio_get_devices_with_cap_ret(NULL,
                                                          CDIO_FS_AUDIO,
                                                          false,
                                                          &driver_id);
    if (ppsz_cd_drives && *ppsz_cd_drives) {
      d=cdda_identify(*ppsz_cd_drives,verbose, NULL);
    } else {
      report("\nUnable find or access a CD-ROM drive with an audio CD"
             " in it.");
      report("\nYou might try specifying the drive, especially if it has"
             " mixed-mode (and non-audio) format tracks");
      exit(1);
    }

    cdio_free_device_list(ppsz_cd_drives);
  }

  if(!d){
    if(!verbose)
      report("\nUnable to open cdrom drive; -v might give more information.");
    exit(1);
  }

  if(verbose)
    cdda_verbose_set(d,CDDA_MESSAGE_PRINTIT,CDDA_MESSAGE_PRINTIT);
  else
    cdda_verbose_set(d,CDDA_MESSAGE_PRINTIT,CDDA_MESSAGE_FORGETIT);

  /* possibly force hand on endianness of drive, sector request size */
  if(force_cdrom_endian!=-1){
    d->bigendianp=force_cdrom_endian;
    switch(force_cdrom_endian){
    case 0:
      report("Forcing CDROM sense to little-endian; ignoring preset and autosense");
      break;
    case 1:
      report("Forcing CDROM sense to big-endian; ignoring preset and autosense");
      break;
    }
  }
  if (force_cdrom_sectors!=-1) {
    if(force_cdrom_sectors<0 || force_cdrom_sectors>100){
      report("Default sector read size must be 1<= n <= 100\n");
      cdda_close(d);
      d=NULL;
      exit(1);
    }
    report("Forcing default to read %ld sectors; "
	   "ignoring preset and autosense",force_cdrom_sectors);
    d->nsectors=force_cdrom_sectors;
  }
  if (force_cdrom_overlap!=-1) {
    if (force_cdrom_overlap<0 || force_cdrom_overlap>CDIO_CD_FRAMES_PER_SEC) {
      report("Search overlap sectors must be 0<= n <=75\n");
      cdda_close(d);
      d=NULL;
      if(logfile && logfile != stdout)
        fclose(logfile);
      exit(1);
    }
    report("Forcing search overlap to %ld sectors; "
	   "ignoring autosense",force_cdrom_overlap);
  }

  switch( cdda_open(d) ) {
  case -2:case -3:case -4:case -5:
    report("\nUnable to open disc.  Is there an audio CD in the drive?");
    exit(1);
  case -6:
    report("\nCdparanoia could not find a way to read audio from this drive.");
    exit(1);
  case 0:
    break;
  default:
    report("\nUnable to open disc.");
    exit(1);
  }

  d->i_test_flags = test_flags;

  if (force_cdrom_speed == 0) force_cdrom_speed = -1;

  if (force_cdrom_speed != -1) {
    report("\nAttempting to set speed to %ldx... ", force_cdrom_speed);
  } else {
    if (verbose)
      report("\nAttempting to set cdrom to full speed... ");
  }

  if (cdda_speed_set(d, force_cdrom_speed)) {
    if (verbose || force_cdrom_speed != -1)
      report("\tCDROM speed set FAILED. Continuing anyway...");
  } else {
    if (verbose)
      report("\tdrive returned OK.");
  }

  if(run_cache_test){
    int warn=analyze_cache(d, stderr, reportfile, force_cdrom_speed);

    if(warn==0){
      reportC("\nDrive tests OK with Paranoia.\n\n");
      return 0;
    }

    if(warn==1)
      reportC("\nWARNING! PARANOIA MAY NOT BE TRUSTWORTHY WITH THIS DRIVE!\n"
	      "\nThe Paranoia library may not model this CDROM drive's cache"
	      "\ncorrectly according to this analysis run. Analysis is not"
	      "\nalways accurate (it can be fooled by machine load or random"
	      "\nkernel latencies), but if a failed result happens more often"
	      "\nthan one time in twenty on an unloaded machine, please mail"
	      "\nthe %s file produced by this failed analysis to"
	      "\[email protected] to assist developers in extending"
	      "\nParanoia to handle this CDROM properly.\n\n",reportfile_name);
    return 1;
  }


  /* Dump the TOC */
  if (query_only || verbose ) display_toc(d);

  if (query_only) exit(0);

  /* bias the disc.  A hack.  Of course. this is never the default. */
  /*
     Some CD-ROM/CD-R drives will add an offset to the position on
     reading audio data. This is usually around 500-700 audio samples
     (ca. 1/75 second) on reading. So when this program queries a
     specific sector, it might not receive exactly that sector, but
     shifted by some amount.

     Note that if ripping includes the end of the CD, this will this
     cause this program to attempt to read partial sectors before or
     past the known user data area of the disc, probably causing read
     errors on most drives and possibly even hard lockups on some
     buggy hardware.

     [Note to libcdio driver hackers: make sure all CD-drivers don't
     try to read outside of the stated disc boundaries.]
  */
  if(sample_offset){
    toc_offset+=sample_offset/588;
    sample_offset%=588;
    if(sample_offset<0){
      sample_offset+=588;
      toc_offset--;
    }
  }

  if (toc_bias) {
    toc_offset = -cdda_track_firstsector(d,1);
  }

  {
    int i;
    for( i=0; i < d->tracks+1; i++ )
      d->disc_toc[i].dwStartSector+=toc_offset;
  }

  if (d->nsectors==1) {
    report("WARNING: The autosensed/selected sectors per read value is\n"
           "         one sector, making it very unlikely Paranoia can \n"
           "         work.\n\n"
           "         Attempting to continue...\n\n");
  }

  /* parse the span, set up begin and end sectors */

  {
    long i_first_lsn;
    long i_last_lsn;
    long batch_first;
    long batch_last;
    int batch_track;

    if (span) {
      /* look for the hyphen */
      char *span2=strchr(span,'-');
      if(strrchr(span,'-')!=span2){
        report("Error parsing span argument");
        exit(1);
      }

      if (span2!=NULL) {
        *span2='\0';
        span2++;
      }

      i_first_lsn=parse_offset(d, span, -1);

      if(i_first_lsn==-1)
        i_last_lsn=parse_offset(d, span2, cdda_disc_firstsector(d));

      else
        i_last_lsn=parse_offset(d, span2, i_first_lsn);

      if (i_first_lsn == -1) {
        if (i_last_lsn == -1) {
          report("Error parsing span argument");
          exit(1);
        } else {
          i_first_lsn=cdda_disc_firstsector(d);
        }
      } else {
        if (i_last_lsn==-1) {
          if (span2) { /* There was a hyphen */
            i_last_lsn=cdda_disc_lastsector(d);
          } else {
            i_last_lsn=
              cdda_track_lastsector(d,cdda_sector_gettrack(d, i_first_lsn));
          }
        }
      }
    } else {
      i_first_lsn = cdda_disc_firstsector(d);
      i_last_lsn  = cdda_disc_lastsector(d);
    }

    {
      int track1 = cdda_sector_gettrack(d, i_first_lsn);

      int track2 = cdda_sector_gettrack(d, i_last_lsn);
      long off1  = i_first_lsn - cdda_track_firstsector(d, track1);
      long off2  = i_last_lsn  - cdda_track_firstsector(d, track2);
      int i;

      for( i=track1; i<=track2; i++ ) {
        if(i != 0 && !cdda_track_audiop(d,i)){
	  report("Selected span contains non audio track at track %02d.  Aborting.\n\n", i);
          exit(1);
          if (i == 0)
            i = cdio_get_first_track_num(d->p_cdio) - 1;
        }
      }

      report("Ripping from sector %7ld (track %2d [%d:%02d.%02d])\n"
	     "\t  to sector %7ld (track %2d [%d:%02d.%02d])\n",
	     i_first_lsn,
	     track1,
	     (int) (off1/(CDIO_CD_FRAMES_PER_MIN)),
	     (int) ((off1/CDIO_CD_FRAMES_PER_SEC) % CDIO_CD_SECS_PER_MIN),
	     (int)(off1 % CDIO_CD_FRAMES_PER_SEC),
	     i_last_lsn,
	     track2,
	     (int) (off2/(CDIO_CD_FRAMES_PER_MIN)),
	     (int) ((off2/CDIO_CD_FRAMES_PER_SEC) % CDIO_CD_SECS_PER_MIN),
	     (int)(off2 % CDIO_CD_FRAMES_PER_SEC));

    }

    if (toc_offset && !force_overread) {
	d->disc_toc[d->tracks].dwStartSector -= toc_offset;
	if (i_last_lsn > cdda_track_lastsector(d, d->tracks))
		i_last_lsn -= toc_offset;
    }
    {
      long cursor;
      int16_t offset_buffer[1176];
      int offset_buffer_used=0;
      int offset_skip=sample_offset*4;
      off_t sectorlen;

#if defined(HAVE_GETUID) && (defined(HAVE_SETEUID) || defined(HAVE_SETEGID))
      int dummy __attribute__((unused));
#endif
      p=paranoia_init(d);
      paranoia_modeset(p,paranoia_mode);
      if(force_cdrom_overlap!=-1)paranoia_overlapset(p,force_cdrom_overlap);

      if(verbose) {
        cdda_verbose_set(d,CDDA_MESSAGE_LOGIT,CDDA_MESSAGE_LOGIT);
        cdio_loglevel_default = CDIO_LOG_INFO;
      } else
        cdda_verbose_set(d,CDDA_MESSAGE_FORGETIT,CDDA_MESSAGE_FORGETIT);

      paranoia_seek(p,cursor=i_first_lsn,SEEK_SET);

      /* this is probably a good idea in general */
#if defined(HAVE_GETUID) && defined(HAVE_SETEUID)
      dummy = seteuid(getuid());
#endif
#if defined(HAVE_GETGID) && defined(HAVE_SETEGID)
      dummy = setegid(getgid());
#endif

      /* we'll need to be able to read one sector past user data if we
         have a sample offset in order to pick up the last bytes.  We
         need to set the disc length forward here so that the libs are
         willing to read past, assuming that works on the hardware, of
         course */
      if(sample_offset && force_overread)
        d->disc_toc[d->tracks].dwStartSector++;

      while(cursor<=i_last_lsn){
        char outfile_name[PATH_MAX];
        if ( batch ){
          batch_first = cursor;
          batch_track = cdda_sector_gettrack(d,cursor);
          batch_last  = cdda_track_lastsector(d, batch_track);
          if (batch_last>i_last_lsn) batch_last=i_last_lsn;
        } else {
          batch_first = i_first_lsn;
          batch_last  = i_last_lsn;
          batch_track = -1;
        }

        callbegin=batch_first;
        callend=batch_last;

        /* argv[optind] is the span, argv[optind+1] (if exists) is outfile */

        if (optind+1<argc) {
          if (!strcmp(argv[optind+1],"-") ){
            out = dup(fileno(stdout));
            if(out==-1){
              report("Cannot dupplicate stdout: %s",
                     strerror(errno));
              exit(1);
            }
            if(batch)
              report("Are you sure you wanted 'batch' "
                     "(-B) output with stdout?");
            report("outputting to stdout\n");
            if(logfile){
              fprintf(logfile,"outputting to stdout\n");
              fflush(logfile);
            }
            outfile_name[0]='\0';
          } else {
            char dirname[PATH_MAX];
            char *basename=split_base_dir(argv[optind+1], dirname,
					  PATH_MAX);

	    if (NULL == basename) {
	      report("Output filename too long");
	      exit(1);
	    }

            if(batch) {
	      if (strlen(argv[optind+1]) - 10 > PATH_MAX) {
		report("Output filename too long");
		exit(1);
	      }
              snprintf(outfile_name, PATH_MAX,
		       " %strack%02d.%s", dirname,
                       batch_track, basename);
            } else
              snprintf(outfile_name, PATH_MAX, "%s%s", dirname, basename);

            if(basename[0]=='\0'){
              switch (output_type) {
              case 0: /* raw */
                strncat(outfile_name, "cdda.raw", sizeof("cdda.raw"));
                break;
              case 1:
                strncat(outfile_name, "cdda.wav", sizeof("cdda.wav"));
                break;
              case 2:
                strncat(outfile_name, "cdda.aifc", sizeof("cdda.aifc"));
                break;
              case 3:
                strncat(outfile_name, "cdda.aiff", sizeof("cdda.aiff"));
                break;
              }
            }

            out=open(outfile_name,O_RDWR|O_CREAT|O_TRUNC|O_BINARY,0666);
            if(out==-1){
              report("Cannot open specified output file %s: %s",
                      outfile_name, strerror(errno));
              exit(1);
            }
            report("outputting to %s\n", outfile_name);
            if(logfile){
              fprintf(logfile,"outputting to %s\n",outfile_name);
              fflush(logfile);
            }
          }
        } else {
          /* default */
          if (batch)
            sprintf(outfile_name,"track%02d.", batch_track);
          else
            outfile_name[0]='\0';

          switch(output_type){
          case 0: /* raw */
            strncat(outfile_name, "cdda.raw", sizeof("cdda.raw"));
            break;
          case 1:
            strncat(outfile_name, "cdda.wav", sizeof("cdda.wav"));
            break;
          case 2:
            strncat(outfile_name, "cdda.aifc", sizeof("cdda.aifc"));
            break;
          case 3:
            strncat(outfile_name, "cdda.aiff", sizeof("cdda.aiff"));
            break;
          }

          out = open(outfile_name, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0666);
          if(out==-1){
            report("Cannot open default output file %s: %s", outfile_name,
                    strerror(errno));
            exit(1);
          }
          report("outputting to %s\n", outfile_name);
          if(logfile){
            fprintf(logfile,"outputting to %s\n",outfile_name);
            fflush(logfile);
          }

        }

	sectorlen = batch_last - batch_first + 1;
	if (cdda_sector_gettrack(d, cursor) == d->tracks &&
		toc_offset > 0 && !force_overread){
		sectorlen += toc_offset;
	}
        switch(output_type) {
        case 0: /* raw */
          break;
        case 1: /* wav */
	  WriteWav(out, sectorlen * CD_FRAMESIZE_RAW);
          break;
        case 2: /* aifc */
	  WriteAifc(out, sectorlen * CD_FRAMESIZE_RAW);
          break;
        case 3: /* aiff */
	  WriteAiff(out, sectorlen * CD_FRAMESIZE_RAW);
          break;
        }

        /* Off we go! */

        if(offset_buffer_used){
          /* partial sector from previous batch read */
          cursor++;
          if (buffering_write(out,
                              ((char *)offset_buffer)+offset_buffer_used,
                              CDIO_CD_FRAMESIZE_RAW-offset_buffer_used)){
            report("Error writing output: %s", strerror(errno));
            exit(1);
          }
        }

        skipped_flag=0;
        while(cursor<=batch_last){
          /* read a sector */
          int16_t *readbuf=paranoia_read_limited(p, callback, max_retries);
          char *err=cdda_errors(d);
          char *mes=cdda_messages(d);

          if(mes || err)
            fprintf(stderr,"\r                               "
                    "                                           \r%s%s\n",
                    mes?mes:"",err?err:"");

          if (err) free(err);
          if (mes) free(mes);
          if( readbuf==NULL) {
	    if(errno==EBADF || errno==ENOMEDIUM){
	      report("\nparanoia_read: CDROM drive unavailable, bailing.\n");
	      exit(1);
	    }
            skipped_flag=1;
            report("\nparanoia_read: Unrecoverable error, bailing.\n");
            break;
          }
          if(skipped_flag && abort_on_skip){
            cursor=batch_last+1;
            break;
          }

          skipped_flag=0;
          cursor++;

          if (output_endian!=bigendianp()) {
            int i;
            for (i=0; i<CDIO_CD_FRAMESIZE_RAW/2; i++)
              readbuf[i]=UINT16_SWAP_LE_BE_C(readbuf[i]);
          }

          callback(cursor*(CD_FRAMEWORDS)-1, PARANOIA_CB_WROTE);

          if (buffering_write(out,((char *)readbuf)+offset_skip,
                             CDIO_CD_FRAMESIZE_RAW-offset_skip)){
            report("Error writing output: %s", strerror(errno));
            exit(1);
          }
          offset_skip=0;

          if (output_endian != bigendianp()){
            int i;
            for (i=0; i<CDIO_CD_FRAMESIZE_RAW/2; i++)
              readbuf[i] = UINT16_SWAP_LE_BE_C(readbuf[i]);
          }

          /* One last bit of silliness to deal with sample offsets */
          if(sample_offset && cursor>batch_last){
	    if (cdda_sector_gettrack(d, batch_last) < d->tracks || force_overread) {
	      int i;

	      /* Need to flush the buffer when overreading into the leadout */
	      if (cdda_sector_gettrack(d, batch_last) == d->tracks)
		paranoia_seek(p, cursor, SEEK_SET);

	      /* read a sector and output the partial offset.  Save the
		 rest for the next batch iteration */
	      readbuf=paranoia_read_limited(p,callback,max_retries);
	      err=cdda_errors(d);mes=cdda_messages(d);

	      if(mes || err)
		fprintf(stderr,"\r                               "
			"                                           \r%s%s\n",
			mes?mes:"",err?err:"");

	      if(err)free(err);if(mes)free(mes);
	      if(readbuf==NULL){
		skipped_flag=1;
		report("\nparanoia_read: Unrecoverable error reading through "
		       "sample_offset shift\n\tat end of track, bailing.\n");
		break;
	      }
	      if (skipped_flag && abort_on_skip) break;
	      skipped_flag=0;
	      /* do not move the cursor */

	      if(output_endian!=bigendianp())
		for(i=0;i<CD_FRAMESIZE_RAW/2;i++)
		  offset_buffer[i]=UINT16_SWAP_LE_BE_C(readbuf[i]);
	      else
		memcpy(offset_buffer,readbuf,CD_FRAMESIZE_RAW);
	      offset_buffer_used=sample_offset*4;
	      callback(cursor* (CD_FRAMEWORDS), PARANOIA_CB_WROTE);
	    } else {
	      memset(offset_buffer, 0, sizeof(offset_buffer));
	      offset_buffer_used = sample_offset * 4;
	    }

	    if(buffering_write(out,(char *)offset_buffer,
			       offset_buffer_used)){
	      report("Error writing output: %s", strerror(errno));
	      exit(1);
	    }
	  }
        }

	/* Write sectors of silent audio to compensate for
	   missing samples that would be in the leadout */
	if (cdda_sector_gettrack(d, batch_last) == d->tracks &&
		toc_offset > 0 && !force_overread)
	{
		char *silence;
		size_t missing_sector_bytes = CD_FRAMESIZE_RAW * toc_offset;

		silence = calloc(toc_offset, CD_FRAMESIZE_RAW);
		if (!silence || buffering_write(out, silence, missing_sector_bytes)) {
		      report("Error writing output: %s", strerror(errno));
		      exit(1);
		}
		free(silence);
	}

        callback(cursor* (CDIO_CD_FRAMESIZE_RAW/2)-1,
		 PARANOIA_CB_FINISHED);
        buffering_close(out);
        if(skipped_flag){
          /* remove the file */
          report("\nRemoving aborted file: %s", outfile_name);
          unlink(outfile_name);
          /* make the cursor correct if we have another track */
          if(batch_track!=-1){
            batch_track++;
            cursor=cdda_track_firstsector(d,batch_track);
            paranoia_seek(p,cursor, SEEK_SET);
            offset_skip=sample_offset*4;
            offset_buffer_used=0;
          }
        }
        report("\n");
      }

      paranoia_free(p);
      p=NULL;
    }
  }

  report("Done.\n\n");

  return 0;
}
Exemple #21
0
int ftp_command_parse(const char *input, ftp_command_t *cmd)
{
    int i;
    int len;
    int match;
    ftp_command_t tmp;
    int c;
    const char *optional_number;

    daemon_assert(input != NULL);
    daemon_assert(cmd != NULL);

    /* see if our input starts with a valid command */
    match = -1;
    for (i=0; (i<NUM_COMMAND) && (match == -1); i++) {
        len = strlen(command_def[i].name);
        if (strncasecmp(input, command_def[i].name, len) == 0) {
	    match = i;
	}
    }

    /* if we didn't find a match, return error */
    if (match == -1) {
        return 0;
    }
    daemon_assert(match >= 0);
    daemon_assert(match < NUM_COMMAND);

    /* copy our command */
    strcpy(tmp.command, command_def[match].name);

    /* advance input past the command */
    input += strlen(command_def[match].name);

    /* now act based on the command */
    switch (command_def[match].arg_type) {

        case ARG_NONE:
	    tmp.num_arg = 0;
	    break;

        case ARG_STRING:
	    if (*input != ' ') {
	        return 0;
	    }
            ++input;
            input = copy_string(tmp.arg[0].string, input);
	    tmp.num_arg = 1;
	    break;

        case ARG_OPTIONAL_STRING:
	    if (*input == ' ') {
	        ++input;
	        input = copy_string(tmp.arg[0].string, input);
	        tmp.num_arg = 1;
	    } else {
	        tmp.num_arg = 0;
	    }
	    break;

        case ARG_HOST_PORT:
	    if (*input != ' ') {
	        return 0;
	    }
	    input++;

            /* parse the host & port information (if any) */
	    input = parse_host_port(&tmp.arg[0].host_port, input);
	    if (input == NULL) {
	        return 0;
	    }
	    tmp.num_arg = 1;
	    break;

       case ARG_HOST_PORT_LONG:
            if (*input != ' ') {
                return 0;
            }
            input++;
 
            /* parse the host & port information (if any) */
            input = parse_host_port_long(&tmp.arg[0].host_port, input);
            if (input == NULL) {
                return 0;
            }
            tmp.num_arg = 1;
            break;    

        case ARG_HOST_PORT_EXT:
            if (*input != ' ') {
                return 0;
            }
            input++;
 
            /* parse the host & port information (if any) */
            input = parse_host_port_ext(&tmp.arg[0].host_port, input);
            if (input == NULL) {
                return 0;
            }
            tmp.num_arg = 1;
            break;
 
        /* the optional number may also be "ALL" */
        case ARG_OPTIONAL_NUMBER:
            if (*input == ' ') {
                ++input;
                optional_number = parse_number(&tmp.arg[0].num, input, 255);
                if (optional_number != NULL) {
                    input = optional_number;
                } else {
                    if ((tolower(input[0]) == 'a') &&
                        (tolower(input[1]) == 'l') &&
                        (tolower(input[2]) == 'l')) 
                    {
			tmp.arg[0].num = EPSV_ALL;
                        input += 3;
                    } else {
                        return 0;
                    }
                }
                tmp.num_arg = 1;
            } else {
                tmp.num_arg = 0;
            }
            break;     

        case ARG_TYPE:
	    if (*input != ' ') {
	        return 0;
	    }
	    input++;

            c = toupper(*input);
            if ((c == 'A') || (c == 'E')) {
	        tmp.arg[0].string[0] = c;
		tmp.arg[0].string[1] = '\0';
		input++;

		if (*input == ' ') {
		    input++;
		    c = toupper(*input);
		    if ((c != 'N') && (c != 'T') && (c != 'C')) {
		        return 0;
		    }
		    tmp.arg[1].string[0] = c;
		    tmp.arg[1].string[1] = '\0';
		    input++;
		    tmp.num_arg = 2;
		} else {
		    tmp.num_arg = 1;
		}
	    } else if (c == 'I') {
	        tmp.arg[0].string[0] = 'I';
	        tmp.arg[0].string[1] = '\0';
		input++;
	        tmp.num_arg = 1;
	    } else if (c == 'L') {
	        tmp.arg[0].string[0] = 'L';
	        tmp.arg[0].string[1] = '\0';
		input++;
		input = parse_number(&tmp.arg[1].num, input, 255);
		if (input == NULL) {
		    return 0;
		}
	        tmp.num_arg = 2;
	    } else {
	        return 0;
	    }

	    break;

        case ARG_STRUCTURE:
	    if (*input != ' ') {
	        return 0;
	    }
	    input++;

            c = toupper(*input);
	    if ((c != 'F') && (c != 'R') && (c != 'P')) {
	        return 0;
	    }
            input++;
	    tmp.arg[0].string[0] = c;
	    tmp.arg[0].string[1] = '\0';
	    tmp.num_arg = 1;
	    break;

        case ARG_MODE:
	    if (*input != ' ') {
	        return 0;
	    }
	    input++;

            c = toupper(*input);
	    if ((c != 'S') && (c != 'B') && (c != 'C')) {
	        return 0;
	    }
            input++;
	    tmp.arg[0].string[0] = c;
	    tmp.arg[0].string[1] = '\0';
	    tmp.num_arg = 1;
	    break;

        case ARG_OFFSET:
	    if (*input != ' ') {
	        return 0;
	    }
	    input++;
	    input = parse_offset(&tmp.arg[0].offset, input);
	    if (input == NULL) {
	        return 0;
	    }
	    tmp.num_arg = 1;
	    break;

        default:
	    daemon_assert(0);
    } 

    /* check for our ending newline */
    if (*input != '\n') {
        return 0;
    }

    /* return our result */
    *cmd = tmp;
    return 1;
}
Exemple #22
0
int
main(int argc, char **argv)
{
    char *fstype = NULL;
    int ch;
    char *cp, type = 0;
    FS_INFO *fs;
    IMG_INFO *img;
    int set = 0;
    char *imgtype = NULL;
    SSIZE_T imgoff = 0;
    DADDR_T count = 0;

    progname = argv[0];
    setlocale(LC_ALL, "");

    while ((ch = getopt(argc, argv, "d:f:i:o:s:u:vV")) > 0) {
	switch (ch) {
	case '?':
	default:
	    fprintf(stderr, "Invalid argument: %s\n", argv[optind]);
	    usage();

	case 'd':
	    type |= DCALC_DD;
	    count = strtoull(optarg, &cp, 0);
	    if (*cp || cp == optarg) {
		fprintf(stderr, "Invalid address: %s\n", optarg);
		usage();
	    }

	    set = 1;
	    break;

	case 'f':
	    fstype = optarg;
	    break;

	case 'i':
	    imgtype = optarg;
	    break;

	case 'o':
	    if ((imgoff = parse_offset(optarg)) == -1) {
		tsk_error_print(stderr);
		exit(1);
	    }
	    break;

	case 's':
	    type |= DCALC_SLACK;
	    count = strtoull(optarg, &cp, 0);
	    if (*cp || cp == optarg) {
		fprintf(stderr, "Invalid address: %s\n", optarg);
		usage();
	    }

	    set = 1;
	    break;

	case 'u':
	    type |= DCALC_DLS;
	    count = strtoull(optarg, &cp, 0);
	    if (*cp || cp == optarg) {
		fprintf(stderr, "Invalid address: %s\n", optarg);
		usage();
	    }

	    set = 1;
	    break;

	case 'v':
	    verbose++;
	    break;

	case 'V':
	    print_version(stdout);
	    exit(0);
	}
    }

    /* We need at least one more argument */
    if (optind == argc) {
	fprintf(stderr, "Missing image name\n");
	usage();
    }

    if ((!type) || (set == 0)) {
	fprintf(stderr, "Calculation type not given (-u, -d, -s)\n");
	usage();
    }

    if ((type & DCALC_DD) && (type & DCALC_DLS) && (type & DCALC_SLACK)) {
	fprintf(stderr, "Only one block type can be given\n");
	usage();
    }


    if ((img =
	    img_open(imgtype, argc - optind,
		(const char **) &argv[optind])) == NULL) {
	tsk_error_print(stderr);
	exit(1);
    }

    if ((fs = fs_open(img, imgoff, fstype)) == NULL) {
	tsk_error_print(stderr);
	if (tsk_errno == TSK_ERR_FS_UNSUPTYPE)
	    fs_print_types(stderr);
	img->close(img);
	exit(1);
    }


    if (-1 == fs_dcalc(fs, type, count)) {
	tsk_error_print(stderr);
	fs->close(fs);
	img->close(img);
	exit(1);
    }

    fs->close(fs);
    img->close(img);

    exit(0);
}
Exemple #23
0
int
main(int argc, char **argv)
{
    FS_INFO *fs;
    DADDR_T bstart = 0, blast = 0;
    int ch;
    int flags =
	FS_FLAG_DATA_UNALLOC | FS_FLAG_DATA_ALIGN | FS_FLAG_DATA_META |
	FS_FLAG_DATA_CONT;
    char *fstype = NULL;
    char lclflags = DLS_CAT, set_bounds = 1;
    char *imgtype = NULL, *cp, *dash;
    SSIZE_T imgoff = 0;
    IMG_INFO *img;

    progname = argv[0];
    setlocale(LC_ALL, "");

    while ((ch = getopt(argc, argv, "bef:i:lo:svV")) > 0) {
	switch (ch) {
	case '?':
	default:
	    fprintf(stderr, "Invalid argument: %s\n", argv[optind]);
	    usage();
	case 'b':
	    flags &= ~FS_FLAG_DATA_ALIGN;
	    break;
	case 'e':
	    flags |= FS_FLAG_DATA_ALLOC;
	    break;
	case 'f':
	    fstype = optarg;
	    break;
	case 'i':
	    imgtype = optarg;
	    break;
	case 'l':
	    lclflags = DLS_LIST;
	    break;
	case 'o':
	    if ((imgoff = parse_offset(optarg)) == -1) {
		tsk_error_print(stderr);
		exit(1);
	    }
	    break;

	case 's':
	    lclflags |= DLS_SLACK;
	    break;
	case 'v':
	    verbose++;
	    break;
	case 'V':
	    print_version(stdout);
	    exit(0);
	}
    }


    /* We need at least one more argument */
    if (optind >= argc) {
	fprintf(stderr, "Missing image name\n");
	usage();
    }

    /* Slack has only the image name */
    if (lclflags & DLS_SLACK) {

	if (lclflags & DLS_LIST) {
	    fprintf(stderr,
		"Other options igroned with the slack space flag, try again\n");
	    exit(1);
	}

	/* There should be no other arguments */
	img =
	    img_open(imgtype, argc - optind,
	    (const char **) &argv[optind]);

	if (img == NULL) {
	    tsk_error_print(stderr);
	    exit(1);
	}

	if ((fs = fs_open(img, imgoff, fstype)) == NULL) {
	    tsk_error_print(stderr);
	    if (tsk_errno == TSK_ERR_FS_UNSUPTYPE)
		fs_print_types(stderr);
	    img->close(img);
	    exit(1);
	}

    }
    else {


	/* We need to determine if the block range was given */
	if ((dash = strchr(argv[argc - 1], '-')) == NULL) {
	    /* No dash in arg - therefore it is an image file name */
	    if ((img =
		    img_open(imgtype, argc - optind,
			(const char **) &argv[optind])) == NULL) {

		tsk_error_print(stderr);
		exit(1);
	    }

	    set_bounds = 1;

	}
	else {
	    /* We have a dash, but it could be part of the file name */
	    *dash = '\0';

	    bstart = strtoull(argv[argc - 1], &cp, 0);
	    if (*cp || cp == argv[argc - 1]) {
		/* Not a number - consider it a file name */
		*dash = '-';
		if ((img =
			img_open(imgtype, argc - optind,
			    (const char **) &argv[optind])) == NULL) {
		    tsk_error_print(stderr);
		    exit(1);
		}

		set_bounds = 1;
	    }
	    else {
		/* Check after the dash */
		dash++;
		blast = strtoull(dash, &cp, 0);
		if (*cp || cp == dash) {
		    /* Not a number - consider it a file name */
		    dash--;
		    *dash = '-';
		    if ((img =
			    img_open(imgtype, argc - optind,
				(const char **) &argv[optind])) == NULL) {
			tsk_error_print(stderr);
			exit(1);
		    }

		    set_bounds = 1;
		}
		else {

		    set_bounds = 0;
		    /* It was a block range, so do not include it in the open */
		    if ((img =
			    img_open(imgtype, argc - optind - 1,
				(const char **) &argv[optind])) == NULL) {
			tsk_error_print(stderr);
			exit(1);
		    }

		}
	    }
	}

	if ((fs = fs_open(img, imgoff, fstype)) == NULL) {
	    tsk_error_print(stderr);
	    if (tsk_errno == TSK_ERR_FS_UNSUPTYPE)
		fs_print_types(stderr);
	    img->close(img);
	    exit(1);
	}


	/* do we need to set the range or just check them? */
	if (set_bounds) {
	    bstart = fs->first_block;
	    blast = fs->last_block;
	}
	else {
	    if (bstart < fs->first_block)
		bstart = fs->first_block;

	    if (blast > fs->last_block)
		blast = fs->last_block;
	}
    }

    if (fs_dls(fs, lclflags, bstart, blast, flags)) {
	tsk_error_print(stderr);
	fs->close(fs);
	img->close(img);
	exit(1);

    }

    fs->close(fs);
    img->close(img);
    exit(0);
}
Exemple #24
0
int main(int argc, char **argv)
{
	//static const char OPTIONS[] = "hvlpsjPr:g:f::A:Ww:m:d:e:b:T:t:o:a:c:O:i:";
	static const char OPTIONS[] = "A:a:b:c:D:d:E:e:F:f:g:hi:jlm:no:O:Ppr:sT:t:vWw:x:y:";
	__sighandler_t sigint_original;
	char * const *file_names = NULL;
	size_t n_files = 0;
	int dither_mode = 0;
	int keep_power_on = 0;
	const char *waveform_id_str = "2";
	int waveform_id = 2;
	int do_enumerate_waveforms = 0;
	int do_log_info = 0;
	int do_wait_power_off = 0;
	int do_synchro = 0;
	int do_infinite_loop = 0;
	int cfa = -1;
	int display_enable = 0;
	int do_fill = 0;
	int fill_color = 0xFF;
	int do_auto_rotate = 0;
	int rotation_angle = -1;
	int do_partial_update = 0;
	int use_manual_temperature = 0;
	int manual_temperature = 25;
	unsigned long pause_ms = 2000;
	const char *mode = NULL;
	const char *fbdev = NULL;
	const char *epdev = NULL;
	const char *background = NULL;
	struct plep_point offset = { 0, 0 };
	enum epdoc_align_h align_h = EPDOC_ALIGN_H_NONE;
	enum epdoc_align_v align_v = EPDOC_ALIGN_V_NONE;
	struct plep_rect crop = { { 0, 0 }, { INT_MAX, INT_MAX } };
	const char *doc_type = NULL;
	const char *conf_file = NULL;
	struct plep *plep;
	struct pldraw *pldraw;
	int onoff = -1;
	int c;
	int ret;
	int use_alternative_vsource = 0;
	while ((c = getopt(argc, argv, OPTIONS)) != -1) {
		switch (c) {
		case 'A':
			if (!strcmp(optarg, "l")) {
			use_alternative_vsource = 1;
			}else if (!strcmp(optarg, "h")) {
			use_alternative_vsource = 2;
			}else if (!strcmp(optarg, "lh")) {
			use_alternative_vsource = 3;
			}else if (!strcmp(optarg, "hl")) {
			use_alternative_vsource = 3;
			}else{
				LOG("invalid alternative VSOURCE selection");
				print_usage();
				exit(EXIT_FAILURE);
			}
			break;
		case 'h':
			print_usage();
			exit(EXIT_SUCCESS);
			break;

		case 'v':
			printf("%s v%s - %s\n%s\n%s\n", APP_NAME, VERSION,
			       DESCRIPTION, COPYRIGHT, LICENSE);
			exit(EXIT_SUCCESS);
			break;

		case 'l':
			do_log_info = 1;
			break;
		case 'P':
			do_partial_update = 1;
			break;

		case 'p':
			do_wait_power_off = 1;
			break;

		case 's':
			do_synchro = 1;
			break;

		case 'j':
			do_infinite_loop = 1;
			break;

		case 'r':
			if (!strcmp(optarg, "auto")) {
				do_auto_rotate = 1;
			} else {
				unsigned long raw_angle;

				if (str2ul(optarg, &raw_angle) < 0) {
					LOG("failed to parse rotation angle");
					print_usage();
					exit(EXIT_FAILURE);
				}

				if ((raw_angle > 270) || (raw_angle % 90)) {
					LOG("invalid rotation angle");
					print_usage();
					exit(EXIT_FAILURE);
				}

				rotation_angle = raw_angle;
			}
			break;

		case 'g':
			if (str2ul(optarg, &pause_ms) < 0) {
				LOG("failed to parse pause duration");
				print_usage();
				exit(EXIT_FAILURE);
			}
			break;

		case 'f':
			if (optarg == NULL) {
				cfa = PLDRAW_CFA_GR_BW;
			} else {
				cfa = pldraw_get_cfa_id(optarg);

				if (cfa < 0) {
					LOG("Invalid CFA identifier: %s",
					    optarg);
					print_usage();
					exit(EXIT_FAILURE);
				}
			}
			break;
		
		case 'F':{
			char* str = optarg;
			if (optarg == NULL) {
				// set color to white (0xFF)
				do_fill = 1;
			} else {
				do_fill = 1;
				if(!strncmp(optarg, "0x", 2) || !strncmp(optarg, "0X", 2)){
					fill_color = strtoul(optarg, NULL, 16);
				}else{
					fill_color = atoi(optarg);
				}
			}
			break;
		}
		case 'T':
			manual_temperature = atoi(optarg);
			use_manual_temperature = 1;
			break;
		case 'W':
			do_enumerate_waveforms = 1;
			break;
		case 'i':
			waveform_id_str = NULL;
			waveform_id = atoi(optarg);
			break;
		case 'w':
			waveform_id_str = optarg;
			break;

		case 'm':
			mode = optarg;
			break;

		case 'd':
			fbdev = optarg;
			break;

		case 'e':
			epdev = optarg;
			break;

		case 'b':
			background = optarg;
			break;

		case 't':
			doc_type = optarg;
			break;

		case 'o':
			if (parse_offset(&offset, optarg) < 0) {
				print_usage();
				exit(EXIT_FAILURE);
			}
			break;

		case 'a':
			if (parse_alignment(&align_h, &align_v, optarg) < 0) {
				print_usage();
				exit(EXIT_FAILURE);
			}
			break;

		case 'c':
			if (parse_crop(&crop, optarg) < 0) {
				print_usage();
				exit(EXIT_FAILURE);
			}
			break;
		case 'O':
			conf_file = optarg;
			if (access(conf_file, F_OK)) {
				LOG_ERRNO("Configuration file");
				exit(EXIT_FAILURE);
			}
			break;
		case 'x':{
			onoff = atoi(optarg);
			break;
		}	
		case 'E':{
			//Enable Display N
			display_enable = atoi(optarg);
			if(display_enable > 3){
				LOG("Invalid arguments");
				exit(EXIT_FAILURE);
			}
			break;
		}
		case 'D':{
			//disable Display N
			display_enable -= atoi(optarg);
			if(display_enable < -3){
				LOG("Invalid arguments");
				exit(EXIT_FAILURE);
			}
			break;
		}
		case 'y':
			dither_mode = atoi(optarg);
			LOG("dither_mode %i", dither_mode);
			if(display_enable < 0 || display_enable > 3){
				LOG("Invalid arguments");
				exit(EXIT_FAILURE);
			}
			break;
		case 'n':{
			keep_power_on = 1;
			break;
		}	
		case '?':
		default:
			LOG("Invalid arguments");
			print_usage();
			exit(EXIT_FAILURE);
			break;
		}
	}

	if (optind < argc) {
		file_names = &argv[optind];
		n_files = argc - optind;
	}

	LOG("%s v%s", APP_NAME, VERSION);

	plep = plep_init(epdev, mode, conf_file);

	if (plep == NULL) {
		LOG("failed to initialise ePDC");
		goto error_plep;
	}

	pldraw = pldraw_init(fbdev, conf_file);

	if (pldraw == NULL) {
		LOG("failed to initialise pldraw");
		goto error_pldraw;
	}

	pldraw_set_plep(pldraw, plep);
	
	if(waveform_id_str){
		waveform_id = plep_get_wfid(plep, waveform_id_str);

		if (waveform_id < 0) {
			LOG("Invalid waveform path: %s", waveform_id_str);
			goto error_pldraw;
		}
	}
	
	if (cfa >= 0)
		pldraw_set_cfa(pldraw, cfa);
	else
		cfa = pldraw_get_cfa(pldraw);

	if (cfa != PLDRAW_CFA_NONE)
		LOG("CFA: %s", pldraw_cfa_name[cfa]);

	if (rotation_angle < 0)
		rotation_angle = pldraw_get_rotation(pldraw);

	if (rotation_angle)
		LOG("rotation: %d", rotation_angle);

	if (do_log_info)
		pldraw_log_info(pldraw);

	sigint_original = signal(SIGINT, sigint_abort);

	if(onoff != -1){
		LOG("POWER ONOFF:%i\n", onoff);
		if(onoff)
			plep_powerup(plep);
		else
			plep_powerdown(plep);
		exit(EXIT_SUCCESS);
	}
	if(display_enable != 0){
		//LOG("DISPLAY ENABLE:%i\n", display_enable);
		if(display_enable>0){
			plep_enable_display(plep, display_enable);
		}else{
			plep_disable_display(plep, display_enable);
		}
		exit(EXIT_SUCCESS);
	}
	if (do_enumerate_waveforms) {
		ret = enumerate_waveforms(plep);
	} else {
		struct epdoc_opt opt;

		plep_set_opt(plep, PLEP_SYNC_UPDATE, do_synchro);

		if (do_wait_power_off)
			plep_set_opt(plep, PLEP_WAIT_POWER_OFF, 1);

		if(do_partial_update){
			plep_set_opt(plep, PLEP_PARTIAL, 1);
		}
		
		if(use_manual_temperature){
			plep_set_opt(plep, PLEP_TEMPERATURE, 1);
			plep_set_hw_opt(plep, PLEP_TEMPERATURE, manual_temperature);
		}else{
			plep_set_opt(plep, PLEP_TEMPERATURE_AUTO, 1);
		}
		opt.dither_mode = dither_mode;
		opt.keep_power_on = keep_power_on;
		opt.do_auto_rotate = do_auto_rotate;
		opt.rotation_angle = rotation_angle;
		opt.wfid = waveform_id;
		opt.offset.x = offset.x;
		opt.offset.y = offset.y;
		opt.align_h = align_h;
		opt.align_v = align_v;
		memcpy(&opt.crop, &crop, sizeof opt.crop);
		opt.doc_type = doc_type;
		opt.use_alternative_vsource = use_alternative_vsource;
		
		if(do_fill){
			pldraw_fill_rect(pldraw, pldraw_get_grey(pldraw, fill_color), &crop);
			plep_update_screen(plep, opt.wfid);
		}else{
		
			ret = show_contents(pldraw, file_names, n_files, &opt,
				    pause_ms, do_infinite_loop, background);
		}
	}

	signal(SIGINT, sigint_original);
	pldraw_free(pldraw);
	plep_free(plep);

	exit((ret < 0) ? EXIT_FAILURE : EXIT_SUCCESS);

error_pldraw:
	plep_free(plep);
error_plep:
	exit(EXIT_FAILURE);
}
Exemple #25
0
int main(int argc, char **argv)
{
	static const char OPTIONS[] = "hvlpsjr:g:f::Ww:m:d:e:b:t:o:a:c:O:";
	__sighandler_t sigint_original;
	char * const *file_names = NULL;
	size_t n_files = 0;
	const char *waveform_id_str = NULL;
	int waveform_id;
	int do_enumerate_waveforms = 0;
	int do_log_info = 0;
	int do_wait_power_off = 0;
	int do_synchro = 0;
	int do_infinite_loop = 0;
	int cfa = -1;
	int do_auto_rotate = 0;
	int rotation_angle = -1;
	unsigned long pause_ms = 2000;
	const char *mode = NULL;
	const char *fbdev = NULL;
	const char *epdev = NULL;
	const char *background = NULL;
	struct plep_point offset = { 0, 0 };
	enum epdoc_align_h align_h = EPDOC_ALIGN_H_NONE;
	enum epdoc_align_v align_v = EPDOC_ALIGN_V_NONE;
	struct plep_rect crop = { { 0, 0 }, { INT_MAX, INT_MAX } };
	const char *doc_type = NULL;
	const char *conf_file = NULL;
	struct plep *plep;
	struct pldraw *pldraw;
	int c;
	int ret;

	while ((c = getopt(argc, argv, OPTIONS)) != -1) {
		switch (c) {
		case 'h':
			print_usage();
			exit(EXIT_SUCCESS);
			break;

		case 'v':
			printf("%s v%s - %s\n%s\n%s\n", APP_NAME, VERSION,
			       DESCRIPTION, COPYRIGHT, LICENSE);
			exit(EXIT_SUCCESS);
			break;

		case 'l':
			do_log_info = 1;
			break;

		case 'p':
			do_wait_power_off = 1;
			break;

		case 's':
			do_synchro = 1;
			break;

		case 'j':
			do_infinite_loop = 1;
			break;

		case 'r':
			if (!strcmp(optarg, "auto")) {
				do_auto_rotate = 1;
			} else {
				unsigned long raw_angle;

				if (str2ul(optarg, &raw_angle) < 0) {
					LOG("failed to parse rotation angle");
					print_usage();
					exit(EXIT_FAILURE);
				}

				if ((raw_angle > 270) || (raw_angle % 90)) {
					LOG("invalid rotation angle");
					print_usage();
					exit(EXIT_FAILURE);
				}

				rotation_angle = raw_angle;
			}
			break;

		case 'g':
			if (str2ul(optarg, &pause_ms) < 0) {
				LOG("failed to parse pause duration");
				print_usage();
				exit(EXIT_FAILURE);
			}
			break;

		case 'f':
			if (optarg == NULL) {
				cfa = PLDRAW_CFA_GR_BW;
			} else {
				cfa = pldraw_get_cfa_id(optarg);

				if (cfa < 0) {
					LOG("Invalid CFA identifier: %s",
					    optarg);
					print_usage();
					exit(EXIT_FAILURE);
				}
			}
			break;

		case 'W':
			do_enumerate_waveforms = 1;
			break;

		case 'w':
			waveform_id_str = optarg;
			break;

		case 'm':
			mode = optarg;
			break;

		case 'd':
			fbdev = optarg;
			break;

		case 'e':
			epdev = optarg;
			break;

		case 'b':
			background = optarg;
			break;

		case 't':
			doc_type = optarg;
			break;

		case 'o':
			if (parse_offset(&offset, optarg) < 0) {
				print_usage();
				exit(EXIT_FAILURE);
			}
			break;

		case 'a':
			if (parse_alignment(&align_h, &align_v, optarg) < 0) {
				print_usage();
				exit(EXIT_FAILURE);
			}
			break;

		case 'c':
			if (parse_crop(&crop, optarg) < 0) {
				print_usage();
				exit(EXIT_FAILURE);
			}
			break;

		case 'O':
			conf_file = optarg;
			if (access(conf_file, F_OK)) {
				LOG_ERRNO("Configuration file");
				exit(EXIT_FAILURE);
			}
			break;

		case '?':
		default:
			LOG("Invalid arguments");
			print_usage();
			exit(EXIT_FAILURE);
			break;
		}
	}

	if (optind < argc) {
		file_names = &argv[optind];
		n_files = argc - optind;
	}

	LOG("%s v%s", APP_NAME, VERSION);

	plep = plep_init(epdev, mode, conf_file);

	if (plep == NULL) {
		LOG("failed to initialise ePDC");
		goto error_plep;
	}

	pldraw = pldraw_init(fbdev, conf_file);

	if (pldraw == NULL) {
		LOG("failed to initialise pldraw");
		goto error_pldraw;
	}

	pldraw_set_plep(pldraw, plep);

	waveform_id = plep_get_wfid(plep, waveform_id_str);

	if (waveform_id < 0) {
		LOG("Invalid waveform path: %s", waveform_id_str);
		goto error_pldraw;
	}

	if (cfa >= 0)
		pldraw_set_cfa(pldraw, cfa);
	else
		cfa = pldraw_get_cfa(pldraw);

	if (cfa != PLDRAW_CFA_NONE)
		LOG("CFA: %s", pldraw_cfa_name[cfa]);

	if (rotation_angle < 0)
		rotation_angle = pldraw_get_rotation(pldraw);

	if (rotation_angle)
		LOG("rotation: %d", rotation_angle);

	if (do_log_info)
		pldraw_log_info(pldraw);

	sigint_original = signal(SIGINT, sigint_abort);

	if (do_enumerate_waveforms) {
		ret = enumerate_waveforms(plep);
	} else {
		struct epdoc_opt opt;

		plep_set_opt(plep, PLEP_SYNC_UPDATE, do_synchro);

		if (do_wait_power_off)
			plep_set_opt(plep, PLEP_WAIT_POWER_OFF, 1);

		opt.do_auto_rotate = do_auto_rotate;
		opt.rotation_angle = rotation_angle;
		opt.wfid = waveform_id;
		opt.offset.x = offset.x;
		opt.offset.y = offset.y;
		opt.align_h = align_h;
		opt.align_v = align_v;
		memcpy(&opt.crop, &crop, sizeof opt.crop);
		opt.doc_type = doc_type;

		ret = show_contents(pldraw, file_names, n_files, &opt,
				    pause_ms, do_infinite_loop, background);
	}

	signal(SIGINT, sigint_original);
	pldraw_free(pldraw);
	plep_free(plep);

	exit((ret < 0) ? EXIT_FAILURE : EXIT_SUCCESS);

error_pldraw:
	plep_free(plep);
error_plep:
	exit(EXIT_FAILURE);
}
static int u32_parse_opt(struct filter_util *qu, char *handle, int argc, char **argv, struct nlmsghdr *n)
{
	struct {
		struct tc_u32_sel sel;
		struct tc_u32_key keys[128];
	} sel;
	struct tcmsg *t = NLMSG_DATA(n);
	struct rtattr *tail;
	int sel_ok = 0;
	int sample_ok = 0;
	__u32 htid = 0;
	__u32 order = 0;

	memset(&sel, 0, sizeof(sel));

//fprintf(stderr, "handle[%s]\n", handle);

	if (handle && get_u32_handle(&t->tcm_handle, handle)) {
		fprintf(stderr, "Illegal filter ID\n");
		return -1;
	}

	if (argc == 0)
		return 0;



	tail = NLMSG_TAIL(n);
	addattr_l(n, MAX_MSG, TCA_OPTIONS, NULL, 0);

	while (argc > 0) {
		if (matches(*argv, "match") == 0) {
			NEXT_ARG();
			if (parse_selector(&argc, &argv, &sel.sel, n)) {
				fprintf(stderr, "Illegal \"match\"\n");
				return -1;
			}
			sel_ok++;
			continue;
		} else if (matches(*argv, "offset") == 0) {
			NEXT_ARG();
			if (parse_offset(&argc, &argv, &sel.sel)) {
				fprintf(stderr, "Illegal \"offset\"\n");
				return -1;
			}
			continue;
		} else if (matches(*argv, "hashkey") == 0) {
			NEXT_ARG();
			if (parse_hashkey(&argc, &argv, &sel.sel)) {
				fprintf(stderr, "Illegal \"hashkey\"\n");
				return -1;
			}
			continue;
		} else if (matches(*argv, "classid") == 0 ||
			   strcmp(*argv, "flowid") == 0) {
			unsigned handle;
			NEXT_ARG();
			if (get_tc_classid(&handle, *argv)) {
				fprintf(stderr, "Illegal \"classid\"\n");
				return -1;
			}
			addattr_l(n, MAX_MSG, TCA_U32_CLASSID, &handle, 4);
			sel.sel.flags |= TC_U32_TERMINAL;
		} else if (matches(*argv, "divisor") == 0) {
			unsigned int divisor;
fprintf(stderr, "parse divisor\n");
			NEXT_ARG();
			if (get_unsigned(&divisor, *argv, 0) || 
			    divisor == 0 ||
			   //divisor > 0x100 || ((divisor - 1) & divisor)) {//richie1124
			   divisor > 0x1000 || ((divisor - 1) & divisor)) {
				fprintf(stderr, "Illegal \"divisor\"\n");
				return -1;
			}
			addattr_l(n, MAX_MSG, TCA_U32_DIVISOR, &divisor, 4);
		} else if (matches(*argv, "order") == 0) {
			NEXT_ARG();
			if (get_u32(&order, *argv, 0)) {
				fprintf(stderr, "Illegal \"order\"\n");
				return -1;
			}
		} else if (strcmp(*argv, "link") == 0) {
			unsigned handle;
			NEXT_ARG();
			if (get_u32_handle(&handle, *argv)) {
				fprintf(stderr, "Illegal \"link\"\n");
				return -1;
			}
			if (handle && TC_U32_NODE(handle)) {
				fprintf(stderr, "\"link\" must be a hash table.\n");
				return -1;
			}
			addattr_l(n, MAX_MSG, TCA_U32_LINK, &handle, 4);
		} else if (strcmp(*argv, "ht") == 0) {
			unsigned handle;
			NEXT_ARG();
			if (get_u32_handle(&handle, *argv)) {
				fprintf(stderr, "Illegal \"ht\"\n");
				return -1;
			}
//fprintf(stderr, "f_u32, handle[%x]\n", handle);
			if (handle && TC_U32_NODE(handle)) {
				fprintf(stderr, "\"ht\" must be a hash table.\n");
				return -1;
			}
			if (sample_ok)
			{
				//htid = (htid&0xFF000)|(handle&0xFFF00000);
				//htid = (htid&0xFFF00)|(handle&0xFFF00000);
				htid = (htid&0xFFF00)|(handle&0xFFF00000);//richie1124
			}
			else
			{
				//htid = (handle&0xFFFFF000);
				htid = (handle&0xFFFFFF00);
				//htid = (handle&0xFFFFFF00);//richie1124
			}
		} else if (strcmp(*argv, "sample") == 0) {
			__u32 hash;
			unsigned divisor = 0x100;

			struct {
				struct tc_u32_sel sel;
				struct tc_u32_key keys[4];
			} sel2;
			memset(&sel2, 0, sizeof(sel2));
			NEXT_ARG();
			if (parse_selector(&argc, &argv, &sel2.sel, n)) {
				fprintf(stderr, "Illegal \"sample\"\n");
				return -1;
			}
			if (sel2.sel.nkeys != 1) {
				fprintf(stderr, "\"sample\" must contain exactly ONE key.\n");
				return -1;
			}
			if (*argv != 0 && strcmp(*argv, "divisor") == 0) {
				NEXT_ARG();
				if (get_unsigned(&divisor, *argv, 0) || divisor == 0 ||
				    divisor > 0x100 || ((divisor - 1) & divisor)) {
					fprintf(stderr, "Illegal sample \"divisor\"\n");
					return -1;
				}
				NEXT_ARG();
			}
			hash = sel2.sel.keys[0].val&sel2.sel.keys[0].mask;
			hash ^= hash>>16;
			hash ^= hash>>8;
			htid = ((hash%divisor)<<12)|(htid&0xFFF00000);
			sample_ok = 1;
			continue;
		} else if (strcmp(*argv, "indev") == 0) {