int main(int argc, char **argv) { int line, tokens; char buffer[BUFSIZ], *inputline, *token[GV_MAXARGS]; /* Load the module if necessary. */ if (modfind(GVINUMMOD) < 0) { if (kldload(GVINUMKLD) < 0 && modfind(GVINUMMOD) < 0) err(1, GVINUMKLD ": Kernel module not available"); } /* Arguments given on the command line. */ if (argc > 1) { argc--; argv++; parseline(argc, argv); /* Interactive mode. */ } else { for (;;) { inputline = readline("gvinum -> "); if (inputline == NULL) { if (ferror(stdin)) { err(1, "can't read input"); } else { printf("\n"); exit(0); } } else if (*inputline) { add_history(inputline); strcpy(buffer, inputline); free(inputline); line++; /* count the lines */ tokens = gv_tokenize(buffer, token, GV_MAXARGS); if (tokens) parseline(tokens, token); } } } exit(0); }
void gvinum_create(int argc, char **argv) { struct gctl_req *req; struct gv_drive *d; struct gv_plex *p; struct gv_sd *s; struct gv_volume *v; FILE *tmp; int drives, errors, fd, flags, i, line, plexes, plex_in_volume; int sd_in_plex, status, subdisks, tokens, undeffd, volumes; const char *errstr; char buf[BUFSIZ], buf1[BUFSIZ], commandline[BUFSIZ], *ed, *sdname; char original[BUFSIZ], tmpfile[20], *token[GV_MAXARGS]; char plex[GV_MAXPLEXNAME], volume[GV_MAXVOLNAME]; tmp = NULL; flags = 0; for (i = 1; i < argc; i++) { /* Force flag used to ignore already created drives. */ if (!strcmp(argv[i], "-f")) { flags |= GV_FLAG_F; /* Else it must be a file. */ } else { if ((tmp = fopen(argv[1], "r")) == NULL) { warn("can't open '%s' for reading", argv[1]); return; } } } /* We didn't get a file. */ if (tmp == NULL) { snprintf(tmpfile, sizeof(tmpfile), "/tmp/gvinum.XXXXXX"); if ((fd = mkstemp(tmpfile)) == -1) { warn("temporary file not accessible"); return; } if ((tmp = fdopen(fd, "w")) == NULL) { warn("can't open '%s' for writing", tmpfile); return; } printconfig(tmp, "# "); fclose(tmp); ed = getenv("EDITOR"); if (ed == NULL) ed = _PATH_VI; snprintf(commandline, sizeof(commandline), "%s %s", ed, tmpfile); status = system(commandline); if (status != 0) { warn("couldn't exec %s; status: %d", ed, status); return; } if ((tmp = fopen(tmpfile, "r")) == NULL) { warn("can't open '%s' for reading", tmpfile); return; } } req = gctl_get_handle(); gctl_ro_param(req, "class", -1, "VINUM"); gctl_ro_param(req, "verb", -1, "create"); gctl_ro_param(req, "flags", sizeof(int), &flags); drives = volumes = plexes = subdisks = 0; plex_in_volume = sd_in_plex = undeffd = 0; plex[0] = '\0'; errors = 0; line = 1; while ((fgets(buf, BUFSIZ, tmp)) != NULL) { /* Skip empty lines and comments. */ if (*buf == '\0' || *buf == '#') { line++; continue; } /* Kill off the newline. */ buf[strlen(buf) - 1] = '\0'; /* * Copy the original input line in case we need it for error * output. */ strlcpy(original, buf, sizeof(original)); tokens = gv_tokenize(buf, token, GV_MAXARGS); if (tokens <= 0) { line++; continue; } /* Volume definition. */ if (!strcmp(token[0], "volume")) { v = gv_new_volume(tokens, token); if (v == NULL) { warnx("line %d: invalid volume definition", line); warnx("line %d: '%s'", line, original); errors++; line++; continue; } /* Reset plex count for this volume. */ plex_in_volume = 0; /* * Set default volume name for following plex * definitions. */ strlcpy(volume, v->name, sizeof(volume)); snprintf(buf1, sizeof(buf1), "volume%d", volumes); gctl_ro_param(req, buf1, sizeof(*v), v); volumes++; /* Plex definition. */ } else if (!strcmp(token[0], "plex")) { p = gv_new_plex(tokens, token); if (p == NULL) { warnx("line %d: invalid plex definition", line); warnx("line %d: '%s'", line, original); errors++; line++; continue; } /* Reset subdisk count for this plex. */ sd_in_plex = 0; /* Default name. */ if (strlen(p->name) == 0) { snprintf(p->name, sizeof(p->name), "%s.p%d", volume, plex_in_volume++); } /* Default volume. */ if (strlen(p->volume) == 0) { snprintf(p->volume, sizeof(p->volume), "%s", volume); } /* * Set default plex name for following subdisk * definitions. */ strlcpy(plex, p->name, sizeof(plex)); snprintf(buf1, sizeof(buf1), "plex%d", plexes); gctl_ro_param(req, buf1, sizeof(*p), p); plexes++; /* Subdisk definition. */ } else if (!strcmp(token[0], "sd")) { s = gv_new_sd(tokens, token); if (s == NULL) { warnx("line %d: invalid subdisk " "definition:", line); warnx("line %d: '%s'", line, original); errors++; line++; continue; } /* Default name. */ if (strlen(s->name) == 0) { if (strlen(plex) == 0) { sdname = find_name("gvinumsubdisk.p", GV_TYPE_SD, GV_MAXSDNAME); snprintf(s->name, sizeof(s->name), "%s.s%d", sdname, undeffd++); free(sdname); } else { snprintf(s->name, sizeof(s->name), "%s.s%d",plex, sd_in_plex++); } } /* Default plex. */ if (strlen(s->plex) == 0) snprintf(s->plex, sizeof(s->plex), "%s", plex); snprintf(buf1, sizeof(buf1), "sd%d", subdisks); gctl_ro_param(req, buf1, sizeof(*s), s); subdisks++; /* Subdisk definition. */ } else if (!strcmp(token[0], "drive")) { d = gv_new_drive(tokens, token); if (d == NULL) { warnx("line %d: invalid drive definition:", line); warnx("line %d: '%s'", line, original); errors++; line++; continue; } snprintf(buf1, sizeof(buf1), "drive%d", drives); gctl_ro_param(req, buf1, sizeof(*d), d); drives++; /* Everything else is bogus. */ } else { warnx("line %d: invalid definition:", line); warnx("line %d: '%s'", line, original); errors++; } line++; } fclose(tmp); unlink(tmpfile); if (!errors && (volumes || plexes || subdisks || drives)) { gctl_ro_param(req, "volumes", sizeof(int), &volumes); gctl_ro_param(req, "plexes", sizeof(int), &plexes); gctl_ro_param(req, "subdisks", sizeof(int), &subdisks); gctl_ro_param(req, "drives", sizeof(int), &drives); errstr = gctl_issue(req); if (errstr != NULL) warnx("create failed: %s", errstr); } gctl_free(req); }