int cgetfirst(char **buf, char **db_array) { (void)cgetclose(); return (cgetnext(buf, db_array)); }
/* * Print the status of each queue listed or all the queues. */ void status(int argc, char **argv) { int c, status; char *cp1, *cp2; char prbuf[100]; if (argc == 1 || (argc == 2 && strcmp(argv[1], "all") == 0)) { printer = prbuf; while (cgetnext(&bp, printcapdb) > 0) { cp1 = prbuf; cp2 = bp; while ((c = *cp2++) && c != '|' && c != ':' && (cp1 - prbuf) < sizeof(prbuf) - 1) *cp1++ = c; *cp1 = '\0'; prstat(); } return; } while (--argc) { printer = *++argv; if ((status = cgetent(&bp, printcapdb, printer)) == -2) { printf("cannot open printer description file\n"); continue; } else if (status == -1) { printf("unknown printer %s\n", printer); continue; } else if (status == -3) fatal("potential reference loop detected in printcap file"); prstat(); } }
int nextprinter(struct printer *pp, int *error) { int status; char *bp; free_printer(pp); status = cgetnext(&bp, printcapdb); if (firstnextmap(&status) == 0) { if (error) *error = status; return 0; } if (error) *error = status; status = getprintcap_int(bp, pp); free(bp); if (error && status) *error = status; return 1; }
/* * Disable queuing and printing and put a message into the status file * (reason for being down). */ void down(int argc, char **argv) { int c, status; char *cp1, *cp2; char prbuf[100]; if (argc == 1) { printf("usage: down {all | printer} [message ...]\n"); return; } if (strcmp(argv[1], "all") == 0) { printer = prbuf; while (cgetnext(&bp, printcapdb) > 0) { cp1 = prbuf; cp2 = bp; while ((c = *cp2++) && c != '|' && c != ':' && (cp1 - prbuf) < sizeof(prbuf) - 1) *cp1++ = c; *cp1 = '\0'; putmsg(argc - 2, argv + 2); } return; } printer = argv[1]; if ((status = cgetent(&bp, printcapdb, printer)) == -2) { printf("cannot open printer description file\n"); return; } else if (status == -1) { printf("unknown printer %s\n", printer); return; } else if (status == -3) fatal("potential reference loop detected in printcap file"); putmsg(argc - 2, argv + 2); }
/* * Db_build() builds the name and capability databases according to the * details above. */ static void db_build(char **ifiles) { DBT key, data; recno_t reccnt; size_t len, bplen; int st; char *bp, *p, *t; data.data = NULL; key.data = NULL; for (reccnt = 0, bplen = 0; (st = cgetnext(&bp, ifiles)) > 0;) { /* * Allocate enough memory to store record, terminating * NULL and one extra byte. */ len = strlen(bp); if (bplen <= len + 2) { bplen += MAX(256, len + 2); if ((data.data = realloc(data.data, bplen)) == NULL) errx(1, "malloc failed"); } /* Find the end of the name field. */ if ((p = strchr(bp, ':')) == NULL) { warnx("no name field: %.*s", (int)MIN(len, 20), bp); continue; } /* First byte of stored record indicates status. */ switch(st) { case 1: ((char *)(data.data))[0] = RECOK; break; case 2: ((char *)(data.data))[0] = TCERR; warnx("record not tc expanded: %.*s", (int)(p - bp), bp); break; } /* Create the stored record. */ memmove(&((u_char *)(data.data))[1], bp, len + 1); data.size = len + 2; /* Store the record under the name field. */ key.data = bp; key.size = p - bp; switch(capdbp->put(capdbp, &key, &data, R_NOOVERWRITE)) { case -1: err(1, "put"); /* NOTREACHED */ case 1: warnx("ignored duplicate: %.*s", (int)key.size, (char *)key.data); continue; } ++reccnt; /* If only one name, ignore the rest. */ *p = '\0'; if (strchr(bp, '|') == NULL) continue; *p = ':'; /* The rest of the names reference the entire name. */ ((char *)(data.data))[0] = SHADOW; memmove(&((u_char *)(data.data))[1], key.data, key.size); data.size = key.size + 1; /* Store references for other names. */ for (p = t = bp;; ++p) { if (p > t && (*p == ':' || *p == '|')) { key.size = p - t; key.data = t; switch(capdbp->put(capdbp, &key, &data, R_NOOVERWRITE)) { case -1: err(1, "put"); /* NOTREACHED */ case 1: warnx("ignored duplicate: %.*s", (int)key.size, (char *)key.data); } t = p + 1; } if (*p == ':') break; } } switch(st) { case -1: err(1, "file argument"); /* NOTREACHED */ case -2: errx(1, "potential reference loop detected"); /* NOTREACHED */ } if (verbose) (void)printf("cap_mkdb: %d capability records\n", reccnt); }
static int typelist(int eargc, char *eargv[], bool verbosity, void (*hook) (const char *, TERMTYPE *tp)) /* apply a function to each entry in given terminfo directories */ { int i; for (i = 0; i < eargc; i++) { #if USE_DATABASE if (_nc_is_dir_path(eargv[i])) { char *cwd_buf = 0; DIR *termdir; DIRENT *subdir; if ((termdir = opendir(eargv[i])) == 0) { (void) fflush(stdout); (void) fprintf(stderr, "%s: can't open terminfo directory %s\n", _nc_progname, eargv[i]); return (EXIT_FAILURE); } else if (verbosity) (void) printf("#\n#%s:\n#\n", eargv[i]); while ((subdir = readdir(termdir)) != 0) { size_t len = NAMLEN(subdir); size_t cwd_len = len + strlen(eargv[i]) + 3; char name_1[PATH_MAX]; DIR *entrydir; DIRENT *entry; cwd_buf = typeRealloc(char, cwd_len, cwd_buf); if (cwd_buf == 0) failed("realloc cwd_buf"); assert(cwd_buf != 0); strncpy(name_1, subdir->d_name, len)[len] = '\0'; if (isDotname(name_1)) continue; (void) sprintf(cwd_buf, "%s/%.*s/", eargv[i], (int) len, name_1); if (chdir(cwd_buf) != 0) continue; entrydir = opendir("."); if (entrydir == 0) { perror(cwd_buf); continue; } while ((entry = readdir(entrydir)) != 0) { char name_2[PATH_MAX]; TERMTYPE lterm; char *cn; int status; len = NAMLEN(entry); strncpy(name_2, entry->d_name, len)[len] = '\0'; if (isDotname(name_2) || !_nc_is_file_path(name_2)) continue; status = _nc_read_file_entry(name_2, <erm); if (status <= 0) { (void) fflush(stdout); (void) fprintf(stderr, "%s: couldn't open terminfo file %s.\n", _nc_progname, name_2); return (EXIT_FAILURE); } /* only visit things once, by primary name */ cn = _nc_first_name(lterm.term_names); if (!strcmp(cn, name_2)) { /* apply the selected hook function */ (*hook) (cn, <erm); } _nc_free_termtype(<erm); } closedir(entrydir); } closedir(termdir); if (cwd_buf != 0) free(cwd_buf); } #if USE_HASHED_DB else { DB *capdbp; char filename[PATH_MAX]; if (make_db_name(filename, eargv[i], sizeof(filename))) { if ((capdbp = _nc_db_open(filename, FALSE)) != 0) { DBT key, data; int code; code = _nc_db_first(capdbp, &key, &data); while (code == 0) { TERMTYPE lterm; int used; char *have; char *cn; if (_nc_db_have_data(&key, &data, &have, &used)) { if (_nc_read_termtype(<erm, have, used) > 0) { /* only visit things once, by primary name */ cn = _nc_first_name(lterm.term_names); /* apply the selected hook function */ (*hook) (cn, <erm); _nc_free_termtype(<erm); } } code = _nc_db_next(capdbp, &key, &data); } _nc_db_close(capdbp); } } } #endif #endif #if USE_TERMCAP #if HAVE_BSD_CGETENT char *db_array[2]; char *buffer = 0; if (verbosity) (void) printf("#\n#%s:\n#\n", eargv[i]); db_array[0] = eargv[i]; db_array[1] = 0; if (cgetfirst(&buffer, db_array)) { show_termcap(buffer, hook); free(buffer); while (cgetnext(&buffer, db_array)) { show_termcap(buffer, hook); free(buffer); } } cgetclose(); #else /* scan termcap text-file only */ if (_nc_is_file_path(eargv[i])) { char buffer[2048]; FILE *fp; if ((fp = fopen(eargv[i], "r")) != 0) { while (fgets(buffer, sizeof(buffer), fp) != 0) { if (*buffer == '#') continue; if (isspace(*buffer)) continue; show_termcap(buffer, hook); } fclose(fp); } } #endif #endif }
/* * db_build() builds the name and capability databases according to the * details above. */ void db_build(char **ifiles) { DBT key, data; recno_t reccnt; size_t len, bplen; int st; char *bp, *p, *t; cgetusedb(0); /* disable reading of .db files in getcap(3) */ data.data = NULL; key.data = NULL; for (reccnt = 0, bplen = 0; (st = (info ? igetnext(&bp, ifiles) : cgetnext(&bp, ifiles))) > 0;) { /* * Allocate enough memory to store record, terminating * NULL and one extra byte. */ len = strlen(bp); if (bplen <= len + 2) { int newbplen = bplen + MAX(256, len + 2); void *newdata; if ((newdata = realloc(data.data, newbplen)) == NULL) err(1, NULL); data.data = newdata; bplen = newbplen; } /* Find the end of the name field. */ if ((p = strchr(bp, info ? ',' : ':')) == NULL) { warnx("no name field: %.*s", (int)MIN(len, 20), bp); continue; } /* First byte of stored record indicates status. */ switch(st) { case 1: ((char *)(data.data))[0] = RECOK; break; case 2: ((char *)(data.data))[0] = TCERR; warnx("Record not tc expanded: %.*s", (int)(p - bp), bp); break; } /* Create the stored record. */ if (info) { (void) memcpy(&((u_char *)(data.data))[1], bp, len + 1); data.size = len + 2; for (t = memchr((char *)data.data + 1, ',', data.size - 1); t; t = memchr(t, ',', data.size - (t - (char *)data.data))) *t++ = ':'; if (memchr((char *)data.data + 1, '\0', data.size - 2)) { warnx("NUL in entry: %.*s", (int)MIN(len, 20), bp); continue; } } else { char *capbeg, *capend; t = (char *)data.data + 1; /* Copy the cap name and trailing ':' */ len = p - bp + 1; memcpy(t, bp, len); t += len; /* Copy entry, collapsing empty fields. */ capbeg = p + 1; while (*capbeg) { /* Skip empty fields. */ if ((len = strspn(capbeg, ": \t\n\r"))) capbeg += len; /* Find the end of this cap and copy it w/ : */ capend = strchr(capbeg, ':'); if (capend) len = capend - capbeg + 1; else len = strlen(capbeg); memcpy(t, capbeg, len); t += len; capbeg += len; } *t = '\0'; data.size = t - (char *)data.data + 1; } /* Store the record under the name field. */ key.data = bp; key.size = p - bp; switch(capdbp->put(capdbp, &key, &data, R_NOOVERWRITE)) { case -1: err(1, "put"); /* NOTREACHED */ case 1: warnx("ignored duplicate: %.*s", (int)key.size, (char *)key.data); continue; } ++reccnt; /* If only one name, ignore the rest. */ if ((p = strchr(bp, '|')) == NULL) continue; /* The rest of the names reference the entire name. */ ((char *)(data.data))[0] = SHADOW; (void) memmove(&((u_char *)(data.data))[1], key.data, key.size); data.size = key.size + 1; /* Store references for other names. */ for (p = t = bp;; ++p) { if (p > t && (*p == (info ? ',' : ':') || *p == '|')) { key.size = p - t; key.data = t; switch(capdbp->put(capdbp, &key, &data, R_NOOVERWRITE)) { case -1: err(1, "put"); /* NOTREACHED */ case 1: warnx("ignored duplicate: %.*s", (int)key.size, (char *)key.data); } t = p + 1; } if (*p == (info ? ',' : ':')) break; } free(bp); } switch(st) { case -1: err(1, "file argument"); /* NOTREACHED */ case -2: errx(1, "potential reference loop detected"); /* NOTREACHED */ } if (verbose) (void)printf("cap_mkdb: %d capability records\n", reccnt); }
int main(int argc, char **argv) { int ch, aflag, lflag; char *buf, *cp; long l; effective_uid = geteuid(); real_uid = getuid(); effective_gid = getegid(); real_gid = getgid(); PRIV_END; /* be safe */ if (gethostname(host, sizeof(host)) != 0) err(1, "gethostname"); openlog("lpq", 0, LOG_LPR); aflag = lflag = 0; while ((ch = getopt(argc, argv, "alP:w:")) != -1) { switch(ch) { case 'a': ++aflag; break; case 'l': /* long output */ ++lflag; break; case 'P': /* printer name */ printer = optarg; break; case 'w': l = strtol(optarg, &cp, 10); if (*cp != '\0' || l < 0 || l >= INT_MAX) errx(1, "wait time must be postive integer: %s", optarg); wait_time = (u_int)l; if (wait_time < 30) warnx("warning: wait time less than 30 seconds"); break; case '?': default: usage(); } } if (!aflag && printer == NULL && (printer = getenv("PRINTER")) == NULL) printer = DEFLP; for (argc -= optind, argv += optind; argc; --argc, ++argv) if (isdigit((unsigned char)argv[0][0])) { if (requests >= MAXREQUESTS) fatal("too many requests"); requ[requests++] = atoi(*argv); } else { if (users >= MAXUSERS) fatal("too many users"); user[users++] = *argv; } if (aflag) { while (cgetnext(&buf, printcapdb) > 0) { if (ckqueue(buf) <= 0) { free(buf); continue; /* no jobs */ } for (cp = buf; *cp; cp++) if (*cp == '|' || *cp == ':') { *cp = '\0'; break; } printer = buf; printf("%s:\n", printer); displayq(lflag); free(buf); printf("\n"); } } else displayq(lflag); exit(0); }