コード例 #1
0
ファイル: driver-hidpp20.c プロジェクト: bentiss/libratbag
static int
hidpp20drv_20_probe(struct ratbag_device *device)
{
    struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
    struct hidpp20_device *dev = drv_data->dev;
    struct hidpp20_feature *feature_list = dev->feature_list;
    unsigned int i;
    int rc;

    log_raw(device->ratbag,
            "'%s' has %d features\n",
            ratbag_device_get_name(device),
            dev->feature_count);

    for (i = 0; i < dev->feature_count; i++) {
        log_raw(device->ratbag, "Init feature %s (0x%04x) \n",
                hidpp20_feature_get_name(feature_list[i].feature),
                feature_list[i].feature);
        rc = hidpp20drv_init_feature(device, feature_list[i].feature);
        if (rc < 0)
            return rc;
    }

    return 0;

}
コード例 #2
0
ファイル: options.c プロジェクト: OPSF/uClinux
static int print_socket_options(void) {
    int fd, len;
    SOCK_OPT *ptr;
    OPT_UNION val;
    char line[STRLEN];

    fd=socket(AF_INET, SOCK_STREAM, 0);

    log_raw("Socket option defaults:");
    log_raw("    %-16s%-10s%-10s%-10s%-10s",
        "Option", "Accept", "Local", "Remote", "OS default");
    for(ptr=sock_opts; ptr->opt_str; ptr++) {
        /* display option name */
        sprintf(line, "    %-16s", ptr->opt_str);
        /* display stunnel default values */
        print_option(line, ptr->opt_type, ptr->opt_val[0]);
        print_option(line, ptr->opt_type, ptr->opt_val[1]);
        print_option(line, ptr->opt_type, ptr->opt_val[2]);
        /* display OS default value */
        len = sizeof(val);
        if(getsockopt(fd, ptr->opt_level, ptr->opt_name, (void *)&val, &len)) {
            if(get_last_socket_error()!=ENOPROTOOPT) {
                log_raw("%s", line); /* dump the name and assigned values */
                sockerror("getsockopt");
                return 0; /* FAILED */
            }
            safeconcat(line, "    --    "); /* write-only value */
        } else
            print_option(line, ptr->opt_type, &val);
        log_raw("%s", line);
    }
    return 1; /* OK */
}
コード例 #3
0
ファイル: hidpp10.c プロジェクト: bentiss/libratbag-old
int
hidpp10_get_firmare_information(struct hidpp10_device *dev,
				uint8_t *major_out,
				uint8_t *minor_out,
				uint8_t *build_out)
{
	unsigned idx = dev->index;
	union hidpp10_message firmware_information = CMD_DEVICE_FIRMWARE_INFORMATION(idx, FIRMWARE_INFO_ITEM_FW_NAME_AND_VERSION(1));
	union hidpp10_message build_information = CMD_DEVICE_FIRMWARE_INFORMATION(idx, FIRMWARE_INFO_ITEM_FW_BUILD_NUMBER(1));
	int res;
	uint8_t maj, min, build;

	log_raw(dev->ratbag_device->ratbag, "Fetching firmware information\n");

	/*
	 * This may fail on some devices
	 * => we can not retrieve their FW version through HID++ 1.0.
	 */
	res = hidpp10_request_command(dev, &firmware_information);
	if (res)
		return res;
	maj = firmware_information.msg.string[1];
	min = firmware_information.msg.string[2];

	res = hidpp10_request_command(dev, &build_information);
	if (res)
		return res;
	build = hidpp10_get_unaligned_u16(&build_information.msg.string[1]);

	*major_out = maj;
	*minor_out = min;
	*build_out = build;

	return 0;
}
コード例 #4
0
ファイル: driver-hidpp20.c プロジェクト: bentiss/libratbag
static void
hidpp20drv_read_button_1b04(struct ratbag_button *button)
{
    struct ratbag_device *device = button->profile->device;
    struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
    struct hidpp20_control_id *control;
    const struct ratbag_button_action *action;
    uint16_t mapping;

    if (!(drv_data->capabilities & HIDPP_CAP_BUTTON_KEY_1b04))
        return;

    control = &drv_data->controls[button->index];
    mapping = control->control_id;
    if (control->reporting.divert || control->reporting.persist)
        mapping = control->reporting.remapped;
    log_raw(device->ratbag,
            " - button%d: %s (%02x) %s%s:%d\n",
            button->index,
            hidpp20_1b04_get_logical_mapping_name(mapping),
            mapping,
            control->reporting.divert || control->reporting.persist ? "(redirected) " : "",
            __FILE__, __LINE__);
    button->type = hidpp20_1b04_get_physical_mapping(control->task_id);
    action = hidpp20_1b04_get_logical_mapping(mapping);
    if (action)
        button->action = *action;

    ratbag_button_enable_action_type(button, RATBAG_BUTTON_ACTION_TYPE_BUTTON);
    ratbag_button_enable_action_type(button, RATBAG_BUTTON_ACTION_TYPE_KEY);
    ratbag_button_enable_action_type(button, RATBAG_BUTTON_ACTION_TYPE_SPECIAL);
}
コード例 #5
0
ファイル: sthreads.c プロジェクト: djs55/stunnel
/* s_log is not initialized here, but we can use log_raw */
void sthreads_init(void) {
    /* create the first (listening) context and put it in the running queue */
    if(!new_context()) {
        log_raw("Unable create the listening context");
        exit(1);
    }
}
コード例 #6
0
ファイル: log.c プロジェクト: soumy/monitor
static void log_buffer_notrunc(const uint8_t *buf, uintptr_t length)
{
    if(buf == NULL || length == 0) {
        return;
    }

    bson b;
    bson_init(&b);
    bson_append_string(&b, "type", "buffer");

    if(range_is_readable(buf, length) != 0) {
        bson_append_binary(&b, "buffer", BSON_BIN_BINARY,
                           (const char *) buf, length);

        char checksum[64];
        sha1(buf, length, checksum);
        bson_append_string(&b, "checksum", checksum);
    }
    else {
        bson_append_string(&b, "buffer", "<INVALID POINTER>");
        bson_append_string(&b, "checksum", "???");
    }

    bson_finish(&b);
    log_raw(bson_data(&b), bson_size(&b));
    bson_destroy(&b);
}
コード例 #7
0
ファイル: options.c プロジェクト: OPSF/uClinux
static char *stralloc(char *str) { /* Allocate static string */
    char *retval;
    
    retval=calloc(strlen(str)+1, 1);
    if(!retval) {
        log_raw("Fatal memory allocation error");
        exit(2);
    }
    strcpy(retval, str);
    return retval;
}
コード例 #8
0
ファイル: hidpp10.c プロジェクト: bentiss/libratbag-old
int
hidpp10_get_usb_refresh_rate(struct hidpp10_device *dev,
			     uint16_t *rate)
{
	unsigned idx = dev->index;
	union hidpp10_message refresh = CMD_USB_REFRESH_RATE(idx, GET_REGISTER_REQ);
	int res;

	log_raw(dev->ratbag_device->ratbag, "Fetching USB refresh rate\n");

	res = hidpp10_request_command(dev, &refresh);
	if (res)
		return res;

	*rate = 1000/refresh.msg.parameters[0];

	return 0;
}
コード例 #9
0
ファイル: hidpp10.c プロジェクト: bentiss/libratbag-old
int
hidpp10_set_hidpp_notifications(struct hidpp10_device *dev,
				uint8_t reporting_flags_r0,
				uint8_t reporting_flags_r2)
{
	unsigned idx = dev->index;
	union hidpp10_message notifications = CMD_HIDPP_NOTIFICATIONS(idx, SET_REGISTER_REQ);
	int res;

	log_raw(dev->ratbag_device->ratbag, "Setting HID++ notifications\n");

	notifications.msg.parameters[0] = reporting_flags_r0;
	notifications.msg.parameters[2] = reporting_flags_r2;

	res = hidpp10_request_command(dev, &notifications);

	return res;
}
コード例 #10
0
ファイル: hidpp10.c プロジェクト: bentiss/libratbag-old
int
hidpp10_get_pairing_information_device_name(struct hidpp10_device *dev,
					    char *name,
					    size_t *name_size)
{
	unsigned int idx = dev->index;
	union hidpp10_message device_name = CMD_PAIRING_INFORMATION(idx, DEVICE_NAME);
	int res;

	log_raw(dev->ratbag_device->ratbag, "Fetching device name\n");

	res = hidpp10_request_command(dev, &device_name);
	if (res)
		return -1;
	*name_size = min(*name_size, device_name.msg.string[1]);
	strncpy_safe(name, (char*)&device_name.msg.string[2], *name_size);

	return 0;
}
コード例 #11
0
ファイル: hidpp10.c プロジェクト: bentiss/libratbag-old
int
hidpp10_set_led_status(struct hidpp10_device *dev,
		       const bool led[4])
{
	unsigned idx = dev->index;
	union hidpp10_message led_status = CMD_LED_STATUS(idx, SET_REGISTER_REQ);
	int res;

	log_raw(dev->ratbag_device->ratbag, "Setting LED status\n");

	/* each led is 4-bits, 0x1 == off, 0x2 == on */
	led_status.msg.parameters[0] |= led[0] ? 0x02 : 0x01; /* running man logo */
	led_status.msg.parameters[0] |= led[1] ? 0x20 : 0x10; /* lowest */
	led_status.msg.parameters[1] |= led[2] ? 0x02 : 0x01; /* middle */
	led_status.msg.parameters[1] |= led[3] ? 0x20 : 0x10; /* highest */

	res = hidpp10_request_command(dev, &led_status);
	return res;
}
コード例 #12
0
ファイル: hidpp10.c プロジェクト: bentiss/libratbag-old
int
hidpp10_get_individual_features(struct hidpp10_device *dev,
				uint8_t *feature_bit_r0,
				uint8_t *feature_bit_r2)
{
	unsigned idx = dev->index;
	union hidpp10_message features = CMD_ENABLE_INDIVIDUAL_FEATURES(idx, GET_REGISTER_REQ);
	int res;

	log_raw(dev->ratbag_device->ratbag, "Fetching individual features\n");

	res = hidpp10_request_command(dev, &features);
	if (res)
		return res;

	*feature_bit_r0 = features.msg.parameters[0];
	*feature_bit_r2 = features.msg.parameters[2];

	return 0;
}
コード例 #13
0
ファイル: hidpp10.c プロジェクト: bentiss/libratbag-old
int
hidpp10_get_optical_sensor_settings(struct hidpp10_device *dev,
				    uint8_t *surface_reflectivity)
{
	unsigned idx = dev->index;
	union hidpp10_message sensor = CMD_OPTICAL_SENSOR_SETTINGS(idx, GET_REGISTER_REQ);
	int res;

	log_raw(dev->ratbag_device->ratbag, "Fetching optical sensor settings\n");

	res = hidpp10_request_command(dev, &sensor);
	if (res)
		return res;

	*surface_reflectivity = sensor.msg.parameters[0];

	/* Don't know what the other values are */

	return 0;
}
コード例 #14
0
ファイル: hidpp10.c プロジェクト: bentiss/libratbag-old
static int
hidpp10_read_memory(struct hidpp10_device *dev, uint8_t page, uint16_t offset,
		    uint8_t bytes[16])
{
	unsigned idx = dev->index;
	union hidpp10_message readmem = CMD_READ_MEMORY(idx, page, offset/2);
	int res;

	log_raw(dev->ratbag_device->ratbag,
		"Reading memory page %d, offset %#x\n",
		page, offset);

	res = hidpp10_request_command(dev, &readmem);
	if (res)
		return res;

	memcpy(bytes, readmem.msg.string, sizeof(readmem.msg.string));

	return 0;
}
コード例 #15
0
ファイル: hidpp10.c プロジェクト: bentiss/libratbag-old
int
hidpp10_set_individual_feature(struct hidpp10_device *dev,
			       uint8_t feature_bit_r0,
			       uint8_t feature_bit_r2)
{
	unsigned idx = RECEIVER_IDX;
	union hidpp10_message mode = CMD_ENABLE_INDIVIDUAL_FEATURES(idx, SET_REGISTER_REQ);
	int res;

	log_raw(dev->ratbag_device->ratbag, "Setting individual features\n");

	if (dev)
		mode.msg.device_idx = dev->index;

	mode.msg.parameters[0] = feature_bit_r0;
	mode.msg.parameters[1] = feature_bit_r2;

	res = hidpp10_request_command(dev, &mode);

	return res;
}
コード例 #16
0
ファイル: hidpp10.c プロジェクト: bentiss/libratbag-old
int
hidpp10_get_current_resolution(struct hidpp10_device *dev,
			       uint16_t *xres,
			       uint16_t *yres)
{
	unsigned idx = dev->index;
	union hidpp10_message resolution = CMD_CURRENT_RESOLUTION(idx, GET_LONG_REGISTER_REQ);
	int res;

	log_raw(dev->ratbag_device->ratbag, "Fetching current resolution\n");

	res = hidpp10_request_command(dev, &resolution);
	if (res)
		return res;

	/* resolution is in 50dpi multiples */
	*xres = hidpp10_get_unaligned_u16le(&resolution.data[4]) * 50;
	*yres = hidpp10_get_unaligned_u16le(&resolution.data[6]) * 50;

	return 0;
}
コード例 #17
0
ファイル: log.c プロジェクト: soumy/monitor
static int open_handles()
{
    do {
        // TODO Use NtCreateFile instead of CreateFileW.
        g_log_handle = CreateFileW(g_log_pipename, GENERIC_WRITE,
                                   FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
                                   FILE_FLAG_WRITE_THROUGH, NULL);

        sleep(50);
    } while (g_log_handle == INVALID_HANDLE_VALUE);

    // The process identifier.
    uint32_t process_identifier = get_current_process_id();
    log_raw((const char *) &process_identifier, sizeof(process_identifier));

#if DEBUG
    g_debug_handle = CreateFileW(g_debug_filepath,
                                 GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
                                 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
#endif
    return 0;
}
コード例 #18
0
ファイル: hidpp10.c プロジェクト: bentiss/libratbag-old
int
hidpp10_get_pairing_information(struct hidpp10_device *dev,
				uint8_t *report_interval,
				uint16_t *wpid,
				uint8_t *device_type)
{
	unsigned int idx = dev->index;
	union hidpp10_message pairing_information = CMD_PAIRING_INFORMATION(idx, DEVICE_PAIRING_INFORMATION);
	int res;

	log_raw(dev->ratbag_device->ratbag, "Fetching pairing information\n");

	res = hidpp10_request_command(dev, &pairing_information);
	if (res)
		return -1;

	*report_interval = pairing_information.msg.string[2];
	*wpid = hidpp10_get_unaligned_u16(&pairing_information.msg.string[3]);
	*device_type = pairing_information.msg.string[7];

	return 0;
}
コード例 #19
0
ファイル: hidpp10.c プロジェクト: bentiss/libratbag-old
int
hidpp10_get_led_status(struct hidpp10_device *dev,
		       bool led[4])
{
	unsigned idx = dev->index;
	union hidpp10_message led_status = CMD_LED_STATUS(idx, GET_REGISTER_REQ);
	int res;

	log_raw(dev->ratbag_device->ratbag, "Fetching LED status\n");

	res = hidpp10_request_command(dev, &led_status);
	if (res)
		return res;

	/* each led is 4-bits, 0x1 == off, 0x2 == on */
	led[0] = !!(led_status.msg.parameters[0] & 0x02); /* running man logo */
	led[1] = !!(led_status.msg.parameters[0] & 0x20); /* lowest */
	led[2] = !!(led_status.msg.parameters[1] & 0x02); /* middle */
	led[3] = !!(led_status.msg.parameters[1] & 0x20); /* highest */

	return 0;
}
コード例 #20
0
ファイル: log.c プロジェクト: mtrojnar/stunnel
void log_flush(LOG_MODE new_mode) {
    struct LIST *tmp;

    CRYPTO_THREAD_write_lock(stunnel_locks[LOCK_LOG_MODE]);
    /* prevent changing LOG_MODE_CONFIGURED to LOG_MODE_ERROR
     * once stderr file descriptor is closed */
    if(log_mode!=LOG_MODE_CONFIGURED)
        log_mode=new_mode;
    /* log_raw() will use the new value of log_mode */
    CRYPTO_THREAD_write_lock(stunnel_locks[LOCK_LOG_BUFFER]);
    while(head) {
        log_raw(head->opt, head->level, head->stamp, head->id, head->text);
        str_free(head->stamp);
        str_free(head->id);
        str_free(head->text);
        tmp=head;
        head=head->next;
        str_free(tmp);
    }
    head=tail=NULL;
    CRYPTO_THREAD_write_unlock(stunnel_locks[LOCK_LOG_BUFFER]);
    CRYPTO_THREAD_write_unlock(stunnel_locks[LOCK_LOG_MODE]);
}
コード例 #21
0
ファイル: hidpp10.c プロジェクト: bentiss/libratbag-old
int
hidpp10_get_current_profile(struct hidpp10_device *dev, int8_t *current_profile)
{
	unsigned idx = dev->index;
	union hidpp10_message profile = CMD_PROFILE(idx, GET_REGISTER_REQ);
	int res;
	int8_t page;

	log_raw(dev->ratbag_device->ratbag, "Fetching current profile\n");

	res = hidpp10_request_command(dev, &profile);
	if (res)
		return res;

	page = profile.msg.parameters[0]; /* FIXME: my mouse is always 0 */
	*current_profile = page;

	/* FIXME: my mouse appears to be on page 5, but with the offset of
	 * 3, it's actually profile 2. not sure how to  change this */
	*current_profile = 2;

	return 0;
}
コード例 #22
0
ファイル: options.c プロジェクト: OPSF/uClinux
void parse_config(char *name, char *parameter) {
#ifdef CONFDIR
    char *default_config_file=CONFDIR "/stunnel.conf";
#else
    char *default_config_file="stunnel.conf";
#endif
    FILE *fp;
    char line[STRLEN], *arg, *opt, *errstr, *filename;
    int line_number, i;
    LOCAL_OPTIONS *section, *new_section;
    
    memset(&options, 0, sizeof(GLOBAL_OPTIONS)); /* reset global options */

    memset(&local_options, 0, sizeof(LOCAL_OPTIONS)); /* reset local options */
    local_options.next=NULL;
    section=&local_options;

    global_options(CMD_INIT, NULL, NULL);
    service_options(CMD_INIT, section, NULL, NULL);
    if(!name)
        name=default_config_file;
    if(!strcasecmp(name, "-help")) {
        global_options(CMD_HELP, NULL, NULL);
        service_options(CMD_HELP, section, NULL, NULL);
        exit(1);
    }
    if(!strcasecmp(name, "-version")) {
        log_raw("%s", stunnel_info());
        log_raw(" ");
        global_options(CMD_DEFAULT, NULL, NULL);
        service_options(CMD_DEFAULT, section, NULL, NULL);
        exit(1);
    }
    if(!strcasecmp(name, "-sockets")) {
        print_socket_options();
        exit(1);
    }
#ifndef USE_WIN32
    if(!strcasecmp(name, "-fd")) {
        if(!parameter) {
            log_raw("No file descriptor specified");
            syntax(default_config_file);
        }
        for(arg=parameter, i=0; *arg; arg++) {
            if(*arg<'0' || *arg>'9') {
                log_raw("Invalid file descriptor %s", parameter);
                syntax(default_config_file);
            }
            i=10*i+*arg-'0';
        }
        fp=fdopen(i, "r");
        if(!fp) {
            log_raw("Invalid file descriptor %s", parameter);
            syntax(default_config_file);
        }
        filename="descriptor";
    } else
#endif
    {
        fp=fopen(name, "r");
        if(!fp) {
#ifdef USE_WIN32
            /* Win32 doesn't seem to set errno in fopen() */
            log_raw("Failed to open configuration file %s", name);
#else
            ioerror(name);
#endif
            syntax(default_config_file);
        }
        filename=name;
    }
    line_number=0;
    while(fgets(line, STRLEN, fp)) {
        line_number++;
        opt=line;
        while(isspace(*opt))
            opt++; /* remove initial whitespaces */
        for(i=strlen(opt)-1; i>=0 && isspace(opt[i]); i--)
            opt[i]='\0'; /* remove trailing whitespaces */
        if(opt[0]=='\0' || opt[0]=='#') /* empty line or comment */
            continue;
        if(opt[0]=='[' && opt[strlen(opt)-1]==']') { /* new section */
            errstr=section_validate(section);
            if(errstr) {
                log_raw("file %s line %d: %s", filename, line_number, errstr);
                exit(1);
            }
            opt++;
            opt[strlen(opt)-1]='\0';
            new_section=calloc(1, sizeof(LOCAL_OPTIONS));
            if(!new_section) {
                log_raw("Fatal memory allocation error");
                exit(2);
            }
            memcpy(new_section, &local_options, sizeof(LOCAL_OPTIONS));
            new_section->servname=stralloc(opt);
            new_section->next=NULL;
            section->next=new_section;
            section=new_section;
            continue;
        }
        arg=strchr(line, '=');
        if(!arg) {
            log_raw("file %s line %d: No '=' found", filename, line_number);
            exit(1);
        }
        *arg++='\0'; /* split into option name and argument value */
        for(i=strlen(opt)-1; i>=0 && isspace(opt[i]); i--)
            opt[i]='\0'; /* remove trailing whitespaces */
        while(isspace(*arg))
            arg++; /* remove initial whitespaces */
        errstr=service_options(CMD_EXEC, section, opt, arg);
        if(section==&local_options && errstr==option_not_found)
            errstr=global_options(CMD_EXEC, opt, arg);
        if(errstr) {
            log_raw("file %s line %d: %s", filename, line_number, errstr);
            exit(1);
        }
    }
    errstr=section_validate(section);
    if(errstr) {
        log_raw("file %s line %d: %s", filename, line_number, errstr);
        exit(1);
    }
    fclose(fp);
    if(!local_options.next && section->option.accept) {
        log_raw("accept option is not allowed in inetd mode");
        log_raw("remove accept option or define a [section]");
        exit(1);
    }
    if(!options.option.client)
        options.option.cert=1; /* Server always needs a certificate */
    if(!options.option.foreground)
        options.option.syslog=1;
}
コード例 #23
0
ファイル: log.c プロジェクト: soumy/monitor
void log_explain(uint32_t index)
{
    bson b;
    char argidx[4];

    bson_init_size(&b, mem_suggested_size(1024));
    bson_append_int(&b, "I", index);
    bson_append_string(&b, "name", sig_apiname(index));
    bson_append_string(&b, "type", "info");
    bson_append_string(&b, "category", sig_category(index));

    bson_append_start_array(&b, "args");
    bson_append_string(&b, "0", "is_success");
    bson_append_string(&b, "1", "retval");

    const char *fmt = sig_paramtypes(index);

    for (uint32_t argnum = 2; *fmt != 0; argnum++, fmt++) {
        ultostr(argnum, argidx, 10);

        // Ignore buffers, they are sent over separately.
        if(*fmt == '!') {
            argnum--;
            fmt++;
            continue;
        }

        const char *argname = sig_param_name(index, argnum-2);

        // On certain formats, we need to tell cuckoo about them for
        // nicer display / matching.
        if(*fmt == 'p' || *fmt == 'P') {
            bson_append_start_array(&b, argidx);
            bson_append_string(&b, "0", argname);
            bson_append_string(&b, "1", "p");
            bson_append_finish_array(&b);
        }
        else {
            bson_append_string(&b, argidx, argname);
        }
    }

    bson_append_finish_array(&b);
    bson_append_start_object(&b, "flags_value");

    for (uint32_t idx = 0; sig_flag_name(index, idx) != NULL; idx++) {
        const flag_repr_t *f = flag_value(sig_flag_value(index, idx));
        bson_append_start_array(&b, sig_flag_name(index, idx));

        for (uint32_t idx2 = 0; f->repr != NULL; idx2++, f++) {
            ultostr(idx, argidx, 10);
            bson_append_start_array(&b, argidx);
            bson_append_int(&b, "0", f->value);
            bson_append_string(&b, "1", f->repr);
            bson_append_finish_array(&b);
        }

        bson_append_finish_array(&b);
    }

    bson_append_finish_object(&b);
    bson_append_start_object(&b, "flags_bitmask");

    for (uint32_t idx = 0; sig_flag_name(index, idx) != NULL; idx++) {
        const flag_repr_t *f = flag_bitmask(sig_flag_value(index, idx));
        bson_append_start_array(&b, sig_flag_name(index, idx));

        for (uint32_t idx2 = 0; f->repr != NULL; idx2++, f++) {
            ultostr(idx, argidx, 10);
            bson_append_start_array(&b, argidx);
            bson_append_int(&b, "0", f->value);
            bson_append_string(&b, "1", f->repr);
            bson_append_finish_array(&b);
        }

        bson_append_finish_array(&b);
    }

    bson_append_finish_object(&b);
    bson_finish(&b);
    log_raw(bson_data(&b), bson_size(&b));
    bson_destroy(&b);
}
コード例 #24
0
ファイル: options.c プロジェクト: OPSF/uClinux
static char *global_options(CMD cmd, char *opt, char *arg) {

    if(cmd==CMD_DEFAULT || cmd==CMD_HELP) {
        log_raw("Global options");
    }

    /* CApath */
    switch(cmd) {
    case CMD_INIT:
#if 0
        options.ca_dir=(char *)X509_get_default_cert_dir();
#endif
        options.ca_dir=NULL;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "CApath"))
            break;
        if(arg[0]) /* not empty */
            options.ca_dir=stralloc(arg);
        else
            options.ca_dir=NULL;
        return NULL; /* OK */
    case CMD_DEFAULT:
#if 0
        log_raw("%-15s = %s", "CApath",
            options.ca_dir ? options.ca_dir : "(none)");
#endif
        break;
    case CMD_HELP:
        log_raw("%-15s = CA certificate directory for 'verify' option",
            "CApath");
        break;
    }

    /* CAfile */
    switch(cmd) {
    case CMD_INIT:
#if 0
        options.ca_file=(char *)X509_get_default_certfile();
#endif
        options.ca_file=NULL;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "CAfile"))
            break;
        if(arg[0]) /* not empty */
            options.ca_file=stralloc(arg);
        else
            options.ca_file=NULL;
        return NULL; /* OK */
    case CMD_DEFAULT:
