📄 getcap.c
字号:
if (r_end > rp) if ((record = realloc(record, (size_t)(rp - record))) == NULL) { errno = ENOMEM; return (-2); } *cap = record; if (tc_not_resolved) return (1); return (0);} static intcdbget(capdbp, bp, name) DB *capdbp; char **bp, *name;{ DBT key, data; char *buf; int st; key.data = name; key.size = strlen(name); for (;;) { /* Get the reference. */ switch(capdbp->get(capdbp, &key, &data, 0)) { case -1: return (-2); case 1: return (-1); } /* If not an index to another record, leave. */ if (((char *)data.data)[0] != SHADOW) break; key.data = (char *)data.data + 1; key.size = data.size - 1; } *bp = (char *)data.data + 1; return (((char *)(data.data))[0] == TCERR ? 1 : 0);}/* * Cgetmatch will return 0 if name is one of the names of the capability * record buf, -1 if not. */intcgetmatch(buf, name) char *buf, *name;{ register char *np, *bp; /* * Start search at beginning of record. */ bp = buf; for (;;) { /* * Try to match a record name. */ np = name; for (;;) if (*np == '\0') if (*bp == '|' || *bp == ':' || *bp == '\0') return (0); else break; else if (*bp++ != *np++) break; /* * Match failed, skip to next name in record. */ bp--; /* a '|' or ':' may have stopped the match */ for (;;) if (*bp == '\0' || *bp == ':') return (-1); /* match failed totally */ else if (*bp++ == '|') break; /* found next name */ }}intcgetfirst(buf, db_array) char **buf, **db_array;{ (void)cgetclose(); return (cgetnext(buf, db_array));}static FILE *pfp;static int slash;static char **dbp;intcgetclose(){ if (pfp != NULL) { (void)fclose(pfp); pfp = NULL; } dbp = NULL; gottoprec = 0; slash = 0; return(0);}/* * Cgetnext() gets either the first or next entry in the logical database * specified by db_array. It returns 0 upon completion of the database, 1 * upon returning an entry with more remaining, and -1 if an error occurs. */intcgetnext(bp, db_array) register char **bp; char **db_array;{ size_t len; int status, i, done; char *cp, *line, *rp, *np, buf[BSIZE], nbuf[BSIZE]; u_int dummy; if (dbp == NULL) dbp = db_array; if (pfp == NULL && (pfp = fopen(*dbp, "r")) == NULL) { (void)cgetclose(); return (-1); } for(;;) { if (toprec && !gottoprec) { gottoprec = 1; line = toprec; } else { line = fgetln(pfp, &len); if (line == NULL && pfp) { (void)fclose(pfp); if (ferror(pfp)) { (void)cgetclose(); return (-1); } else { if (*++dbp == NULL) { (void)cgetclose(); return (0); } else if ((pfp = fopen(*dbp, "r")) == NULL) { (void)cgetclose(); return (-1); } else continue; } } else line[len - 1] = '\0'; if (len == 1) { slash = 0; continue; } if (isspace(*line) || *line == ':' || *line == '#' || slash) { if (line[len - 2] == '\\') slash = 1; else slash = 0; continue; } if (line[len - 2] == '\\') slash = 1; else slash = 0; } /* * Line points to a name line. */ i = 0; done = 0; np = nbuf; for (;;) { for (cp = line; *cp != '\0'; cp++) { if (*cp == ':') { *np++ = ':'; done = 1; break; } if (*cp == '\\') break; *np++ = *cp; } if (done) { *np = '\0'; break; } else { /* name field extends beyond the line */ line = fgetln(pfp, &len); if (line == NULL && pfp) { (void)fclose(pfp); if (ferror(pfp)) { (void)cgetclose(); return (-1); } } else line[len - 1] = '\0'; } } rp = buf; for(cp = nbuf; *cp != NULL; cp++) if (*cp == '|' || *cp == ':') break; else *rp++ = *cp; *rp = '\0'; /* * XXX * Last argument of getent here should be nbuf if we want true * sequential access in the case of duplicates. * With NULL, getent will return the first entry found * rather than the duplicate entry record. This is a * matter of semantics that should be resolved. */ status = getent(bp, &dummy, db_array, -1, buf, 0, NULL); if (status == -2 || status == -3) (void)cgetclose(); return (status + 1); } /* NOTREACHED */}/* * Cgetstr retrieves the value of the string capability cap from the * capability record pointed to by buf. A pointer to a decoded, NUL * terminated, malloc'd copy of the string is returned in the char * * pointed to by str. The length of the string not including the trailing * NUL is returned on success, -1 if the requested string capability * couldn't be found, -2 if a system error was encountered (storage * allocation failure). */intcgetstr(buf, cap, str) char *buf, *cap; char **str;{ register u_int m_room; register char *bp, *mp; int len; char *mem; /* * Find string capability cap */ bp = cgetcap(buf, cap, '='); if (bp == NULL) return (-1); /* * Conversion / storage allocation loop ... Allocate memory in * chunks SFRAG in size. */ if ((mem = malloc(SFRAG)) == NULL) { errno = ENOMEM; return (-2); /* couldn't even allocate the first fragment */ } m_room = SFRAG; mp = mem; while (*bp != ':' && *bp != '\0') { /* * Loop invariants: * There is always room for one more character in mem. * Mp always points just past last character in mem. * Bp always points at next character in buf. */ if (*bp == '^') { bp++; if (*bp == ':' || *bp == '\0') break; /* drop unfinished escape */ *mp++ = *bp++ & 037; } else if (*bp == '\\') { bp++; if (*bp == ':' || *bp == '\0') break; /* drop unfinished escape */ if ('0' <= *bp && *bp <= '7') { register int n, i; n = 0; i = 3; /* maximum of three octal digits */ do { n = n * 8 + (*bp++ - '0'); } while (--i && '0' <= *bp && *bp <= '7'); *mp++ = n; } else switch (*bp++) { case 'b': case 'B': *mp++ = '\b'; break; case 't': case 'T': *mp++ = '\t'; break; case 'n': case 'N': *mp++ = '\n'; break; case 'f': case 'F': *mp++ = '\f'; break; case 'r': case 'R': *mp++ = '\r'; break; case 'e': case 'E': *mp++ = ESC; break; case 'c': case 'C': *mp++ = ':'; break; default: /* * Catches '\', '^', and * everything else. */ *mp++ = *(bp-1); break; } } else *mp++ = *bp++; m_room--; /* * Enforce loop invariant: if no room left in current * buffer, try to get some more. */ if (m_room == 0) { size_t size = mp - mem; if ((mem = realloc(mem, size + SFRAG)) == NULL) return (-2); m_room = SFRAG; mp = mem + size; } } *mp++ = '\0'; /* loop invariant let's us do this */ m_room--; len = mp - mem - 1; /* * Give back any extra memory and return value and success. */ if (m_room != 0) if ((mem = realloc(mem, (size_t)(mp - mem))) == NULL) return (-2); *str = mem; return (len);}/* * Cgetustr retrieves the value of the string capability cap from the * capability record pointed to by buf. The difference between cgetustr() * and cgetstr() is that cgetustr does not decode escapes but rather treats * all characters literally. A pointer to a NUL terminated malloc'd * copy of the string is returned in the char pointed to by str. The * length of the string not including the trailing NUL is returned on success, * -1 if the requested string capability couldn't be found, -2 if a system * error was encountered (storage allocation failure). */intcgetustr(buf, cap, str) char *buf, *cap, **str;{ register u_int m_room; register char *bp, *mp; int len; char *mem; /* * Find string capability cap */ if ((bp = cgetcap(buf, cap, '=')) == NULL) return (-1); /* * Conversion / storage allocation loop ... Allocate memory in * chunks SFRAG in size. */ if ((mem = malloc(SFRAG)) == NULL) { errno = ENOMEM; return (-2); /* couldn't even allocate the first fragment */ } m_room = SFRAG; mp = mem; while (*bp != ':' && *bp != '\0') { /* * Loop invariants: * There is always room for one more character in mem. * Mp always points just past last character in mem. * Bp always points at next character in buf. */ *mp++ = *bp++; m_room--; /* * Enforce loop invariant: if no room left in current * buffer, try to get some more. */ if (m_room == 0) { size_t size = mp - mem; if ((mem = realloc(mem, size + SFRAG)) == NULL) return (-2); m_room = SFRAG; mp = mem + size; } } *mp++ = '\0'; /* loop invariant let's us do this */ m_room--; len = mp - mem - 1; /* * Give back any extra memory and return value and success. */ if (m_room != 0) if ((mem = realloc(mem, (size_t)(mp - mem))) == NULL) return (-2); *str = mem; return (len);}/* * Cgetnum retrieves the value of the numeric capability cap from the * capability record pointed to by buf. The numeric value is returned in * the long pointed to by num. 0 is returned on success, -1 if the requested * numeric capability couldn't be found. */intcgetnum(buf, cap, num) char *buf, *cap; long *num;{ register long n; register int base, digit; register char *bp; /* * Find numeric capability cap */ bp = cgetcap(buf, cap, '#'); if (bp == NULL) return (-1); /* * Look at value and determine numeric base: * 0x... or 0X... hexadecimal, * else 0... octal, * else decimal. */ if (*bp == '0') { bp++; if (*bp == 'x' || *bp == 'X') { bp++; base = 16; } else base = 8; } else base = 10; /* * Conversion loop ... */ n = 0; for (;;) { if ('0' <= *bp && *bp <= '9') digit = *bp - '0'; else if ('a' <= *bp && *bp <= 'f') digit = 10 + *bp - 'a'; else if ('A' <= *bp && *bp <= 'F') digit = 10 + *bp - 'A'; else break; if (digit >= base) break; n = n * base + digit; bp++; } /* * Return value and success. */ *num = n; return (0);}/* * Compare name field of record. */static intnfcmp(nf, rec) char *nf, *rec;{ char *cp, tmp; int ret; for (cp = rec; *cp != ':'; cp++) ; tmp = *(cp + 1); *(cp + 1) = '\0'; ret = strcmp(nf, rec); *(cp + 1) = tmp; return (ret);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -