static void send_opt(Telnet telnet, int cmd, int option) { unsigned char b[3]; b[0] = IAC; b[1] = cmd; b[2] = option; telnet->bufsize = sk_write(telnet->s, (char *)b, 3); log_option(telnet, "client", cmd, option); }
static void proc_rec_opt(Telnet telnet, int cmd, int option) { const struct Opt *const *o; log_option(telnet, "server", cmd, option); for (o = opts; *o; o++) { if ((*o)->option == option && (*o)->ack == cmd) { switch (telnet->opt_states[(*o)->index]) { case REQUESTED: telnet->opt_states[(*o)->index] = ACTIVE; activate_option(telnet, *o); break; case ACTIVE: break; case INACTIVE: telnet->opt_states[(*o)->index] = ACTIVE; send_opt(telnet, (*o)->send, option); activate_option(telnet, *o); break; case REALLY_INACTIVE: send_opt(telnet, (*o)->nsend, option); break; } return; } else if ((*o)->option == option && (*o)->nak == cmd) { switch (telnet->opt_states[(*o)->index]) { case REQUESTED: telnet->opt_states[(*o)->index] = INACTIVE; refused_option(telnet, *o); break; case ACTIVE: telnet->opt_states[(*o)->index] = INACTIVE; send_opt(telnet, (*o)->nsend, option); option_side_effects(telnet, *o, 0); break; case INACTIVE: case REALLY_INACTIVE: break; } return; } } /* * If we reach here, the option was one we weren't prepared to * cope with. If the request was positive (WILL or DO), we send * a negative ack to indicate refusal. If the request was * negative (WONT / DONT), we must do nothing. */ if (cmd == WILL || cmd == DO) send_opt(telnet, (cmd == WILL ? DONT : WONT), option); }
/* option bytes: [code][len][data1][data2]..[dataLEN] */ int FAST_FUNC add_option_string(uint8_t *optionptr, uint8_t *string) { int end = end_option(optionptr); /* end position + string length + option code/length + end option */ if (end + string[OPT_LEN] + 2 + 1 >= DHCP_OPTIONS_BUFSIZE) { bb_error_msg("option 0x%02x did not fit into the packet", string[OPT_CODE]); return 0; } log_option("Adding option", string); memcpy(optionptr + end, string, string[OPT_LEN] + 2); optionptr[end + string[OPT_LEN] + 2] = DHCP_END; return string[OPT_LEN] + 2; }
/* Add an option (supplied in binary form) to the options. * Option format: [code][len][data1][data2]..[dataLEN] */ void FAST_FUNC udhcp_add_binary_option(struct dhcp_packet *packet, uint8_t *addopt) { unsigned len; uint8_t *optionptr = packet->options; unsigned end = udhcp_end_option(optionptr); len = OPT_DATA + addopt[OPT_LEN]; /* end position + (option code/length + addopt length) + end option */ if (end + len + 1 >= DHCP_OPTIONS_BUFSIZE) { //TODO: learn how to use overflow option if we exhaust packet->options[] bb_error_msg("option 0x%02x did not fit into the packet", addopt[OPT_CODE]); return; } log_option("adding option", addopt); memcpy(optionptr + end, addopt, len); optionptr[end + len] = DHCP_END; }
/* get an option with bounds checking (warning, result is not aligned). */ uint8_t* FAST_FUNC get_option(struct dhcp_packet *packet, int code) { uint8_t *optionptr; int len; int rem; int overload = 0; enum { FILE_FIELD101 = FILE_FIELD * 0x101, SNAME_FIELD101 = SNAME_FIELD * 0x101, }; /* option bytes: [code][len][data1][data2]..[dataLEN] */ optionptr = packet->options; rem = sizeof(packet->options); while (1) { if (rem <= 0) { bb_error_msg("bogus packet, malformed option field"); return NULL; } if (optionptr[OPT_CODE] == DHCP_PADDING) { rem--; optionptr++; continue; } if (optionptr[OPT_CODE] == DHCP_END) { if ((overload & FILE_FIELD101) == FILE_FIELD) { /* can use packet->file, and didn't look at it yet */ overload |= FILE_FIELD101; /* "we looked at it" */ optionptr = packet->file; rem = sizeof(packet->file); continue; } if ((overload & SNAME_FIELD101) == SNAME_FIELD) { /* can use packet->sname, and didn't look at it yet */ overload |= SNAME_FIELD101; /* "we looked at it" */ optionptr = packet->sname; rem = sizeof(packet->sname); continue; } break; } len = 2 + optionptr[OPT_LEN]; rem -= len; if (rem < 0) continue; /* complain and return NULL */ if (optionptr[OPT_CODE] == code) { log_option("Option found", optionptr); return optionptr + OPT_DATA; } if (optionptr[OPT_CODE] == DHCP_OPTION_OVERLOAD) { overload |= optionptr[OPT_DATA]; /* fall through */ } optionptr += len; } /* log3 because udhcpc uses it a lot - very noisy */ log3("Option 0x%02x not found", code); return NULL; }
static boolean set_option(const char *name, union nh_optvalue value, boolean isstring) { boolean is_ui = FALSE; struct nh_option_desc *option = NULL; if (options) option = find_option(options, name); if (!option && !program_state.game_running && birth_options) option = find_option(birth_options, name); if (!option && ui_options) { option = find_option(ui_options, name); is_ui = TRUE; } if (!option) return FALSE; /* if this option change affects game options (!is_ui) and happens during a replay (program_state.viewing) and the change isn't triggered by the replay (!program_state.restoring) */ if (!is_ui && program_state.viewing && !program_state.restoring) return FALSE; /* Nope, sorry. That would mess up the replay */ if (isstring) value = string_to_optvalue(option, value.s); if (!option_value_ok(option, value)) return FALSE; if (copy_option_value(option, value) && !is_ui) log_option(option); /* prev value != new value */ if (option->type == OPTTYPE_BOOL) { int i; boolean *bvar = NULL; const struct nh_boolopt_map *boolmap = boolopt_map; if (is_ui) boolmap = ui_boolopt_map; for (i = 0; boolmap[i].optname && !bvar; i++) if (!strcmp(option->name, boolmap[i].optname)) bvar = boolmap[i].addr; if (!bvar) /* shouldn't happen */ return FALSE; *bvar = option->value.b; if (is_ui && ui_option_callback) /* allow the ui to "see" changes to booleans, but the return value doesn't mattter as the option was set here. */ ui_option_callback(option); return TRUE; } else if (is_ui) return ui_option_callback(option); /* regular non-boolean options */ else if (!strcmp("comment", option->name)) { /* do nothing */ } else if (!strcmp("disclose", option->name)) { flags.end_disclose = option->value.e; } else if (!strcmp("fruit", option->name)) { strncpy(pl_fruit, option->value.s, PL_FSIZ); if (objects) /* don't do fruitadd before the game is running */ fruitadd(pl_fruit); } else if (!strcmp("menustyle", option->name)) { flags.menu_style = option->value.e; } else if (!strcmp("packorder", option->name)) { if (!change_inv_order(option->value.s)) return FALSE; } else if (!strcmp("pickup_burden", option->name)) { flags.pickup_burden = option->value.e; } else if (!strcmp("runmode", option->name)) { iflags.runmode = option->value.e; } else if (!strcmp("autopickup_rules", option->name)) { if (iflags.ap_rules) { free(iflags.ap_rules->rules); free(iflags.ap_rules); iflags.ap_rules = NULL; } iflags.ap_rules = copy_autopickup_rules(option->value.ar); } /* birth options */ else if (!strcmp("align", option->name)) { flags.init_align = option->value.e; } else if (!strcmp("gender", option->name)) { flags.init_gend = option->value.e; } else if (!strcmp("race", option->name)) { flags.init_race = option->value.e; } else if (!strcmp("role", option->name)) { flags.init_role = option->value.e; } else if (!strcmp("catname", option->name)) { strncpy(catname, option->value.s, PL_PSIZ); } else if (!strcmp("dogname", option->name)) { strncpy(dogname, option->value.s, PL_PSIZ); } else if (!strcmp("horsename", option->name)) { strncpy(horsename, option->value.s, PL_PSIZ); } else if (!strcmp("pettype", option->name)) { preferred_pet = (char)option->value.e; } else /* unrecognized option */ return FALSE; /* assume that any recognized option has been handled. */ return TRUE; }
/* Get an option with bounds checking (warning, result is not aligned) */ uint8_t* FAST_FUNC udhcp_get_option(struct dhcp_packet *packet, int code) { uint8_t *optionptr; int len; int rem; int overload = 0; enum { FILE_FIELD101 = FILE_FIELD * 0x101, SNAME_FIELD101 = SNAME_FIELD * 0x101, }; /* option bytes: [code][len][data1][data2]..[dataLEN] */ optionptr = packet->options; rem = sizeof(packet->options); while (1) { if (rem <= 0) { complain: bb_error_msg("bad packet, malformed option field"); return NULL; } /* DHCP_PADDING and DHCP_END have no [len] byte */ if (optionptr[OPT_CODE] == DHCP_PADDING) { rem--; optionptr++; continue; } if (optionptr[OPT_CODE] == DHCP_END) { if ((overload & FILE_FIELD101) == FILE_FIELD) { /* can use packet->file, and didn't look at it yet */ overload |= FILE_FIELD101; /* "we looked at it" */ optionptr = packet->file; rem = sizeof(packet->file); continue; } if ((overload & SNAME_FIELD101) == SNAME_FIELD) { /* can use packet->sname, and didn't look at it yet */ overload |= SNAME_FIELD101; /* "we looked at it" */ optionptr = packet->sname; rem = sizeof(packet->sname); continue; } break; } if (rem <= OPT_LEN) goto complain; /* complain and return NULL */ len = 2 + optionptr[OPT_LEN]; rem -= len; if (rem < 0) goto complain; /* complain and return NULL */ if (optionptr[OPT_CODE] == code) { if (optionptr[OPT_LEN] == 0) { /* So far no valid option with length 0 known. * Having this check means that searching * for DHCP_MESSAGE_TYPE need not worry * that returned pointer might be unsafe * to dereference. */ goto complain; /* complain and return NULL */ } log_option("option found", optionptr); return optionptr + OPT_DATA; } if (optionptr[OPT_CODE] == DHCP_OPTION_OVERLOAD) { if (len >= 3) overload |= optionptr[OPT_DATA]; /* fall through */ } optionptr += len; } /* log3 because udhcpc uses it a lot - very noisy */ log3("option 0x%02x not found", code); return NULL; }
int setOptions( char *uuid, SANE_Handle *openDeviceHandle, int *request_resolution ) { int option = 0; SANE_Status status; SANE_Fixed v_f; SANE_Int v_i; SANE_Bool v_b; char *v_c; //const char *modes[] = { SANE_VALUE_SCAN_MODE_COLOR, SANE_VALUE_SCAN_MODE_GRAY, "Grayscale", NULL }; const char *modes_colour[] = { SANE_VALUE_SCAN_MODE_COLOR, "Color", SANE_VALUE_SCAN_MODE_GRAY, "Grayscale", NULL }; const char *modes_gray[] = { SANE_VALUE_SCAN_MODE_GRAY, "Grayscale", NULL }; const char *speeds[] = { "Auto", "Normal", "Fast", NULL }; const char *compression[] = { "None", NULL }; const char *sources[] = { "Auto", SANE_I18N ("Auto"), "Flatbed", SANE_I18N ("Flatbed"), "FlatBed", "Normal", SANE_I18N ("Normal"), NULL }; int testScanner = 0; char *devName = getScanParam(uuid, SCAN_PARAM_DEVNAME); if ( strstr(devName, "test") != 0 ) { testScanner = 1; } free(devName); for (option = 0; option < 9999; option++) { const SANE_Option_Descriptor *sod = sane_get_option_descriptor (openDeviceHandle, option); // No more options if (sod == NULL) break; // Just a placeholder if (sod->type == SANE_TYPE_GROUP || sod->name == NULL || option == 0) continue; log_option( option, sod ); // Validation if ( (sod->cap & SANE_CAP_SOFT_SELECT) && (sod->cap & SANE_CAP_HARD_SELECT) ) { o_log(DEBUGM, "The backend said that '%s' is both hardward and software settable! Err", sod->name); updateScanProgress(uuid, SCAN_ERRO_FROM_SCANNER, 0); return 0; } // we MUST set this value if ( (sod->cap & SANE_CAP_SOFT_DETECT) && ((sod->cap & SANE_CAP_INACTIVE) == 0) ) { // A hardware setting if ( sod->cap & SANE_CAP_HARD_SELECT ) { o_log(DEBUGM, "We've got no way of telling the user to set the hardward %s! Err", sod->name); } // a software setting else { int paramSetRet = 0; // Set scanning Source if ( strcmp(sod->name, SANE_NAME_SCAN_SOURCE) == 0 ) { if ( !setDefaultScannerOption(openDeviceHandle, sod, option, ¶mSetRet) ) { int i, j; int foundMatch = 0; for (i = 0; sources[i] != NULL; i++) { for (j = 0; sod->constraint.string_list[j]; j++) { if (strcmp (sources[i], sod->constraint.string_list[j]) == 0) break; } if (sod->constraint.string_list[j] != NULL) { v_c = o_strdup(sources[i]); status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, (void *)v_c, ¶mSetRet); free(v_c); foundMatch = 1; break; } } if( foundMatch == 0 ) { o_log(DEBUGM, "Non of the available options are appropriate."); } } } // Set scanning mode else if ( strcmp(sod->name, SANE_NAME_SCAN_MODE ) == 0 ) { const char **modes; char *requested_mode = getScanParam(uuid, SCAN_PARAM_FORMAT ); if( 0 == strcmp( "colour", requested_mode ) ) { modes = modes_colour; } else { modes = modes_gray; } free( requested_mode ); int i, j; int foundMatch = 0; for (i = 0; modes[i] != NULL; i++) { for (j = 0; sod->constraint.string_list[j]; j++) { if (strcmp (modes[i], sod->constraint.string_list[j]) == 0) break; } if (sod->constraint.string_list[j] != NULL) { v_c = o_strdup(modes[i]); status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, (void *)v_c, ¶mSetRet); free(v_c); foundMatch = 1; break; } } if( foundMatch == 0 ) { o_log(DEBUGM, "Non of the available options are appropriate."); } } else if ( strcmp(sod->name, "batch-scan" ) == 0 ) { v_b = SANE_FALSE; status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_b, ¶mSetRet); } else if ( strcmp(sod->name, "compression") == 0 ) { int i, j; int foundMatch = 0; for (i = 0; compression[i] != NULL; i++) { for (j = 0; sod->constraint.string_list[j]; j++) { o_log(DEBUGM, "n list: %s", sod->constraint.string_list[j]); if (strcmp (compression[i], sod->constraint.string_list[j]) == 0) break; } if (sod->constraint.string_list[j] != NULL) { o_log(DEBUGM, "Attempting to set compresstion to: %s", compression[i]); v_c = o_strdup(compression[i]); status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, (void *)v_c, ¶mSetRet); free(v_c); foundMatch = 1; break; } } if( foundMatch == 0 ) { o_log(DEBUGM, "Non of the available options are appropriate."); } } // Set scanning depth else if ( strcmp(sod->name, SANE_NAME_BIT_DEPTH) == 0 ) { if ( !setDefaultScannerOption(openDeviceHandle, sod, option, ¶mSetRet) ) { if( sod->type == SANE_TYPE_STRING ) { v_c = o_strdup("8"); status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, (void *)v_c, ¶mSetRet); free(v_c); } if (sod->type == SANE_TYPE_FIXED) { v_f = SANE_FIX( 8 ); status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_f, ¶mSetRet); } else { v_i = 8; status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_i, ¶mSetRet); } } } // Set Preview mode else if ( strcmp(sod->name, SANE_NAME_PREVIEW) == 0 ) { if ( !setDefaultScannerOption(openDeviceHandle, sod, option, ¶mSetRet) ) { v_b = SANE_FALSE; status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_b, ¶mSetRet); } } // Set scanning resolution else if ( strcmp(sod->name, SANE_NAME_SCAN_RESOLUTION) == 0 ) { char *request_resolution_s; request_resolution_s = getScanParam(uuid, SCAN_PARAM_REQUESTED_RESOLUTION); *request_resolution = atoi(request_resolution_s); free(request_resolution_s); if (sod->type == SANE_TYPE_FIXED) { v_f = SANE_FIX( *request_resolution ); status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_f, ¶mSetRet); } else if (sod->type == SANE_TYPE_INT) { int sane_resolution = *request_resolution; status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &sane_resolution, ¶mSetRet); } else { int sane_resolution = *request_resolution; if( sod->constraint.range->quant != 0 ) sane_resolution = sane_resolution * sod->constraint.range->quant; status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &sane_resolution, ¶mSetRet); } } else if ( strcmp(sod->name, SANE_NAME_SCAN_TL_Y) == 0 ) { v_f = sod->constraint.range->min; status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_f, ¶mSetRet); } else if ( strcmp(sod->name, SANE_NAME_SCAN_TL_X) == 0 ) { v_f = sod->constraint.range->min; status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_f, ¶mSetRet); } else if ( strcmp(sod->name, SANE_NAME_SCAN_BR_Y) == 0 ) { int pagelength; char *length_s; v_f = sod->constraint.range->max; length_s = getScanParam(uuid, SCAN_PARAM_LENGTH); pagelength = atoi(length_s); if(pagelength && pagelength >= 20 && pagelength < 100) v_f = SANE_FIX( ( SANE_UNFIX(v_f) * (double)pagelength) / 100); free(length_s); status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_f, ¶mSetRet); } else if ( strcmp(sod->name, SANE_NAME_SCAN_BR_X) == 0 ) { v_f = sod->constraint.range->max; status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_f, ¶mSetRet); } else if ( strcmp(sod->name, SANE_NAME_BRIGHTNESS) == 0 ) { v_f = 0; status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_f, ¶mSetRet); } else if ( strcmp(sod->name, SANE_NAME_CONTRAST) == 0 ) { v_f = 0; status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_f, ¶mSetRet); } else if ( strcmp(sod->name, SANE_NAME_SCAN_SPEED) == 0) { if ( !setDefaultScannerOption(openDeviceHandle, sod, option, ¶mSetRet) ) { int i, j; int foundMatch = 0; for (i = 0; speeds[i] != NULL; i++) { for (j = 0; sod->constraint.string_list[j]; j++) { if (strcmp (speeds[i], sod->constraint.string_list[j]) == 0) break; } if (sod->constraint.string_list[j] != NULL) { v_c = o_strdup(speeds[i]); status = control_option (openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, (void *)v_c, ¶mSetRet); free(v_c); foundMatch = 1; break; } } if( foundMatch == 0 ) { o_log(DEBUGM, "Non of the available options are appropriate."); } } } else if ( strcmp(sod->name, "custom-gamma") == 0 ) { v_b = SANE_FALSE; status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_b, ¶mSetRet); } // For the test 'virtual scanner' else if (testScanner == 1) { if ( strcmp(sod->name, "hand-scanner" ) == 0 ) { v_b = SANE_FALSE; status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_b, ¶mSetRet); } else if ( strcmp(sod->name, "three-pass") == 0 ){ v_b = SANE_FALSE; status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_b, ¶mSetRet); } else if ( strcmp(sod->name, "three-pass-order") == 0 ) { status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, "RGB", ¶mSetRet); } else if ( strcmp(sod->name, "test-raw_imageture") == 0 ) { status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, "Color pattern", ¶mSetRet); } else if ( strcmp(sod->name, "read-delay") == 0 ) { v_b = SANE_TRUE; status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_b, ¶mSetRet); } else if ( strcmp(sod->name, "fuzzy-parameters") == 0 ) { v_b = SANE_TRUE; status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_b, ¶mSetRet); } else if ( strcmp(sod->name, "read-delay-duration") == 0 ) { v_i = 1000; status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_i, ¶mSetRet); } else if ( strcmp(sod->name, "read-limit") == 0 ) { v_b = SANE_TRUE; status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_b, ¶mSetRet); } else if ( strcmp(sod->name, "read-limit-size") == 0 ) { v_i = sod->constraint.range->max; status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_i, ¶mSetRet); } else if ( strcmp(sod->name, "read-return-value") == 0 ) { status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, "Default", ¶mSetRet); } else if ( strcmp(sod->name, "ppl-loss") == 0 ) { v_i = 0; status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_i, ¶mSetRet); } else if ( strcmp(sod->name, "invert-endianess") == 0 ) { v_b = SANE_FALSE; status = control_option(openDeviceHandle, sod, option, SANE_ACTION_SET_VALUE, &v_b, ¶mSetRet); } } // not a 'well known' option else { // try setting automatically if ( !setDefaultScannerOption(openDeviceHandle, sod, option, ¶mSetRet) ) o_log(DEBUGM, "Could not set authmatically", sod->name); } if( status != SANE_STATUS_GOOD ) { handleSaneErrors("Cannot set no to", sod->name, status, paramSetRet); updateScanProgress(uuid, SCAN_ERRO_FROM_SCANNER, status); return 0; } if ( paramSetRet & SANE_INFO_RELOAD_OPTIONS ) { //start from the beginning again. option = 0; } } // setable option } else { o_log(DEBUGM, "The option does not need to be set."); } } // options loop return 1; }