#if 0
        log_raw("%-15s = %s", "CAfile",
            options.ca_file ? options.ca_file : "(none)");
#endif
        break;
    case CMD_HELP:
        log_raw("%-15s = CA certificate file for 'verify' option",
            "CAfile");
        break;
    }

    /* cert */
    switch(cmd) {
    case CMD_INIT:
#ifdef CONFDIR
        options.cert=CONFDIR "/stunnel.pem";
#else
        options.cert="stunnel.pem";
#endif
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "cert"))
            break;
        options.cert=stralloc(arg);
        options.option.cert=1;
        return NULL; /* OK */
    case CMD_DEFAULT:
        log_raw("%-15s = %s", "cert", options.cert);
        break;
    case CMD_HELP:
        log_raw("%-15s = certificate chain", "cert");
        break;
    }

    /* chroot */
#ifdef HAVE_CHROOT
    switch(cmd) {
    case CMD_INIT:
        options.chroot_dir=NULL;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "chroot"))
            break;
        options.chroot_dir=stralloc(arg);
        return NULL; /* OK */
    case CMD_DEFAULT:
        break;
    case CMD_HELP:
        log_raw("%-15s = directory to chroot stunnel process", "chroot");
        break;
    }
#endif /* HAVE_CHROOT */

    /* ciphers */
    switch(cmd) {
    case CMD_INIT:
        options.cipher_list=SSL_DEFAULT_CIPHER_LIST;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "ciphers"))
            break;
        options.cipher_list=stralloc(arg);
        return NULL; /* OK */
    case CMD_DEFAULT:
        log_raw("%-15s = %s", "ciphers", SSL_DEFAULT_CIPHER_LIST);
        break;
    case CMD_HELP:
        log_raw("%-15s = list of permitted SSL ciphers", "ciphers");
        break;
    }

    /* client */
    switch(cmd) {
    case CMD_INIT:
        options.option.client=0;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "client"))
            break;
        if(!strcasecmp(arg, "yes"))
            options.option.client=1;
        else if(!strcasecmp(arg, "no"))
            options.option.client=0;
        else
            return "argument should be either 'yes' or 'no'";
        return NULL; /* OK */
    case CMD_DEFAULT:
        break;
    case CMD_HELP:
        log_raw("%-15s = yes|no client mode (remote service uses SSL)",
            "client");
        break;
    }

    /* CRLpath */
    switch(cmd) {
    case CMD_INIT:
        options.crl_dir=NULL;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "CRLpath"))
            break;
        if(arg[0]) /* not empty */
            options.crl_dir=stralloc(arg);
        else
            options.crl_dir=NULL;
        return NULL; /* OK */
    case CMD_DEFAULT:
        break;
    case CMD_HELP:
        log_raw("%-15s = CRL directory", "CRLpath");
        break;
    }

    /* CRLfile */
    switch(cmd) {
    case CMD_INIT:
        options.crl_file=NULL;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "CRLfile"))
            break;
        if(arg[0]) /* not empty */
            options.crl_file=stralloc(arg);
        else
            options.crl_file=NULL;
        return NULL; /* OK */
    case CMD_DEFAULT:
        break;
    case CMD_HELP:
        log_raw("%-15s = CRL file", "CRLfile");
        break;
    }

    /* debug */
    switch(cmd) {
    case CMD_INIT:
        options.debug_level=5;
#if !defined (USE_WIN32) && !defined (__vms)
        options.facility=LOG_DAEMON;
#endif
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "debug"))
            break;
        if(!parse_debug_level(arg))
            return "Illegal debug argument";
        return NULL; /* OK */
    case CMD_DEFAULT:
        log_raw("%-15s = %d", "debug", options.debug_level);
        break;
    case CMD_HELP:
        log_raw("%-15s = [facility].level (e.g. daemon.info)", "debug");
        break;
    }

    /* EGD is only supported when compiled with OpenSSL 0.9.5a or later */
