static int edit(void) { int c, fd; struct disklabel label; FILE *fp; if ((fd = mkstemp(tmpfil)) == -1 || (fp = fdopen(fd, "w")) == NULL) { warnx("can't create %s", tmpfil); return (1); } display(fp, NULL); fclose(fp); for (;;) { if (!editit()) break; fp = fopen(tmpfil, "r"); if (fp == NULL) { warnx("can't reopen %s for reading", tmpfil); break; } bzero((char *)&label, sizeof(label)); c = getasciilabel(fp, &label); fclose(fp); if (c) { lab = label; if (writelabel() == 0) { (void) unlink(tmpfil); return (0); } } printf("re-edit the label? [y]: "); fflush(stdout); c = getchar(); if (c != EOF && c != (int)'\n') while (getchar() != (int)'\n') ; if (c == (int)'n') break; } (void) unlink(tmpfil); return (1); }
int edit(struct disklabel *lp, int f) { int first, ch, fd, error = 0; struct disklabel label; FILE *fp; u_int64_t total_sectors, starting_sector, ending_sector; if ((fd = mkstemp(tmpfil)) == -1 || (fp = fdopen(fd, "w")) == NULL) { if (fd != -1) close(fd); warn("%s", tmpfil); return (1); } display(fp, lp, 0, 1); fprintf(fp, "\n# Notes:\n"); fprintf(fp, "# Up to 16 partitions are valid, named from 'a' to 'p'. Partition 'a' is\n" "# your root filesystem, 'b' is your swap, and 'c' should cover your whole\n" "# disk. Any other partition is free for any use. 'size' and 'offset' are\n" "# in 512-byte blocks. fstype should be '4.2BSD', 'swap', or 'none' or some\n" "# other values. fsize/bsize/cpg should typically be '2048 16384 16' for a\n" "# 4.2BSD filesystem (or '512 4096 16' except on alpha, sun4, ...)\n"); fclose(fp); for (;;) { if (editit(tmpfil) == -1) break; fp = fopen(tmpfil, "r"); if (fp == NULL) { warn("%s", tmpfil); break; } /* Get values set by OS and not the label. */ if (ioctl(f, DIOCGPDINFO, &label) < 0) err(4, "ioctl DIOCGPDINFO"); ending_sector = DL_GETBEND(&label); starting_sector = DL_GETBSTART(&label); total_sectors = DL_GETDSIZE(&label); memset(&label, 0, sizeof(label)); error = getasciilabel(fp, &label); DL_SETBEND(&label, ending_sector); DL_SETBSTART(&label, starting_sector); DL_SETDSIZE(&label, total_sectors); if (error == 0) { if (cmplabel(lp, &label) == 0) { puts("No changes."); fclose(fp); (void) unlink(tmpfil); return (0); } *lp = label; if (writelabel(f, bootarea, lp) == 0) { fclose(fp); (void) unlink(tmpfil); return (0); } } fclose(fp); printf("re-edit the label? [y]: "); fflush(stdout); first = ch = getchar(); while (ch != '\n' && ch != EOF) ch = getchar(); if (first == 'n' || first == 'N') break; } (void)unlink(tmpfil); return (1); }
/* * Parse edit command. Returns 0 on success, -1 on error. */ int eparse(const char *cmd, const char *left, const char *right) { FILE *file; size_t nread; int fd; char *filename; char buf[BUFSIZ], *text; /* Skip whitespace. */ while (isspace(*cmd)) ++cmd; text = NULL; switch (*cmd) { case '\0': /* Edit empty file. */ break; case 'b': /* Both strings. */ if (left == NULL) goto RIGHT; if (right == NULL) goto LEFT; /* Neither column is blank, so print both. */ if (asprintf(&text, "%s\n%s\n", left, right) == -1) err(2, "could not allocate memory"); break; case 'l': LEFT: /* Skip if there is no left column. */ if (left == NULL) break; if (asprintf(&text, "%s\n", left) == -1) err(2, "could not allocate memory"); break; case 'r': RIGHT: /* Skip if there is no right column. */ if (right == NULL) break; if (asprintf(&text, "%s\n", right) == -1) err(2, "could not allocate memory"); break; default: return (-1); } /* Create temp file. */ if (asprintf(&filename, "%s/sdiff.XXXXXXXXXX", tmpdir) == -1) err(2, "asprintf"); if ((fd = mkstemp(filename)) == -1) err(2, "mkstemp"); if (text != NULL) { size_t len; ssize_t nwritten; len = strlen(text); if ((nwritten = write(fd, text, len)) == -1 || (size_t)nwritten != len) { warn("error writing to temp file"); cleanup(filename); } } close(fd); /* text is no longer used. */ free(text); /* Edit temp file. */ if (editit(filename) == -1) { warn("error editing %s", filename); cleanup(filename); } /* Open temporary file. */ if (!(file = fopen(filename, "r"))) { warn("could not open edited file: %s", filename); cleanup(filename); } /* Copy temporary file contents to output file. */ for (nread = sizeof(buf); nread == sizeof(buf);) { size_t nwritten; nread = fread(buf, sizeof(*buf), sizeof(buf), file); /* Test for error or end of file. */ if (nread != sizeof(buf) && (ferror(file) || !feof(file))) { warnx("error reading edited file: %s", filename); cleanup(filename); } /* * If we have nothing to read, break out of loop * instead of writing nothing. */ if (!nread) break; /* Write data we just read. */ nwritten = fwrite(buf, sizeof(*buf), nread, outfp); if (nwritten != nread) { warnx("error writing to output file"); cleanup(filename); } } /* We've reached the end of the temporary file, so remove it. */ if (unlink(filename)) warn("could not delete: %s", filename); fclose(file); free(filename); return (0); }
/* * Run an editor on the file at "fpp" of "size" bytes, * and return a new file pointer. * Signals must be handled by the caller. * "Type" is 'e' for _PATH_EX, 'v' for _PATH_VI. */ FILE * run_editor(FILE *fp, off_t size, int type, int readonly) { FILE *nf = NULL; int t; time_t modtime; char *edit, tempname[PATHSIZE]; struct stat statb; (void)snprintf(tempname, sizeof(tempname), "%s/mail.ReXXXXXXXXXX", tmpdir); if ((t = mkstemp(tempname)) == -1 || (nf = Fdopen(t, "w")) == NULL) { warn("%s", tempname); goto out; } if (readonly && fchmod(t, 0400) == -1) { warn("%s", tempname); (void)rm(tempname); goto out; } if (size >= 0) while (--size >= 0 && (t = getc(fp)) != EOF) (void)putc(t, nf); else while ((t = getc(fp)) != EOF) (void)putc(t, nf); (void)fflush(nf); if (fstat(fileno(nf), &statb) < 0) modtime = 0; else modtime = statb.st_mtime; if (ferror(nf)) { (void)Fclose(nf); warn("%s", tempname); (void)rm(tempname); nf = NULL; goto out; } if (Fclose(nf) < 0) { warn("%s", tempname); (void)rm(tempname); nf = NULL; goto out; } nf = NULL; if (type == 'e') { edit = value("EDITOR"); if (edit == NULL || edit[0] == '\0') edit = _PATH_EX; } else { edit = value("VISUAL"); if (edit == NULL || edit[0] == '\0') edit = _PATH_VI; } if (editit(edit, tempname) == -1) { (void)rm(tempname); goto out; } /* * If in read only mode or file unchanged, just remove the editor * temporary and return. */ if (readonly) { (void)rm(tempname); goto out; } if (stat(tempname, &statb) < 0) { warn("%s", tempname); goto out; } if (modtime == statb.st_mtime) { (void)rm(tempname); goto out; } /* * Now switch to new file. */ if ((nf = Fopen(tempname, "a+")) == NULL) { warn("%s", tempname); (void)rm(tempname); goto out; } (void)rm(tempname); out: return(nf); }
static void mode_edit(int fd, int page, int edit, int argc, char *argv[]) { int i; u_char data[255]; u_char *mode_pars; struct mode_header { u_char mdl; /* Mode data length */ u_char medium_type; u_char dev_spec_par; u_char bdl; /* Block descriptor length */ }; struct mode_page_header { u_char page_code; u_char page_length; }; struct mode_header *mh; struct mode_page_header *mph; char *fmt = mode_lookup(page); if (!fmt && verbose) { fprintf(stderr, "No mode data base entry in \"%s\" for page %d; binary %s only.\n", mode_db, page, (edit ? "edit" : "display")); } if (edit) { if (!fmt) { fprintf(stderr, "Sorry: can't edit without a format.\n"); exit(1); } if (pagectl != 0 && pagectl != 3) { fprintf(stderr, "It only makes sense to edit page 0 (current) or page 3 (saved values)\n"); exit(1); } verbose = 1; mode_sense(fd, data, sizeof(data), 1, page); mh = (struct mode_header *)data; mph = (struct mode_page_header *) (((char *)mh) + sizeof(*mh) + mh->bdl); mode_pars = (char *)mph + sizeof(*mph); edit_init(); scsireq_buff_decode_visit(mode_pars, mh->mdl, fmt, edit_check, 0); mode_sense(fd, data, sizeof(data), 0, page); edit_rewind(); scsireq_buff_decode_visit(mode_pars, mh->mdl, fmt, edit_defaults, 0); edit_rewind(); scsireq_buff_decode_visit(mode_pars, mh->mdl, fmt, edit_report, 0); fclose(edit_file); if (editit(edit_name) == -1 && errno != ECHILD) err(1, "edit %s", edit_name); if ((edit_file = fopen(edit_name, "r")) == NULL) err(1, "open %s", edit_name); edit_rewind(); scsireq_buff_encode_visit(mode_pars, mh->mdl, fmt, edit_get, 0); /* Eliminate block descriptors: */ bcopy((char *)mph, ((char *)mh) + sizeof(*mh), sizeof(*mph) + mph->page_length); mh->bdl = 0; mph = (struct mode_page_header *) (((char *)mh) + sizeof(*mh)); mode_pars = ((char *)mph) + 2; #if 0 /* Turn this on to see what you're sending to the * device: */ edit_rewind(); scsireq_buff_decode_visit(mode_pars, mh->mdl, fmt, arg_put, 0); #endif edit_done(); /* Make it permanent if pageselect is three. */ mph->page_code &= ~0xC0; /* Clear PS and RESERVED */ mh->mdl = 0; /* Reserved for mode select */ mode_select(fd, (char *)mh, sizeof(*mh) + mh->bdl + sizeof(*mph) + mph->page_length, (pagectl == 3)); exit(0); } mode_sense(fd, data, sizeof(data), pagectl, page); /* Skip over the block descriptors. */ mh = (struct mode_header *)data; mph = (struct mode_page_header *)(((char *)mh) + sizeof(*mh) + mh->bdl); mode_pars = (char *)mph + sizeof(*mph); if (!fmt) { for (i = 0; i < mh->mdl; i++) { printf("%02x%c",mode_pars[i], (((i + 1) % 8) == 0) ? '\n' : ' '); } putc('\n', stdout); } else { verbose = 1; scsireq_buff_decode_visit(mode_pars, mh->mdl, fmt, arg_put, 0); } }
int main(int argc, char **argv) { struct quotause *qup, *protoprivs, *curprivs; long id, protoid; long long lim; int i, quotatype, range, tmpfd; uid_t startuid, enduid; u_int32_t *limp; char *protoname, *cp, *oldoptarg, ch; int eflag = 0, tflag = 0, pflag = 0; char *fspath = NULL; char buf[MAXLOGNAME]; if (argc < 2) usage(); if (getuid()) errx(1, "permission denied"); quotatype = USRQUOTA; protoprivs = NULL; curprivs = NULL; protoname = NULL; while ((ch = getopt(argc, argv, "ugtf:p:e:")) != -1) { switch(ch) { case 'f': fspath = optarg; break; case 'p': protoname = optarg; pflag++; break; case 'g': quotatype = GRPQUOTA; break; case 'u': quotatype = USRQUOTA; break; case 't': tflag++; break; case 'e': if ((qup = malloc(sizeof(*qup))) == NULL) errx(2, "out of memory"); bzero(qup, sizeof(*qup)); i = 0; oldoptarg = optarg; for (cp = optarg; (cp = strsep(&optarg, ":")) != NULL; i++) { if (cp != oldoptarg) *(cp - 1) = ':'; limp = NULL; switch (i) { case 0: strlcpy(qup->fsname, cp, sizeof(qup->fsname)); break; case 1: limp = &qup->dqblk.dqb_bsoftlimit; break; case 2: limp = &qup->dqblk.dqb_bhardlimit; break; case 3: limp = &qup->dqblk.dqb_isoftlimit; break; case 4: limp = &qup->dqblk.dqb_ihardlimit; break; default: warnx("incorrect quota specification: " "%s", oldoptarg); usage(); break; /* XXX: report an error */ } if (limp != NULL) { lim = strtoll(cp, NULL, 10); if (lim < 0 || lim > UINT_MAX) errx(1, "invalid limit value: " "%lld", lim); *limp = (u_int32_t)lim; } } qup->dqblk.dqb_bsoftlimit = btodb((off_t)qup->dqblk.dqb_bsoftlimit * 1024); qup->dqblk.dqb_bhardlimit = btodb((off_t)qup->dqblk.dqb_bhardlimit * 1024); if (protoprivs == NULL) { protoprivs = curprivs = qup; } else { curprivs->next = qup; curprivs = qup; } eflag++; pflag++; break; default: usage(); } } argc -= optind; argv += optind; if (pflag) { if (protoprivs == NULL) { if ((protoid = getentry(protoname, quotatype)) == -1) exit(1); protoprivs = getprivs(protoid, quotatype, fspath); for (qup = protoprivs; qup; qup = qup->next) { qup->dqblk.dqb_btime = 0; qup->dqblk.dqb_itime = 0; } } for (; argc-- > 0; argv++) { if (strspn(*argv, "0123456789-") == strlen(*argv) && (cp = strchr(*argv, '-')) != NULL) { *cp++ = '\0'; startuid = atoi(*argv); enduid = atoi(cp); if (enduid < startuid) errx(1, "ending uid (%d) must be >= starting uid (%d) when using uid ranges", enduid, startuid); range = 1; } else { startuid = enduid = 0; range = 0; } for ( ; startuid <= enduid; startuid++) { if (range) snprintf(buf, sizeof(buf), "%d", startuid); else snprintf(buf, sizeof(buf), "%s", *argv); if ((id = getentry(buf, quotatype)) < 0) continue; if (eflag) { for (qup = protoprivs; qup; qup = qup->next) { curprivs = getprivs(id, quotatype, qup->fsname); if (curprivs == NULL) continue; strcpy(qup->qfname, curprivs->qfname); strcpy(qup->fsname, curprivs->fsname); } } putprivs(id, quotatype, protoprivs); } } exit(0); } tmpfd = mkstemp(tmpfil); fchown(tmpfd, getuid(), getgid()); if (tflag) { protoprivs = getprivs(0, quotatype, fspath); if (writetimes(protoprivs, tmpfd, quotatype) == 0) exit(1); if (editit(tmpfil) && readtimes(protoprivs, tmpfil)) putprivs(0, quotatype, protoprivs); freeprivs(protoprivs); close(tmpfd); unlink(tmpfil); exit(0); } for ( ; argc > 0; argc--, argv++) { if ((id = getentry(*argv, quotatype)) == -1) continue; curprivs = getprivs(id, quotatype, fspath); if (writeprivs(curprivs, tmpfd, *argv, quotatype) == 0) continue; if (editit(tmpfil) && readprivs(curprivs, tmpfil)) putprivs(id, quotatype, curprivs); freeprivs(curprivs); } close(tmpfd); unlink(tmpfil); exit(0); }
int main(int argc, char **argv) { uid_t uid; char *basename; int opt; int i; int tmpfd = -1; basename = argv[0]; if (argc < 2) { usage(); } if (quotactl(Q_SYNC, (char *)NULL, 0, (caddr_t)NULL) < 0 && errno == EINVAL) { (void) printf("Warning: " "Quotas are not compiled into this kernel\n"); (void) sleep(3); } if (getuid()) { (void) fprintf(stderr, "%s: permission denied\n", basename); exit(32); } setupfs(); if (fsqlist == NULL) { (void) fprintf(stderr, "%s: no UFS filesystems with %s file\n", MNTTAB, QFNAME); exit(32); } tmpfd = mkstemp(tmpfil); if (tmpfd == -1 || fchown(tmpfd, getuid(), getgid()) == -1) { fprintf(stderr, "failure in temporary file %s\n", tmpfil); exit(32); } (void) close(tmpfd); while ((opt = getopt(argc, argv, "p:tV")) != EOF) switch (opt) { case 't': gettimes(0); if (editit()) puttimes(0); (void) unlink(tmpfil); exit(0); /*NOTREACHED*/ case 'p': uid = getentry(optarg); if (uid > MAXUID) { (void) unlink(tmpfil); exit(32); } getprivs(uid); if (optind == argc) { (void) unlink(tmpfil); usage(); } for (i = optind; i < argc; i++) { uid = getentry(argv[i]); if (uid > MAXUID) { (void) unlink(tmpfil); exit(32); } getdiscq(uid); putprivs(uid); } (void) unlink(tmpfil); exit(0); /*NOTREACHED*/ case 'V': /* Print command line */ { char *optt; int optc; (void) printf("edquota -F UFS"); for (optc = 1; optc < argc; optc++) { optt = argv[optc]; if (optt) (void) printf(" %s ", optt); } (void) putchar('\n'); } break; case '?': usage(); } for (i = optind; i < argc; i++) { uid = getentry(argv[i]); if (uid > MAXUID) continue; getprivs(uid); if (editit()) putprivs(uid); if (uid == 0) { (void) printf("edquota: Note that uid 0's quotas " "are used as default values for other users,\n"); (void) printf("not as a limit on the uid 0 user.\n"); } } (void) unlink(tmpfil); return (0); }
int main(int argc, char *argv[]) { struct quotause *qup, *protoprivs, *curprivs; u_int id, protoid; int quotatype, tmpfd; char *protoname = NULL; int ch; int tflag = 0, pflag = 0; if (argc < 2) usage(); if (getuid()) errx(1, "%s", strerror(EPERM)); quotatype = USRQUOTA; while ((ch = getopt(argc, argv, "ugtp:")) != -1) { switch(ch) { case 'p': protoname = optarg; pflag++; break; case 'g': quotatype = GRPQUOTA; break; case 'u': quotatype = USRQUOTA; break; case 't': tflag++; break; default: usage(); } } argc -= optind; argv += optind; if (pflag) { if (getentry(protoname, quotatype, &protoid) == -1) exit(1); protoprivs = getprivs(protoid, quotatype); for (qup = protoprivs; qup; qup = qup->next) { qup->dqblk.dqb_btime = 0; qup->dqblk.dqb_itime = 0; } while (argc-- > 0) { if (getentry(*argv++, quotatype, &id) == -1) continue; putprivs(id, quotatype, protoprivs); } exit(0); } if ((tmpfd = mkstemp(tmpfil)) == -1) errx(1, "%s", tmpfil); if (tflag) { protoprivs = getprivs(0, quotatype); if (writetimes(protoprivs, tmpfd, quotatype) == 0) { unlink(tmpfil); exit(1); } if (editit(tmpfil) == -1) { unlink(tmpfil); err(1, "error starting editor"); } if (readtimes(protoprivs, tmpfd)) putprivs(0, quotatype, protoprivs); freeprivs(protoprivs); unlink(tmpfil); exit(0); } for ( ; argc > 0; argc--, argv++) { if (getentry(*argv, quotatype, &id) == -1) continue; curprivs = getprivs(id, quotatype); if (writeprivs(curprivs, tmpfd, *argv, quotatype) == 0) continue; if (editit(tmpfil) == -1) { warn("error starting editor"); continue; } if (readprivs(curprivs, tmpfd)) putprivs(id, quotatype, curprivs); freeprivs(curprivs); } close(tmpfd); unlink(tmpfil); exit(0); }
int main(int argc, char *argv[]) { struct quotause *qup, *protoprivs, *curprivs; long id, protoid; int i, quotatype, range, tmpfd; uid_t startuid, enduid; uint64_t lim; char *protoname, *cp, *endpt, *oldoptarg; int eflag = 0, tflag = 0, pflag = 0, ch; char *fspath = NULL; char buf[MAXLOGNAME]; if (argc < 2) usage(); if (getuid()) errx(1, "permission denied"); quotatype = USRQUOTA; protoprivs = NULL; curprivs = NULL; protoname = NULL; while ((ch = getopt(argc, argv, "ughtf:p:e:")) != -1) { switch(ch) { case 'f': fspath = optarg; break; case 'p': if (eflag) { warnx("cannot specify both -e and -p"); usage(); /* not reached */ } protoname = optarg; pflag++; break; case 'g': quotatype = GRPQUOTA; break; case 'h': hflag++; break; case 'u': quotatype = USRQUOTA; break; case 't': tflag++; break; case 'e': if (pflag) { warnx("cannot specify both -e and -p"); usage(); /* not reached */ } if ((qup = calloc(1, sizeof(*qup))) == NULL) errx(2, "out of memory"); oldoptarg = optarg; for (i = 0, cp = optarg; (cp = strsep(&optarg, ":")) != NULL; i++) { if (cp != oldoptarg) *(cp - 1) = ':'; if (i > 0 && !isdigit(*cp)) { warnx("incorrect quota specification: " "%s", oldoptarg); usage(); /* Not Reached */ } switch (i) { case 0: strlcpy(qup->fsname, cp, sizeof(qup->fsname)); break; case 1: lim = strtoll(cp, &endpt, 10); qup->dqblk.dqb_bsoftlimit = cvtblkval(lim, *endpt, "block soft limit"); continue; case 2: lim = strtoll(cp, &endpt, 10); qup->dqblk.dqb_bhardlimit = cvtblkval(lim, *endpt, "block hard limit"); continue; case 3: lim = strtoll(cp, &endpt, 10); qup->dqblk.dqb_isoftlimit = cvtinoval(lim, *endpt, "inode soft limit"); continue; case 4: lim = strtoll(cp, &endpt, 10); qup->dqblk.dqb_ihardlimit = cvtinoval(lim, *endpt, "inode hard limit"); continue; default: warnx("incorrect quota specification: " "%s", oldoptarg); usage(); /* Not Reached */ } } if (protoprivs == NULL) { protoprivs = curprivs = qup; } else { curprivs->next = qup; curprivs = qup; } eflag++; break; default: usage(); /* Not Reached */ } } argc -= optind; argv += optind; if (pflag || eflag) { if (pflag) { if ((protoid = getentry(protoname, quotatype)) == -1) exit(1); protoprivs = getprivs(protoid, quotatype, fspath); if (protoprivs == NULL) exit(0); for (qup = protoprivs; qup; qup = qup->next) { qup->dqblk.dqb_btime = 0; qup->dqblk.dqb_itime = 0; } } for (; argc-- > 0; argv++) { if (strspn(*argv, "0123456789-") == strlen(*argv) && (cp = strchr(*argv, '-')) != NULL) { *cp++ = '\0'; startuid = atoi(*argv); enduid = atoi(cp); if (enduid < startuid) errx(1, "ending uid (%d) must be >= starting uid (%d) when using uid ranges", enduid, startuid); range = 1; } else { startuid = enduid = 0; range = 0; } for ( ; startuid <= enduid; startuid++) { if (range) snprintf(buf, sizeof(buf), "%d", startuid); else snprintf(buf, sizeof(buf), "%s", *argv); if ((id = getentry(buf, quotatype)) < 0) continue; if (pflag) { putprivs(id, protoprivs); continue; } for (qup = protoprivs; qup; qup = qup->next) { curprivs = getprivs(id, quotatype, qup->fsname); if (curprivs == NULL) continue; curprivs->dqblk = qup->dqblk; putprivs(id, curprivs); freeprivs(curprivs); } } } if (pflag) freeprivs(protoprivs); exit(0); } tmpfd = mkstemp(tmpfil); fchown(tmpfd, getuid(), getgid()); if (tflag) { if ((protoprivs = getprivs(0, quotatype, fspath)) != NULL) { if (writetimes(protoprivs, tmpfd, quotatype) != 0 && editit(tmpfil) && readtimes(protoprivs, tmpfil)) putprivs(0L, protoprivs); freeprivs(protoprivs); } close(tmpfd); unlink(tmpfil); exit(0); } for ( ; argc > 0; argc--, argv++) { if ((id = getentry(*argv, quotatype)) == -1) continue; if ((curprivs = getprivs(id, quotatype, fspath)) == NULL) exit(1); if (writeprivs(curprivs, tmpfd, *argv, quotatype) == 0) continue; if (editit(tmpfil) && readprivs(curprivs, tmpfil)) putprivs(id, curprivs); freeprivs(curprivs); } close(tmpfd); unlink(tmpfil); exit(0); }