size_t _ti_store_extra(TIC *tic, int wrn, char *id, char type, char flag, short num, char *str, size_t strl, int flags) { size_t l; _DIAGASSERT(tic != NULL); if (strcmp(id, "use") != 0) { if (_ti_find_extra(&tic->extras, id) != NULL) return 0; if (!(flags & TIC_EXTRA)) { if (wrn != 0) dowarn(flags, "%s: %s: unknown capability", tic->name, id); return 0; } } l = strlen(id) + 1; if (l > UINT16_T_MAX) { dowarn(flags, "%s: %s: cap name is too long", tic->name, id); return 0; } if (!_ti_grow_tbuf(&tic->extras, l + strl + (sizeof(uint16_t) * 2) + 1)) return 0; le16enc(tic->extras.buf + tic->extras.bufpos, l); tic->extras.bufpos += sizeof(uint16_t); memcpy(tic->extras.buf + tic->extras.bufpos, id, l); tic->extras.bufpos += l; tic->extras.buf[tic->extras.bufpos++] = type; switch (type) { case 'f': tic->extras.buf[tic->extras.bufpos++] = flag; break; case 'n': le16enc(tic->extras.buf + tic->extras.bufpos, num); tic->extras.bufpos += sizeof(uint16_t); break; case 's': le16enc(tic->extras.buf + tic->extras.bufpos, strl); tic->extras.bufpos += sizeof(uint16_t); memcpy(tic->extras.buf + tic->extras.bufpos, str, strl); tic->extras.bufpos += strl; break; } tic->extras.entries++; return 1; }
static void crfile(int me, int count) { int fd, val; char fname[MAXPATHLEN], buf[MAXPATHLEN]; ft_mkname(fname, dirname, me, count); fd = open(fname, O_RDWR | O_CREAT | O_TRUNC, 0666); if (fd < 0 && errno == EISDIR) { val = rmdir(fname); warn(val, "rmdir", fname); fd = open(fname, O_RDWR | O_CREAT | O_TRUNC, 0666); } warn(fd, "creating", fname); val = lseek(fd, (rand() % M), 0); warn(val, "lseek", 0); val = write(fd, crmsg, sizeof(crmsg) - 1); warn(val, "write", 0); val = lseek(fd, -(sizeof(crmsg) - 1), 1); warn(val, "lseek", 0); val = read(fd, buf, sizeof(crmsg) - 1); warn(val, "read", 0); if (strncmp(crmsg, buf, sizeof(crmsg) - 1)) dowarn(me, "compare", 0); val = close(fd); warn(val, "close", 0); }
/* * unlfile() * Unlink some of the files. */ static void unlfile(int me, int count) { int val, i; char fname[MAXPATHLEN]; i = count - 10; if (i < 0) i = 0; for (; i < count; i++) { ft_mkname(fname, dirname, me, i); val = rmdir(fname); if (val < 0) val = unlink(fname); if (val == 0 || errno == ENOENT) continue; dowarn(me, "unlink", fname); } }
TIC * _ti_compile(char *cap, int flags) { char *token, *p, *e, *name, *desc, *alias; signed char flag; long cnum; short num; ssize_t ind; size_t len; TBUF buf; TIC *tic; _DIAGASSERT(cap != NULL); name = _ti_get_token(&cap, ','); if (name == NULL) { dowarn(flags, "no seperator found: %s", cap); return NULL; } desc = strrchr(name, '|'); if (desc != NULL) *desc++ = '\0'; alias = strchr(name, '|'); if (alias != NULL) *alias++ = '\0'; tic = calloc(sizeof(*tic), 1); if (tic == NULL) return NULL; buf.buf = NULL; buf.buflen = 0; tic->name = strdup(name); if (tic->name == NULL) goto error; if (alias != NULL && flags & TIC_ALIAS) { tic->alias = strdup(alias); if (tic->alias == NULL) goto error; } if (desc != NULL && flags & TIC_DESCRIPTION) { tic->desc = strdup(desc); if (tic->desc == NULL) goto error; } for (token = _ti_get_token(&cap, ','); token != NULL && *token != '\0'; token = _ti_get_token(&cap, ',')) { /* Skip commented caps */ if (!(flags & TIC_COMMENT) && token[0] == '.') continue; /* Obsolete entries */ if (token[0] == 'O' && token[1] == 'T') { if (!(flags & TIC_EXTRA)) continue; token += 2; } /* str cap */ p = strchr(token, '='); if (p != NULL) { *p++ = '\0'; /* Don't use the string if we already have it */ ind = _ti_strindex(token); if (ind != -1 && _ti_find_cap(&tic->strs, 's', ind) != NULL) continue; /* Encode the string to our scratch buffer */ buf.bufpos = 0; if (encode_string(tic->name, token, &buf, p, flags) == -1) goto error; if (buf.bufpos > UINT16_T_MAX) { dowarn(flags, "%s: %s: string is too long", tic->name, token); continue; } if (!VALID_STRING(buf.buf)) { dowarn(flags, "%s: %s: invalid string", tic->name, token); continue; } if (ind == -1) _ti_store_extra(tic, 1, token, 's', -1, -2, buf.buf, buf.bufpos, flags); else { if (!_ti_grow_tbuf(&tic->strs, (sizeof(uint16_t) * 2) + buf.bufpos)) goto error; le16enc(tic->strs.buf + tic->strs.bufpos, ind); tic->strs.bufpos += sizeof(uint16_t); le16enc(tic->strs.buf + tic->strs.bufpos, buf.bufpos); tic->strs.bufpos += sizeof(uint16_t); memcpy(tic->strs.buf + tic->strs.bufpos, buf.buf, buf.bufpos); tic->strs.bufpos += buf.bufpos; tic->strs.entries++; } continue; } /* num cap */ p = strchr(token, '#'); if (p != NULL) { *p++ = '\0'; /* Don't use the number if we already have it */ ind = _ti_numindex(token); if (ind != -1 && _ti_find_cap(&tic->nums, 'n', ind) != NULL) continue; cnum = strtol(p, &e, 0); if (*e != '\0') { dowarn(flags, "%s: %s: not a number", tic->name, token); continue; } if (!VALID_NUMERIC(cnum)) { dowarn(flags, "%s: %s: number out of range", tic->name, token); continue; } num = (short)cnum; if (ind == -1) _ti_store_extra(tic, 1, token, 'n', -1, num, NULL, 0, flags); else { if (_ti_grow_tbuf(&tic->nums, sizeof(uint16_t) * 2) == NULL) goto error; le16enc(tic->nums.buf + tic->nums.bufpos, ind); tic->nums.bufpos += sizeof(uint16_t); le16enc(tic->nums.buf + tic->nums.bufpos, num); tic->nums.bufpos += sizeof(uint16_t); tic->nums.entries++; } continue; } flag = 1; len = strlen(token) - 1; if (token[len] == '@') { flag = CANCELLED_BOOLEAN; token[len] = '\0'; } ind = _ti_flagindex(token); if (ind == -1 && flag == CANCELLED_BOOLEAN) { if ((ind = _ti_numindex(token)) != -1) { if (_ti_find_cap(&tic->nums, 'n', ind) != NULL) continue; if (_ti_grow_tbuf(&tic->nums, sizeof(uint16_t) * 2) == NULL) goto error; le16enc(tic->nums.buf + tic->nums.bufpos, ind); tic->nums.bufpos += sizeof(uint16_t); le16enc(tic->nums.buf + tic->nums.bufpos, (uint16_t)CANCELLED_NUMERIC); tic->nums.bufpos += sizeof(uint16_t); tic->nums.entries++; continue; } else if ((ind = _ti_strindex(token)) != -1) { if (_ti_find_cap(&tic->strs, 's', ind) != NULL) continue; if (_ti_grow_tbuf(&tic->strs, (sizeof(uint16_t) * 2) + 1) == NULL) goto error; le16enc(tic->strs.buf + tic->strs.bufpos, ind); tic->strs.bufpos += sizeof(uint16_t); le16enc(tic->strs.buf + tic->strs.bufpos, 0); tic->strs.bufpos += sizeof(uint16_t); tic->strs.entries++; continue; } } if (ind == -1) _ti_store_extra(tic, 1, token, 'f', flag, 0, NULL, 0, flags); else if (_ti_find_cap(&tic->flags, 'f', ind) == NULL) { if (_ti_grow_tbuf(&tic->flags, sizeof(uint16_t) + 1) == NULL) goto error; le16enc(tic->flags.buf + tic->flags.bufpos, ind); tic->flags.bufpos += sizeof(uint16_t); tic->flags.buf[tic->flags.bufpos++] = flag; tic->flags.entries++; } } free(buf.buf); return tic; error: free(buf.buf); _ti_freetic(tic); return NULL; }
static int encode_string(const char *term, const char *cap, TBUF *tbuf, const char *str, int flags) { int slash, i, num; char ch, *p, *s, last; if (_ti_grow_tbuf(tbuf, strlen(str) + 1) == NULL) return -1; p = s = tbuf->buf + tbuf->bufpos; slash = 0; last = '\0'; /* Convert escape codes */ while ((ch = *str++) != '\0') { if (slash == 0 && ch == '\\') { slash = 1; continue; } if (slash == 0) { if (last != '%' && ch == '^') { ch = *str++; if (((unsigned char)ch) >= 128) dowarn(flags, "%s: %s: illegal ^ character", term, cap); if (ch == '\0') break; if (ch == '?') ch = '\177'; else if ((ch &= 037) == 0) ch = (char)128; } *p++ = ch; last = ch; continue; } slash = 0; if (ch >= '0' && ch <= '7') { num = ch - '0'; for (i = 0; i < 2; i++) { if (*str < '0' || *str > '7') { if (isdigit((unsigned char)*str)) dowarn(flags, "%s: %s: non octal" " digit", term, cap); else break; } num = num * 8 + *str++ - '0'; } if (num == 0) num = 0200; *p++ = (char)num; continue; } switch (ch) { case 'a': *p++ = '\a'; break; case 'b': *p++ = '\b'; break; case 'e': /* FALLTHROUGH */ case 'E': *p++ = '\033'; break; case 'f': *p++ = '\014'; break; case 'l': /* FALLTHROUGH */ case 'n': *p++ = '\n'; break; case 'r': *p++ = '\r'; break; case 's': *p++ = ' '; break; case 't': *p++ = '\t'; break; default: /* We should warn here */ case '^': case ',': case ':': case '|': *p++ = ch; break; } last = ch; } *p++ = '\0'; tbuf->bufpos += p - s; return 0; }
int main(int argc, char **argv) { wint_t ch; CHAR *c; CSET cur_set; /* current character set */ LINE *l; /* current line */ int extra_lines; /* # of lines above first line */ int cur_col; /* current column */ int cur_line; /* line number of current position */ int max_line; /* max value of cur_line */ int this_line; /* line l points to */ int nflushd_lines; /* number of lines that were flushed */ int adjust, opt, warned, width; (void)setlocale(LC_CTYPE, ""); max_bufd_lines = 128; compress_spaces = 1; /* compress spaces into tabs */ while ((opt = getopt(argc, argv, "bfhl:px")) != -1) switch (opt) { case 'b': /* do not output backspaces */ no_backspaces = 1; break; case 'f': /* allow half forward line feeds */ fine = 1; break; case 'h': /* compress spaces into tabs */ compress_spaces = 1; break; case 'l': /* buffered line count */ if ((max_bufd_lines = atoi(optarg)) <= 0) errx(1, "bad -l argument %s", optarg); break; case 'p': /* pass unknown control sequences */ pass_unknown_seqs = 1; break; case 'x': /* do not compress spaces into tabs */ compress_spaces = 0; break; case '?': default: usage(); } if (optind != argc) usage(); /* this value is in half lines */ max_bufd_lines *= 2; adjust = cur_col = extra_lines = warned = 0; cur_line = max_line = nflushd_lines = this_line = 0; cur_set = last_set = CS_NORMAL; lines = l = alloc_line(); while ((ch = getwchar()) != WEOF) { if (!iswgraph(ch)) { switch (ch) { case BS: /* can't go back further */ if (cur_col == 0) continue; --cur_col; continue; case CR: cur_col = 0; continue; case ESC: /* just ignore EOF */ switch(getwchar()) { case RLF: cur_line -= 2; break; case RHLF: cur_line--; break; case FHLF: cur_line++; if (cur_line > max_line) max_line = cur_line; } continue; case NL: cur_line += 2; if (cur_line > max_line) max_line = cur_line; cur_col = 0; continue; case SPACE: ++cur_col; continue; case SI: cur_set = CS_NORMAL; continue; case SO: cur_set = CS_ALTERNATE; continue; case TAB: /* adjust column */ cur_col |= 7; ++cur_col; continue; case VT: cur_line -= 2; continue; } if (iswspace(ch)) { if ((width = wcwidth(ch)) > 0) cur_col += width; continue; } if (!pass_unknown_seqs) continue; } /* Must stuff ch in a line - are we at the right one? */ if (cur_line != this_line - adjust) { LINE *lnew; int nmove; adjust = 0; nmove = cur_line - this_line; if (!fine) { /* round up to next line */ if (cur_line & 1) { adjust = 1; nmove++; } } if (nmove < 0) { for (; nmove < 0 && l->l_prev; nmove++) l = l->l_prev; if (nmove) { if (nflushd_lines == 0) { /* * Allow backup past first * line if nothing has been * flushed yet. */ for (; nmove < 0; nmove++) { lnew = alloc_line(); l->l_prev = lnew; lnew->l_next = l; l = lines = lnew; extra_lines++; } } else { if (!warned++) dowarn(cur_line); cur_line -= nmove; } } } else { /* may need to allocate here */ for (; nmove > 0 && l->l_next; nmove--) l = l->l_next; for (; nmove > 0; nmove--) { lnew = alloc_line(); lnew->l_prev = l; l->l_next = lnew; l = lnew; } } this_line = cur_line + adjust; nmove = this_line - nflushd_lines; if (nmove >= max_bufd_lines + BUFFER_MARGIN) { nflushd_lines += nmove - max_bufd_lines; flush_lines(nmove - max_bufd_lines); } } /* grow line's buffer? */ if (l->l_line_len + 1 >= l->l_lsize) { int need; need = l->l_lsize ? l->l_lsize * 2 : 90; if ((l->l_line = realloc(l->l_line, (unsigned)need * sizeof(CHAR))) == NULL) err(1, (char *)NULL); l->l_lsize = need; } c = &l->l_line[l->l_line_len++]; c->c_char = ch; c->c_set = cur_set; c->c_column = cur_col; c->c_width = wcwidth(ch); /* * If things are put in out of order, they will need sorting * when it is flushed. */ if (cur_col < l->l_max_col) l->l_needs_sort = 1; else l->l_max_col = cur_col; if (c->c_width > 0) cur_col += c->c_width; } if (ferror(stdin)) err(1, NULL); if (max_line == 0) exit(0); /* no lines, so just exit */ /* goto the last line that had a character on it */ for (; l->l_next; l = l->l_next) this_line++; flush_lines(this_line - nflushd_lines + extra_lines + 1); /* make sure we leave things in a sane state */ if (last_set != CS_NORMAL) PUTC('\017'); /* flush out the last few blank lines */ nblank_lines = max_line - this_line; if (max_line & 1) nblank_lines++; else if (!nblank_lines) /* missing a \n on the last line? */ nblank_lines = 2; flush_blanks(); exit(0); }
/* * Sys call to allow users to find out * their current position wrt quota's * and to allow super users to alter it. */ qquota() { register struct a { int cmd; int uid; int arg; caddr_t addr; } *uap = (struct a *)u.u_ap; register struct quota *q; #ifndef QUOTA u.u_error = EINVAL; return; #else if (uap->uid < 0) uap->uid = u.u_ruid; if (uap->uid != u.u_ruid && uap->uid != u.u_quota->q_uid && !suser()) return; if (uap->cmd != Q_SYNC && uap->cmd != Q_SETUID) { q = getquota((uid_t)uap->uid, uap->cmd == Q_DOWARN, 0); if (q == NOQUOTA) { u.u_error = ESRCH; return; } if (u.u_error) goto bad; } switch (uap->cmd) { case Q_SETDLIM: u.u_error = setdlim(q, (dev_t)uap->arg, uap->addr); break; case Q_GETDLIM: u.u_error = getdlim(q, (dev_t)uap->arg, uap->addr); break; case Q_SETDUSE: u.u_error = setduse(q, (dev_t)uap->arg, uap->addr); break; case Q_SETWARN: u.u_error = setwarn(q, (dev_t)uap->arg, uap->addr); break; case Q_DOWARN: u.u_error = dowarn(q, (dev_t)uap->arg); break; case Q_SYNC: u.u_error = qsync((dev_t)uap->arg); return; case Q_SETUID: u.u_error = qsetuid((uid_t)uap->uid, uap->arg); return; default: u.u_error = EINVAL; break; } bad: delquota(q); #endif }