#if SSLEAY_VERSION_NUMBER >= 0x0090581fL
    switch(cmd) {
    case CMD_INIT:
        options.egd_sock=NULL;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "EGD"))
            break;
        options.egd_sock=stralloc(arg);
        return NULL; /* OK */
    case CMD_DEFAULT:
#ifdef EGD_SOCKET
        log_raw("%-15s = %s", "EGD", EGD_SOCKET);
#endif
        break;
    case CMD_HELP:
        log_raw("%-15s = path to Entropy Gathering Daemon socket", "EGD");
        break;
    }
#endif /* OpenSSL 0.9.5a */

    /* foreground */
#ifndef USE_WIN32
    switch(cmd) {
    case CMD_INIT:
        options.option.syslog=0;
        options.option.foreground=0;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "foreground"))
            break;
        if(!strcasecmp(arg, "yes"))
            options.option.foreground=1;
        else if(!strcasecmp(arg, "no"))
            options.option.foreground=0;
        else
            return "argument should be either 'yes' or 'no'";
        return NULL; /* OK */
    case CMD_DEFAULT:
        break;
    case CMD_HELP:
        log_raw("%-15s = yes|no foreground mode (don't fork, log to stderr)",
            "foreground");
        break;
    }
#endif

    /* key */
    switch(cmd) {
    case CMD_INIT:
        options.key=NULL;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "key"))
            break;
        options.key=stralloc(arg);
        return NULL; /* OK */
    case CMD_DEFAULT:
        log_raw("%-15s = %s", "key", options.cert); /* set in stunnel.c */
        break;
    case CMD_HELP:
        log_raw("%-15s = certificate private key", "key");
        break;
    }

    /* options */
    switch(cmd) {
    case CMD_INIT:
        options.ssl_options=0;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "options"))
            break;
        if(!parse_ssl_option(arg))
            return "Illegal SSL option";
        return NULL; /* OK */
    case CMD_DEFAULT:
        break;
    case CMD_HELP:
        log_raw("%-15s = SSL option", "options");
        log_raw("%18sset an SSL option", "");
        break;
    }

    /* output */
    switch(cmd) {
    case CMD_INIT:
        options.output_file=NULL;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "output"))
            break;
        options.output_file=stralloc(arg);
        return NULL; /* OK */
    case CMD_DEFAULT:
        break;
    case CMD_HELP:
        log_raw("%-15s = file to append log messages", "output");
        break;
    }

    /* pid */
