static void enablepr(void) { struct stat stbuf; if (cgetstr(bp, "sd", &SD) == -1) SD = _PATH_DEFSPOOL; if (cgetstr(bp, "lo", &LO) == -1) LO = DEFLOCK; (void)snprintf(line, sizeof(line), "%s/%s", SD, LO); printf("%s:\n", printer); /* * Turn off the group execute bit of the lock file to enable queuing. */ PRIV_START; if (stat(line, &stbuf) >= 0) { stbuf.st_mode &= ~S_IXGRP; if (chmod(line, stbuf.st_mode & 0777) < 0) printf("\tcannot enable queuing\n"); else printf("\tqueuing enabled\n"); } PRIV_END; }
static void disablepr(void) { int fd; struct stat stbuf; if (cgetstr(bp, "sd", &SD) == -1) SD = _PATH_DEFSPOOL; if (cgetstr(bp, "lo", &LO) == -1) LO = DEFLOCK; (void)snprintf(line, sizeof(line), "%s/%s", SD, LO); printf("%s:\n", printer); /* * Turn on the group execute bit of the lock file to disable queuing. */ PRIV_START; if (stat(line, &stbuf) >= 0) { stbuf.st_mode |= S_IXGRP; if (chmod(line, stbuf.st_mode & 0777) < 0) printf("\tcannot disable queuing\n"); else printf("\tqueuing disabled\n"); } else if (errno == ENOENT) { if ((fd = safe_open(line, O_WRONLY|O_CREAT|O_NOFOLLOW, 0670)) < 0) printf("\tcannot create lock file\n"); else { (void)fchown(fd, DEFUID, -1); (void)close(fd); printf("\tqueuing disabled\n"); } } else printf("\tcannot stat lock file\n"); PRIV_END; }
int plot_arc(void *v, int x, int y, int x0, int y0, int x1, int y1) { struct plotctx *pl = v; char *p; if (!(pl->caps & _PLOT_RC)) { pl->caps |= _PLOT_RC; if (cgetstr(pl->buf, "rc", &p) > 0) pl->rc = p; } if (pl->rc) { plot_move(pl, x, y); return (_plot_out(pl, pl->rc, x0 * pl->xnum / pl->xdenom, y0 * pl->ynum / pl->ydenom, x1 * pl->xnum / pl->xdenom, y1 * pl->ynum / pl->ydenom)); #if 0 } else if (pl->flags & ARCVSLN || ((pl->caps & _PLOT_CO || cgetstr(pl->buf, "co", &p) > 0) || (pl->caps & _PLOT_LN || cgetstr(pl->buf, "ln", &p) > 0))) { /* TODO emulate through the line */ flags |= ARCVSLN; #endif } else { /* TODO emulate through the point */ errno = EOPNOTSUPP; return (-1); } return (0); }
static void startpr(int enable) { struct stat stbuf; if (cgetstr(bp, "sd", &SD) == -1) SD = _PATH_DEFSPOOL; if (cgetstr(bp, "lo", &LO) == -1) LO = DEFLOCK; (void)snprintf(line, sizeof(line), "%s/%s", SD, LO); printf("%s:\n", printer); /* * Turn off the owner execute bit of the lock file to enable printing. * If we are marking the printer "up" also turn off group execute bit. */ PRIV_START; if (enable && stat(line, &stbuf) >= 0) { if (enable == 2) stbuf.st_mode &= ~(S_IXUSR|S_IXGRP); else stbuf.st_mode &= ~S_IXUSR; if (chmod(line, stbuf.st_mode & 0777) < 0) printf("\tcannot enable printing\n"); else printf("\tprinting enabled\n"); } PRIV_END; if (!startdaemon(printer)) printf("\tcouldn't start daemon\n"); else printf("\tdaemon started\n"); }
void recvjob(void) { struct stat stb; int status; /* * Perform lookup for printer name or abbreviation */ if ((status = cgetent(&bp, printcapdb, printer)) == -2) frecverr("cannot open printer description file"); else if (status == -1) frecverr("unknown printer %s", printer); else if (status == -3) fatal("potential reference loop detected in printcap file"); if (cgetstr(bp, "lf", &LF) == -1) LF = _PATH_CONSOLE; if (cgetstr(bp, "sd", &SD) == -1) SD = _PATH_DEFSPOOL; if (cgetstr(bp, "lo", &LO) == -1) LO = DEFLOCK; (void)close(2); /* set up log file */ PRIV_START; if (open(LF, O_WRONLY|O_APPEND, 0664) < 0) { syslog(LOG_ERR, "%s: %m", LF); (void)open(_PATH_DEVNULL, O_WRONLY); } PRIV_END; if (chdir(SD) < 0) frecverr("%s: %s: %m", printer, SD); if (stat(LO, &stb) == 0) { if (stb.st_mode & 010) { /* queue is disabled */ putchar('\1'); /* return error code */ exit(1); } } else if (stat(SD, &stb) < 0) frecverr("%s: %s: %m", printer, SD); minfree = 2 * read_number("minfree"); /* scale KB to 512 blocks */ signal(SIGTERM, rcleanup); signal(SIGPIPE, rcleanup); if (readjob()) printjob(); }
/* * Perform lookup for printer name or abbreviation -- */ static int chkprinter(const char *s) { int stat; int len; if ((stat = cgetent(&bp, printcapdb, s)) == -2) { printf("pac: can't open printer description file\n"); exit(3); } else if (stat == -1) return(0); else if (stat == -3) fatal("potential reference loop detected in printcap file"); if (cgetstr(bp, "af", &acctfile) == -1) { printf("accounting not enabled for printer %s\n", printer); exit(2); } if (!pflag && (cgetnum(bp, "pc", &price100) == 0)) price = price100/10000.0; len = strlen(acctfile) + 5; sumfile = (char *) malloc(len); if (sumfile == NULL) err(1, "pac"); strlcpy(sumfile, acctfile, len); strlcat(sumfile, "_sum", len); return(1); }
static int getmodemparms (const char *modem) { char *bp, *db_array [3], *modempath; int ndx, stat; modem_parm_t *mpp; modempath = getenv ("MODEMS"); ndx = 0; if (modempath != NULL) db_array [ndx++] = modempath; db_array [ndx++] = _PATH_MODEMS; db_array [ndx] = NULL; if ((stat = cgetent (&bp, db_array, (char *)modem)) < 0) { switch (stat) { case -1: warnx ("unknown modem %s", modem); break; case -2: warnx ("can't open modem description file"); break; case -3: warnx ("possible reference loop in modem description file"); break; } return 0; } for (mpp = modem_parms; mpp->name; mpp++) { switch (mpp->modem_parm_type) { case mpt_string: if (cgetstr (bp, (char *)mpp->name, mpp->value.string) == -1) *mpp->value.string = mpp->default_value.string; break; case mpt_number: { long l; if (cgetnum (bp, (char *)mpp->name, &l) == -1) *mpp->value.number = mpp->default_value.number; else *mpp->value.number = (unsigned int)l; } break; case mpt_boolean: *mpp->value.number = cgetflag ((char *)mpp->name); break; default: break; } } strncpy (modem_name, modem, sizeof (modem_name) - 1); modem_name [sizeof (modem_name) - 1] = '\0'; return 1; }
/*ARGSUSED*/ char * getstr(char *id, char **cpp) { # ifdef HAS_CGETENT char *answer; return((cgetstr(area, id, &answer) > 0) ? answer : 0); # else return(0); # endif }
/* * It provides similar functionality to cgetstr(), * except that it provides for both a long and a short * capability name and allows for a default to be specified. */ static int capdb_getaltstr(char *bp, const char *shrt, const char *lng, const char *dflt, char **result) { int status; status = cgetstr(bp, (char *)/*XXX*/lng, result); if (status >= 0 || status == PCAPERR_OSERR) return status; status = cgetstr(bp, (char *)/*XXX*/shrt, result); if (status >= 0 || status == PCAPERR_OSERR) return status; if (dflt) { *result = strdup(dflt); if (*result == NULL) return PCAPERR_OSERR; return strlen(*result); } return PCAPERR_NOTFOUND; }
/* * Perform lookup for printer name or abbreviation -- */ static void chkprinter(char *s) { int status; if ((status = cgetent(&bp, printcapdb, s)) == -2) errx(1, "cannot open printer description file"); else if (status == -1) errx(1, "%s: unknown printer", s); if (cgetstr(bp, "sd", &SD) == -1) SD = _PATH_DEFSPOOL; if (cgetstr(bp, "lo", &LO) == -1) LO = DEFLOCK; cgetstr(bp, "rg", &RG); if (cgetnum(bp, "mx", &MX) < 0) MX = DEFMX; if (cgetnum(bp, "mc", &MC) < 0) MC = DEFMAXCOPIES; if (cgetnum(bp, "du", &DU) < 0) DU = DEFUID; SC = (cgetcap(bp, "sc", ':') != NULL); SH = (cgetcap(bp, "sh", ':') != NULL); }
/* * Perform lookup for printer name or abbreviation -- */ static void chkprinter(const char *s) { char *cp; getprintcap(s); RG = cgetstr(bp, "rg", &cp) == -1 ? NULL : cp; if (cgetnum(bp, "mx", &MX) < 0) MX = DEFMX; if (cgetnum(bp,"mc", &MC) < 0) MC = DEFMAXCOPIES; if (cgetnum(bp, "du", &DU) < 0) DU = DEFUID; SC = (cgetcap(bp, "sc", ':') != NULL); }
/* * Get a table entry. */ void gettable(char *name, char *buf) { struct gettystrs *sp; struct gettynums *np; struct gettyflags *fp; long n; char *dba[2]; dba[0] = _PATH_GETTYTAB; dba[1] = 0; if (cgetent(&buf, dba, name) != 0) return; for (sp = gettystrs; sp->field; sp++) cgetstr(buf, sp->field, &sp->value); for (np = gettynums; np->field; np++) { if (cgetnum(buf, np->field, &n) == -1) np->set = 0; else { np->set = 1; np->value = n; } } for (fp = gettyflags; fp->field; fp++) { if (cgetcap(buf, fp->field, ':') == NULL) fp->set = 0; else { fp->set = 1; fp->value = 1 ^ fp->invrt; } } #ifdef DEBUG printf("name=\"%s\", buf=\"%s\"\n", name, buf); for (sp = gettystrs; sp->field; sp++) printf("cgetstr: %s=%s\n", sp->field, sp->value); for (np = gettynums; np->field; np++) printf("cgetnum: %s=%d\n", np->field, np->value); for (fp = gettyflags; fp->field; fp++) printf("cgetflags: %s='%c' set='%c'\n", fp->field, fp->value + '0', fp->set + '0'); exit(1); #endif /* DEBUG */ }
/* * Write a message into the status file (assumes PRIV_START already called) */ static void upstat(char *msg) { int fd; char statfile[MAXPATHLEN]; if (cgetstr(bp, "st", &ST) == -1) ST = DEFSTAT; (void)snprintf(statfile, sizeof(statfile), "%s/%s", SD, ST); fd = safe_open(statfile, O_WRONLY|O_CREAT|O_NOFOLLOW, 0660); if (fd < 0 || flock(fd, LOCK_EX) < 0) { printf("\tcannot create status file\n"); return; } (void)fchown(fd, DEFUID, -1); (void)ftruncate(fd, 0); if (msg == (char *)NULL) (void)write(fd, "\n", 1); else (void)write(fd, msg, strlen(msg)); (void)close(fd); }
void try_remote(const char *host, const char *path, const char *entry) { const char *paths[] = { "/etc/remote", NULL, NULL }; char *cp, *s; long l; int error; if (path != NULL) { paths[0] = path; paths[1] = "/etc/remote"; } if (entry != NULL && cgetset(entry) != 0) cu_errx(1, "cgetset failed"); error = cgetent(&cp, (char**)paths, (char*)host); if (error < 0) { switch (error) { case -1: cu_errx(1, "unknown host %s", host); case -2: cu_errx(1, "can't open remote file"); case -3: cu_errx(1, "loop in remote file"); default: cu_errx(1, "unknown error in remote file"); } } if (line_path == NULL && cgetstr(cp, "dv", &s) >= 0) line_path = s; if (line_speed == -1 && cgetnum(cp, "br", &l) >= 0) { if (l < 0 || l > INT_MAX) cu_errx(1, "speed out of range"); line_speed = l; } }
/* XXX - could be common w/ lpd */ static int ckqueue(char *cap) { struct dirent *d; DIR *dirp; char *spooldir; if (cgetstr(cap, "sd", &spooldir) >= 0) { dirp = opendir(spooldir); free(spooldir); } else dirp = opendir(_PATH_DEFSPOOL); if (dirp == NULL) return (-1); while ((d = readdir(dirp)) != NULL) { if (d->d_name[0] != 'c' || d->d_name[1] != 'f') continue; /* daemon control files only */ closedir(dirp); return (1); /* found something */ } closedir(dirp); return (0); }
struct disklabel * getdiskbyname(const char *name) { static struct disklabel disk; struct disklabel *dp = &disk; struct partition *pp; char *buf; char *db_array[2] = { _PATH_DISKTAB, 0 }; char *cp, *cq; /* can't be register */ char p, max, psize[3], pbsize[3], pfsize[3], poffset[3], ptype[3]; u_int32_t *dx; if (cgetent(&buf, db_array, (char *) name) < 0) return NULL; bzero((char *)&disk, sizeof(disk)); /* * typename */ cq = dp->d_typename; cp = buf; while (cq < dp->d_typename + sizeof(dp->d_typename) - 1 && (*cq = *cp) && *cq != '|' && *cq != ':') cq++, cp++; *cq = '\0'; if (cgetstr(buf, "ty", &cq) > 0 && strcmp(cq, "removable") == 0) dp->d_flags |= D_REMOVABLE; else if (cq && strcmp(cq, "simulated") == 0) dp->d_flags |= D_RAMDISK; if (cgetcap(buf, "sf", ':') != NULL) dp->d_flags |= D_BADSECT; #define getnumdflt(field, dname, dflt) \ { long f; (field) = (cgetnum(buf, dname, &f) == -1) ? (dflt) : f; } getnumdflt(dp->d_secsize, "se", DEV_BSIZE); getnumdflt(dp->d_ntracks, "nt", 0); getnumdflt(dp->d_nsectors, "ns", 0); getnumdflt(dp->d_ncylinders, "nc", 0); if (cgetstr(buf, "dt", &cq) > 0) dp->d_type = gettype(cq, dktypenames); else getnumdflt(dp->d_type, "dt", 0); getnumdflt(dp->d_secpercyl, "sc", dp->d_nsectors * dp->d_ntracks); getnumdflt(dp->d_secperunit, "su", dp->d_secpercyl * dp->d_ncylinders); getnumdflt(dp->d_rpm, "rm", 3600); getnumdflt(dp->d_interleave, "il", 1); getnumdflt(dp->d_trackskew, "sk", 0); getnumdflt(dp->d_cylskew, "cs", 0); getnumdflt(dp->d_headswitch, "hs", 0); getnumdflt(dp->d_trkseek, "ts", 0); getnumdflt(dp->d_bbsize, "bs", BBSIZE); getnumdflt(dp->d_sbsize, "sb", 0); strcpy(psize, "px"); strcpy(pbsize, "bx"); strcpy(pfsize, "fx"); strcpy(poffset, "ox"); strcpy(ptype, "tx"); max = 'a' - 1; pp = &dp->d_partitions[0]; for (p = 'a'; p < 'a' + MAXPARTITIONS; p++, pp++) { long l; psize[1] = pbsize[1] = pfsize[1] = poffset[1] = ptype[1] = p; if (cgetnum(buf, psize, &l) == -1) pp->p_size = 0; else { pp->p_size = l; cgetnum(buf, poffset, &l); pp->p_offset = l; getnumdflt(pp->p_fsize, pfsize, 0); if (pp->p_fsize) { long bsize; if (cgetnum(buf, pbsize, &bsize) == 0) pp->p_frag = bsize / pp->p_fsize; else pp->p_frag = 8; } getnumdflt(pp->p_fstype, ptype, 0); if (pp->p_fstype == 0 && cgetstr(buf, ptype, &cq) > 0) pp->p_fstype = gettype(cq, fstypenames); max = p; } } dp->d_npartitions = max + 1 - 'a'; (void)strcpy(psize, "dx"); dx = dp->d_drivedata; for (p = '0'; p < '0' + NDDATA; p++, dx++) { psize[1] = p; getnumdflt(*dx, psize, 0); } dp->d_magic = DISKMAGIC; dp->d_magic2 = DISKMAGIC; free(buf); return (dp); }
/* * Print the status of the printer queue. */ static void prstat(void) { struct stat stbuf; int fd, i; struct dirent *dp; DIR *dirp; if (cgetstr(bp, "sd", &SD) == -1) SD = _PATH_DEFSPOOL; if (cgetstr(bp, "lo", &LO) == -1) LO = DEFLOCK; if (cgetstr(bp, "st", &ST) == -1) ST = DEFSTAT; printf("%s:\n", printer); (void)snprintf(line, sizeof(line), "%s/%s", SD, LO); PRIV_START; i = stat(line, &stbuf); PRIV_END; if (i >= 0) { printf("\tqueuing is %s\n", (stbuf.st_mode & 010) ? "disabled" : "enabled"); printf("\tprinting is %s\n", (stbuf.st_mode & 0100) ? "disabled" : "enabled"); } else { printf("\tqueuing is enabled\n"); printf("\tprinting is enabled\n"); } PRIV_START; dirp = opendir(SD); PRIV_END; if (dirp == NULL) { printf("\tcannot examine spool directory\n"); return; } i = 0; while ((dp = readdir(dirp)) != NULL) { if (*dp->d_name == 'c' && dp->d_name[1] == 'f') i++; } closedir(dirp); if (i == 0) printf("\tno entries\n"); else if (i == 1) printf("\t1 entry in spool area\n"); else printf("\t%d entries in spool area\n", i); PRIV_START; fd = safe_open(line, O_RDONLY|O_NOFOLLOW, 0); PRIV_END; if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) { (void)close(fd); /* unlocks as well */ printf("\tprinter idle\n"); return; } (void)close(fd); (void)snprintf(line, sizeof(line), "%s/%s", SD, ST); PRIV_START; fd = safe_open(line, O_RDONLY|O_NOFOLLOW, 0); PRIV_END; if (fd >= 0) { (void)flock(fd, LOCK_SH); if (fstat(fd, &stbuf) == 0 && stbuf.st_size > 0) { putchar('\t'); while ((i = read(fd, line, sizeof(line))) > 0) (void)fwrite(line, 1, i, stdout); } (void)close(fd); /* unlocks as well */ } }
struct disklabel * getdiskbyname(const char *name) { static struct disklabel disk; struct disklabel *dp = &disk; struct partition *pp; char *buf; char *db_array[2] = { _PATH_DISKTAB, 0 }; char *cp, *cq; char p, max, psize[3], pbsize[3], pfsize[3], poffset[3], ptype[3]; u_int32_t *dx; if (cgetent(&buf, db_array, (char *) name) < 0) return NULL; bzero((char *)&disk, sizeof(disk)); /* * typename */ cq = dp->d_typename; cp = buf; while (cq < dp->d_typename + sizeof(dp->d_typename) - 1 && (*cq = *cp) && *cq != '|' && *cq != ':') cq++, cp++; *cq = '\0'; if (cgetcap(buf, "sf", ':') != NULL) dp->d_flags |= D_BADSECT; #define getnumdflt(field, dname, dflt) \ { long f; (field) = (cgetnum(buf, dname, &f) == -1) ? (dflt) : f; } #define getnum(field, dname) \ { long f; cgetnum(buf, dname, &f); field = f; } getnumdflt(dp->d_secsize, "se", DEV_BSIZE); getnum(dp->d_ntracks, "nt"); getnum(dp->d_nsectors, "ns"); getnum(dp->d_ncylinders, "nc"); if (cgetstr(buf, "dt", &cq) > 0) dp->d_type = (u_short)gettype(cq, dktypenames); else getnumdflt(dp->d_type, "dt", 0); getnumdflt(dp->d_secpercyl, "sc", dp->d_nsectors * dp->d_ntracks); /* XXX */ dp->d_secperunith = 0; getnumdflt(dp->d_secperunit, "su", dp->d_secpercyl * dp->d_ncylinders); getnumdflt(dp->d_bbsize, "bs", BBSIZE); getnumdflt(dp->d_sbsize, "sb", SBSIZE); strlcpy(psize, "px", sizeof psize); strlcpy(pbsize, "bx", sizeof pbsize); strlcpy(pfsize, "fx", sizeof pfsize); strlcpy(poffset, "ox", sizeof poffset); strlcpy(ptype, "tx", sizeof ptype); max = 'a' - 1; pp = &dp->d_partitions[0]; dp->d_version = 1; for (p = 'a'; p < 'a' + MAXPARTITIONS; p++, pp++) { long f; psize[1] = pbsize[1] = pfsize[1] = poffset[1] = ptype[1] = p; /* XXX */ if (cgetnum(buf, psize, &f) == -1) DL_SETPSIZE(pp, 0); else { u_int32_t fsize, frag = 8; DL_SETPSIZE(pp, f); /* XXX */ pp->p_offseth = 0; getnum(pp->p_offset, poffset); getnumdflt(fsize, pfsize, 0); if (fsize) { long bsize; if (cgetnum(buf, pbsize, &bsize) == 0) frag = bsize / fsize; pp->p_fragblock = DISKLABELV1_FFS_FRAGBLOCK(fsize, frag); } getnumdflt(pp->p_fstype, ptype, 0); if (pp->p_fstype == 0 && cgetstr(buf, ptype, &cq) > 0) pp->p_fstype = (u_char)gettype(cq, fstypenames); max = p; } } dp->d_npartitions = max + 1 - 'a'; (void)strlcpy(psize, "dx", sizeof psize); dx = dp->d_drivedata; for (p = '0'; p < '0' + NDDATA; p++, dx++) { psize[1] = p; getnumdflt(*dx, psize, 0); } dp->d_magic = DISKMAGIC; dp->d_magic2 = DISKMAGIC; free(buf); return (dp); }
static void getremcap(char *host) { char **p, ***q, *bp, *rempath; int stat; rempath = getenv("REMOTE"); if (rempath != NULL) { if (*rempath != '/') /* we have an entry */ cgetset(rempath); else { /* we have a path */ db_array[1] = rempath; db_array[2] = _PATH_REMOTE; } } if ((stat = cgetent(&bp, db_array, host)) < 0) { if ((DV != NULL) || (host[0] == '/' && access(DV = host, R_OK | W_OK) == 0)) { CU = DV; HO = host; HW = 1; DU = 0; if (!BR) BR = DEFBR; FS = DEFFS; return; } switch (stat) { case -1: fprintf(stderr, "%s: unknown host %s\n", __progname, host); break; case -2: fprintf(stderr, "%s: can't open host description file\n", __progname); break; case -3: fprintf(stderr, "%s: possible reference loop in host description file\n", __progname); break; } exit(3); } for (p = capstrings, q = caps; *p != NULL; p++, q++) if (**q == NULL) cgetstr(bp, *p, *q); if (!BR && (cgetnum(bp, "br", &BR) == -1)) BR = DEFBR; if (!LD && (cgetnum(bp, "ld", &LD) == -1)) LD = TTYDISC; if (cgetnum(bp, "fs", &FS) == -1) FS = DEFFS; if (DU < 0) DU = 0; else DU = cgetflag("du"); if (DV == NOSTR) { fprintf(stderr, "%s: missing device spec\n", host); exit(3); } if (DU && CU == NOSTR) CU = DV; if (DU && PN == NOSTR) { fprintf(stderr, "%s: missing phone number\n", host); exit(3); } if (DU && AT == NOSTR) { fprintf(stderr, "%s: missing acu type\n", host); exit(3); } HD = cgetflag("hd"); /* * This effectively eliminates the "hw" attribute * from the description file */ if (!HW) HW = (CU == NOSTR) || (DU && equal(DV, CU)); HO = host; /* * see if uppercase mode should be turned on initially */ if (cgetflag("ra")) setboolean(value(RAISE), 1); if (cgetflag("ec")) setboolean(value(ECHOCHECK), 1); if (cgetflag("be")) setboolean(value(BEAUTIFY), 1); if (cgetflag("nb")) setboolean(value(BEAUTIFY), 0); if (cgetflag("sc")) setboolean(value(SCRIPT), 1); if (cgetflag("tb")) setboolean(value(TABEXPAND), 1); if (cgetflag("vb")) setboolean(value(VERBOSE), 1); if (cgetflag("nv")) setboolean(value(VERBOSE), 0); if (cgetflag("ta")) setboolean(value(TAND), 1); if (cgetflag("nt")) setboolean(value(TAND), 0); if (cgetflag("rw")) setboolean(value(RAWFTP), 1); if (cgetflag("hd")) setboolean(value(HALFDUPLEX), 1); if (cgetflag("dc")) setboolean(value(DC), 1); if (cgetflag("hf")) setboolean(value(HARDWAREFLOW), 1); if (RE == NOSTR) RE = (char *)"tip.record"; if (EX == NOSTR) EX = (char *)"\t\n\b\f"; if (ES != NOSTR) vstring("es", ES); if (FO != NOSTR) vstring("fo", FO); if (PR != NOSTR) vstring("pr", PR); if (RC != NOSTR) vstring("rc", RC); if (cgetnum(bp, "dl", &DL) == -1) DL = 0; if (cgetnum(bp, "cl", &CL) == -1) CL = 0; if (cgetnum(bp, "et", &ET) == -1) ET = 10; }
static void getremcap(char *host) { char **p, ***q; char *bp; char *rempath; int stat; rempath = getenv("REMOTE"); if (rempath != NULL) { if (*rempath != '/') /* we have an entry */ cgetset(rempath); else { /* we have a path */ db_array[1] = rempath; db_array[2] = _PATH_REMOTE; } } if ((stat = cgetent(&bp, db_array, host)) < 0) { if (DV || (host[0] == '/' && access(DV = host, R_OK | W_OK) == 0)) { CU = DV; HO = host; HW = 1; DU = 0; if (!BR) BR = DEFBR; FS = BUFSIZ; return; } switch(stat) { case -1: warnx("unknown host %s", host); break; case -2: warnx("can't open host description file"); break; case -3: warnx("possible reference loop in host description file"); break; } exit(3); } for (p = capstrings, q = caps; *p != NULL; p++, q++) if (**q == NULL) cgetstr(bp, *p, *q); if (!BR && (cgetnum(bp, "br", &BR) == -1)) BR = DEFBR; if (cgetnum(bp, "fs", &FS) == -1) FS = BUFSIZ; if (DU < 0) DU = 0; else DU = cgetflag("du"); if (DV == NULL) { fprintf(stderr, "%s: missing device spec\n", host); exit(3); } if (DU && CU == NULL) CU = DV; if (DU && PN == NULL) { fprintf(stderr, "%s: missing phone number\n", host); exit(3); } HD = cgetflag("hd"); /* * This effectively eliminates the "hw" attribute * from the description file */ if (!HW) HW = (CU == NULL) || (DU && equal(DV, CU)); HO = host; /* If login script, verify access */ if (LI != NULL) { if (*LI == '~') (void) expand_tilde (&LI, NULL); if (access (LI, F_OK | X_OK) != 0) { printf("tip (warning): can't open login script \"%s\"\n", LI); LI = NULL; } } /* If logout script, verify access */ if (LO != NULL) { if (*LO == '~') (void) expand_tilde (&LO, NULL); if (access (LO, F_OK | X_OK) != 0) { printf("tip (warning): can't open logout script \"%s\"\n", LO); LO = NULL; } } /* * see if uppercase mode should be turned on initially */ if (cgetflag("ra")) boolean(value(RAISE)) = 1; if (cgetflag("ec")) boolean(value(ECHOCHECK)) = 1; if (cgetflag("be")) boolean(value(BEAUTIFY)) = 1; if (cgetflag("nb")) boolean(value(BEAUTIFY)) = 0; if (cgetflag("sc")) boolean(value(SCRIPT)) = 1; if (cgetflag("tb")) boolean(value(TABEXPAND)) = 1; if (cgetflag("vb")) boolean(value(VERBOSE)) = 1; if (cgetflag("nv")) boolean(value(VERBOSE)) = 0; if (cgetflag("ta")) boolean(value(TAND)) = 1; if (cgetflag("nt")) boolean(value(TAND)) = 0; if (cgetflag("rw")) boolean(value(RAWFTP)) = 1; if (cgetflag("hd")) boolean(value(HALFDUPLEX)) = 1; if (RE == NULL) RE = (char *)"tip.record"; if (EX == NULL) EX = (char *)"\t\n\b\f"; if (ES != NULL) vstring("es", ES); if (FO != NULL) vstring("fo", FO); if (PR != NULL) vstring("pr", PR); if (RC != NULL) vstring("rc", RC); if (cgetnum(bp, "dl", &DL) == -1) DL = 0; if (cgetnum(bp, "cl", &CL) == -1) CL = 0; if (cgetnum(bp, "et", &ET) == -1) ET = 10; }
struct disklabel * getdiskbyname(const char *name) { static struct disklabel disk; struct disklabel *dp = &disk; struct partition *pp; char *buf; char *cp, *cq; /* can't be */ char p, max, psize[3], pbsize[3], pfsize[3], poffset[3], ptype[3]; u_int32_t *dx; long f; _DIAGASSERT(name != NULL); if (cgetent(&buf, db_array, name) < 0) return NULL; memset(&disk, 0, sizeof(disk)); /* * typename */ cq = dp->d_typename; cp = buf; while (cq < dp->d_typename + sizeof(dp->d_typename) - 1 && (*cq = *cp) && *cq != '|' && *cq != ':') cq++, cp++; *cq = '\0'; /* * boot name (optional) xxboot, bootxx */ cgetstr(buf, "b0", &dp->d_boot0); cgetstr(buf, "b1", &dp->d_boot1); if (cgetstr(buf, "ty", &cq) >= 0) { if (strcmp(cq, "removable") == 0) dp->d_flags |= D_REMOVABLE; else if (strcmp(cq, "simulated") == 0) dp->d_flags |= D_RAMDISK; free(cq); } if (cgetcap(buf, "sf", ':') != NULL) dp->d_flags |= D_BADSECT; #define getnumdflt(field, dname, dflt) \ (field) = ((cgetnum(buf, dname, &f) == -1) ? (dflt) : (u_int32_t) f) #define getnum(field, dname) \ if (cgetnum(buf, dname, &f) != -1) field = (u_int32_t)f getnumdflt(dp->d_secsize, "se", DEV_BSIZE); getnum(dp->d_ntracks, "nt"); getnum(dp->d_nsectors, "ns"); getnum(dp->d_ncylinders, "nc"); if (cgetstr(buf, "dt", &cq) >= 0) { dp->d_type = gettype(cq, dktypenames); free(cq); } else getnumdflt(dp->d_type, "dt", 0); getnumdflt(dp->d_secpercyl, "sc", dp->d_nsectors * dp->d_ntracks); getnumdflt(dp->d_secperunit, "su", dp->d_secpercyl * dp->d_ncylinders); getnumdflt(dp->d_rpm, "rm", 3600); getnumdflt(dp->d_interleave, "il", 1); getnumdflt(dp->d_trackskew, "sk", 0); getnumdflt(dp->d_cylskew, "cs", 0); getnumdflt(dp->d_headswitch, "hs", 0); getnumdflt(dp->d_trkseek, "ts", 0); getnumdflt(dp->d_bbsize, "bs", BBSIZE); getnumdflt(dp->d_sbsize, "sb", SBLOCKSIZE); strcpy(psize, "px"); /* XXX: strcpy is safe */ strcpy(pbsize, "bx"); /* XXX: strcpy is safe */ strcpy(pfsize, "fx"); /* XXX: strcpy is safe */ strcpy(poffset, "ox"); /* XXX: strcpy is safe */ strcpy(ptype, "tx"); /* XXX: strcpy is safe */ max = 'a' - 1; pp = &dp->d_partitions[0]; for (p = 'a'; p < 'a' + MAXPARTITIONS; p++, pp++) { long ff; psize[1] = pbsize[1] = pfsize[1] = poffset[1] = ptype[1] = p; if (cgetnum(buf, psize, &ff) == -1) pp->p_size = 0; else { pp->p_size = (u_int32_t)ff; getnum(pp->p_offset, poffset); getnumdflt(pp->p_fsize, pfsize, 0); if (pp->p_fsize) { long bsize; if (cgetnum(buf, pbsize, &bsize) == -1) pp->p_frag = 8; else pp->p_frag = (u_int8_t)(bsize / pp->p_fsize); } getnumdflt(pp->p_fstype, ptype, 0); if (pp->p_fstype == 0) if (cgetstr(buf, ptype, &cq) >= 0) { pp->p_fstype = gettype(cq, fstypenames); free(cq); } max = p; } } dp->d_npartitions = max + 1 - 'a'; strcpy(psize, "dx"); /* XXX: strcpy is safe */ dx = dp->d_drivedata; for (p = '0'; p < '0' + NDDATA; p++, dx++) { psize[1] = p; getnumdflt(*dx, psize, 0); } dp->d_magic = DISKMAGIC; dp->d_magic2 = DISKMAGIC; free(buf); return (dp); }
static void abortpr(int dis) { FILE *fp; struct stat stbuf; int pid, fd; if (cgetstr(bp, "sd", &SD) == -1) SD = _PATH_DEFSPOOL; if (cgetstr(bp, "lo", &LO) == -1) LO = DEFLOCK; (void)snprintf(line, sizeof(line), "%s/%s", SD, LO); printf("%s:\n", printer); PRIV_START; /* * Turn on the owner execute bit of the lock file to disable printing. */ if (dis) { if (stat(line, &stbuf) >= 0) { stbuf.st_mode |= S_IXUSR; if (chmod(line, stbuf.st_mode & 0777) < 0) printf("\tcannot disable printing\n"); else { upstat("printing disabled\n"); printf("\tprinting disabled\n"); } } else if (errno == ENOENT) { if ((fd = safe_open(line, O_WRONLY|O_CREAT|O_NOFOLLOW, 0760)) < 0) printf("\tcannot create lock file\n"); else { (void)fchown(fd, DEFUID, -1); (void)close(fd); upstat("printing disabled\n"); printf("\tprinting disabled\n"); printf("\tno daemon to abort\n"); } goto out; } else { printf("\tcannot stat lock file\n"); goto out; } } /* * Kill the current daemon to stop printing now. */ fd = safe_open(line, O_RDONLY|O_NOFOLLOW, 0); if (fd < 0 || (fp = fdopen(fd, "r")) == NULL) { if (fd >= 0) close(fd); printf("\tcannot open lock file\n"); goto out; } if (!get_line(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) { (void)fclose(fp); /* unlocks as well */ printf("\tno daemon to abort\n"); goto out; } (void)fclose(fp); if (kill(pid = atoi(line), SIGTERM) < 0) { if (errno == ESRCH) printf("\tno daemon to abort\n"); else printf("\tWarning: daemon (pid %d) not killed\n", pid); } else printf("\tdaemon (pid %d) killed\n", pid); out: PRIV_END; }
/* * Display the current state of the queue. Format = 1 if long format. */ void displayq(int format) { struct queue *q; int i, rank, nitems, fd, ret, len; char *cp, *ecp, *p; struct queue **queue; struct winsize win; struct stat statb; FILE *fp; termwidth = 80; if (isatty(STDOUT_FILENO)) { if ((p = getenv("COLUMNS")) != NULL) termwidth = atoi(p); else if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) == 0 && win.ws_col > 0) termwidth = win.ws_col; } if (termwidth < 60) termwidth = 60; lflag = format; totsize = 0; if ((i = cgetent(&bp, printcapdb, printer)) == -2) fatal("can't open printer description file"); else if (i == -1) fatal("unknown printer"); else if (i == -3) fatal("potential reference loop detected in printcap file"); if (cgetstr(bp, DEFLP, &LP) < 0) LP = _PATH_DEFDEVLP; if (cgetstr(bp, "rp", &RP) < 0) RP = DEFLP; if (cgetstr(bp, "sd", &SD) < 0) SD = _PATH_DEFSPOOL; if (cgetstr(bp,"lo", &LO) < 0) LO = DEFLOCK; if (cgetstr(bp, "st", &ST) < 0) ST = DEFSTAT; cgetstr(bp, "rm", &RM); if ((cp = checkremote()) != NULL) printf("Warning: %s\n", cp); /* * Print out local queue * Find all the control files in the spooling directory */ PRIV_START; if (chdir(SD) < 0) fatal("cannot chdir to spooling directory"); PRIV_END; if ((nitems = getq(&queue)) < 0) fatal("cannot examine spooling area"); PRIV_START; ret = stat(LO, &statb); PRIV_END; if (ret >= 0) { if (statb.st_mode & S_IXUSR) { if (remote) printf("%s: ", host); printf("Warning: %s is down: ", printer); PRIV_START; fd = safe_open(ST, O_RDONLY|O_NOFOLLOW, 0); PRIV_END; if (fd >= 0 && flock(fd, LOCK_SH) == 0) { while ((i = read(fd, line, sizeof(line))) > 0) (void)fwrite(line, 1, i, stdout); (void)close(fd); /* unlocks as well */ } else putchar('\n'); } if (statb.st_mode & S_IXGRP) { if (remote) printf("%s: ", host); printf("Warning: %s queue is turned off\n", printer); } } if (nitems) { PRIV_START; fd = safe_open(LO, O_RDONLY|O_NOFOLLOW, 0); PRIV_END; if (fd < 0 || (fp = fdopen(fd, "r")) == NULL) { if (fd >= 0) close(fd); nodaemon(); } else { /* get daemon pid */ cp = current; ecp = cp + sizeof(current) - 1; while ((i = getc(fp)) != EOF && i != '\n') { if (cp < ecp) *cp++ = i; } *cp = '\0'; i = atoi(current); if (i <= 0) { ret = -1; } else { PRIV_START; ret = kill(i, 0); PRIV_END; } if (ret < 0 && errno != EPERM) { nodaemon(); } else { /* read current file name */ cp = current; ecp = cp + sizeof(current) - 1; while ((i = getc(fp)) != EOF && i != '\n') { if (cp < ecp) *cp++ = i; } *cp = '\0'; /* * Print the status file. */ if (remote) printf("%s: ", host); PRIV_START; fd = safe_open(ST, O_RDONLY|O_NOFOLLOW, 0); PRIV_END; if (fd >= 0 && flock(fd, LOCK_SH) == 0) { while ((i = read(fd, line, sizeof(line))) > 0) (void)fwrite(line, 1, i, stdout); (void)close(fd); /* unlocks as well */ } else putchar('\n'); } (void)fclose(fp); } /* * Now, examine the control files and print out the jobs to * be done for each user. */ if (!lflag) header(); /* The currently printed job is treated specially. */ if (!remote && current[0] != '\0') inform(current, 0); for (i = 0, rank = 1; i < nitems; i++) { q = queue[i]; if (remote || strcmp(current, q->q_name) != 0) inform(q->q_name, rank++); free(q); } } free(queue); if (!remote) { if (nitems == 0) puts("no entries"); return; } /* * Print foreign queue * Note that a file in transit may show up in either queue. */ if (nitems) putchar('\n'); (void)snprintf(line, sizeof(line), "%c%s", format + '\3', RP); cp = line; cp += strlen(cp); for (i = 0; i < requests && cp - line < sizeof(line) - 1; i++) { len = line + sizeof(line) - cp; if (snprintf(cp, len, " %d", requ[i]) >= len) { cp += strlen(cp); break; } cp += strlen(cp); } for (i = 0; i < users && cp - line < sizeof(line) - 1; i++) { len = line + sizeof(line) - cp; if (snprintf(cp, len, " %s", user[i]) >= len) { cp += strlen(cp); break; } } if (cp-line < sizeof(line) - 1) strlcat(line, "\n", sizeof(line)); else line[sizeof(line) - 2] = '\n'; fd = getport(RM, 0); if (fd < 0) { if (from != host) printf("%s: ", host); (void)printf("connection to %s is down\n", RM); } else { struct sigaction osa, nsa; char *visline; int n = 0; i = strlen(line); if (write(fd, line, i) != i) fatal("Lost connection"); memset(&nsa, 0, sizeof(nsa)); nsa.sa_handler = alarmer; sigemptyset(&nsa.sa_mask); nsa.sa_flags = 0; (void)sigaction(SIGALRM, &nsa, &osa); alarm(wait_time); if ((visline = (char *)malloc(4 * sizeof(line) + 1)) == NULL) fatal("Out of memory"); while ((i = read(fd, line, sizeof(line))) > 0) { n = strvisx(visline, line, i, VIS_SAFE|VIS_NOSLASH); (void)fwrite(visline, 1, n, stdout); alarm(wait_time); } /* XXX some LPR implementations may not end stream with '\n' */ if (n > 0 && visline[n-1] != '\n') putchar('\n'); alarm(0); (void)sigaction(SIGALRM, &osa, NULL); free(visline); (void)close(fd); } }
void rmjob(void) { int i, nitems; int assassinated = 0; struct dirent **files; char *cp; if ((i = cgetent(&bp, printcapdb, printer)) == -2) fatal("can't open printer description file"); else if (i == -1) fatal("unknown printer"); else if (i == -3) fatal("potential reference loop detected in printcap file"); if (cgetstr(bp, DEFLP, &LP) < 0) LP = _PATH_DEFDEVLP; if (cgetstr(bp, "rp", &RP) < 0) RP = DEFLP; if (cgetstr(bp, "sd", &SD) < 0) SD = _PATH_DEFSPOOL; if (cgetstr(bp,"lo", &LO) < 0) LO = DEFLOCK; cgetstr(bp, "rm", &RM); if ((cp = checkremote()) != NULL) printf("Warning: %s\n", cp); /* * If the format was `lprm -' and the user isn't the super-user, * then fake things to look like he said `lprm user'. */ if (users < 0) { if (getuid() == 0) all = 1; /* all files in local queue */ else { user[0] = person; users = 1; } } if (!strcmp(person, "-all")) { if (from == host) fatal("The login name \"-all\" is reserved"); all = 1; /* all those from 'from' */ person = root; } PRIV_START; if (chdir(SD) < 0) fatal("cannot chdir to spool directory"); if ((nitems = scandir(".", &files, iscf, NULL)) < 0) fatal("cannot access spool directory"); PRIV_END; if (nitems) { /* * Check for an active printer daemon. If one is running * and it is reading our file, kill it, then remove stuff. * Lastly, restart the daemon if it is not (or no longer) * running. */ if (lockchk(LO) && chk(current)) { PRIV_START; assassinated = kill(cur_daemon, SIGINT) == 0; PRIV_END; if (!assassinated) fatal("cannot kill printer daemon"); } /* * process the files */ for (i = 0; i < nitems; i++) process(files[i]->d_name); } rmremote(); /* * Restart the printer daemon if it was killed */ if (assassinated && !startdaemon(printer)) fatal("cannot restart printer daemon"); exit(0); }
int getlist(char ** db_array, char *name, struct blacklist *blist, struct blacklist *blistnew) { char *buf, *method, *file, *message; int fd, black = 0, serror; size_t blc, bls; struct bl *bl = NULL; gzFile gzf; if (cgetent(&buf, db_array, name) != 0) err(1, "Can't find \"%s\" in spamd config", name); buf = fix_quoted_colons(buf); if (cgetcap(buf, "black", ':') != NULL) { /* use new list */ black = 1; blc = blistnew->blc; bls = blistnew->bls; bl = blistnew->bl; } else if (cgetcap(buf, "white", ':') != NULL) { /* apply to most recent blacklist */ black = 0; blc = blist->blc; bls = blist->bls; bl = blist->bl; } else errx(1, "Must have \"black\" or \"white\" in %s", name); switch (cgetstr(buf, "msg", &message)) { case -1: if (black) errx(1, "No msg for blacklist \"%s\"", name); break; case -2: errx(1, "malloc failed"); } switch (cgetstr(buf, "method", &method)) { case -1: method = NULL; break; case -2: errx(1, "malloc failed"); } switch (cgetstr(buf, "file", &file)) { case -1: errx(1, "No file given for %slist %s", black ? "black" : "white", name); case -2: errx(1, "malloc failed"); default: fd = open_file(method, file); if (fd == -1) err(1, "Can't open %s by %s method", file, method ? method : "file"); free(method); free(file); gzf = gzdopen(fd, "r"); if (gzf == NULL) errx(1, "gzdopen"); } free(buf); bl = add_blacklist(bl, &blc, &bls, gzf, !black); serror = errno; gzclose(gzf); if (bl == NULL) { errno = serror; warn("Could not add %slist %s", black ? "black" : "white", name); return (0); } if (black) { blistnew->message = message; blistnew->name = name; blistnew->black = black; blistnew->bl = bl; blistnew->blc = blc; blistnew->bls = bls; } else { /* whitelist applied to last active blacklist */ blist->bl = bl; blist->blc = blc; blist->bls = bls; } if (debug) fprintf(stderr, "%slist %s %zu entries\n", black ? "black" : "white", name, blc / 2); return (black); }
/* * Get a table entry. */ void gettable(const char *name, char *buf) { struct gettystrs *sp; struct gettynums *np; struct gettyflags *fp; long n; int l; char *p; char *msg = NULL; const char *dba[2]; static int firsttime = 1; dba[0] = _PATH_GETTYTAB; dba[1] = NULL; if (firsttime) { /* * we need to strdup() anything in the strings array * initially in order to simplify things later */ for (sp = gettystrs; sp->field; sp++) if (sp->value != NULL) { /* handle these ones more carefully */ if (sp >= &gettystrs[4] && sp <= &gettystrs[6]) l = 2; else l = strlen(sp->value) + 1; if ((p = malloc(l)) != NULL) { strncpy(p, sp->value, l); p[l-1] = '\0'; } /* * replace, even if NULL, else we'll * have problems with free()ing static mem */ sp->value = p; } firsttime = 0; } switch (cgetent(&buf, (char **)dba, (char *)name)) { case 1: msg = "%s: couldn't resolve 'tc=' in gettytab '%s'"; case 0: break; case -1: msg = "%s: unknown gettytab entry '%s'"; break; case -2: msg = "%s: retrieving gettytab entry '%s': %m"; break; case -3: msg = "%s: recursive 'tc=' reference gettytab entry '%s'"; break; default: msg = "%s: unexpected cgetent() error for entry '%s'"; break; } if (msg != NULL) { syslog(LOG_ERR, msg, "getty", name); return; } for (sp = gettystrs; sp->field; sp++) { if ((l = cgetstr(buf, (char*)sp->field, &p)) >= 0) { if (sp->value) { /* prefer existing value */ if (strcmp(p, sp->value) != 0) free(sp->value); else { free(p); p = sp->value; } } sp->value = p; } else if (l == -1) { free(sp->value); sp->value = NULL; } } for (np = gettynums; np->field; np++) { if (cgetnum(buf, (char*)np->field, &n) == -1) np->set = 0; else { np->set = 1; np->value = n; } } for (fp = gettyflags; fp->field; fp++) { if (cgetcap(buf, (char *)fp->field, ':') == NULL) fp->set = 0; else { fp->set = 1; fp->value = 1 ^ fp->invrt; } } #ifdef DEBUG printf("name=\"%s\", buf=\"%s\"\r\n", name, buf); for (sp = gettystrs; sp->field; sp++) printf("cgetstr: %s=%s\r\n", sp->field, sp->value); for (np = gettynums; np->field; np++) printf("cgetnum: %s=%d\r\n", np->field, np->value); for (fp = gettyflags; fp->field; fp++) printf("cgetflags: %s='%c' set='%c'\r\n", fp->field, fp->value + '0', fp->set + '0'); #endif /* DEBUG */ }
void * plot_open(const char *name, const char *def, FILE *fp) { struct plotctx *pl; char *p, *dba[2]; long n; int err, ontty; ontty = isatty(fileno(fp)); if (name == NULL && ontty && (p = getenv("PLOTCAP")) != NULL) { if ((p = strdup(p)) == NULL) return (NULL); } else { dba[0] = _PATH_PLOTCAP; dba[1] = NULL; if (name == NULL) { if (ontty) name = getenv("TERM"); if (name == NULL) name = def; if (name == NULL) return (NULL); } if (cgetent(&p, dba, name) != 0) { if (cgetent(&p, dba, def) != 0) return (NULL); else name = def; } } if ((pl = malloc(sizeof(*pl))) == NULL) { free(p); return (NULL); } memset(pl, 0, sizeof(*pl)); pl->buf = p; if (cgetnum(pl->buf, "w", &n) == 0) pl->dx = pl->w = n; if (cgetnum(pl->buf, "h", &n) < 0) pl->dx = pl->w = 0; else pl->dx = pl->h = n; if (cgetcap(pl->buf, "le", ':')) pl->flags |= LENDIAN; /* scale at 1:1 */ pl->ox = pl->oy = 0; pl->xnum = pl->xdenom = pl->ynum = pl->ydenom = 1; pl->fp = fp? fp : stdout; if (cgetstr(pl->buf, "in", &p) > 0) if (_plot_out(pl, p)) { err = errno; free(pl->buf); free(pl); errno = err; return (NULL); } return (pl); }
/* * Remove incomplete jobs from spooling area. */ static void cleanpr(void) { int i, n; char *cp, *cp1, *lp; struct dirent **queue; int nitems; if (cgetstr(bp, "sd", &SD) == -1) SD = _PATH_DEFSPOOL; printf("%s:\n", printer); /* XXX depends on SD being non-NUL */ for (lp = line, cp = SD; (lp - line) < sizeof(line) && (*lp++ = *cp++) != '\0'; ) ; lp[-1] = '/'; if (lp - line >= sizeof(line)) { printf("\tspool directory name too long\n"); return; } PRIV_START; nitems = scandir(SD, &queue, doselect, sortq); PRIV_END; if (nitems < 0) { printf("\tcannot examine spool directory\n"); return; } if (nitems == 0) return; i = 0; do { cp = queue[i]->d_name; if (*cp == 'c') { n = 0; while (i + 1 < nitems) { cp1 = queue[i + 1]->d_name; if (*cp1 != 'd' || strcmp(cp + 3, cp1 + 3)) break; i++; n++; } if (n == 0) { if (strlcpy(lp, cp, sizeof(line) - (lp - line)) >= sizeof(line) - (lp - line)) printf("\tpath too long, %s/%s", SD, cp); else unlinkf(line); } } else { /* * Must be a df with no cf (otherwise, it would have * been skipped above) or a tf file (which can always * be removed). */ if (strlcpy(lp, cp, sizeof(line) - (lp - line)) >= sizeof(line) - (lp - line)) printf("\tpath too long, %s/%s", SD, cp); else unlinkf(line); } } while (++i < nitems); }
/* * Put the specified jobs at the top of printer queue. */ void topq(int argc, char **argv) { int i; struct stat stbuf; int status, changed; if (argc < 3) { printf("usage: topq printer [jobnum ...] [user ...]\n"); return; } --argc; printer = *++argv; status = cgetent(&bp, printcapdb, printer); if (status == -2) { printf("cannot open printer description file\n"); return; } else if (status == -1) { printf("%s: unknown printer\n", printer); return; } else if (status == -3) fatal("potential reference loop detected in printcap file"); if (cgetstr(bp, "sd", &SD) == -1) SD = _PATH_DEFSPOOL; if (cgetstr(bp, "lo", &LO) == -1) LO = DEFLOCK; printf("%s:\n", printer); PRIV_START; if (chdir(SD) < 0) { printf("\tcannot chdir to %s\n", SD); goto out; } PRIV_END; nitems = getq(&queue); if (nitems == 0) return; changed = 0; mtime = queue[0]->q_time; for (i = argc; --i; ) { if (doarg(argv[i]) == 0) { printf("\tjob %s is not in the queue\n", argv[i]); continue; } else changed++; } for (i = 0; i < nitems; i++) free(queue[i]); free(queue); if (!changed) { printf("\tqueue order unchanged\n"); return; } /* * Turn on the public execute bit of the lock file to * get lpd to rebuild the queue after the current job. */ PRIV_START; if (changed && stat(LO, &stbuf) >= 0) { stbuf.st_mode |= S_IXOTH; (void)chmod(LO, stbuf.st_mode & 0777); } out: PRIV_END; }
static void putmsg(int argc, char **argv) { int fd; char *cp1, *cp2; char buf[1024]; struct stat stbuf; if (cgetstr(bp, "sd", &SD) == -1) SD = _PATH_DEFSPOOL; if (cgetstr(bp, "lo", &LO) == -1) LO = DEFLOCK; if (cgetstr(bp, "st", &ST) == -1) ST = DEFSTAT; printf("%s:\n", printer); /* * Turn on the group execute bit of the lock file to disable queuing and * turn on the owner execute bit of the lock file to disable printing. */ (void)snprintf(line, sizeof(line), "%s/%s", SD, LO); PRIV_START; if (stat(line, &stbuf) >= 0) { stbuf.st_mode |= (S_IXGRP|S_IXUSR); if (chmod(line, stbuf.st_mode & 0777) < 0) printf("\tcannot disable queuing\n"); else printf("\tprinter and queuing disabled\n"); } else if (errno == ENOENT) { if ((fd = safe_open(line, O_WRONLY|O_CREAT|O_NOFOLLOW, 0770)) < 0) printf("\tcannot create lock file\n"); else { (void)fchown(fd, DEFUID, -1); (void)close(fd); printf("\tprinter and queuing disabled\n"); } PRIV_END; return; } else printf("\tcannot stat lock file\n"); /* * Write the message into the status file. */ (void)snprintf(line, sizeof(line), "%s/%s", SD, ST); fd = safe_open(line, O_WRONLY|O_CREAT|O_NOFOLLOW, 0660); if (fd < 0 || flock(fd, LOCK_EX) < 0) { printf("\tcannot create status file\n"); PRIV_END; return; } PRIV_END; (void)fchown(fd, DEFUID, -1); (void)ftruncate(fd, 0); if (argc <= 0) { (void)write(fd, "\n", 1); (void)close(fd); return; } cp1 = buf; while (--argc >= 0) { cp2 = *argv++; while ((cp1 - buf) < sizeof(buf) - 1 && (*cp1++ = *cp2++)) ; cp1[-1] = ' '; } cp1[-1] = '\n'; *cp1 = '\0'; (void)write(fd, buf, strlen(buf)); (void)close(fd); }