version 1.39, 2003/10/27 00:12:42 |
version 1.51, 2012/03/13 21:13:35 |
Line 45 __RCSID("$NetBSD$"); |
|
Line 45 __RCSID("$NetBSD$"); |
|
#endif |
#endif |
#endif /* LIBC_SCCS and not lint */ |
#endif /* LIBC_SCCS and not lint */ |
|
|
|
#ifndef SMALL |
#include "namespace.h" |
#include "namespace.h" |
|
#endif |
#include <sys/types.h> |
#include <sys/types.h> |
#include <sys/param.h> |
#include <sys/param.h> |
|
|
#include <assert.h> |
#include <assert.h> |
|
#include <stddef.h> |
#include <ctype.h> |
#include <ctype.h> |
|
#ifndef SMALL |
#include <db.h> |
#include <db.h> |
|
#endif |
#include <errno.h> |
#include <errno.h> |
#include <fcntl.h> |
#include <fcntl.h> |
#include <limits.h> |
#include <limits.h> |
Line 60 __RCSID("$NetBSD$"); |
|
Line 65 __RCSID("$NetBSD$"); |
|
#include <string.h> |
#include <string.h> |
#include <unistd.h> |
#include <unistd.h> |
|
|
#ifdef __weak_alias |
#if defined(__weak_alias) && !defined(SMALL) |
__weak_alias(cgetcap,_cgetcap) |
__weak_alias(cgetcap,_cgetcap) |
__weak_alias(cgetclose,_cgetclose) |
__weak_alias(cgetclose,_cgetclose) |
__weak_alias(cgetent,_cgetent) |
__weak_alias(cgetent,_cgetent) |
Line 71 __weak_alias(cgetnum,_cgetnum) |
|
Line 76 __weak_alias(cgetnum,_cgetnum) |
|
__weak_alias(cgetset,_cgetset) |
__weak_alias(cgetset,_cgetset) |
__weak_alias(cgetstr,_cgetstr) |
__weak_alias(cgetstr,_cgetstr) |
__weak_alias(cgetustr,_cgetustr) |
__weak_alias(cgetustr,_cgetustr) |
|
__weak_alias(csetexpandtc,_csetexpandtc) |
#endif |
#endif |
|
|
#define BFRAG 1024 |
#define BFRAG 1024 |
Line 86 __weak_alias(cgetustr,_cgetustr) |
|
Line 92 __weak_alias(cgetustr,_cgetustr) |
|
static size_t topreclen; /* toprec length */ |
static size_t topreclen; /* toprec length */ |
static char *toprec; /* Additional record specified by cgetset() */ |
static char *toprec; /* Additional record specified by cgetset() */ |
static int gottoprec; /* Flag indicating retrieval of toprecord */ |
static int gottoprec; /* Flag indicating retrieval of toprecord */ |
|
static int expandtc = 1; /* flag to expand tc= or not */ |
|
|
static int cdbget __P((DB *, char **, const char *)); |
#ifndef SMALL |
static int getent __P((char **, size_t *, char **, int, const char *, int, char *)); |
static int cdbget(DB *, char **, const char *); |
static int nfcmp __P((char *, char *)); |
#endif |
|
static int getent(char **, size_t *, const char * const *, int, |
|
const char *, int, char *); |
|
static int nfcmp(char *, char *); |
|
|
/* |
/* |
* Cgetset() allows the addition of a user specified buffer to be added |
* Cgetset() allows the addition of a user specified buffer to be added |
Line 97 static int nfcmp __P((char *, char *)); |
|
Line 107 static int nfcmp __P((char *, char *)); |
|
* virtual database. 0 is returned on success, -1 on failure. |
* virtual database. 0 is returned on success, -1 on failure. |
*/ |
*/ |
int |
int |
cgetset(ent) |
cgetset(const char *ent) |
const char *ent; |
|
{ |
{ |
const char *source, *check; |
const char *source, *check; |
char *dest; |
char *dest; |
|
|
if (ent == NULL) { |
if (ent == NULL) { |
if (toprec) |
if (toprec != NULL) |
free(toprec); |
free(toprec); |
toprec = NULL; |
toprec = NULL; |
topreclen = 0; |
topreclen = 0; |
return (0); |
return 0; |
} |
} |
topreclen = strlen(ent); |
topreclen = strlen(ent); |
if ((toprec = malloc (topreclen + 1)) == NULL) { |
if ((toprec = malloc(topreclen + 1)) == NULL) { |
errno = ENOMEM; |
errno = ENOMEM; |
return (-1); |
return -1; |
} |
} |
gottoprec = 0; |
gottoprec = 0; |
|
|
source=ent; |
source = ent; |
dest=toprec; |
dest = toprec; |
while (*source) { /* Strip whitespace */ |
while (*source != '\0') { /* Strip whitespace */ |
*dest++ = *source++; /* Do not check first field */ |
*dest++ = *source++; /* Do not check first field */ |
while (*source == ':') { |
while (*source == ':') { |
check=source+1; |
check = source + 1; |
while (*check && (isspace((unsigned char)*check) || |
while (*check && (isspace((unsigned char)*check) || |
(*check=='\\' && isspace((unsigned char)check[1])))) |
(*check=='\\' && isspace((unsigned char)check[1])))) |
++check; |
++check; |
if( *check == ':' ) |
if (*check == ':') |
source=check; |
source = check; |
else |
else |
break; |
break; |
|
|
} |
} |
} |
} |
*dest=0; |
*dest = 0; |
|
|
return (0); |
return 0; |
} |
} |
|
|
/* |
/* |
Line 171 cgetcap(buf, cap, type) |
|
Line 180 cgetcap(buf, cap, type) |
|
*/ |
*/ |
for (;;) |
for (;;) |
if (*bp == '\0') |
if (*bp == '\0') |
return (NULL); |
return NULL; |
else |
else if (*bp++ == ':') |
if (*bp++ == ':') |
break; |
break; |
|
|
|
/* |
/* |
* Try to match (cap, type) in buf. |
* Try to match (cap, type) in buf. |
Line 184 cgetcap(buf, cap, type) |
|
Line 192 cgetcap(buf, cap, type) |
|
if (*cp != '\0') |
if (*cp != '\0') |
continue; |
continue; |
if (*bp == '@') |
if (*bp == '@') |
return (NULL); |
return NULL; |
if (type == ':') { |
if (type == ':') { |
if (*bp != '\0' && *bp != ':') |
if (*bp != '\0' && *bp != ':') |
continue; |
continue; |
return(bp); |
return bp; |
} |
} |
if (*bp != type) |
if (*bp != type) |
continue; |
continue; |
bp++; |
bp++; |
return (*bp == '@' ? NULL : bp); |
return *bp == '@' ? NULL : bp; |
} |
} |
/* NOTREACHED */ |
/* NOTREACHED */ |
} |
} |
Line 207 cgetcap(buf, cap, type) |
|
Line 215 cgetcap(buf, cap, type) |
|
* encountered (couldn't open/read a file, etc.), and -3 if a potential |
* encountered (couldn't open/read a file, etc.), and -3 if a potential |
* reference loop is detected. |
* reference loop is detected. |
*/ |
*/ |
|
/* coverity[+alloc : arg-*0] */ |
int |
int |
cgetent(buf, db_array, name) |
cgetent(char **buf, const char * const *db_array, const char *name) |
char **buf, **db_array; |
|
const char *name; |
|
{ |
{ |
size_t dummy; |
size_t dummy; |
|
|
Line 218 cgetent(buf, db_array, name) |
|
Line 225 cgetent(buf, db_array, name) |
|
_DIAGASSERT(db_array != NULL); |
_DIAGASSERT(db_array != NULL); |
_DIAGASSERT(name != NULL); |
_DIAGASSERT(name != NULL); |
|
|
return (getent(buf, &dummy, db_array, -1, name, 0, NULL)); |
return getent(buf, &dummy, db_array, -1, name, 0, NULL); |
|
} |
|
|
|
void |
|
csetexpandtc(int etc) |
|
{ |
|
expandtc = etc; |
} |
} |
|
|
/* |
/* |
Line 239 cgetent(buf, db_array, name) |
|
Line 252 cgetent(buf, db_array, name) |
|
* names interpolated, a name can't be found, or depth exceeds |
* names interpolated, a name can't be found, or depth exceeds |
* MAX_RECURSION. |
* MAX_RECURSION. |
*/ |
*/ |
|
/* coverity[+alloc : arg-*0] */ |
static int |
static int |
getent(cap, len, db_array, fd, name, depth, nfield) |
getent(char **cap, size_t *len, const char * const *db_array, int fd, |
char **cap, **db_array, *nfield; |
const char *name, int depth, char *nfield) |
const char *name; |
|
size_t *len; |
|
int fd, depth; |
|
{ |
{ |
|
#ifndef SMALL |
DB *capdbp; |
DB *capdbp; |
char *r_end, *rp = NULL, **db_p; /* pacify gcc */ |
char pbuf[MAXPATHLEN]; |
int myfd = 0, eof, foundit, retval; |
char *cbuf; |
|
int retval; |
size_t clen; |
size_t clen; |
char *record, *cbuf, *newrecord; |
#endif |
|
char *record, *newrecord; |
|
char *r_end, *rp; /* pacify gcc */ |
|
const char * const *db_p; |
|
int myfd, eof, foundit; |
int tc_not_resolved; |
int tc_not_resolved; |
char pbuf[MAXPATHLEN]; |
|
|
|
_DIAGASSERT(cap != NULL); |
_DIAGASSERT(cap != NULL); |
_DIAGASSERT(len != NULL); |
_DIAGASSERT(len != NULL); |
Line 261 getent(cap, len, db_array, fd, name, dep |
|
Line 277 getent(cap, len, db_array, fd, name, dep |
|
_DIAGASSERT(name != NULL); |
_DIAGASSERT(name != NULL); |
/* nfield may be NULL */ |
/* nfield may be NULL */ |
|
|
|
myfd = 0; |
|
rp = NULL; |
|
|
/* |
/* |
* Return with ``loop detected'' error if we've recursed more than |
* Return with ``loop detected'' error if we've recursed more than |
* MAX_RECURSION times. |
* MAX_RECURSION times. |
*/ |
*/ |
if (depth > MAX_RECURSION) |
if (depth > MAX_RECURSION) |
return (-3); |
return -3; |
|
|
/* |
/* |
* Check if we have a top record from cgetset(). |
* Check if we have a top record from cgetset(). |
*/ |
*/ |
if (depth == 0 && toprec != NULL && cgetmatch(toprec, name) == 0) { |
if (depth == 0 && toprec != NULL && cgetmatch(toprec, name) == 0) { |
if ((record = malloc (topreclen + BFRAG)) == NULL) { |
if ((record = malloc(topreclen + BFRAG)) == NULL) { |
errno = ENOMEM; |
errno = ENOMEM; |
return (-2); |
return -2; |
} |
} |
(void)strcpy(record, toprec); /* XXX: strcpy is safe */ |
(void)strcpy(record, toprec); /* XXX: strcpy is safe */ |
db_p = db_array; |
db_p = db_array; |
Line 287 getent(cap, len, db_array, fd, name, dep |
|
Line 306 getent(cap, len, db_array, fd, name, dep |
|
*/ |
*/ |
if ((record = malloc(BFRAG)) == NULL) { |
if ((record = malloc(BFRAG)) == NULL) { |
errno = ENOMEM; |
errno = ENOMEM; |
return (-2); |
return -2; |
} |
} |
r_end = record + BFRAG; |
r_end = record + BFRAG; |
foundit = 0; |
foundit = 0; |
Line 305 getent(cap, len, db_array, fd, name, dep |
|
Line 324 getent(cap, len, db_array, fd, name, dep |
|
if (fd >= 0) { |
if (fd >= 0) { |
(void)lseek(fd, (off_t)0, SEEK_SET); |
(void)lseek(fd, (off_t)0, SEEK_SET); |
} else { |
} else { |
|
#ifndef SMALL |
(void)snprintf(pbuf, sizeof(pbuf), "%s.db", *db_p); |
(void)snprintf(pbuf, sizeof(pbuf), "%s.db", *db_p); |
if ((capdbp = dbopen(pbuf, O_RDONLY, 0, DB_HASH, 0)) |
if (expandtc && |
|
(capdbp = dbopen(pbuf, O_RDONLY, 0, DB_HASH, 0)) |
!= NULL) { |
!= NULL) { |
free(record); |
free(record); |
retval = cdbget(capdbp, &record, name); |
retval = cdbget(capdbp, &record, name); |
if (retval < 0) { |
if (retval < 0) { |
/* no record available */ |
/* no record available */ |
(void)capdbp->close(capdbp); |
(void)capdbp->close(capdbp); |
return (retval); |
return retval; |
} |
} |
/* save the data; close frees it */ |
/* save the data; close frees it */ |
clen = strlen(record); |
clen = strlen(record); |
cbuf = malloc(clen + 1); |
if ((cbuf = malloc(clen + 1)) == NULL) { |
|
(void)capdbp->close(capdbp); |
|
errno = ENOMEM; |
|
return -2; |
|
} |
memmove(cbuf, record, clen + 1); |
memmove(cbuf, record, clen + 1); |
if (capdbp->close(capdbp) < 0) { |
if (capdbp->close(capdbp) < 0) { |
int serrno = errno; |
int serrno = errno; |
|
|
free(cbuf); |
free(cbuf); |
errno = serrno; |
errno = serrno; |
return (-2); |
return -2; |
} |
} |
*len = clen; |
*len = clen; |
*cap = cbuf; |
*cap = cbuf; |
return (retval); |
return retval; |
} else { |
} else |
|
#endif |
|
{ |
fd = open(*db_p, O_RDONLY, 0); |
fd = open(*db_p, O_RDONLY, 0); |
if (fd < 0) { |
if (fd < 0) { |
/* No error on unfound file. */ |
/* No error on unfound file. */ |
Line 357 getent(cap, len, db_array, fd, name, dep |
|
Line 384 getent(cap, len, db_array, fd, name, dep |
|
*/ |
*/ |
b_end = buf; |
b_end = buf; |
bp = buf; |
bp = buf; |
cp = 0; |
cp = NULL; |
slash = 0; |
slash = 0; |
for (;;) { |
for (;;) { |
|
|
/* |
/* |
* Read in a line implementing (\, newline) |
* Read in a line implementing (\, newline) |
* line continuation. |
* line continuation. |
Line 368 getent(cap, len, db_array, fd, name, dep |
|
Line 394 getent(cap, len, db_array, fd, name, dep |
|
rp = record; |
rp = record; |
for (;;) { |
for (;;) { |
if (bp >= b_end) { |
if (bp >= b_end) { |
int n; |
ssize_t n; |
|
|
n = read(fd, buf, sizeof(buf)); |
n = read(fd, buf, sizeof(buf)); |
if (n <= 0) { |
if (n <= 0) { |
Line 379 getent(cap, len, db_array, fd, name, dep |
|
Line 405 getent(cap, len, db_array, fd, name, dep |
|
|
|
free(record); |
free(record); |
errno = serrno; |
errno = serrno; |
return (-2); |
return -2; |
} else { |
} else { |
fd = -1; |
fd = -1; |
eof = 1; |
eof = 1; |
Line 410 getent(cap, len, db_array, fd, name, dep |
|
Line 436 getent(cap, len, db_array, fd, name, dep |
|
* to the colon (eliminating the |
* to the colon (eliminating the |
* field). |
* field). |
*/ |
*/ |
if (cp) |
if (cp != NULL) |
rp = cp; |
rp = cp; |
else |
else |
cp = rp; |
cp = rp; |
Line 431 getent(cap, len, db_array, fd, name, dep |
|
Line 457 getent(cap, len, db_array, fd, name, dep |
|
* some more. |
* some more. |
*/ |
*/ |
if (rp >= r_end) { |
if (rp >= r_end) { |
u_int pos; |
ptrdiff_t pos; |
size_t newsize; |
size_t newsize; |
|
|
pos = rp - record; |
pos = rp - record; |
Line 442 getent(cap, len, db_array, fd, name, dep |
|
Line 468 getent(cap, len, db_array, fd, name, dep |
|
if (myfd) |
if (myfd) |
(void)close(fd); |
(void)close(fd); |
errno = ENOMEM; |
errno = ENOMEM; |
return (-2); |
return -2; |
} |
} |
record = newrecord; |
record = newrecord; |
r_end = record + newsize; |
r_end = record + newsize; |
Line 470 getent(cap, len, db_array, fd, name, dep |
|
Line 496 getent(cap, len, db_array, fd, name, dep |
|
/* |
/* |
* See if this is the record we want ... |
* See if this is the record we want ... |
*/ |
*/ |
if (cgetmatch(record, name) == 0) { |
if (cgetmatch(record, name) == 0) |
if (nfield == NULL || !nfcmp(nfield, record)) { |
if (nfield == NULL || !nfcmp(nfield, record)) { |
foundit = 1; |
foundit = 1; |
break; /* found it! */ |
break; /* found it! */ |
} |
} |
} |
|
} |
} |
} |
} |
if (foundit) |
if (foundit) |
break; |
break; |
} |
} |
|
|
if (!foundit) |
if (!foundit) |
return (-1); |
return -1; |
|
|
/* |
/* |
* Got the capability record, but now we have to expand all tc=name |
* Got the capability record, but now we have to expand all tc=name |
* references in it ... |
* references in it ... |
*/ |
*/ |
tc_exp: { |
tc_exp: |
|
tc_not_resolved = 0; |
|
if (expandtc) { |
char *newicap, *s; |
char *newicap, *s; |
size_t ilen, newilen; |
size_t ilen, newilen; |
int diff, iret, tclen; |
int iret; |
|
ptrdiff_t diff, tclen; |
char *icap, *scan, *tc, *tcstart, *tcend; |
char *icap, *scan, *tc, *tcstart, *tcend; |
|
|
/* |
/* |
|
|
* scanned for tc=name constructs. |
* scanned for tc=name constructs. |
*/ |
*/ |
scan = record; |
scan = record; |
tc_not_resolved = 0; |
|
for (;;) { |
for (;;) { |
if ((tc = cgetcap(scan, "tc", '=')) == NULL) |
if ((tc = cgetcap(scan, "tc", '=')) == NULL) |
break; |
break; |
|
|
if (myfd) |
if (myfd) |
(void)close(fd); |
(void)close(fd); |
free(record); |
free(record); |
return (iret); |
return iret; |
} |
} |
if (iret == 1) |
if (iret == 1) |
tc_not_resolved = 1; |
tc_not_resolved = 1; |
|
|
for (;;) |
for (;;) |
if (*s == '\0') |
if (*s == '\0') |
break; |
break; |
else |
else if (*s++ == ':') |
if (*s++ == ':') |
break; |
break; |
|
newilen -= s - newicap; |
newilen -= s - newicap; |
newicap = s; |
newicap = s; |
|
|
/* make sure interpolated record is `:'-terminated */ |
/* make sure interpolated record is `:'-terminated */ |
s += newilen; |
s += newilen; |
if (*(s-1) != ':') { |
if (*(s - 1) != ':') { |
*s = ':'; /* overwrite NUL with : */ |
*s = ':'; /* overwrite NUL with : */ |
newilen++; |
newilen++; |
} |
} |
|
|
*/ |
*/ |
diff = newilen - tclen; |
diff = newilen - tclen; |
if (diff >= r_end - rp) { |
if (diff >= r_end - rp) { |
u_int pos, tcpos, tcposend; |
ptrdiff_t pos, tcpos, tcposend; |
size_t newsize; |
size_t newsize; |
|
|
pos = rp - record; |
pos = rp - record; |
|
|
(void)close(fd); |
(void)close(fd); |
free(icap); |
free(icap); |
errno = ENOMEM; |
errno = ENOMEM; |
return (-2); |
return -2; |
} |
} |
record = newrecord; |
record = newrecord; |
r_end = record + newsize; |
r_end = record + newsize; |
|
|
* Start scan on `:' so next cgetcap works properly |
* Start scan on `:' so next cgetcap works properly |
* (cgetcap always skips first field). |
* (cgetcap always skips first field). |
*/ |
*/ |
scan = s-1; |
scan = s - 1; |
} |
} |
|
|
} |
} |
|
|
realloc(record, (size_t)(rp - record))) == NULL) { |
realloc(record, (size_t)(rp - record))) == NULL) { |
free(record); |
free(record); |
errno = ENOMEM; |
errno = ENOMEM; |
return (-2); |
return -2; |
} |
} |
record = newrecord; |
record = newrecord; |
} |
} |
|
|
*cap = record; |
*cap = record; |
if (tc_not_resolved) |
if (tc_not_resolved) |
return (1); |
return 1; |
return (0); |
return 0; |
} |
} |
|
|
|
#ifndef SMALL |
static int |
static int |
cdbget(capdbp, bp, name) |
cdbget(DB *capdbp, char **bp, const char *name) |
DB *capdbp; |
|
char **bp; |
|
const char *name; |
|
{ |
{ |
DBT key; |
DBT key; |
DBT data; |
DBT data; |
Line 649 cdbget(capdbp, bp, name) |
|
Line 673 cdbget(capdbp, bp, name) |
|
_DIAGASSERT(bp != NULL); |
_DIAGASSERT(bp != NULL); |
_DIAGASSERT(name != NULL); |
_DIAGASSERT(name != NULL); |
|
|
/* LINTED key is not modified */ |
key.data = __UNCONST(name); |
key.data = (char *)name; |
|
key.size = strlen(name); |
key.size = strlen(name); |
|
|
for (;;) { |
for (;;) { |
/* Get the reference. */ |
/* Get the reference. */ |
switch(capdbp->get(capdbp, &key, &data, 0)) { |
switch(capdbp->get(capdbp, &key, &data, 0)) { |
case -1: |
case -1: |
return (-2); |
return -2; |
case 1: |
case 1: |
return (-1); |
return -1; |
} |
} |
|
|
/* If not an index to another record, leave. */ |
/* If not an index to another record, leave. */ |
Line 671 cdbget(capdbp, bp, name) |
|
Line 694 cdbget(capdbp, bp, name) |
|
} |
} |
|
|
*bp = (char *)data.data + 1; |
*bp = (char *)data.data + 1; |
return (((char *)(data.data))[0] == TCERR ? 1 : 0); |
return ((char *)(data.data))[0] == TCERR ? 1 : 0; |
} |
} |
|
#endif |
|
|
/* |
/* |
* Cgetmatch will return 0 if name is one of the names of the capability |
* Cgetmatch will return 0 if name is one of the names of the capability |
* record buf, -1 if not. |
* record buf, -1 if not. |
*/ |
*/ |
int |
int |
cgetmatch(buf, name) |
cgetmatch(const char *buf, const char *name) |
const char *buf, *name; |
|
{ |
{ |
const char *np, *bp; |
const char *np, *bp; |
|
|
Line 699 cgetmatch(buf, name) |
|
Line 722 cgetmatch(buf, name) |
|
for (;;) |
for (;;) |
if (*np == '\0') { |
if (*np == '\0') { |
if (*bp == '|' || *bp == ':' || *bp == '\0') |
if (*bp == '|' || *bp == ':' || *bp == '\0') |
return (0); |
return 0; |
else |
else |
break; |
break; |
} else |
} else if (*bp++ != *np++) |
if (*bp++ != *np++) |
break; |
break; |
|
|
|
/* |
/* |
* Match failed, skip to next name in record. |
* Match failed, skip to next name in record. |
Line 712 cgetmatch(buf, name) |
|
Line 734 cgetmatch(buf, name) |
|
if (bp > buf) |
if (bp > buf) |
bp--; /* a '|' or ':' may have stopped the match */ |
bp--; /* a '|' or ':' may have stopped the match */ |
else |
else |
return (-1); |
return -1; |
for (;;) |
for (;;) |
if (*bp == '\0' || *bp == ':') |
if (*bp == '\0' || *bp == ':') |
return (-1); /* match failed totally */ |
return -1; /* match failed totally */ |
else |
else if (*bp++ == '|') |
if (*bp++ == '|') |
break; /* found next name */ |
break; /* found next name */ |
|
} |
} |
} |
} |
|
|
int |
int |
cgetfirst(buf, db_array) |
cgetfirst(char **buf, const char * const *db_array) |
char **buf, **db_array; |
|
{ |
{ |
|
|
_DIAGASSERT(buf != NULL); |
_DIAGASSERT(buf != NULL); |
_DIAGASSERT(db_array != NULL); |
_DIAGASSERT(db_array != NULL); |
|
|
(void)cgetclose(); |
(void)cgetclose(); |
return (cgetnext(buf, db_array)); |
return cgetnext(buf, db_array); |
} |
} |
|
|
static FILE *pfp; |
static FILE *pfp; |
static int slash; |
static int slash; |
static char **dbp; |
static const char * const *dbp; |
|
|
int |
int |
cgetclose() |
cgetclose(void) |
{ |
{ |
if (pfp != NULL) { |
if (pfp != NULL) { |
(void)fclose(pfp); |
(void)fclose(pfp); |
|
|
dbp = NULL; |
dbp = NULL; |
gottoprec = 0; |
gottoprec = 0; |
slash = 0; |
slash = 0; |
return(0); |
return 0; |
} |
} |
|
|
/* |
/* |
|
|
* specified by db_array. It returns 0 upon completion of the database, 1 |
* 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. |
* upon returning an entry with more remaining, and -1 if an error occurs. |
*/ |
*/ |
|
/* coverity[+alloc : arg-*0] */ |
int |
int |
cgetnext(bp, db_array) |
cgetnext(char **bp, const char * const *db_array) |
char **bp; |
|
char **db_array; |
|
{ |
{ |
size_t len; |
size_t len = 0; |
int status, done; |
int status, done; |
char *cp, *line, *rp, *np, buf[BSIZE], nbuf[BSIZE]; |
char *cp, *line, *rp, *np, buf[BSIZE], nbuf[BSIZE]; |
size_t dummy; |
size_t dummy; |
Line 772 cgetnext(bp, db_array) |
|
Line 791 cgetnext(bp, db_array) |
|
if (dbp == NULL) |
if (dbp == NULL) |
dbp = db_array; |
dbp = db_array; |
|
|
if (pfp == NULL && (pfp = fopen(*dbp, "r")) == NULL) { |
if (pfp == NULL && (pfp = fopen(*dbp, "re")) == NULL) { |
(void)cgetclose(); |
(void)cgetclose(); |
return (-1); |
return -1; |
} |
} |
for(;;) { |
for (;;) { |
if (toprec && !gottoprec) { |
if (toprec != NULL && !gottoprec) { |
gottoprec = 1; |
gottoprec = 1; |
line = toprec; |
line = toprec; |
} else { |
} else { |
line = fgetln(pfp, &len); |
line = fgetln(pfp, &len); |
if (line == NULL && pfp) { |
if (line == NULL) { |
|
if (pfp == NULL) |
|
return -1; |
if (ferror(pfp)) { |
if (ferror(pfp)) { |
(void)cgetclose(); |
(void)cgetclose(); |
return (-1); |
return -1; |
} else { |
} else { |
(void)fclose(pfp); |
(void)fclose(pfp); |
pfp = NULL; |
pfp = NULL; |
if (*++dbp == NULL) { |
if (*++dbp == NULL) { |
(void)cgetclose(); |
(void)cgetclose(); |
return (0); |
return 0; |
} else if ((pfp = |
} else if ((pfp = |
fopen(*dbp, "r")) == NULL) { |
fopen(*dbp, "re")) == NULL) { |
(void)cgetclose(); |
(void)cgetclose(); |
return (-1); |
return -1; |
} else |
} else |
continue; |
continue; |
} |
} |
Line 846 cgetnext(bp, db_array) |
|
Line 867 cgetnext(bp, db_array) |
|
if (line == NULL && pfp) { |
if (line == NULL && pfp) { |
if (ferror(pfp)) { |
if (ferror(pfp)) { |
(void)cgetclose(); |
(void)cgetclose(); |
return (-1); |
return -1; |
} |
} |
(void)fclose(pfp); |
(void)fclose(pfp); |
pfp = NULL; |
pfp = NULL; |
Line 859 cgetnext(bp, db_array) |
|
Line 880 cgetnext(bp, db_array) |
|
if (len > sizeof(buf)) |
if (len > sizeof(buf)) |
return -1; |
return -1; |
rp = buf; |
rp = buf; |
for(cp = nbuf; *cp != '\0'; cp++) |
for (cp = nbuf; *cp != '\0'; cp++) |
if (*cp == '|' || *cp == ':') |
if (*cp == '|' || *cp == ':') |
break; |
break; |
else |
else |
Line 878 cgetnext(bp, db_array) |
|
Line 899 cgetnext(bp, db_array) |
|
if (status == -2 || status == -3) |
if (status == -2 || status == -3) |
(void)cgetclose(); |
(void)cgetclose(); |
|
|
return (status + 1); |
return status + 1; |
} |
} |
/* NOTREACHED */ |
/* NOTREACHED */ |
} |
} |
Line 893 cgetnext(bp, db_array) |
|
Line 914 cgetnext(bp, db_array) |
|
* allocation failure). |
* allocation failure). |
*/ |
*/ |
int |
int |
cgetstr(buf, cap, str) |
cgetstr(char *buf, const char *cap, char **str) |
char *buf; |
|
const char *cap; |
|
char **str; |
|
{ |
{ |
u_int m_room; |
u_int m_room; |
const char *bp; |
const char *bp; |
char *mp; |
char *mp; |
int len; |
ptrdiff_t len; |
char *mem, *newmem; |
char *mem, *newmem; |
|
|
_DIAGASSERT(buf != NULL); |
_DIAGASSERT(buf != NULL); |
Line 913 cgetstr(buf, cap, str) |
|
Line 931 cgetstr(buf, cap, str) |
|
*/ |
*/ |
bp = cgetcap(buf, cap, '='); |
bp = cgetcap(buf, cap, '='); |
if (bp == NULL) |
if (bp == NULL) |
return (-1); |
return -1; |
|
|
/* |
/* |
* Conversion / storage allocation loop ... Allocate memory in |
* Conversion / storage allocation loop ... Allocate memory in |
Line 921 cgetstr(buf, cap, str) |
|
Line 939 cgetstr(buf, cap, str) |
|
*/ |
*/ |
if ((mem = malloc(SFRAG)) == NULL) { |
if ((mem = malloc(SFRAG)) == NULL) { |
errno = ENOMEM; |
errno = ENOMEM; |
return (-2); /* couldn't even allocate the first fragment */ |
return -2; /* couldn't even allocate the first fragment */ |
} |
} |
m_room = SFRAG; |
m_room = SFRAG; |
mp = mem; |
mp = mem; |
Line 995 cgetstr(buf, cap, str) |
|
Line 1013 cgetstr(buf, cap, str) |
|
|
|
if ((newmem = realloc(mem, size + SFRAG)) == NULL) { |
if ((newmem = realloc(mem, size + SFRAG)) == NULL) { |
free(mem); |
free(mem); |
return (-2); |
return -2; |
} |
} |
mem = newmem; |
mem = newmem; |
m_room = SFRAG; |
m_room = SFRAG; |
Line 1012 cgetstr(buf, cap, str) |
|
Line 1030 cgetstr(buf, cap, str) |
|
if (m_room != 0) { |
if (m_room != 0) { |
if ((newmem = realloc(mem, (size_t)(mp - mem))) == NULL) { |
if ((newmem = realloc(mem, (size_t)(mp - mem))) == NULL) { |
free(mem); |
free(mem); |
return (-2); |
return -2; |
} |
} |
mem = newmem; |
mem = newmem; |
} |
} |
*str = mem; |
*str = mem; |
return (len); |
_DIAGASSERT(__type_fit(int, len)); |
|
return (int)len; |
} |
} |
|
|
/* |
/* |
Line 1031 cgetstr(buf, cap, str) |
|
Line 1050 cgetstr(buf, cap, str) |
|
* error was encountered (storage allocation failure). |
* error was encountered (storage allocation failure). |
*/ |
*/ |
int |
int |
cgetustr(buf, cap, str) |
cgetustr(char *buf, const char *cap, char **str) |
char *buf; |
|
const char *cap; |
|
char **str; |
|
{ |
{ |
u_int m_room; |
u_int m_room; |
const char *bp; |
const char *bp; |
char *mp; |
char *mp; |
int len; |
size_t len; |
char *mem, *newmem; |
char *mem, *newmem; |
|
|
_DIAGASSERT(buf != NULL); |
_DIAGASSERT(buf != NULL); |
Line 1050 cgetustr(buf, cap, str) |
|
Line 1066 cgetustr(buf, cap, str) |
|
* Find string capability cap |
* Find string capability cap |
*/ |
*/ |
if ((bp = cgetcap(buf, cap, '=')) == NULL) |
if ((bp = cgetcap(buf, cap, '=')) == NULL) |
return (-1); |
return -1; |
|
|
/* |
/* |
* Conversion / storage allocation loop ... Allocate memory in |
* Conversion / storage allocation loop ... Allocate memory in |
Line 1058 cgetustr(buf, cap, str) |
|
Line 1074 cgetustr(buf, cap, str) |
|
*/ |
*/ |
if ((mem = malloc(SFRAG)) == NULL) { |
if ((mem = malloc(SFRAG)) == NULL) { |
errno = ENOMEM; |
errno = ENOMEM; |
return (-2); /* couldn't even allocate the first fragment */ |
return -2; /* couldn't even allocate the first fragment */ |
} |
} |
m_room = SFRAG; |
m_room = SFRAG; |
mp = mem; |
mp = mem; |
Line 1082 cgetustr(buf, cap, str) |
|
Line 1098 cgetustr(buf, cap, str) |
|
|
|
if ((newmem = realloc(mem, size + SFRAG)) == NULL) { |
if ((newmem = realloc(mem, size + SFRAG)) == NULL) { |
free(mem); |
free(mem); |
return (-2); |
return -2; |
} |
} |
mem = newmem; |
mem = newmem; |
m_room = SFRAG; |
m_room = SFRAG; |
Line 1099 cgetustr(buf, cap, str) |
|
Line 1115 cgetustr(buf, cap, str) |
|
if (m_room != 0) { |
if (m_room != 0) { |
if ((newmem = realloc(mem, (size_t)(mp - mem))) == NULL) { |
if ((newmem = realloc(mem, (size_t)(mp - mem))) == NULL) { |
free(mem); |
free(mem); |
return (-2); |
return -2; |
} |
} |
mem = newmem; |
mem = newmem; |
} |
} |
*str = mem; |
*str = mem; |
return (len); |
_DIAGASSERT(__type_fit(int, len)); |
|
return (int)len; |
} |
} |
|
|
/* |
/* |
Line 1114 cgetustr(buf, cap, str) |
|
Line 1131 cgetustr(buf, cap, str) |
|
* numeric capability couldn't be found. |
* numeric capability couldn't be found. |
*/ |
*/ |
int |
int |
cgetnum(buf, cap, num) |
cgetnum(char *buf, const char *cap, long *num) |
char *buf; |
|
const char *cap; |
|
long *num; |
|
{ |
{ |
long n; |
long n; |
int base, digit; |
int base, digit; |
Line 1132 cgetnum(buf, cap, num) |
|
Line 1146 cgetnum(buf, cap, num) |
|
*/ |
*/ |
bp = cgetcap(buf, cap, '#'); |
bp = cgetcap(buf, cap, '#'); |
if (bp == NULL) |
if (bp == NULL) |
return (-1); |
return -1; |
|
|
/* |
/* |
* Look at value and determine numeric base: |
* Look at value and determine numeric base: |
Line 1175 cgetnum(buf, cap, num) |
|
Line 1189 cgetnum(buf, cap, num) |
|
* Return value and success. |
* Return value and success. |
*/ |
*/ |
*num = n; |
*num = n; |
return (0); |
return 0; |
} |
} |
|
|
|
|
Line 1183 cgetnum(buf, cap, num) |
|
Line 1197 cgetnum(buf, cap, num) |
|
* Compare name field of record. |
* Compare name field of record. |
*/ |
*/ |
static int |
static int |
nfcmp(nf, rec) |
nfcmp(char *nf, char *rec) |
char *nf, *rec; |
|
{ |
{ |
char *cp, tmp; |
char *cp, tmp; |
int ret; |
int ret; |
|
|
_DIAGASSERT(rec != NULL); |
_DIAGASSERT(rec != NULL); |
|
|
for (cp = rec; *cp != ':'; cp++) |
for (cp = rec; *cp != ':'; cp++) |
; |
continue; |
|
|
tmp = *(cp + 1); |
tmp = *(cp + 1); |
*(cp + 1) = '\0'; |
*(cp + 1) = '\0'; |
ret = strcmp(nf, rec); |
ret = strcmp(nf, rec); |
*(cp + 1) = tmp; |
*(cp + 1) = tmp; |
|
|
return (ret); |
return ret; |
} |
} |