#ifndef USE_WIN32
    switch(cmd) {
    case CMD_INIT:
        options.pidfile=PIDFILE;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "pid"))
            break;
        if(arg[0]) /* is argument not empty? */
            options.pidfile=stralloc(arg);
        else
            options.pidfile=NULL; /* empty -> do not create a pid file */
        return NULL; /* OK */
    case CMD_DEFAULT:
        log_raw("%-15s = %s", "pid", PIDFILE);
        break;
    case CMD_HELP:
        log_raw("%-15s = pid file (empty to disable creating)", "pid");
        break;
    }
#endif

    /* RNDbytes */
    switch(cmd) {
    case CMD_INIT:
        options.random_bytes=RANDOM_BYTES;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "RNDbytes"))
            break;
        options.random_bytes=atoi(arg);
        return NULL; /* OK */
    case CMD_DEFAULT:
        log_raw("%-15s = %d", "RNDbytes", RANDOM_BYTES);
        break;
    case CMD_HELP:
        log_raw("%-15s = bytes to read from random seed files", "RNDbytes");
        break;
    }

    /* RNDfile */
    switch(cmd) {
    case CMD_INIT:
        options.rand_file=NULL;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "RNDfile"))
            break;
        options.rand_file=stralloc(arg);
        return NULL; /* OK */
    case CMD_DEFAULT:
#ifdef RANDOM_FILE
        log_raw("%-15s = %s", "RNDfile", RANDOM_FILE);
#endif
        break;
    case CMD_HELP:
        log_raw("%-15s = path to file with random seed data", "RNDfile");
        break;
    }

    /* RNDoverwrite */
    switch(cmd) {
    case CMD_INIT:
        options.option.rand_write=1;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "RNDoverwrite"))
            break;
        if(!strcasecmp(arg, "yes"))
            options.option.rand_write=1;
        else if(!strcasecmp(arg, "no"))
            options.option.rand_write=0;
        else
            return "argument should be either 'yes' or 'no'";
        return NULL; /* OK */
    case CMD_DEFAULT:
        log_raw("%-15s = yes", "RNDoverwrite");
        break;
    case CMD_HELP:
        log_raw("%-15s = yes|no overwrite seed datafiles with new random data",
            "RNDoverwrite");
        break;
    }

    /* service */
    switch(cmd) {
    case CMD_INIT:
        local_options.servname=stralloc("stunnel");
#ifdef USE_WIN32
        options.win32_service="stunnel";
        options.win32_name="stunnel " VERSION " on Win32";
#endif
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "service"))
            break;
        local_options.servname=stralloc(arg);
#ifdef USE_WIN32
        options.win32_service=stralloc(arg);
        {
            char tmpstr[STRLEN];

            safecopy(tmpstr, "stunnel " VERSION " on Win32 (");
            safeconcat(tmpstr, arg);
            safeconcat(tmpstr, ")");
            options.win32_name=stralloc(tmpstr);
        }
#endif
        return NULL; /* OK */
    case CMD_DEFAULT:
#ifdef USE_WIN32
        log_raw("%-15s = %s", "service", options.win32_service);
#endif
        break;
    case CMD_HELP:
        log_raw("%-15s = service name", "service");
        break;
    }

    /* session */
    switch(cmd) {
    case CMD_INIT:
        options.session_timeout=300;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "session"))
            break;
        if(atoi(arg)>0)
            options.session_timeout=atoi(arg);
        else
            return "Illegal session timeout";
        return NULL; /* OK */
    case CMD_DEFAULT:
        log_raw("%-15s = %ld seconds", "session", options.session_timeout);
        break;
    case CMD_HELP:
        log_raw("%-15s = session cache timeout (in seconds)", "session");
        break;
    }

