void rds(char *arg) { int c; char *val, err[0xff]; struct pcimaxfm_rds_set rds_set; while (*arg != '\0') { if ((c = (getsubopt(&arg, rds_params_name, &val))) == -1) ERROR_MSG("Invalid RDS parameter \"%s\".", val); if (validate_rds(c, val, sizeof(err), err)) { ERROR_MSG("%s", err); } dev_open(); rds_set.param = c; rds_set.value = val; if(ioctl(fd, PCIMAXFM_RDS_SET, &rds_set) == -1) { ERROR_MSG("Writing RDS parameter %s = \"%s\" failed.", rds_params_name[rds_set.param], rds_set.value); } NOTICE_MSG("RDS: %-4s = \"%s\"", rds_params_name[rds_set.param], rds_set.value); } }
static void test_opts(char opts[], unsigned char flags[]) { int c; char *p, *o, *val, *pat[] = { [Remount] = "remount", [Bind] = "bind", NULL }; o = strdup(opts); if (!o) AuFin("stdup"); p = o; while (*p) { c = getsubopt(&p, pat, &val); switch (c) { case Remount: flags[Remount] = 1; break; case Bind: flags[Bind] = 1; break; } } free(o); }
/* * Given an export and the clients hostname(s) * determine the security flavors that this * client is permitted to use. * * This is somewhat more complicated than the "old" * routine because the options may contain multiple * security flavors (sec=) each with its own access * lists. So a client could be granted access based * on a number of security flavors. Note that the * type of access might not always be the same, the * client may get readonly access with one flavor * and readwrite with another, however the client * is not told this detail, it gets only the list * of flavors, and only if the client is using * version 3 of the mount protocol. */ static int getclientsflavors_new(struct share *sh, struct netbuf *nb, struct nd_hostservlist *clnames, int *flavors) { char *opts, *p, *val; char *lasts; char *f; int access_ok, count, c; opts = strdup(sh->sh_opts); if (opts == NULL) { syslog(LOG_ERR, "getclientsflavors: no memory"); return (0); } p = opts; count = c = 0; /* default access is rw */ access_ok = 1; while (*p) { switch (getsubopt(&p, optlist, &val)) { case OPT_SEC: /* * Before a new sec=xxx option, check if we need * to move the c index back to the previous count. */ if (!access_ok) { c = count; } /* get all the sec=f1[:f2] flavors */ while ((f = strtok_r(val, ":", &lasts)) != NULL) { flavors[c++] = map_flavor(f); val = NULL; } /* for a new sec=xxx option, default is rw access */ access_ok = 1; break; case OPT_RO: case OPT_RW: if (in_access_list(nb, clnames, val)) { count = c; access_ok = 1; } else { access_ok = 0; } break; } } if (!access_ok) { c = count; } free(opts); return (c); }
static void * ml_alloc(char *outopts, enum htmltype type) { struct html *h; const char *toks[4]; char *v; toks[0] = "style"; toks[1] = "man"; toks[2] = "includes"; toks[3] = NULL; h = mandoc_calloc(1, sizeof(struct html)); h->type = type; h->tags.head = NULL; h->symtab = mchars_alloc(); while (outopts && *outopts) switch (getsubopt(&outopts, UNCONST(toks), &v)) { case (0): h->style = v; break; case (1): h->base_man = v; break; case (2): h->base_includes = v; break; default: break; } return(h); }
void sous_options (char * ssopt, int * cnx_auto, int * delai) { int subopt; char * chaine = ssopt; char * value = NULL; int val_delai; char * tokens[] = { "auto", "nonauto", "delai", NULL }; while ((subopt = getsubopt(& chaine, tokens, & value)) != -1) { switch (subopt) { case 0 : /* auto */ * cnx_auto = 1; break; case 1 : /* nonauto */ * cnx_auto = 0; break; case 2 : /* delai=... */ if (value == NULL) { fprintf(stderr, "delai attendu\n"); break; } if (sscanf(value, "%d", & val_delai) != 1) { fprintf(stderr, "delai invalide\n"); break; } * delai = val_delai; break; } } }
void * ascii_alloc(char *outopts) { struct termp *p; const char *toks[2]; char *v; if (NULL == (p = term_alloc(TERMENC_ASCII))) return(NULL); p->type = TERMTYPE_CHAR; p->letter = ascii_letter; p->begin = ascii_begin; p->end = ascii_end; p->endline = ascii_endline; p->advance = ascii_advance; toks[0] = "width"; toks[1] = NULL; while (outopts && *outopts) switch (getsubopt(&outopts, UNCONST(toks), &v)) { case (0): p->defrmargin = (size_t)atoi(v); break; default: break; } /* Enforce a lower boundary. */ if (p->defrmargin < 58) p->defrmargin = 58; return(p); }
void dummy_parse_opts(char* opts) { char* value; while (*opts != '\0') { switch(getsubopt(&opts, options_list, &value)) { case MIN_RATE: if (value != NULL) backend_dummy.MINIMUM_RATE = atoi(value); break; case MAX_RATE: if (value != NULL) backend_dummy.MAXIMUM_RATE = atoi(value); break; case FILE_MODE: if (value != NULL) { filename = strdup(value); file_mode = 1; } break; } } }
static int strtoadv(char *advstr) { char *dummy, *locstr = advstr; return (getsubopt(&locstr, legal_madvice, &dummy)); }
/* * If the option string contains a "sec=" * option, then use new option syntax. */ static int newopts(char *opts) { char *head, *p, *val; if (!opts || *opts == '\0') return (0); head = strdup(opts); if (head == NULL) { syslog(LOG_ERR, "opts: no memory"); return (0); } p = head; while (*p) { if (getsubopt(&p, optlist, &val) == OPT_SEC) { free(head); return (1); } } free(head); return (0); }
/* * Return 1 if "ignore" appears in the options string */ int ignore(char *opts) { char *value; char *saveptr, *my_opts; int rval = 0; if (opts == NULL || *opts == NULL) return (0); /* * we make a copy of the option string to pass to getsubopt(), * because getsubopt() modifies the string. We also save * the original pointer returned by strdup, because getsubopt * changes the pointer passed into it. If strdup fails (unlikely), * we act as if the "ignore" option isn't set rather than fail. */ if ((saveptr = my_opts = strdup(opts)) == NULL) nomem(); while (*my_opts != '\0') { if (getsubopt(&my_opts, mntopts, &value) == IGNORE) rval = 1; } free(saveptr); return (rval); }
/* * This routine is used to parse the suboptions of '-o' option. * * The option should be of the form: * net=<addr>,cid=<cid>,type=<3des|aes|sha1|rsa> * * This routine will pass the values of each of the suboptions back in the * supplied arguments, 'net', 'cid' and 'ka'. * * Returns: * KEYGEN_SUCCESS or KEYGEN_ERROR. */ static int process_option(char *arg, char **net, char **cid, wbku_key_attr_t *ka) { char *value; wbku_retcode_t ret; while (*arg != '\0') { switch (getsubopt(&arg, opts, &value)) { case NET: /* * Network number. */ *net = value; break; case CID: /* * Client ID. */ *cid = value; break; case TYPE: /* * Key type. */ ret = wbku_str_to_keyattr(value, ka, WBKU_ANY_KEY); if (ret != WBKU_SUCCESS) { wbku_printerr("%s\n", wbku_retmsg(ret)); return (KEYGEN_ERROR); } break; default: wbku_printerr("%s is not a valid option\n", value); return (KEYGEN_ERROR); } } /* * Sanity checks */ if (*net != NULL && **net == '\0') { wbku_printerr("Missing net option value\n"); return (KEYGEN_ERROR); } if (*cid != NULL && **cid == '\0') { wbku_printerr("Missing cid option value\n"); return (KEYGEN_ERROR); } if (*cid != NULL && *net == NULL) { wbku_printerr( "The cid option requires net option specification\n"); return (KEYGEN_ERROR); } if (ka->ka_type == WBKU_KEY_UNKNOWN) { wbku_printerr("Missing key type option value\n"); return (KEYGEN_ERROR); } return (KEYGEN_SUCCESS); }
int devio_options(struct etfs_devio *dev, char *optstr) { struct chipio *cio; char *value; static char *opts[] ={ "use", // 0 "gpmc", // 1 "cs", // 2 "wp", // 3 "cfg", // 4 NULL } ; cio = dev->cio = &chipio; cio->gpmc_pbase = OMAP3530_GPMC_BASE; cio->cs = 0; // Chip select cio->wp = 0; // Wait pin cio->cfg = 0; //do we need to touch the OMAP_GPMC_CONFIG reg. while (*optstr) { switch (getsubopt(&optstr, opts, &value)) { case 0: fprintf(stderr, "Device specific options:\n"); fprintf(stderr, " -D use,gpmc=xxxx,cs=[chip select 0-7],wp=[wait pin0-3],cfg\n"); return (-1); case 1: cio->gpmc_pbase = strtol(value, NULL, 0); break; case 2: cio->cs = strtol(value, NULL, 0); if (cio->cs > 0 && cio->cs >= OMAP_MAX_CHIP_SELECT) { fprintf(stderr, "Chip select out of range 0-7\n"); return (EINVAL); } break; case 3: cio->wp = strtol(value, NULL, 10); if (cio->wp > 0 && cio->wp >= OMAP_MAX_WAIT_PINS) { fprintf(stderr, "Wait pin out of range 0-3\n"); return (EINVAL); } break; case 4: cio->cfg = 1; break; default: dev->log(_SLOG_ERROR, "Invalid -D suboption."); return (EINVAL); } } return (EOK); }
TEST(stdlib, getsubopt) { char* const tokens[] = { const_cast<char*>("a"), const_cast<char*>("b"), const_cast<char*>("foo"), nullptr }; std::string input = "a,b,foo=bar,a,unknown"; char* subopts = &input[0]; char* value = nullptr; ASSERT_EQ(0, getsubopt(&subopts, tokens, &value)); ASSERT_EQ(nullptr, value); ASSERT_EQ(1, getsubopt(&subopts, tokens, &value)); ASSERT_EQ(nullptr, value); ASSERT_EQ(2, getsubopt(&subopts, tokens, &value)); ASSERT_STREQ("bar", value); ASSERT_EQ(0, getsubopt(&subopts, tokens, &value)); ASSERT_EQ(nullptr, value); ASSERT_EQ(-1, getsubopt(&subopts, tokens, &value)); }
static bool parse_next_subopt(char **subs, char **value) { static char *const subopts[] = { NULL }; int opt = getsubopt(subs, subopts, value); if (*value == NULL) { fprintf(stderr, "No value given to suboption <%s>\n", subopts[opt]); return true; } return false; }
int main (int argc, char **argv) { char *subopts, *value; int opt; while ((opt = getopt (argc, argv, "at:o:")) != -1) switch (opt) { case 'a': do_all = 1; break; case 't': type = optarg; break; case 'o': subopts = optarg; while (*subopts != '\0') switch (getsubopt (&subopts, mount_opts, &value)) { case RO_OPTION: read_only = 1; break; case RW_OPTION: read_only = 0; break; case READ_SIZE_OPTION: if (value == NULL) abort (); read_size = atoi (value); break; case WRITE_SIZE_OPTION: if (value == NULL) abort (); write_size = atoi (value); break; default: /* Unknown suboption. */ printf ("Unknown suboption `%s'\n", value); break; } break; default: abort (); } /* Do the real work. */ return 0; }
static void parse_next_subopt(char **subs, char **value) { static char *const subopts[] = { NULL }; int opt = getsubopt(subs, subopts, value); if (value == NULL) { fprintf(stderr, "No value given to suboption <%s>\n", subopts[opt]); usage(); exit(1); } }
int parse_subopt(char **subs, const char * const *subopts, char **value) { int opt = getsubopt(subs, (char * const *)subopts, value); if (opt == -1) { fprintf(stderr, "Invalid suboptions specified\n"); return -1; } if (*value == NULL) { fprintf(stderr, "No value given to suboption <%s>\n", subopts[opt]); return -1; } return opt; }
static int hsmci_args (SIM_HBA *hba, char *options) { SIM_MMC_EXT *ext; hsmci_ext_t *hsmci; char *value; int opt; int val; int idx; ext = (SIM_MMC_EXT *)hba->ext; hsmci = (hsmci_ext_t *)ext->handle; for (idx = 0; idx < strlen(options); idx++) { if (':'==options[idx]) options[idx] = ','; } strlwr(options); if (*options == '\0') return (0); while (*options != '\0') { if ((opt = getsubopt(&options, opts, &value)) == -1) continue; switch (opt) { case 0: val = strtoull(value, 0, 0); if ((val > 1) || (val < 0)) { slogf (_SLOGC_SIM_MMC, _SLOG_ERROR, "MMC: wrong MCI port option %d", val); slogf (_SLOGC_SIM_MMC, _SLOG_ERROR, "MMC: G45 MCI port must be 0 or 1"); } else { hsmci->port = val; } break; default: slogf (_SLOGC_SIM_MMC, _SLOG_ERROR, "MMC: Unrecognized options %s\n", value); return (-1); } } return (0); }
int ModbusSerialInitDevice( device * const dev ) { char *value, *ptr; int res = 1; modbus_serial_device *pDevice; char *params; fprintf (stderr, "ModbusSerialInitDevice()\n"); pDevice = (modbus_serial_device *) malloc (sizeof (modbus_serial_device)); if (pDevice != NULL) { pDevice->station = -1; // pDevice->index = START_INDEX; params = (char *) dev->pInfo; fprintf (stderr, "ModbusSerialInitDevice<%s>\n", params); if (params[0] > 0) { // convert parametres string in comma separated ptr = params; while ((ptr = strchr (ptr, ' ')) != NULL) *ptr++ = ','; // recognize options ptr = params; alloc_mb_serial_opts(); while (*ptr != '\0') { switch (getsubopt (&ptr, modbus_serial_opts, &value)) { case STATION: if (value != NULL) { pDevice->station = atoi (value); if ( pDevice->station < 1 || pDevice->station > 247 ) pDevice->station = -1; } break; default: break; } } free_mb_serial_opts(); } // data present dev->plc_area = (unsigned char *) malloc (7167); } free (dev->pInfo); // free string params temporary stored in pInfo dev->pInfo = (void *) pDevice; // set pInfo to mininet_device pointer return res; }
/* * Return 1 if opt appears in optlist */ int hasopt(char *opt, char *optlist) { char *value; char *opts[2]; opts[0] = opt; opts[1] = NULL; if (optlist == NULL) return (0); while (*optlist != '\0') { if (getsubopt(&optlist, opts, &value) == 0) return (1); } return (0); }
/* * Parses options string. The values of the two options will be returned * by 'preempt' and 'accept', and the mask 'modify_mask' will be updated * accordingly. * * Returns 0 on success, errno on failures. * * Used by do_create() and do_modify(). * * Note that "opts" could be modified internally in this function. */ static int str2opt(char *opts, uint32_t *modify_mask, boolean_t *preempt, boolean_t *accept) { char *value; int opt; uint32_t mask = 0; enum { o_preempt = 0, o_un_preempt, o_accept, o_no_accept }; static char *myopts[] = { "preempt", "un_preempt", "accept", "no_accept", NULL }; while (*opts != '\0') { switch ((opt = getsubopt(&opts, myopts, &value))) { case o_preempt: case o_un_preempt: if (mask & VRRP_CONF_PREEMPT) return (EINVAL); mask |= VRRP_CONF_PREEMPT; *preempt = (opt == o_preempt); break; case o_accept: case o_no_accept: if (mask & VRRP_CONF_ACCEPT) return (EINVAL); mask |= VRRP_CONF_ACCEPT; *accept = (opt == o_accept); break; default: return (EINVAL); } } *modify_mask |= mask; return (0); }
static void parse_summary_list(char* subopts, reprompib_options_t* opts_p) { char * value; int index; if (subopts != NULL) { while (*subopts != '\0') { index = getsubopt(&subopts, summary_opts, &value); if (index >=0 && index < reprompib_get_number_summary_methods()) { opts_p->print_summary_methods |= reprompib_get_summary_method(index)->mask; } else { reprompib_print_error_and_exit("Invalid list of summary methods (--summary=<list of comma-separated methods> [min, max, mean, median])"); } } } if (opts_p->print_summary_methods == 0) { // no method specified - use all of them for (index=0; index < reprompib_get_number_summary_methods(); index++) { opts_p->print_summary_methods |= reprompib_get_summary_method(index)->mask; } } }
static void * ml_alloc(char *outopts, enum htmltype type) { struct html *h; const char *toks[4]; char *v; toks[0] = "style"; toks[1] = "man"; toks[2] = "includes"; toks[3] = NULL; h = calloc(1, sizeof(struct html)); if (NULL == h) { perror(NULL); exit((int)MANDOCLEVEL_SYSERR); } h->type = type; h->tags.head = NULL; h->symtab = chars_init(CHARS_HTML); while (outopts && *outopts) switch (getsubopt(&outopts, UNCONST(toks), &v)) { case (0): h->style = v; break; case (1): h->base_man = v; break; case (2): h->base_includes = v; break; default: break; } return(h); }
void * html_alloc(const struct mchars *mchars, char *outopts) { struct html *h; const char *toks[5]; char *v; toks[0] = "style"; toks[1] = "man"; toks[2] = "includes"; toks[3] = "fragment"; toks[4] = NULL; h = mandoc_calloc(1, sizeof(struct html)); h->tags.head = NULL; h->symtab = mchars; while (outopts && *outopts) switch (getsubopt(&outopts, UNCONST(toks), &v)) { case 0: h->style = v; break; case 1: h->base_man = v; break; case 2: h->base_includes = v; break; case 3: h->oflags |= HTML_FRAGMENT; break; default: break; } return(h); }
/* this function is redundant with server.c, needs merging */ int get_ip_subopt(char **server, char **client, char *arg) { int unknown = 0; char *value = NULL; while(*arg != '\0' && !unknown) { switch(getsubopt(&arg, token, &value)) { case SERVER: *server = value; break; case CLIENT: *client = value; break; default: unknown = 1; break; } } return (unknown); }
/* * Return 1 if "ignore" appears in the options string */ static int ignore(char *opts) { char *value; char *s; if (opts == NULL) return (0); s = strdup(opts); if (s == NULL) return (0); opts = s; while (*opts != '\0') { if (getsubopt(&opts, mntopts, &value) == IGNORE) { free(s); return (1); } } free(s); return (0); }
/* * Given an export and the clients hostname(s) * determine the security flavors that this * client is permitted to use. * * This routine is called only for "old" syntax, i.e. * only one security flavor is allowed. So we need * to determine two things: the particular flavor, * and whether the client is allowed to use this * flavor, i.e. is in the access list. * * Note that if there is no access list, then the * default is that access is granted. */ static int getclientsflavors_old(struct share *sh, struct netbuf *nb, struct nd_hostservlist *clnames, int *flavors) { char *opts, *p, *val; int ok = 0; int defaultaccess = 1; opts = strdup(sh->sh_opts); if (opts == NULL) { syslog(LOG_ERR, "getclientsflavors: no memory"); return (0); } flavors[0] = AUTH_SYS; p = opts; while (*p) { switch (getsubopt(&p, optlist, &val)) { case OPT_SECURE: flavors[0] = AUTH_DES; break; case OPT_RO: case OPT_RW: defaultaccess = 0; if (in_access_list(nb, clnames, val)) ok++; break; } } free(opts); return (defaultaccess || ok); }
static struct termp * ascii_init(enum termenc enc, char *outopts) { const char *toks[4]; char *v; struct termp *p; p = mandoc_calloc(1, sizeof(struct termp)); p->tabwidth = 5; p->defrmargin = 78; p->begin = ascii_begin; p->end = ascii_end; p->hspan = ascii_hspan; p->type = TERMTYPE_CHAR; p->enc = TERMENC_ASCII; p->advance = ascii_advance; p->endline = ascii_endline; p->letter = ascii_letter; p->width = ascii_width; #ifdef USE_WCHAR if (TERMENC_ASCII != enc) { v = TERMENC_LOCALE == enc ? setlocale(LC_ALL, "") : setlocale(LC_CTYPE, "en_US.UTF-8"); if (NULL != v && MB_CUR_MAX > 1) { p->enc = enc; p->advance = locale_advance; p->endline = locale_endline; p->letter = locale_letter; p->width = locale_width; } } #endif toks[0] = "indent"; toks[1] = "width"; toks[2] = "mdoc"; toks[3] = NULL; while (outopts && *outopts) switch (getsubopt(&outopts, UNCONST(toks), &v)) { case (0): p->defindent = (size_t)atoi(v); break; case (1): p->defrmargin = (size_t)atoi(v); break; case (2): /* * Temporary, undocumented mode * to imitate mdoc(7) output style. */ p->mdocstyle = 1; p->defindent = 5; break; default: break; } /* Enforce a lower boundary. */ if (p->defrmargin < 58) p->defrmargin = 58; return(p); }
static void advice_opts(char *optstr, const char *execname, char *cfgfile, int lineno) { char *value; int opt; int advice = 0; while (*optstr != '\0') { opt = getsubopt(&optstr, legal_optstr, &value); if (opt < 0) { madverr(errfp, dgettext(TEXT_DOMAIN, "%s: invalid advice option (%s)" " for %s - cfgfile: %s, line: %d\n"), madvident, value, execname, cfgfile, lineno); break; } else if (!value) { madverr(errfp, dgettext(TEXT_DOMAIN, "%s: option missing advice" " for %s - cfgfile: %s, line: %d\n"), madvident, execname, cfgfile, lineno); break; } advice = strtoadv(value); if (advice < 0) { madverr(errfp, dgettext(TEXT_DOMAIN, "%s: invalid advice specified (%s)" " for %s - cfgfile: %s, line: %d\n"), madvident, value, execname, cfgfile, lineno); break; } switch (opt) { case OPT_MADV: advice_all = advice; break; case OPT_HEAP: if (advice_heap < 0) { advice_heap = advice; } else { madverr(errfp, dgettext(TEXT_DOMAIN, "%s: duplicate advice specified " "(%s) for %s - cfgfile: %s, line: %d\n"), madvident, value, execname, cfgfile, lineno); } break; case OPT_SHM: if (advice_shm < 0) { advice_shm = advice; } else { madverr(errfp, dgettext(TEXT_DOMAIN, "%s: duplicate advice specified " "(%s) for %s - cfgfile: %s, line: %d\n"), madvident, value, execname, cfgfile, lineno); } break; case OPT_ISM: if (advice_ism < 0) { advice_ism = advice; } else { madverr(errfp, dgettext(TEXT_DOMAIN, "%s: duplicate advice specified " "(%s) for %s - cfgfile: %s, line: %d\n"), madvident, value, execname, cfgfile, lineno); } break; case OPT_DISM: if (advice_dism < 0) { advice_dism = advice; } else { madverr(errfp, dgettext(TEXT_DOMAIN, "%s: duplicate advice specified " "(%s) for %s - cfgfile: %s, line: %d\n"), madvident, value, execname, cfgfile, lineno); } break; case OPT_MAP: if (advice_map < 0) { advice_map = advice; } else { madverr(errfp, dgettext(TEXT_DOMAIN, "%s: duplicate advice specified " "(%s) for %s - cfgfile: %s, line: %d\n"), madvident, value, execname, cfgfile, lineno); } break; case OPT_MAPSHARED: if (advice_mapshared < 0) { advice_mapshared = advice; } else { madverr(errfp, dgettext(TEXT_DOMAIN, "%s: duplicate advice specified " "(%s) for %s - cfgfile: %s, line: %d\n"), madvident, value, execname, cfgfile, lineno); } break; case OPT_MAPPRIVATE: if (advice_mapprivate < 0) { advice_mapprivate = advice; } else { madverr(errfp, dgettext(TEXT_DOMAIN, "%s: duplicate advice specified " "(%s) for %s - cfgfile: %s, line: %d\n"), madvident, value, execname, cfgfile, lineno); } break; case OPT_MAPANON: if (advice_mapanon < 0) { advice_mapanon = advice; } else { madverr(errfp, dgettext(TEXT_DOMAIN, "%s: duplicate advice specified " "(%s) for %s - cfgfile: %s, line: %d\n"), madvident, value, execname, cfgfile, lineno); } break; default: madverr(errfp, dgettext(TEXT_DOMAIN, "%s: invalid advice option (%s)" " for %s - cfgfile: %s, line: %d\n"), madvident, value, execname, cfgfile, lineno); break; } } }
int main(int argc, char **argv) { char *value, *subs; int i; char *subopts[] = { #define SUB_VAL 0 "val", #define SUB_YUV_MODE 1 "mode", #define SUB_DIR 2 "dir", NULL }; int fd = -1; /* bitfield for OptSetCodec */ /* command args */ const char *device = "/dev/video0"; /* -d device */ int ch; int yuv_mode = 0; unsigned short gpio_out = 0x0; /* GPIO output data */ unsigned short gpio_dir = 0x0; /* GPIO direction bits */ int gpio_set_dir = 0; int passthrough = 0; long audio_mute = 0; long stereo_mode = 0; long bilingual_mode = 0; int debug_level = 0; __u32 reset = 0; int new_debug_level, gdebug_level; double timestamp; char *ptsstr; char short_options[26 * 2 * 2 + 1]; if (argc == 1) { usage(); return 0; } while (1) { int option_index = 0; int idx = 0; for (i = 0; long_options[i].name; i++) { if (!isalpha(long_options[i].val)) continue; short_options[idx++] = long_options[i].val; if (long_options[i].has_arg == required_argument) short_options[idx++] = ':'; } short_options[idx] = 0; ch = getopt_long(argc, argv, short_options, long_options, &option_index); if (ch == -1) break; options[(int)ch] = 1; switch (ch) { case OptSetYuvMode: { subs = optarg; while (*subs != '\0') { switch (getsubopt(&subs, subopts, &value)) { case SUB_YUV_MODE: if (value == NULL) { fprintf(stderr, "No value given to suboption <mode>\n"); usage(); return 1; } yuv_mode = strtol(value, 0L, 0); if (yuv_mode < 0 || yuv_mode > 3) { fprintf(stderr, "invalid yuv mode\n"); return 1; } break; } } } break; case OptHelp: usage(); return 0; case OptSetDebugLevel:{ debug_level = strtol(optarg, 0L, 0); break; } case OptSetDevice: device = optarg; if (device[0] >= '0' && device[0] <= '9' && strlen(device) <= 3) { static char newdev[20]; sprintf(newdev, "/dev/video%s", device); device = newdev; } break; case OptReset: reset = strtol(optarg, 0L, 0); break; case OptPassThrough: passthrough = strtol(optarg, 0L, 0); break; case OptSetAudioMute: audio_mute = strtol(optarg, 0L, 0); break; case OptSetStereoMode: stereo_mode = strtol(optarg, 0L, 0); break; case OptSetBilingualMode: bilingual_mode = strtol(optarg, 0L, 0); break; case OptSetGPIO: subs = optarg; while (*subs != '\0') { switch (getsubopt(&subs, subopts, &value)) { case SUB_DIR: if (value == NULL) { fprintf(stderr, "No value given to suboption <dir>\n"); usage(); exit(1); } gpio_dir = strtol(value, 0L, 0); gpio_set_dir = 1; break; case SUB_VAL: if (value == NULL) { fprintf(stderr, "No value given to suboption <val>\n"); usage(); exit(1); } gpio_out = (unsigned short)strtol(value, 0L, 0); break; default: fprintf(stderr, "Invalid suboptions specified\n"); usage(); exit(1); break; } } break; case ':': fprintf(stderr, "Option `%s' requires a value\n", argv[optind]); usage(); return 1; case '?': fprintf(stderr, "Unknown argument `%s'\n", argv[optind]); usage(); return 1; } } if (optind < argc) { printf("unknown arguments: "); while (optind < argc) printf("%s ", argv[optind++]); printf("\n"); usage(); return 1; } fd = open(device, O_RDWR); if (fd < 0) { fprintf(stderr, "Failed to open %s: %s\n", device, strerror(errno)); exit(1); } /* Setting Opts */ if (options[OptFrameSync]) { printf("ioctl: VIDEO_GET_EVENT\n"); for (;;) { struct video_event ev; int fps = 30; v4l2_std_id std; if (ioctl(fd, VIDIOC_G_STD, &std) == 0) fps = (std & V4L2_STD_525_60) ? 30 : 25; if (ioctl(fd, VIDEO_GET_EVENT, &ev) < 0) { fprintf(stderr, "ioctl: VIDEO_GET_EVENT failed\n"); break; #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) } else if (ev.timestamp.tv_sec == 0 && ev.timestamp.tv_nsec == 0) { #else } else if (ev.timestamp == 0) { #endif unsigned long long pts = 0, frame = 0; struct timeval tv; gettimeofday(&tv, NULL); timestamp = (double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0); ioctl(fd, VIDEO_GET_PTS, &pts); ioctl(fd, VIDEO_GET_FRAME_COUNT, &frame); ptsstr = pts_to_string(pts, fps); printf("%10.6f: pts %-20s, %lld frames\n", timestamp, ptsstr, frame); } } } if (options[OptSetGPIO]) { struct v4l2_dbg_register reg; reg.match.type = V4L2_CHIP_MATCH_HOST; reg.match.addr = 0; reg.reg = IVTV_REG_GPIO_DIR_OFFSET; reg.val = gpio_dir; if (gpio_set_dir && doioctl(fd, VIDIOC_DBG_S_REGISTER, ®, "VIDIOC_DBG_S_REGISTER") == 0) printf("GPIO dir set to 0x%04llx\n", reg.val); reg.reg = IVTV_REG_GPIO_OUT_OFFSET; reg.val = gpio_out; if (doioctl(fd, VIDIOC_DBG_S_REGISTER, ®, "VIDIOC_DBG_S_REGISTER") == 0) printf("GPIO out set to 0x%04llx\n", reg.val); } if (options[OptListGPIO]) { struct v4l2_dbg_register reg; reg.match.type = V4L2_CHIP_MATCH_HOST; reg.match.addr = 0; reg.reg = IVTV_REG_GPIO_IN_OFFSET; if (ioctl(fd, VIDIOC_DBG_G_REGISTER, ®) == 0) printf("GPIO in: 0x%04llx\n", reg.val); reg.reg = IVTV_REG_GPIO_DIR_OFFSET; if (ioctl(fd, VIDIOC_DBG_G_REGISTER, ®) == 0) printf("GPIO dir: 0x%04llx\n", reg.val); reg.reg = IVTV_REG_GPIO_OUT_OFFSET; if (ioctl(fd, VIDIOC_DBG_G_REGISTER, ®) == 0) printf("GPIO out: 0x%04llx\n", reg.val); } if (options[OptSetDebugLevel]) { char buf[20]; new_debug_level = debug_level; sprintf(buf, "%d", debug_level); if (dowrite(buf, "/sys/module/ivtv/parameters/debug") == 0) { printf(" set debug level: "); print_debug_mask(new_debug_level); printf("\n"); } } if (options[OptGetDebugLevel]) { char *buf = doread("/sys/module/ivtv/parameters/debug"); gdebug_level = 0; if (buf) { gdebug_level = atol(buf); printf(" debug level: "); print_debug_mask(gdebug_level); printf("\n"); } } if (options[OptPassThrough]) { long source = passthrough ? VIDEO_SOURCE_DEMUX : VIDEO_SOURCE_MEMORY; doioctl(fd, VIDEO_SELECT_SOURCE, (void *)source, "IVTV_IOC_PASSTHROUGH"); } if (options[OptSetAudioMute]) { doioctl(fd, AUDIO_SET_MUTE, (void *)audio_mute, "AUDIO_SET_MUTE"); } if (options[OptSetStereoMode]) { doioctl(fd, AUDIO_CHANNEL_SELECT, (void *)stereo_mode, "AUDIO_CHANNEL_SELECT"); } if (options[OptSetBilingualMode]) { doioctl(fd, AUDIO_BILINGUAL_CHANNEL_SELECT, (void *)bilingual_mode, "AUDIO_BILINGUAL_CHANNEL_SELECT"); } if (options[OptReset]) doioctl(fd, VIDIOC_INT_RESET, &reset, "VIDIOC_INT_RESET"); if (options[OptSetYuvMode]) { struct ivtv_dma_frame frame; struct v4l2_format fmt; const enum v4l2_field map[4] = { V4L2_FIELD_INTERLACED_TB, V4L2_FIELD_INTERLACED_BT, V4L2_FIELD_NONE, V4L2_FIELD_ANY, }; printf("set yuv mode\n"); memset(&frame, 0, sizeof(frame)); frame.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; if (ioctl(fd, IVTV_IOC_DMA_FRAME, &frame) < 0) { fprintf(stderr, "Unable to switch to user DMA YUV mode\n"); exit(1); } fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; ioctl(fd, VIDIOC_G_FMT, &fmt); fmt.fmt.pix.field = map[yuv_mode]; doioctl(fd, VIDIOC_S_FMT, &fmt, "VIDIOC_S_FMT"); } if (options[OptGetYuvMode]) { struct ivtv_dma_frame frame; struct v4l2_format fmt; memset(&frame, 0, sizeof(frame)); frame.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; if (ioctl(fd, IVTV_IOC_DMA_FRAME, &frame) < 0) { fprintf(stderr, "Unable to switch to user DMA YUV mode\n"); exit(1); } fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; doioctl(fd, VIDIOC_G_FMT, &fmt, "VIDIOC_G_FMT"); printf("Current yuv_mode %d %s\n", fmt.fmt.pix.field, field2s(fmt.fmt.pix.field)); } close(fd); exit(app_result); }