1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-14 19:24:43 +03:00
samba-mirror/ctdb/lib/popt/poptconfig.c
Martin Schwenke 85a4024651 Clean up warnings: popt sure does some strange things
popt generates 4 compiler warnings with GCC 4.6.  There are 2
different types:

* 3 instances of:

    warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]

  One occurs in the _free() hack that is used to try and avoid a
  compiler warning.  I guess GCC got smarter?  ;-)

  The other is where an array of constant strings is passed to
  execvp(2), which arguably has the wrong type, since it has no need
  to modify the strings.

  Both of these can be worked around by casting to intptr_t before
  casting to the desired argument type.

  In poptReadConfigFile() the variable file is declared to be a
  constant string.  However, it is then passed to read(2) straight
  away and an attempt is made to cast away the "const".  However, to
  protect the value the of file is assigned to (const char *) chptr
  before it is passed to any other functions, so this protects the
  value anyway.  I'm not sure exactly what the thinking was
  here... but there seems to be no use having file be constant.

* 1 instance of:

    warning: variable ‘rc’ set but not used [-Wunused-but-set-variable]

  for the result of an execvp(2) call.  Recast the return type to
  void.  However, due to some #if-fu in the function, that can make rc
  unused in this function.  So we also need to wrap the declaration of
  rc in some corresponding #if-fu to make it disappear if not used.

Signed-off-by: Martin Schwenke <martin@meltin.net>

(This used to be ctdb commit ac9236e64bd0b61740cc787819a1222bc6a67d4a)
2011-11-11 14:28:30 +11:00

192 lines
4.6 KiB
C

/** \ingroup popt
* \file popt/poptconfig.c
*/
/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions, available from
ftp://ftp.rpm.org/pub/rpm/dist. */
#include "system.h"
#include "poptint.h"
/*@-compmempass@*/ /* FIX: item->option.longName kept, not dependent. */
static void configLine(poptContext con, char * line)
/*@modifies con @*/
{
/*@-type@*/
int nameLength = strlen(con->appName);
/*@=type@*/
const char * entryType;
const char * opt;
poptItem item = alloca(sizeof(*item));
int i, j;
/*@-boundswrite@*/
memset(item, 0, sizeof(*item));
/*@-type@*/
if (strncmp(line, con->appName, nameLength)) return;
/*@=type@*/
line += nameLength;
if (*line == '\0' || !isspace(*line)) return;
while (*line != '\0' && isspace(*line)) line++;
entryType = line;
while (*line == '\0' || !isspace(*line)) line++;
*line++ = '\0';
while (*line != '\0' && isspace(*line)) line++;
if (*line == '\0') return;
opt = line;
while (*line == '\0' || !isspace(*line)) line++;
*line++ = '\0';
while (*line != '\0' && isspace(*line)) line++;
if (*line == '\0') return;
/*@-temptrans@*/ /* FIX: line alias is saved */
if (opt[0] == '-' && opt[1] == '-')
item->option.longName = opt + 2;
else if (opt[0] == '-' && opt[2] == '\0')
item->option.shortName = opt[1];
/*@=temptrans@*/
if (poptParseArgvString(line, &item->argc, &item->argv)) return;
/*@-modobserver@*/
item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN;
for (i = 0, j = 0; i < item->argc; i++, j++) {
const char * f;
if (!strncmp(item->argv[i], "--POPTdesc=", sizeof("--POPTdesc=")-1)) {
f = item->argv[i] + sizeof("--POPTdesc=");
if (f[0] == '$' && f[1] == '"') f++;
item->option.descrip = f;
item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
j--;
} else
if (!strncmp(item->argv[i], "--POPTargs=", sizeof("--POPTargs=")-1)) {
f = item->argv[i] + sizeof("--POPTargs=");
if (f[0] == '$' && f[1] == '"') f++;
item->option.argDescrip = f;
item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
item->option.argInfo |= POPT_ARG_STRING;
j--;
} else
if (j != i)
item->argv[j] = item->argv[i];
}
if (j != i) {
item->argv[j] = NULL;
item->argc = j;
}
/*@=modobserver@*/
/*@=boundswrite@*/
/*@-nullstate@*/ /* FIX: item->argv[] may be NULL */
if (!strcmp(entryType, "alias"))
(void) poptAddItem(con, item, 0);
else if (!strcmp(entryType, "exec"))
(void) poptAddItem(con, item, 1);
/*@=nullstate@*/
}
/*@=compmempass@*/
int poptReadConfigFile(poptContext con, const char * fn)
{
char * file;
const char * chptr, * end;
char * buf;
/*@dependent@*/ char * dst;
int fd, rc;
off_t fileLength;
fd = open(fn, O_RDONLY);
if (fd < 0)
return (errno == ENOENT ? 0 : POPT_ERROR_ERRNO);
fileLength = lseek(fd, 0, SEEK_END);
if (fileLength == -1 || lseek(fd, 0, 0) == -1) {
rc = errno;
(void) close(fd);
/*@-mods@*/
errno = rc;
/*@=mods@*/
return POPT_ERROR_ERRNO;
}
file = alloca(fileLength + 1);
if (read(fd, (char *)file, fileLength) != fileLength) {
rc = errno;
(void) close(fd);
/*@-mods@*/
errno = rc;
/*@=mods@*/
return POPT_ERROR_ERRNO;
}
if (close(fd) == -1)
return POPT_ERROR_ERRNO;
/*@-boundswrite@*/
dst = buf = alloca(fileLength + 1);
chptr = file;
end = (file + fileLength);
/*@-infloops@*/ /* LCL: can't detect chptr++ */
while (chptr < end) {
switch (*chptr) {
case '\n':
*dst = '\0';
dst = buf;
while (*dst && isspace(*dst)) dst++;
if (*dst && *dst != '#')
configLine(con, dst);
chptr++;
/*@switchbreak@*/ break;
case '\\':
*dst++ = *chptr++;
if (chptr < end) {
if (*chptr == '\n')
dst--, chptr++;
/* \ at the end of a line does not insert a \n */
else
*dst++ = *chptr++;
}
/*@switchbreak@*/ break;
default:
*dst++ = *chptr++;
/*@switchbreak@*/ break;
}
}
/*@=infloops@*/
/*@=boundswrite@*/
return 0;
}
int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv)
{
char * fn, * home;
int rc;
/*@-type@*/
if (!con->appName) return 0;
/*@=type@*/
rc = poptReadConfigFile(con, "/etc/popt");
if (rc) return rc;
#if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
if (getuid() != geteuid()) return 0;
#endif
if ((home = getenv("HOME"))) {
fn = alloca(strlen(home) + 20);
strcpy(fn, home);
strcat(fn, "/.popt");
rc = poptReadConfigFile(con, fn);
if (rc) return rc;
}
return 0;
}