#ifndef USE_WIN32
    /* setgid */
    switch(cmd) {
    case CMD_INIT:
        options.setgid_group=NULL;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "setgid"))
            break;
        options.setgid_group=stralloc(arg);
        return NULL; /* OK */
    case CMD_DEFAULT:
        break;
    case CMD_HELP:
        log_raw("%-15s = groupname for setgid()", "setgid");
        break;
    }
#endif

#ifndef USE_WIN32
    /* setuid */
    switch(cmd) {
    case CMD_INIT:
        options.setuid_user=NULL;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "setuid"))
            break;
        options.setuid_user=stralloc(arg);
        return NULL; /* OK */
    case CMD_DEFAULT:
        break;
    case CMD_HELP:
        log_raw("%-15s = username for setuid()", "setuid");
        break;
    }
#endif

    /* socket */
    switch(cmd) {
    case CMD_INIT:
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "socket"))
            break;
        if(!parse_socket_option(arg))
            return "Illegal socket option";
        return NULL; /* OK */
    case CMD_DEFAULT:
        break;
    case CMD_HELP:
        log_raw("%-15s = a|l|r:option=value[:value]", "socket");
        log_raw("%18sset an option on accept/local/remote socket", "");
        break;
    }

    /* taskbar */
#ifdef USE_WIN32
    switch(cmd) {
    case CMD_INIT:
        options.option.taskbar=1;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "taskbar"))
            break;
        if(!strcasecmp(arg, "yes"))
            options.option.taskbar=1;
        else if(!strcasecmp(arg, "no"))
            options.option.taskbar=0;
        else
            return "argument should be either 'yes' or 'no'";
        return NULL; /* OK */
    case CMD_DEFAULT:
        log_raw("%-15s = yes", "taskbar");
        break;
    case CMD_HELP:
        log_raw("%-15s = yes|no enable the taskbar icon", "taskbar");
        break;
    }
#endif

    /* verify */
    switch(cmd) {
    case CMD_INIT:
        options.verify_level=-1;
        options.verify_use_only_my=0;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "verify"))
            break;
        options.verify_level=SSL_VERIFY_NONE;
        switch(atoi(arg)) {
        case 3:
            options.verify_use_only_my=1;
        case 2:
            options.verify_level|=SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
        case 1:
            options.verify_level|=SSL_VERIFY_PEER;
        case 0:
            return NULL; /* OK */
        default:
            return "Bad verify level";
        }
    case CMD_DEFAULT:
        log_raw("%-15s = none", "verify");
        break;
    case CMD_HELP:
        log_raw("%-15s = level of peer certificate verification", "verify");
        log_raw("%18slevel 1 - verify peer certificate if present", "");
        log_raw("%18slevel 2 - require valid peer certificate always", "");
        log_raw("%18slevel 3 - verify peer with locally installed certificate",
        "");
        break;
    }

    if(cmd==CMD_EXEC)
        return option_not_found;
    return NULL; /* OK */
}
コード例 #25
0
ファイル: driver-hidpp20.c プロジェクト: bentiss/libratbag
static int
hidpp20drv_init_feature(struct ratbag_device *device, uint16_t feature)
{
    struct hidpp20drv_data *drv_data = ratbag_get_drv_data(device);
    struct ratbag *ratbag = device->ratbag;
    int rc;
    uint8_t feature_index, feature_type, feature_version;

    rc = hidpp_root_get_feature(drv_data->dev,
                                feature,
                                &feature_index,
                                &feature_type,
                                &feature_version);

    switch (feature) {
    case HIDPP_PAGE_ROOT:
    case HIDPP_PAGE_FEATURE_SET:
        /* these features are mandatory and already handled */
        break;
    case HIDPP_PAGE_MOUSE_POINTER_BASIC: {
        drv_data->capabilities |= HIDPP_CAP_RESOLUTION_2200;
        break;
    }
    case HIDPP_PAGE_ADJUSTABLE_DPI: {
        log_debug(ratbag, "device has adjustable dpi\n");
        /* we read the profile once to get the correct number of
         * supported resolutions. */
        rc = hidpp20drv_read_resolution_dpi_2201(device);
        if (rc < 0)
            return 0; /* this is not a hard failure */
        ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_SWITCHABLE_RESOLUTION);
        drv_data->capabilities |= HIDPP_CAP_SWITCHABLE_RESOLUTION_2201;
        break;
    }
    case HIDPP_PAGE_SPECIAL_KEYS_BUTTONS: {
        log_debug(ratbag, "device has programmable keys/buttons\n");
        drv_data->capabilities |= HIDPP_CAP_BUTTON_KEY_1b04;
        ratbag_device_set_capability(device, RATBAG_DEVICE_CAP_BUTTON_KEY);
        /* we read the profile once to get the correct number of
         * supported buttons. */
        if (!hidpp20drv_read_special_key_mouse(device))
            device->num_buttons = drv_data->num_controls;
        break;
    }
    case HIDPP_PAGE_BATTERY_LEVEL_STATUS: {
        uint16_t level, next_level;
        enum hidpp20_battery_status status;

        rc = hidpp20_batterylevel_get_battery_level(drv_data->dev, &level, &next_level);
        if (rc < 0)
            return rc;
        status = rc;

        log_debug(ratbag, "device battery level is %d%% (next %d%%), status %d \n",
                  level, next_level, status);

        drv_data->capabilities |= HIDPP_CAP_BATTERY_LEVEL_1000;
        break;
    }
    case HIDPP_PAGE_KBD_REPROGRAMMABLE_KEYS: {
        log_debug(ratbag, "device has programmable keys/buttons\n");
        drv_data->capabilities |= HIDPP_CAP_KBD_REPROGRAMMABLE_KEYS_1b00;

        /* we read the profile once to get the correct number of
         * supported buttons. */
        if (!hidpp20drv_read_kbd_reprogrammable_key(device))
            device->num_buttons = drv_data->num_controls;
        break;
    }
    case HIDPP_PAGE_ADJUSTABLE_REPORT_RATE: {
        log_debug(ratbag, "device has adjustable report rate\n");
        break;
    }
    case HIDPP_PAGE_COLOR_LED_EFFECTS: {
        log_debug(ratbag, "device has color effects\n");
        break;
    }
    case HIDPP_PAGE_ONBOARD_PROFILES: {
        log_debug(ratbag, "device has onboard profiles\n");
        drv_data->capabilities |= HIDPP_CAP_ONBOARD_PROFILES_8100;

        rc = hidpp20_onboard_profiles_allocate(drv_data->dev, &drv_data->profiles);
        if (rc < 0)
            return rc;

        drv_data->num_profiles = drv_data->profiles->num_profiles;
        drv_data->num_resolutions = drv_data->profiles->num_modes;
        drv_data->num_buttons = drv_data->profiles->num_buttons;

        break;
    }
    case HIDPP_PAGE_MOUSE_BUTTON_SPY: {
        log_debug(ratbag, "device has configurable mouse button spy\n");
        break;
    }
    default:
        log_raw(device->ratbag, "unknown feature 0x%04x\n", feature);
    }
    return 0;
}
コード例 #26
0
ファイル: hidpp20.c プロジェクト: phomes/libratbag
int
hidpp20_special_key_mouse_set_control(struct ratbag_device *device,
				      struct hidpp20_control_id *control)
{
	uint8_t feature_index, feature_type, feature_version;
	union hidpp20_message msg = {
		.msg.report_id = REPORT_ID_LONG,
		.msg.device_idx = 0xff,
		.msg.address = CMD_SPECIAL_KEYS_BUTTONS_SET_REPORTING,
		.msg.parameters[0] = control->control_id >> 8,
		.msg.parameters[1] = control->control_id & 0xff,
		.msg.parameters[2] = 0x00,
		.msg.parameters[3] = control->reporting.remapped >> 8,
		.msg.parameters[4] = control->reporting.remapped & 0xff,
	};
	int rc;


	rc = hidpp_root_get_feature(device,
				    HIDPP_PAGE_SPECIAL_KEYS_BUTTONS,
				    &feature_index,
				    &feature_type,
				    &feature_version);
	if (rc)
		return rc;

	msg.msg.sub_id = feature_index;
	if (control->reporting.divert)
		msg.msg.parameters[2] |= 0x03;
	if (control->reporting.persist)
		msg.msg.parameters[2] |= 0x0c;
	if (control->reporting.raw_XY)
		msg.msg.parameters[2] |= 0x20;

	return hidpp20_request_command(device, &msg);
}

/* -------------------------------------------------------------------------- */
/* 0x2200: Mouse Pointer Basic Optical Sensors                                */
/* -------------------------------------------------------------------------- */

#define CMD_MOUSE_POINTER_BASIC_GET_INFO		0x00

int
hidpp20_mousepointer_get_mousepointer_info(struct ratbag_device *device,
					   uint16_t *resolution,
					   uint8_t *flags)
{
	uint8_t feature_index, feature_type, feature_version;
	union hidpp20_message msg = {
		.msg.report_id = REPORT_ID_LONG,
		.msg.device_idx = 0xff,
		.msg.address = CMD_MOUSE_POINTER_BASIC_GET_INFO,
		.msg.parameters[0] = feature_index,
	};
	int rc;

	rc = hidpp_root_get_feature(device,
				    HIDPP_PAGE_MOUSE_POINTER_BASIC,
				    &feature_index,
				    &feature_type,
				    &feature_version);
	if (rc)
		return rc;

	msg.msg.sub_id = feature_index;

	rc = hidpp20_request_command(device, &msg);
	if (rc)
		return rc;

	*resolution = hidpp20_get_unaligned_u16(msg.msg.parameters);
	*flags = msg.msg.parameters[2];

	return 0;
}

