fixdep.c: avoit doing memcmp in most cases

uidgid_get.c: add forgotten copyright notice
pwd/grp/shadow: avoid collisions with libc names
This commit is contained in:
Denis Vlasenko 2006-12-30 21:11:57 +00:00
parent 80602a98bc
commit cb04ff5c68
7 changed files with 191 additions and 108 deletions

View File

@ -21,50 +21,71 @@
* POSIX Standard: 9.2.1 Group Database Access <grp.h>
*/
#if !ENABLE_USE_BB_PWD_GRP
#if !defined CONFIG_USE_BB_PWD_GRP
#include <grp.h>
#else
#ifndef _GRP_H
#define _GRP_H 1
#include <sys/types.h>
#include <features.h>
#include <stdio.h>
#define _GRP_H 1
/* The group structure. */
struct group
{
char *gr_name; /* Group name. */
char *gr_passwd; /* Password. */
gid_t gr_gid; /* Group ID. */
char **gr_mem; /* Member list. */
struct group {
char *gr_name; /* Group name. */
char *gr_passwd; /* Password. */
gid_t gr_gid; /* Group ID. */
char **gr_mem; /* Member list. */
};
/* We don't reimplement this, just supplying prototype */
/* The function itself is in libc */
/* Set the group set for the current user to GROUPS (N of them). */
extern int setgroups(size_t __n, __const gid_t *__groups);
#define setgrent bb_internal_setgrent
#define endgrent bb_internal_endgrent
#define getgrent bb_internal_getgrent
#define fgetgrent bb_internal_fgetgrent
#define putgrent bb_internal_putgrent
#define getgrgid bb_internal_getgrgid
#define getgrnam bb_internal_getgrnam
#define getgrent_r bb_internal_getgrent_r
#define getgrgid_r bb_internal_getgrgid_r
#define getgrnam_r bb_internal_getgrnam_r
#define fgetgrent_r bb_internal_fgetgrent_r
#define getgrouplist bb_internal_getgrouplist
#define initgroups bb_internal_initgroups
/* All function names below should be remapped by #defines above
* in order to not collide with libc names.
* In theory it isn't necessary, but I saw weird interactions at link time.
* Let's play safe */
/* Rewind the group-file stream. */
extern void setgrent (void);
extern void setgrent(void);
/* Close the group-file stream. */
extern void endgrent (void);
extern void endgrent(void);
/* Read an entry from the group-file stream, opening it if necessary. */
extern struct group *getgrent (void);
extern struct group *getgrent(void);
/* Read a group entry from STREAM. */
extern struct group *fgetgrent (FILE *__stream);
extern struct group *fgetgrent(FILE *__stream);
/* Write the given entry onto the given stream. */
extern int putgrent (__const struct group *__restrict __p,
extern int putgrent(__const struct group *__restrict __p,
FILE *__restrict __f);
/* Search for an entry with a matching group ID. */
extern struct group *getgrgid (gid_t __gid);
extern struct group *getgrgid(gid_t __gid);
/* Search for an entry with a matching group name. */
extern struct group *getgrnam (__const char *__name);
extern struct group *getgrnam(__const char *__name);
/* Reentrant versions of some of the functions above.
@ -74,41 +95,38 @@ extern struct group *getgrnam (__const char *__name);
other reentrant functions so the chances are good this is what the
POSIX people would choose. */
extern int getgrent_r (struct group *__restrict __resultbuf,
extern int getgrent_r(struct group *__restrict __resultbuf,
char *__restrict __buffer, size_t __buflen,
struct group **__restrict __result);
/* Search for an entry with a matching group ID. */
extern int getgrgid_r (gid_t __gid, struct group *__restrict __resultbuf,
extern int getgrgid_r(gid_t __gid, struct group *__restrict __resultbuf,
char *__restrict __buffer, size_t __buflen,
struct group **__restrict __result);
/* Search for an entry with a matching group name. */
extern int getgrnam_r (__const char *__restrict __name,
extern int getgrnam_r(__const char *__restrict __name,
struct group *__restrict __resultbuf,
char *__restrict __buffer, size_t __buflen,
struct group **__restrict __result);
/* Read a group entry from STREAM. This function is not standardized
an probably never will. */
extern int fgetgrent_r (FILE *__restrict __stream,
extern int fgetgrent_r(FILE *__restrict __stream,
struct group *__restrict __resultbuf,
char *__restrict __buffer, size_t __buflen,
struct group **__restrict __result);
/* Set the group set for the current user to GROUPS (N of them). */
extern int setgroups (size_t __n, __const gid_t *__groups);
/* Store at most *NGROUPS members of the group set for USER into
*GROUPS. Also include GROUP. The actual number of groups found is
returned in *NGROUPS. Return -1 if the if *NGROUPS is too small. */
extern int getgrouplist (__const char *__user, gid_t __group,
extern int getgrouplist(__const char *__user, gid_t __group,
gid_t *__groups, int *__ngroups);
/* Initialize the group set for the current user
by reading the group database and using all groups
of which USER is a member. Also include GROUP. */
extern int initgroups (__const char *__user, gid_t __group);
extern int initgroups(__const char *__user, gid_t __group);
#endif /* grp.h */

View File

@ -21,52 +21,68 @@
* POSIX Standard: 9.2.2 User Database Access <pwd.h>
*/
#if !defined CONFIG_USE_BB_PWD_GRP
#if !ENABLE_USE_BB_PWD_GRP
#include <pwd.h>
#else
#ifndef _PWD_H
#define _PWD_H 1
#include <sys/types.h>
#include <features.h>
#include <stdio.h>
#define _PWD_H 1
/* The passwd structure. */
struct passwd
{
char *pw_name; /* Username. */
char *pw_passwd; /* Password. */
uid_t pw_uid; /* User ID. */
gid_t pw_gid; /* Group ID. */
char *pw_gecos; /* Real name. */
char *pw_dir; /* Home directory. */
char *pw_shell; /* Shell program. */
struct passwd {
char *pw_name; /* Username. */
char *pw_passwd; /* Password. */
uid_t pw_uid; /* User ID. */
gid_t pw_gid; /* Group ID. */
char *pw_gecos; /* Real name. */
char *pw_dir; /* Home directory. */
char *pw_shell; /* Shell program. */
};
#define setpwent bb_internal_setpwent
#define endpwent bb_internal_endpwent
#define getpwent bb_internal_getpwent
#define fgetpwent bb_internal_fgetpwent
#define putpwent bb_internal_putpwent
#define getpwuid bb_internal_getpwuid
#define getpwnam bb_internal_getpwnam
#define getpwent_r bb_internal_getpwent_r
#define getpwuid_r bb_internal_getpwuid_r
#define getpwnam_r bb_internal_getpwnam_r
#define fgetpwent_r bb_internal_fgetpwent_r
#define getpw bb_internal_getpw
/* All function names below should be remapped by #defines above
* in order to not collide with libc names.
* In theory it isn't necessary, but I saw weird interactions at link time.
* Let's play safe */
/* Rewind the password-file stream. */
extern void setpwent (void);
extern void setpwent(void);
/* Close the password-file stream. */
extern void endpwent (void);
extern void endpwent(void);
/* Read an entry from the password-file stream, opening it if necessary. */
extern struct passwd *getpwent (void);
extern struct passwd *getpwent(void);
/* Read an entry from STREAM. */
extern struct passwd *fgetpwent (FILE *__stream);
extern struct passwd *fgetpwent(FILE *__stream);
/* Write the given entry onto the given stream. */
extern int putpwent (__const struct passwd *__restrict __p,
extern int putpwent(__const struct passwd *__restrict __p,
FILE *__restrict __f);
/* Search for an entry with a matching user ID. */
extern struct passwd *getpwuid (uid_t __uid);
extern struct passwd *getpwuid(uid_t __uid);
/* Search for an entry with a matching username. */
extern struct passwd *getpwnam (__const char *__name);
extern struct passwd *getpwnam(__const char *__name);
/* Reentrant versions of some of the functions above.
@ -76,24 +92,23 @@ extern struct passwd *getpwnam (__const char *__name);
other reentrant functions so the chances are good this is what the
POSIX people would choose. */
extern int getpwent_r (struct passwd *__restrict __resultbuf,
extern int getpwent_r(struct passwd *__restrict __resultbuf,
char *__restrict __buffer, size_t __buflen,
struct passwd **__restrict __result);
extern int getpwuid_r (uid_t __uid,
extern int getpwuid_r(uid_t __uid,
struct passwd *__restrict __resultbuf,
char *__restrict __buffer, size_t __buflen,
struct passwd **__restrict __result);
extern int getpwnam_r (__const char *__restrict __name,
extern int getpwnam_r(__const char *__restrict __name,
struct passwd *__restrict __resultbuf,
char *__restrict __buffer, size_t __buflen,
struct passwd **__restrict __result);
/* Read an entry from STREAM. This function is not standardized and
probably never will. */
extern int fgetpwent_r (FILE *__restrict __stream,
extern int fgetpwent_r(FILE *__restrict __stream,
struct passwd *__restrict __resultbuf,
char *__restrict __buffer, size_t __buflen,
struct passwd **__restrict __result);
@ -101,7 +116,7 @@ extern int fgetpwent_r (FILE *__restrict __stream,
/* Re-construct the password-file line for the given uid
in the given buffer. This knows the format that the caller
will expect, but this need not be the format of the password file. */
extern int getpw (uid_t __uid, char *__buffer);
extern int getpw(uid_t __uid, char *__buffer);
#endif /* pwd.h */
#endif

View File

@ -20,11 +20,13 @@
/* Declaration of types and functions for shadow password suite */
#if !ENABLE_USE_BB_SHADOW
#include <shadow.h>
#else
#ifndef _SHADOW_H
#define _SHADOW_H 1
#define _SHADOW_H 1
/* Paths to the user database files */
#ifndef _PATH_SHADOW
@ -44,6 +46,28 @@ struct spwd {
unsigned long int sp_flag; /* Reserved */
};
#define setspent bb_internal_setspent
#define endspent bb_internal_endspent
#define getspent bb_internal_getspent
#define getspnam bb_internal_getspnam
#define sgetspent bb_internal_sgetspent
#define fgetspent bb_internal_fgetspent
#define putspent bb_internal_putspent
#define getspent_r bb_internal_getspent_r
#define getspnam_r bb_internal_getspnam_r
#define sgetspent_r bb_internal_sgetspent_r
#define fgetspent_r bb_internal_fgetspent_r
#define lckpwdf bb_internal_lckpwdf
#define ulckpwdf bb_internal_ulckpwdf
/* All function names below should be remapped by #defines above
* in order to not collide with libc names.
* In theory it isn't necessary, but I saw weird interactions at link time.
* Let's play safe */
/* Open database for reading */
extern void setspent(void);

View File

@ -43,13 +43,13 @@
/**********************************************************************/
/* Prototypes for internal functions. */
static int __pgsreader(int (*parserfunc)(void *d, char *line), void *data,
static int bb__pgsreader(int (*parserfunc)(void *d, char *line), void *data,
char *__restrict line_buff, size_t buflen, FILE *f);
static int __parsepwent(void *pw, char *line);
static int __parsegrent(void *gr, char *line);
static int bb__parsepwent(void *pw, char *line);
static int bb__parsegrent(void *gr, char *line);
#if ENABLE_USE_BB_SHADOW
static int __parsespent(void *sp, char *line);
static int bb__parsespent(void *sp, char *line);
#endif
/**********************************************************************/
@ -58,7 +58,7 @@ static int __parsespent(void *sp, char *line);
* 0: success
* ENOENT: end-of-file encountered
* ERANGE: buflen too small
* other error values possible. See __pgsreader.
* other error values possible. See bb__pgsreader.
*
* Also, *result == resultbuf on success and NULL on failure.
*
@ -76,7 +76,7 @@ int fgetpwent_r(FILE *__restrict stream, struct passwd *__restrict resultbuf,
*result = NULL;
rv = __pgsreader(__parsepwent, resultbuf, buffer, buflen, stream);
rv = bb__pgsreader(bb__parsepwent, resultbuf, buffer, buflen, stream);
if (!rv) {
*result = resultbuf;
}
@ -92,7 +92,7 @@ int fgetgrent_r(FILE *__restrict stream, struct group *__restrict resultbuf,
*result = NULL;
rv = __pgsreader(__parsegrent, resultbuf, buffer, buflen, stream);
rv = bb__pgsreader(bb__parsegrent, resultbuf, buffer, buflen, stream);
if (!rv) {
*result = resultbuf;
}
@ -109,7 +109,7 @@ int fgetspent_r(FILE *__restrict stream, struct spwd *__restrict resultbuf,
*result = NULL;
rv = __pgsreader(__parsespent, resultbuf, buffer, buflen, stream);
rv = bb__pgsreader(bb__parsespent, resultbuf, buffer, buflen, stream);
if (!rv) {
*result = resultbuf;
}
@ -175,7 +175,7 @@ int sgetspent_r(const char *string, struct spwd *result_buf,
strcpy(buffer, string);
}
rv = __parsespent(result_buf, buffer);
rv = bb__parsespent(result_buf, buffer);
if (!rv) {
*result = result_buf;
}
@ -187,50 +187,46 @@ int sgetspent_r(const char *string, struct spwd *result_buf,
/**********************************************************************/
#ifdef GETXXKEY_R_FUNC
#error GETXXKEY_R_FUNC is already defined!
#endif
#define GETXXKEY_R_FUNC getpwnam_R
#define GETXXKEY_R_PARSER __parsepwent
#define GETXXKEY_R_FUNC getpwnam_r
#define GETXXKEY_R_PARSER bb__parsepwent
#define GETXXKEY_R_ENTTYPE struct passwd
#define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->pw_name, key))
#define DO_GETXXKEY_R_KEYTYPE const char *__restrict
#define DO_GETXXKEY_R_PATHNAME _PATH_PASSWD
#define GETXXKEY_R_KEYTYPE const char *__restrict
#define GETXXKEY_R_PATHNAME _PATH_PASSWD
#include "pwd_grp_internal.c"
#define GETXXKEY_R_FUNC getgrnam_R
#define GETXXKEY_R_PARSER __parsegrent
#define GETXXKEY_R_FUNC getgrnam_r
#define GETXXKEY_R_PARSER bb__parsegrent
#define GETXXKEY_R_ENTTYPE struct group
#define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->gr_name, key))
#define DO_GETXXKEY_R_KEYTYPE const char *__restrict
#define DO_GETXXKEY_R_PATHNAME _PATH_GROUP
#define GETXXKEY_R_KEYTYPE const char *__restrict
#define GETXXKEY_R_PATHNAME _PATH_GROUP
#include "pwd_grp_internal.c"
#if ENABLE_USE_BB_SHADOW
#define GETXXKEY_R_FUNC getspnam_R
#define GETXXKEY_R_PARSER __parsespent
#define GETXXKEY_R_FUNC getspnam_r
#define GETXXKEY_R_PARSER bb__parsespent
#define GETXXKEY_R_ENTTYPE struct spwd
#define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->sp_namp, key))
#define DO_GETXXKEY_R_KEYTYPE const char *__restrict
#define DO_GETXXKEY_R_PATHNAME _PATH_SHADOW
#define GETXXKEY_R_KEYTYPE const char *__restrict
#define GETXXKEY_R_PATHNAME _PATH_SHADOW
#include "pwd_grp_internal.c"
#endif
#define GETXXKEY_R_FUNC getpwuid_R
#define GETXXKEY_R_PARSER __parsepwent
#define GETXXKEY_R_FUNC getpwuid_r
#define GETXXKEY_R_PARSER bb__parsepwent
#define GETXXKEY_R_ENTTYPE struct passwd
#define GETXXKEY_R_TEST(ENT) ((ENT)->pw_uid == key)
#define DO_GETXXKEY_R_KEYTYPE uid_t
#define DO_GETXXKEY_R_PATHNAME _PATH_PASSWD
#define GETXXKEY_R_KEYTYPE uid_t
#define GETXXKEY_R_PATHNAME _PATH_PASSWD
#include "pwd_grp_internal.c"
#define GETXXKEY_R_FUNC getgrgid_R
#define GETXXKEY_R_PARSER __parsegrent
#define GETXXKEY_R_FUNC getgrgid_r
#define GETXXKEY_R_PARSER bb__parsegrent
#define GETXXKEY_R_ENTTYPE struct group
#define GETXXKEY_R_TEST(ENT) ((ENT)->gr_gid == key)
#define DO_GETXXKEY_R_KEYTYPE gid_t
#define DO_GETXXKEY_R_PATHNAME _PATH_GROUP
#define GETXXKEY_R_KEYTYPE gid_t
#define GETXXKEY_R_PATHNAME _PATH_GROUP
#include "pwd_grp_internal.c"
/**********************************************************************/
@ -347,6 +343,8 @@ int getpw(uid_t uid, char *buf)
/**********************************************************************/
/* FIXME: we don't have such CONFIG_xx - ?! */
#if defined CONFIG_USE_BB_THREADSAFE_SHADOW && defined PTHREAD_MUTEX_INITIALIZER
static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
# define LOCK pthread_mutex_lock(&mylock)
@ -394,7 +392,7 @@ int getpwent_r(struct passwd *__restrict resultbuf,
}
}
rv = __pgsreader(__parsepwent, resultbuf, buffer, buflen, pwf);
rv = bb__pgsreader(bb__parsepwent, resultbuf, buffer, buflen, pwf);
if (!rv) {
*result = resultbuf;
}
@ -441,7 +439,7 @@ int getgrent_r(struct group *__restrict resultbuf,
}
}
rv = __pgsreader(__parsegrent, resultbuf, buffer, buflen, grf);
rv = bb__pgsreader(bb__parsegrent, resultbuf, buffer, buflen, grf);
if (!rv) {
*result = resultbuf;
}
@ -488,7 +486,7 @@ int getspent_r(struct spwd *resultbuf, char *buffer,
}
}
rv = __pgsreader(__parsespent, resultbuf, buffer, buflen, spf);
rv = bb__pgsreader(bb__parsespent, resultbuf, buffer, buflen, spf);
if (!rv) {
*result = resultbuf;
}
@ -560,7 +558,7 @@ int initgroups(const char *user, gid_t gid)
*group_list = gid;
num_groups = 1;
while (!__pgsreader(__parsegrent, &group, buff, sizeof(buff), grfile)) {
while (!bb__pgsreader(bb__parsegrent, &group, buff, sizeof(buff), grfile)) {
assert(group.gr_mem); /* Must have at least a NULL terminator. */
if (group.gr_gid != gid) {
for (m=group.gr_mem ; *m ; m++) {
@ -705,7 +703,7 @@ DO_UNLOCK:
#endif
/**********************************************************************/
/* Internal uClibc functions. */
/* Internal uClibc functions. */
/**********************************************************************/
static const unsigned char pw_off[] = {
@ -718,7 +716,7 @@ static const unsigned char pw_off[] = {
offsetof(struct passwd, pw_shell) /* 6 */
};
static int __parsepwent(void *data, char *line)
static int bb__parsepwent(void *data, char *line)
{
char *endptr;
char *p;
@ -772,7 +770,7 @@ static const unsigned char gr_off[] = {
offsetof(struct group, gr_gid) /* 2 - not a char ptr */
};
static int __parsegrent(void *data, char *line)
static int bb__parsegrent(void *data, char *line)
{
char *endptr;
char *p;
@ -862,6 +860,7 @@ static int __parsegrent(void *data, char *line)
}
/**********************************************************************/
#if ENABLE_USE_BB_SHADOW
static const unsigned char sp_off[] = {
offsetof(struct spwd, sp_namp), /* 0 */
@ -875,7 +874,7 @@ static const unsigned char sp_off[] = {
offsetof(struct spwd, sp_flag) /* 8 - not a char ptr */
};
static int __parsespent(void *data, char * line)
static int bb__parsespent(void *data, char * line)
{
char *endptr;
char *p;
@ -928,7 +927,7 @@ static int __parsespent(void *data, char * line)
* Returns 0 on success and ENOENT for end-of-file (glibc concession).
*/
static int __pgsreader(int (*parserfunc)(void *d, char *line), void *data,
static int bb__pgsreader(int (*parserfunc)(void *d, char *line), void *data,
char *__restrict line_buff, size_t buflen, FILE *f)
{
int line_len;
@ -966,7 +965,7 @@ static int __pgsreader(int (*parserfunc)(void *d, char *line), void *data,
/* Skip empty lines, comment lines, and lines with leading
* whitespace. */
if (*line_buff && (*line_buff != '#') && !isspace(*line_buff)) {
if (parserfunc == __parsegrent) { /* Do evil group hack. */
if (parserfunc == bb__parsegrent) { /* Do evil group hack. */
/* The group entry parsing function needs to know where
* the end of the buffer is so that it can construct the
* group member ptr table. */

View File

@ -22,7 +22,7 @@
#error GETXXKEY_R_FUNC is not defined!
#endif
int GETXXKEY_R_FUNC(DO_GETXXKEY_R_KEYTYPE key,
int GETXXKEY_R_FUNC(GETXXKEY_R_KEYTYPE key,
GETXXKEY_R_ENTTYPE *__restrict resultbuf,
char *__restrict buffer, size_t buflen,
GETXXKEY_R_ENTTYPE **__restrict result)
@ -32,11 +32,11 @@ int GETXXKEY_R_FUNC(DO_GETXXKEY_R_KEYTYPE key,
*result = NULL;
stream = fopen(DO_GETXXKEY_R_PATHNAME, "r");
stream = fopen(GETXXKEY_R_PATHNAME, "r");
if (!stream)
return errno;
while (1) {
rv = __pgsreader(GETXXKEY_R_PARSER, resultbuf, buffer, buflen, stream);
rv = bb__pgsreader(GETXXKEY_R_PARSER, resultbuf, buffer, buflen, stream);
if (!rv) {
if (GETXXKEY_R_TEST(resultbuf)) { /* Found key? */
*result = resultbuf;
@ -58,5 +58,5 @@ int GETXXKEY_R_FUNC(DO_GETXXKEY_R_KEYTYPE key,
#undef GETXXKEY_R_PARSER
#undef GETXXKEY_R_ENTTYPE
#undef GETXXKEY_R_TEST
#undef DO_GETXXKEY_R_KEYTYPE
#undef DO_GETXXKEY_R_PATHNAME
#undef GETXXKEY_R_KEYTYPE
#undef GETXXKEY_R_PATHNAME

View File

@ -1,3 +1,30 @@
/*
Copyright (c) 2001-2006, Gerrit Pape
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "busybox.h"
int get_uidgid(struct bb_uidgid_t *u, const char *ug, int numeric_ok)

View File

@ -239,11 +239,11 @@ void parse_config_file(char *map, size_t len)
/* We have at least 5 chars: for() has
* "p < end-4", not "p <= end-4"
* therefore we don't need to check p <= end-5 here */
if (p[4] == '_') {
if (p[4] == '_')
if (!memcmp(p, "SKIP", 4)) goto conf5;
}
/* Ehhh, gcc is too stupid to just compare it as 32bit int */
if (!memcmp(p, "USE_", 4)) goto conf4;
if (p[0] == 'U')
if (!memcmp(p, "USE_", 4)) goto conf4;
continue;
conf4: off = 4;