14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/** \ingroup popt
24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * \file popt/poptconfig.c
34a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */
44a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
54a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING
64a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project   file accompanying popt source distributions, available from
74a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project   ftp://ftp.rpm.org/pub/rpm/dist. */
84a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
94a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "system.h"
104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "poptint.h"
114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*@access poptContext @*/
124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*@-compmempass@*/	/* FIX: item->option.longName kept, not dependent. */
144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic void configLine(poptContext con, char * line)
154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	/*@modifies con @*/
164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    size_t nameLength;
184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    const char * entryType;
194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    const char * opt;
204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    poptItem item = alloca(sizeof(*item));
214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int i, j;
224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (con->appName == NULL)
244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	return;
254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    nameLength = strlen(con->appName);
264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*@-boundswrite@*/
284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    memset(item, 0, sizeof(*item));
294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (strncmp(line, con->appName, nameLength)) return;
314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    line += nameLength;
334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (*line == '\0' || !isspace(*line)) return;
344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    while (*line != '\0' && isspace(*line)) line++;
364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    entryType = line;
374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    while (*line == '\0' || !isspace(*line)) line++;
384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    *line++ = '\0';
394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    while (*line != '\0' && isspace(*line)) line++;
414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (*line == '\0') return;
424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    opt = line;
434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    while (*line == '\0' || !isspace(*line)) line++;
444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    *line++ = '\0';
454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    while (*line != '\0' && isspace(*line)) line++;
474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (*line == '\0') return;
484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /*@-temptrans@*/ /* FIX: line alias is saved */
504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (opt[0] == '-' && opt[1] == '-')
514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	item->option.longName = opt + 2;
524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else if (opt[0] == '-' && opt[2] == '\0')
534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	item->option.shortName = opt[1];
544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /*@=temptrans@*/
554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (poptParseArgvString(line, &item->argc, &item->argv)) return;
574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /*@-modobserver@*/
594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN;
604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    for (i = 0, j = 0; i < item->argc; i++, j++) {
614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	const char * f;
624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	if (!strncmp(item->argv[i], "--POPTdesc=", sizeof("--POPTdesc=")-1)) {
634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    f = item->argv[i] + sizeof("--POPTdesc=");
644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    if (f[0] == '$' && f[1] == '"') f++;
654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    item->option.descrip = f;
664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    j--;
684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	} else
694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	if (!strncmp(item->argv[i], "--POPTargs=", sizeof("--POPTargs=")-1)) {
704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    f = item->argv[i] + sizeof("--POPTargs=");
714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    if (f[0] == '$' && f[1] == '"') f++;
724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    item->option.argDescrip = f;
734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    item->option.argInfo |= POPT_ARG_STRING;
754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    j--;
764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	} else
774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	if (j != i)
784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    item->argv[j] = item->argv[i];
794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (j != i) {
814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	item->argv[j] = NULL;
824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	item->argc = j;
834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /*@=modobserver@*/
854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*@=boundswrite@*/
864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /*@-nullstate@*/ /* FIX: item->argv[] may be NULL */
884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (!strcmp(entryType, "alias"))
894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	(void) poptAddItem(con, item, 0);
904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    else if (!strcmp(entryType, "exec"))
914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	(void) poptAddItem(con, item, 1);
924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /*@=nullstate@*/
934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*@=compmempass@*/
954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint poptReadConfigFile(poptContext con, const char * fn)
974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    const char * file, * chptr, * end;
994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    char * buf;
1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*@dependent@*/ char * dst;
1014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int fd, rc;
1024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    off_t fileLength;
1034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    fd = open(fn, O_RDONLY);
1054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (fd < 0)
1064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	return (errno == ENOENT ? 0 : POPT_ERROR_ERRNO);
1074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    fileLength = lseek(fd, 0, SEEK_END);
1094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (fileLength == -1 || lseek(fd, 0, 0) == -1) {
1104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	rc = errno;
1114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	(void) close(fd);
1124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	errno = rc;
1134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	return POPT_ERROR_ERRNO;
1144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    file = alloca(fileLength + 1);
1174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (read(fd, (char *)file, fileLength) != fileLength) {
1184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	rc = errno;
1194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	(void) close(fd);
1204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	errno = rc;
1214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	return POPT_ERROR_ERRNO;
1224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (close(fd) == -1)
1244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	return POPT_ERROR_ERRNO;
1254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*@-boundswrite@*/
1274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    dst = buf = alloca(fileLength + 1);
1284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    chptr = file;
1304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    end = (file + fileLength);
1314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /*@-infloops@*/	/* LCL: can't detect chptr++ */
1324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    while (chptr < end) {
1334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	switch (*chptr) {
1344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	  case '\n':
1354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    *dst = '\0';
1364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    dst = buf;
1374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    while (*dst && isspace(*dst)) dst++;
1384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    if (*dst && *dst != '#')
1394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		configLine(con, dst);
1404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    chptr++;
1414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    /*@switchbreak@*/ break;
1424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	  case '\\':
1434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    *dst++ = *chptr++;
1444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    if (chptr < end) {
1454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		if (*chptr == '\n')
1464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		    dst--, chptr++;
1474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		    /* \ at the end of a line does not insert a \n */
1484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		else
1494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project		    *dst++ = *chptr++;
1504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    }
1514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    /*@switchbreak@*/ break;
1524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	  default:
1534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    *dst++ = *chptr++;
1544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	    /*@switchbreak@*/ break;
1554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	}
1564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /*@=infloops@*/
1584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*@=boundswrite@*/
1594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return 0;
1614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv)
1644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
1654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    char * fn, * home;
1664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    int rc;
1674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (con->appName == NULL) return 0;
1694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    rc = poptReadConfigFile(con, "/etc/popt");
1714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (rc) return rc;
1724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if ((home = getenv("HOME"))) {
1744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	fn = alloca(strlen(home) + 20);
1754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	strcpy(fn, home);
1764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	strcat(fn, "/.popt");
1774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	rc = poptReadConfigFile(con, fn);
1784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project	if (rc) return rc;
1794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return 0;
1824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project