/* -------------------------------------------------------------------------- */
/* 0x2201: Adjustable DPI                                                     */
/* -------------------------------------------------------------------------- */

#define CMD_ADJUSTABLE_DPI_GET_SENSOR_COUNT		0x00
#define CMD_ADJUSTABLE_DPI_GET_SENSOR_DPI_LIST		0x10
#define CMD_ADJUSTABLE_DPI_GET_SENSOR_DPI		0x20
#define CMD_ADJUSTABLE_DPI_SET_SENSOR_DPI		0x30

static int
hidpp20_adjustable_dpi_get_count(struct ratbag_device *device, uint8_t reg)
{
	int rc;
	union hidpp20_message msg = {
		.msg.report_id = REPORT_ID_LONG,
		.msg.device_idx = 0xff,
		.msg.sub_id = reg,
		.msg.address = CMD_ADJUSTABLE_DPI_GET_SENSOR_COUNT,
	};

	rc = hidpp20_request_command(device, &msg);
	if (rc)
		return rc;

	return msg.msg.parameters[0];
}

static int
hidpp20_adjustable_dpi_get_dpi_list(struct ratbag_device *device,
				    uint8_t reg,
				    struct hidpp20_sensor *sensor)
{
	int rc;
	unsigned i = 1, dpi_index = 0;
	union hidpp20_message msg = {
		.msg.report_id = REPORT_ID_LONG,
		.msg.device_idx = 0xff,
		.msg.sub_id = reg,
		.msg.address = CMD_ADJUSTABLE_DPI_GET_SENSOR_DPI_LIST,
		.msg.parameters[0] = sensor->index,
	};

	rc = hidpp20_request_command(device, &msg);
	if (rc)
		return rc;

	sensor->dpi_min = 0xffff;

	sensor->index = msg.msg.parameters[0];
	while (i < LONG_MESSAGE_LENGTH - 4U &&
	       hidpp20_get_unaligned_u16(&msg.msg.parameters[i]) != 0) {
		uint16_t value = hidpp20_get_unaligned_u16(&msg.msg.parameters[i]);

		if (value > 0xe000) {
			sensor->dpi_steps = value - 0xe000;
		} else {
			sensor->dpi_min = value < sensor->dpi_min ? value : sensor->dpi_min;
			sensor->dpi_max = value > sensor->dpi_max ? value : sensor->dpi_max;
			sensor->dpi_list[dpi_index++] = value;
		}
		assert(sensor->dpi_list[dpi_index] == 0x0000);
		i += 2;
	}

	return 0;
}


static int
hidpp20_adjustable_dpi_get_dpi(struct ratbag_device *device,
			       uint8_t reg,
			       struct hidpp20_sensor *sensor)
{
	int rc;
	union hidpp20_message msg = {
		.msg.report_id = REPORT_ID_LONG,
		.msg.device_idx = 0xff,
		.msg.sub_id = reg,
		.msg.address = CMD_ADJUSTABLE_DPI_GET_SENSOR_DPI,
		.msg.parameters[0] = sensor->index,
	};

	rc = hidpp20_request_command(device, &msg);
	if (rc)
		return rc;

	sensor->dpi = hidpp20_get_unaligned_u16(&msg.msg.parameters[1]);
	sensor->default_dpi = hidpp20_get_unaligned_u16(&msg.msg.parameters[3]);

	return 0;
}

int hidpp20_adjustable_dpi_get_sensors(struct ratbag_device *device,
				       struct hidpp20_sensor **sensors_list)
{
	uint8_t feature_index, feature_type, feature_version;
	struct hidpp20_sensor *s_list, *sensor;
	uint8_t num_sensors;
	unsigned i;
	int rc;


	rc = hidpp_root_get_feature(device,
				    HIDPP_PAGE_ADJUSTABLE_DPI,
				    &feature_index,
				    &feature_type,
				    &feature_version);
	if (rc)
		return rc;

	rc = hidpp20_adjustable_dpi_get_count(device, feature_index);
	if (rc < 0)
		return rc;

	num_sensors = rc;
	if (num_sensors == 0) {
		*sensors_list = NULL;
		return 0;
	}

	s_list = zalloc(num_sensors * sizeof(struct hidpp20_sensor));

	for (i = 0; i < num_sensors; i++) {
		sensor = &s_list[i];
		sensor->index = i;
		rc = hidpp20_adjustable_dpi_get_dpi_list(device,
							 feature_index,
							 sensor);
		if (rc)
			goto err;

		rc = hidpp20_adjustable_dpi_get_dpi(device, feature_index, sensor);
		if (rc)
			goto err;

		log_raw(device->ratbag,
			"sensor %d: current dpi: %d (default: %d) min: %d max: %d steps: %d\n",
			sensor->index,
			sensor->dpi,
			sensor->default_dpi,
			sensor->dpi_min,
			sensor->dpi_max,
			sensor->dpi_steps);
	}

	*sensors_list = s_list;
	return num_sensors;
err:
	free(s_list);
	return rc;
}
コード例 #27
0
ファイル: hidpp20.c プロジェクト: phomes/libratbag
int
hidpp20_batterylevel_get_battery_level(struct ratbag_device *device,
				       uint16_t *level,
				       uint16_t *next_level)
{
	uint8_t feature_index, feature_type, feature_version;
	union hidpp20_message msg = {
		.msg.report_id = REPORT_ID_LONG,
		.msg.device_idx = 0xff,
		.msg.address = CMD_BATTERY_LEVEL_STATUS_GET_BATTERY_LEVEL_STATUS,
	};
	int rc;

	rc = hidpp_root_get_feature(device,
				    HIDPP_PAGE_BATTERY_LEVEL_STATUS,
				    &feature_index,
				    &feature_type,
				    &feature_version);
	if (rc)
		return rc;

	msg.msg.sub_id = feature_index;

	rc = hidpp20_request_command(device, &msg);
	if (rc)
		return rc;

	*level = msg.msg.parameters[0];
	*next_level = msg.msg.parameters[1];

	return msg.msg.parameters[2];
}

/* -------------------------------------------------------------------------- */
/* 0x1b00: KBD reprogrammable keys and mouse buttons                          */
/* -------------------------------------------------------------------------- */

#define CMD_KBD_REPROGRAMMABLE_KEYS_GET_COUNT		0x00
#define CMD_KBD_REPROGRAMMABLE_KEYS_GET_CTRL_ID_INFO	0x10

static int
hidpp20_kbd_reprogrammable_keys_get_count(struct ratbag_device *device, uint8_t reg)
{
	union hidpp20_message msg = {
		.msg.report_id = REPORT_ID_LONG,
		.msg.device_idx = 0xff,
		.msg.sub_id = reg,
		.msg.address = CMD_KBD_REPROGRAMMABLE_KEYS_GET_COUNT,
	};
	int rc;

	rc = hidpp20_request_command(device, &msg);
	if (rc)
		return rc;

	return msg.msg.parameters[0];
}

static int
hidpp20_kbd_reprogrammable_keys_get_info(struct ratbag_device *device,
					 uint8_t reg,
					 struct hidpp20_control_id *control)
{
	int rc;
	union hidpp20_message msg = {
		.msg.report_id = REPORT_ID_LONG,
		.msg.device_idx = 0xff,
		.msg.sub_id = reg,
		.msg.address = CMD_KBD_REPROGRAMMABLE_KEYS_GET_CTRL_ID_INFO,
		.msg.parameters[0] = control->index,
	};

	rc = hidpp20_request_command(device, &msg);
	if (rc)
		return rc;

	control->control_id = hidpp20_get_unaligned_u16(&msg.msg.parameters[0]);
	control->task_id = hidpp20_get_unaligned_u16(&msg.msg.parameters[2]);
	control->flags = msg.msg.parameters[4];

	return 0;
}

int
hidpp20_kbd_reprogrammable_keys_get_controls(struct ratbag_device *device,
					     struct hidpp20_control_id **controls_list)
{
	uint8_t feature_index, feature_type, feature_version;
	struct hidpp20_control_id *c_list, *control;
	uint8_t num_controls;
	unsigned i;
	int rc;

	rc = hidpp_root_get_feature(device,
				    HIDPP_PAGE_KBD_REPROGRAMMABLE_KEYS,
				    &feature_index,
				    &feature_type,
				    &feature_version);
	if (rc)
		return rc;

	rc = hidpp20_kbd_reprogrammable_keys_get_count(device, feature_index);
	if (rc < 0)
		return rc;

	num_controls = rc;
	if (num_controls == 0) {
		*controls_list = NULL;
		return 0;
	}

	c_list = zalloc(num_controls * sizeof(struct hidpp20_control_id));

	for (i = 0; i < num_controls; i++) {
		control = &c_list[i];
		control->index = i;
		rc = hidpp20_kbd_reprogrammable_keys_get_info(device,
							      feature_index,
							      control);
		if (rc)
			goto err;

		/* 0x1b00 and 0x1b04 have the same control/task id mappings.
		 * I hope */
		log_raw(device->ratbag,
			"control %d: cid: '%s' (%d) tid: '%s' (%d) flags: 0x%02x\n",
			control->index,
			hidpp20_1b04_get_logical_mapping_name(control->control_id),
			control->control_id,
			hidpp20_1b04_get_physical_mapping_name(control->task_id),
			control->task_id,
			control->flags);
	}

	*controls_list = c_list;
	return num_controls;
err:
	free(c_list);
	return rc;
}

/* -------------------------------------------------------------------------- */
/* 0x1b04: Special keys and mouse buttons                                     */
/* -------------------------------------------------------------------------- */

#define CMD_SPECIAL_KEYS_BUTTONS_GET_COUNT		0x00
#define CMD_SPECIAL_KEYS_BUTTONS_GET_INFO		0x10
#define CMD_SPECIAL_KEYS_BUTTONS_GET_REPORTING		0x20
#define CMD_SPECIAL_KEYS_BUTTONS_SET_REPORTING		0x30

static int
hidpp20_special_keys_buttons_get_count(struct ratbag_device *device, uint8_t reg)
{
	int rc;
	union hidpp20_message msg = {
		.msg.report_id = REPORT_ID_LONG,
		.msg.device_idx = 0xff,
		.msg.sub_id = reg,
		.msg.address = CMD_SPECIAL_KEYS_BUTTONS_GET_COUNT,
	};

	rc = hidpp20_request_command(device, &msg);
	if (rc)
		return rc;

	return msg.msg.parameters[0];
}

static int
hidpp20_special_keys_buttons_get_info(struct ratbag_device *device,
				    uint8_t reg,
				    struct hidpp20_control_id *control)
{
	int rc;
	union hidpp20_message msg = {
		.msg.report_id = REPORT_ID_LONG,
		.msg.device_idx = 0xff,
		.msg.sub_id = reg,
		.msg.address = CMD_SPECIAL_KEYS_BUTTONS_GET_INFO,
		.msg.parameters[0] = control->index,
	};

	rc = hidpp20_request_command(device, &msg);
	if (rc)
		return rc;

	control->control_id = hidpp20_get_unaligned_u16(&msg.msg.parameters[0]);
	control->task_id = hidpp20_get_unaligned_u16(&msg.msg.parameters[2]);
	control->flags = msg.msg.parameters[4];
	control->position = msg.msg.parameters[5];
	control->group = msg.msg.parameters[6];
	control->group_mask = msg.msg.parameters[7];
	control->raw_XY = msg.msg.parameters[8] & 0x01;

	return 0;
}


static int
hidpp20_special_keys_buttons_get_reporting(struct ratbag_device *device,
					   uint8_t reg,
					   struct hidpp20_control_id *control)
{
	int rc;
	union hidpp20_message msg = {
		.msg.report_id = REPORT_ID_LONG,
		.msg.device_idx = 0xff,
		.msg.sub_id = reg,
		.msg.address = CMD_SPECIAL_KEYS_BUTTONS_GET_REPORTING,
		.msg.parameters[0] = control->control_id >> 8,
		.msg.parameters[1] = control->control_id & 0xff,
	};

	rc = hidpp20_request_command(device, &msg);
	if (rc)
		return rc;

	control->reporting.remapped = hidpp20_get_unaligned_u16(&msg.msg.parameters[3]);
	control->reporting.raw_XY = !!(msg.msg.parameters[2] & 0x10);
	control->reporting.persist = !!(msg.msg.parameters[2] & 0x04);
	control->reporting.divert = !!(msg.msg.parameters[2] & 0x01);

	return 0;
}

int hidpp20_special_key_mouse_get_controls(struct ratbag_device *device,
					   struct hidpp20_control_id **controls_list)
{
	uint8_t feature_index, feature_type, feature_version;
	struct hidpp20_control_id *c_list, *control;
	uint8_t num_controls;
	unsigned i;
	int rc;


	rc = hidpp_root_get_feature(device,
				    HIDPP_PAGE_SPECIAL_KEYS_BUTTONS,
				    &feature_index,
				    &feature_type,
				    &feature_version);
	if (rc)
		return rc;

	rc = hidpp20_special_keys_buttons_get_count(device, feature_index);
	if (rc < 0)
		return rc;

	num_controls = rc;
	if (num_controls == 0) {
		*controls_list = NULL;
		return 0;
	}

	c_list = zalloc(num_controls * sizeof(struct hidpp20_control_id));

	for (i = 0; i < num_controls; i++) {
		control = &c_list[i];
		control->index = i;
		rc = hidpp20_special_keys_buttons_get_info(device,
							   feature_index,
							   control);
		if (rc)
			goto err;

		rc = hidpp20_special_keys_buttons_get_reporting(device,
								feature_index,
								control);
		if (rc)
			goto err;

		log_raw(device->ratbag,
			"control %d: cid: '%s' (%d) tid: '%s' (%d) flags: 0x%02x pos: %d group: %d gmask: 0x%02x raw_XY: %s\n"
			"      reporting: raw_xy: %s persist: %s divert: %s remapped: '%s' (%d)\n",
			control->index,
			hidpp20_1b04_get_logical_mapping_name(control->control_id),
			control->control_id,
			hidpp20_1b04_get_physical_mapping_name(control->task_id),
			control->task_id,
			control->flags,
			control->position,
			control->group,
			control->group_mask,
			control->raw_XY ? "yes" : "no",
			control->reporting.raw_XY ? "yes" : "no",
			control->reporting.persist ? "yes" : "no",
			control->reporting.divert ? "yes" : "no",
			hidpp20_1b04_get_logical_mapping_name(control->reporting.remapped),
			control->reporting.remapped);
	}

	*controls_list = c_list;
	return num_controls;
err:
	free(c_list);
	return rc;
}
コード例 #28
0
ファイル: hidpp20.c プロジェクト: phomes/libratbag
int
hidpp_root_get_feature(struct ratbag_device *device,
		       uint16_t feature,
		       uint8_t *feature_index,
		       uint8_t *feature_type,
		       uint8_t *feature_version)
{
	int rc;
	union hidpp20_message msg = {
		.msg.report_id = REPORT_ID_LONG,
		.msg.device_idx = 0xff,
		.msg.sub_id = HIDPP_PAGE_ROOT_IDX,
		.msg.address = CMD_ROOT_GET_FEATURE,
		.msg.parameters[0] = feature >> 8,
		.msg.parameters[1] = feature & 0xff,
	};

	rc = hidpp20_request_command(device, &msg);
	if (rc)
		return rc;

	*feature_index = msg.msg.parameters[0];
	*feature_type = msg.msg.parameters[1];
	*feature_version = msg.msg.parameters[2];

	log_raw(device->ratbag, "feature 0x%04x is at 0x%02x\n", feature, *feature_index);
	return 0;
}

int
hidpp20_root_get_protocol_version(struct ratbag_device *device,
				  unsigned *major,
				  unsigned *minor)
{
	int rc;
	union hidpp20_message msg = {
		.msg.report_id = REPORT_ID_LONG,
		.msg.device_idx = 0xff,
		.msg.sub_id = HIDPP_PAGE_ROOT_IDX,
		.msg.address = CMD_ROOT_GET_PROTOCOL_VERSION,
	};

	rc = hidpp20_request_command_allow_error(device, &msg, true);

	if (rc == ERR_INVALID_SUBID) {
		*major = 1;
		*minor = 0;
		return 0;
	}

	if (rc == 0) {
		*major = msg.msg.parameters[0];
		*minor = msg.msg.parameters[1];
	}

	return rc;
}

/* -------------------------------------------------------------------------- */
/* 0x0001: Feature Set                                                        */
/* -------------------------------------------------------------------------- */

#define CMD_FEATURE_SET_GET_COUNT			0x00
#define CMD_FEATURE_SET_GET_FEATURE_ID			0x10

static int
hidpp20_feature_set_get_count(struct ratbag_device *device, uint8_t reg)
{
	int rc;
	union hidpp20_message msg = {
		.msg.report_id = REPORT_ID_LONG,
		.msg.device_idx = 0xff,
		.msg.sub_id = reg,
		.msg.address = CMD_FEATURE_SET_GET_COUNT,
	};

	rc = hidpp20_request_command(device, &msg);
	if (rc)
		return rc;

	return msg.msg.parameters[0];
}

static int
hidpp20_feature_set_get_feature_id(struct ratbag_device *device,
				   uint8_t reg,
				   uint8_t feature_index,
				   uint16_t *feature,
				   uint8_t *type)
{
	int rc;
	union hidpp20_message msg = {
		.msg.report_id = REPORT_ID_LONG,
		.msg.device_idx = 0xff,
		.msg.sub_id = reg,
		.msg.address = CMD_FEATURE_SET_GET_FEATURE_ID,
		.msg.parameters[0] = feature_index,
	};

	rc = hidpp20_request_command(device, &msg);
	if (rc)
		return rc;

	*feature = hidpp20_get_unaligned_u16(msg.msg.parameters);
	*type = msg.msg.parameters[2];

	return 0;
}

int hidpp20_feature_set_get(struct ratbag_device *device,
			    struct hidpp20_feature **feature_list)
{
	uint8_t feature_index, feature_type, feature_version;
	struct hidpp20_feature *flist;
	int rc;
	uint8_t feature_count;
	unsigned int i;

	rc = hidpp_root_get_feature(device,
				    HIDPP_PAGE_FEATURE_SET,
				    &feature_index,
				    &feature_type,
				    &feature_version);
	if (rc)
		return rc;

	rc = hidpp20_feature_set_get_count(device, feature_index);
	if (rc < 0)
		return rc;

	feature_count = (uint8_t)rc;

	if (!feature_count) {
		*feature_list = NULL;
		return 0;
	}

	flist = zalloc(feature_count * sizeof(struct hidpp20_feature));

	for (i = 0; i < feature_count; i++) {
		rc = hidpp20_feature_set_get_feature_id(device,
							feature_index,
							i,
							&flist[i].feature,
							&flist[i].type);
		if (rc)
			goto err;
	}

	*feature_list = flist;
	return feature_count;
err:
	free(flist);
	return rc;
}
コード例 #29
0
ファイル: options.c プロジェクト: OPSF/uClinux
static void syntax(char *confname) {
    log_raw(" ");
    log_raw("Syntax:");
#ifdef USE_WIN32
    log_raw("stunnel [filename] | -help | -version | -sockets"
            " | -install | -uninstall");
#else
    log_raw("stunnel [filename] | -fd [n] | -help | -version | -sockets");
#endif
    log_raw("    filename    - use specified config file instead of %s",
        confname);
    log_raw("    -fd n       - read the config file from specified file descriptor");
    log_raw("    -help       - get config file help");
    log_raw("    -version    - display version and defaults");
    log_raw("    -sockets    - display default socket options");
#ifdef USE_WIN32
    log_raw("    -install    - install NT service");
    log_raw("    -uninstall  - uninstall NT service");
#endif
    exit(1);
}
コード例 #30
0
ファイル: options.c プロジェクト: OPSF/uClinux
static char *service_options(CMD cmd, LOCAL_OPTIONS *section,
        char *opt, char *arg) {

    if(cmd==CMD_DEFAULT || cmd==CMD_HELP) {
        log_raw(" ");
        log_raw("Service-level options");
    }

    /* accept */
    switch(cmd) {
    case CMD_INIT:
        section->option.accept=0;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "accept"))
            break;
        section->option.accept=1;
        if(!name2nums(arg, "0.0.0.0",
                &section->localnames, &section->localport))
            exit(2);
        return NULL; /* OK */
    case CMD_DEFAULT:
        break;
    case CMD_HELP:
        log_raw("%-15s = [host:]port accept connections on specified host:port",
            "accept");
        break;
    }

    /* connect */
    switch(cmd) {
    case CMD_INIT:
        section->option.remote=0;
        section->remote_address=NULL;
        section->remotenames=NULL;
        section->remoteport=0;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "connect"))
            break;
        section->option.remote=1;
        section->remote_address=stralloc(arg);
        if(!section->option.delayed_lookup && !name2nums(arg, "127.0.0.1",
                &section->remotenames, &section->remoteport)) {
            log_raw("Cannot resolve '%s' - delaying DNS lookup", arg);
            section->option.delayed_lookup=1;
        }
        return NULL; /* OK */
    case CMD_DEFAULT:
        break;
    case CMD_HELP:
        log_raw("%-15s = [host:]port connect remote host:port",
            "connect");
        break;
    }

    /* delay */
    switch(cmd) {
    case CMD_INIT:
        section->option.delayed_lookup=0;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "delay"))
            break;
        if(!strcasecmp(arg, "yes"))
            section->option.delayed_lookup=1;
        else if(!strcasecmp(arg, "no"))
            section->option.delayed_lookup=0;
        else
            return "argument should be either 'yes' or 'no'";
        return NULL; /* OK */
    case CMD_DEFAULT:
        break;
    case CMD_HELP:
        log_raw("%-15s = yes|no delay DNS lookup for 'connect' option",
            "delay");
        break;
    }

    /* exec */
#ifndef USE_WIN32
    switch(cmd) {
    case CMD_INIT:
        section->option.program=0;
        section->execname=NULL;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "exec"))
            break;
        section->option.program=1;
        section->execname=stralloc(arg);
        return NULL; /* OK */
    case CMD_DEFAULT:
        break;
    case CMD_HELP:
        log_raw("%-15s = file execute local inetd-type program",
            "exec");
        break;
    }
#endif

    /* execargs */
#ifndef USE_WIN32
    switch(cmd) {
    case CMD_INIT:
        section->execargs=NULL;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "execargs"))
            break;
        section->execargs=argalloc(arg);
        return NULL; /* OK */
    case CMD_DEFAULT:
        break;
    case CMD_HELP:
        log_raw("%-15s = arguments for 'exec' (including $0)",
            "execargs");
        break;
    }
#endif

    /* ident */
    switch(cmd) {
    case CMD_INIT:
        section->username=NULL;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "ident"))
            break;
        section->username=stralloc(arg);
        return NULL; /* OK */
    case CMD_DEFAULT:
        break;
    case CMD_HELP:
        log_raw("%-15s = username for IDENT (RFC 1413) checking", "ident");
        break;
    }

    /* local */
    switch(cmd) {
    case CMD_INIT:
        section->local_ip=NULL;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "local"))
            break;
        if(!host2nums(arg, &(section->local_ip)))
            exit(2);
        return NULL; /* OK */
    case CMD_DEFAULT:
        break;
    case CMD_HELP:
        log_raw("%-15s = IP address to be used as source for remote"
            " connections", "local");
        break;
    }

    /* protocol */
    switch(cmd) {
    case CMD_INIT:
        section->protocol=NULL;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "protocol"))
            break;
        section->protocol=stralloc(arg);
        return NULL; /* OK */
    case CMD_DEFAULT:
        break;
    case CMD_HELP:
        log_raw("%-15s = protocol to negotiate before SSL initialization",
            "protocol");
        log_raw("%18scurrently supported: cifs, nntp, pop3, smtp", "");
        break;
    }

    /* pty */
#ifndef USE_WIN32
    switch(cmd) {
    case CMD_INIT:
        section->option.pty=0;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "pty"))
            break;
        if(!strcasecmp(arg, "yes"))
            section->option.pty=1;
        else if(!strcasecmp(arg, "no"))
            section->option.pty=0;
        else
            return "argument should be either 'yes' or 'no'";
        return NULL; /* OK */
    case CMD_DEFAULT:
        break;
    case CMD_HELP:
        log_raw("%-15s = yes|no allocate pseudo terminal for 'exec' option",
            "pty");
        break;
    }
#endif

    /* TIMEOUTbusy */
    switch(cmd) {
    case CMD_INIT:
        section->timeout_busy=300; /* 5 minutes */
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "TIMEOUTbusy"))
            break;
        if(atoi(arg)>0)
            section->timeout_busy=atoi(arg);
        else
            return "Illegal busy timeout";
        return NULL; /* OK */
    case CMD_DEFAULT:
        log_raw("%-15s = %d seconds", "TIMEOUTbusy", section->timeout_busy);
        break;
    case CMD_HELP:
        log_raw("%-15s = seconds to wait for expected data", "TIMEOUTbusy");
        break;
    }

    /* TIMEOUTclose */
    switch(cmd) {
    case CMD_INIT:
        section->timeout_close=60; /* 1 minute */
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "TIMEOUTclose"))
            break;
        if(atoi(arg)>0 || !strcmp(arg, "0"))
            section->timeout_close=atoi(arg);
        else
            return "Illegal close timeout";
        return NULL; /* OK */
    case CMD_DEFAULT:
        log_raw("%-15s = %d seconds", "TIMEOUTclose", section->timeout_close);
        break;
    case CMD_HELP:
        log_raw("%-15s = seconds to wait for close_notify"
            " (set to 0 for buggy MSIE)", "TIMEOUTclose");
        break;
    }

    /* TIMEOUTidle */
    switch(cmd) {
    case CMD_INIT:
        section->timeout_idle=43200; /* 12 hours */
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "TIMEOUTidle"))
            break;
        if(atoi(arg)>0)
            section->timeout_idle=atoi(arg);
        else
            return "Illegal idle timeout";
        return NULL; /* OK */
    case CMD_DEFAULT:
        log_raw("%-15s = %d seconds", "TIMEOUTidle", section->timeout_idle);
        break;
    case CMD_HELP:
        log_raw("%-15s = seconds to keep idle connection", "TIMEOUTidle");
        break;
    }

    /* transparent */
#ifndef USE_WIN32
    switch(cmd) {
    case CMD_INIT:
        section->option.transparent=0;
        break;
    case CMD_EXEC:
        if(strcasecmp(opt, "transparent"))
            break;
        if(!strcasecmp(arg, "yes"))
            section->option.transparent=1;
        else if(!strcasecmp(arg, "no"))
            section->option.transparent=0;
        else
            return "argument should be either 'yes' or 'no'";
        return NULL; /* OK */
    case CMD_DEFAULT:
        break;
    case CMD_HELP:
        log_raw("%-15s = yes|no transparent proxy mode",
            "transparent");
        break;
    }
#endif

    if(cmd==CMD_EXEC)
        return option_not_found;
    return NULL; /* OK */
}