A couple more unsigned char changes to silence compiler warnings
[rsync/rsync.git] / popt / poptconfig.c
CommitLineData
cc248aae
WD
1/** \ingroup popt
2 * \file popt/poptconfig.c
3 */
4
5/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
62402cb1 6 file accompanying popt source distributions, available from
cc248aae 7 ftp://ftp.rpm.org/pub/rpm/dist. */
62402cb1 8
b348deae 9#include "system.h"
62402cb1
MP
10#include "poptint.h"
11
cc248aae 12/*@-compmempass@*/ /* FIX: item->option.longName kept, not dependent. */
37101856 13static void configLine(poptContext con, unsigned char * line)
cc248aae
WD
14 /*@modifies con @*/
15{
16 /*@-type@*/
62402cb1 17 int nameLength = strlen(con->appName);
cc248aae
WD
18 /*@=type@*/
19 const char * entryType;
20 const char * opt;
b17f1d76 21 poptItem item = (poptItem) alloca(sizeof(*item));
cc248aae 22 int i, j;
62402cb1 23
cc248aae
WD
24 memset(item, 0, sizeof(*item));
25
26 /*@-type@*/
62402cb1 27 if (strncmp(line, con->appName, nameLength)) return;
cc248aae
WD
28 /*@=type@*/
29
62402cb1 30 line += nameLength;
cc248aae 31 if (*line == '\0' || !isspace(*line)) return;
62402cb1 32
cc248aae
WD
33 while (*line != '\0' && isspace(*line)) line++;
34 entryType = line;
35 while (*line == '\0' || !isspace(*line)) line++;
62402cb1 36 *line++ = '\0';
62402cb1 37
cc248aae
WD
38 while (*line != '\0' && isspace(*line)) line++;
39 if (*line == '\0') return;
40 opt = line;
41 while (*line == '\0' || !isspace(*line)) line++;
62402cb1 42 *line++ = '\0';
62402cb1 43
cc248aae
WD
44 while (*line != '\0' && isspace(*line)) line++;
45 if (*line == '\0') return;
46
47 /*@-temptrans@*/ /* FIX: line alias is saved */
62402cb1 48 if (opt[0] == '-' && opt[1] == '-')
cc248aae
WD
49 item->option.longName = opt + 2;
50 else if (opt[0] == '-' && opt[2] == '\0')
51 item->option.shortName = opt[1];
52 /*@=temptrans@*/
53
54 if (poptParseArgvString(line, &item->argc, &item->argv)) return;
55
56 /*@-modobserver@*/
57 item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN;
58 for (i = 0, j = 0; i < item->argc; i++, j++) {
59 const char * f;
60 if (!strncmp(item->argv[i], "--POPTdesc=", sizeof("--POPTdesc=")-1)) {
61 f = item->argv[i] + sizeof("--POPTdesc=");
62 if (f[0] == '$' && f[1] == '"') f++;
63 item->option.descrip = f;
64 item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
65 j--;
66 } else
67 if (!strncmp(item->argv[i], "--POPTargs=", sizeof("--POPTargs=")-1)) {
68 f = item->argv[i] + sizeof("--POPTargs=");
69 if (f[0] == '$' && f[1] == '"') f++;
70 item->option.argDescrip = f;
71 item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
72 item->option.argInfo |= POPT_ARG_STRING;
73 j--;
74 } else
75 if (j != i)
76 item->argv[j] = item->argv[i];
77 }
78 if (j != i) {
79 item->argv[j] = NULL;
80 item->argc = j;
62402cb1 81 }
cc248aae
WD
82 /*@=modobserver@*/
83
84 /*@-nullstate@*/ /* FIX: item->argv[] may be NULL */
85 if (!strcmp(entryType, "alias"))
86 (void) poptAddItem(con, item, 0);
87 else if (!strcmp(entryType, "exec"))
88 (void) poptAddItem(con, item, 1);
89 /*@=nullstate@*/
62402cb1 90}
cc248aae 91/*@=compmempass@*/
62402cb1 92
cc248aae
WD
93int poptReadConfigFile(poptContext con, const char * fn)
94{
ff3184ca
WD
95 const unsigned char * file, * chptr, * end;
96 unsigned char * buf;
97/*@dependent@*/ unsigned char * dst;
62402cb1 98 int fd, rc;
cc248aae 99 off_t fileLength;
62402cb1
MP
100
101 fd = open(fn, O_RDONLY);
cc248aae
WD
102 if (fd < 0)
103 return (errno == ENOENT ? 0 : POPT_ERROR_ERRNO);
62402cb1
MP
104
105 fileLength = lseek(fd, 0, SEEK_END);
cc248aae
WD
106 if (fileLength == -1 || lseek(fd, 0, 0) == -1) {
107 rc = errno;
108 (void) close(fd);
109 /*@-mods@*/
110 errno = rc;
111 /*@=mods@*/
112 return POPT_ERROR_ERRNO;
113 }
62402cb1 114
cc248aae
WD
115 file = alloca(fileLength + 1);
116 if (read(fd, (char *)file, fileLength) != fileLength) {
62402cb1 117 rc = errno;
cc248aae
WD
118 (void) close(fd);
119 /*@-mods@*/
62402cb1 120 errno = rc;
cc248aae 121 /*@=mods@*/
62402cb1
MP
122 return POPT_ERROR_ERRNO;
123 }
cc248aae
WD
124 if (close(fd) == -1)
125 return POPT_ERROR_ERRNO;
62402cb1 126
cc248aae 127 dst = buf = alloca(fileLength + 1);
62402cb1
MP
128
129 chptr = file;
130 end = (file + fileLength);
cc248aae 131 /*@-infloops@*/ /* LCL: can't detect chptr++ */
62402cb1
MP
132 while (chptr < end) {
133 switch (*chptr) {
134 case '\n':
135 *dst = '\0';
136 dst = buf;
137 while (*dst && isspace(*dst)) dst++;
cc248aae 138 if (*dst && *dst != '#')
62402cb1 139 configLine(con, dst);
62402cb1 140 chptr++;
cc248aae 141 /*@switchbreak@*/ break;
62402cb1
MP
142 case '\\':
143 *dst++ = *chptr++;
144 if (chptr < end) {
145 if (*chptr == '\n')
146 dst--, chptr++;
147 /* \ at the end of a line does not insert a \n */
148 else
149 *dst++ = *chptr++;
150 }
cc248aae 151 /*@switchbreak@*/ break;
62402cb1
MP
152 default:
153 *dst++ = *chptr++;
cc248aae 154 /*@switchbreak@*/ break;
62402cb1
MP
155 }
156 }
cc248aae 157 /*@=infloops@*/
6afe7f23 158
62402cb1
MP
159 return 0;
160}
161
37101856
WD
162int poptReadDefaultConfig(poptContext con, /*@unused@*/ UNUSED(int useEnv))
163{
62402cb1
MP
164 char * fn, * home;
165 int rc;
166
cc248aae 167 /*@-type@*/
62402cb1 168 if (!con->appName) return 0;
cc248aae 169 /*@=type@*/
62402cb1
MP
170
171 rc = poptReadConfigFile(con, "/etc/popt");
172 if (rc) return rc;
173 if (getuid() != geteuid()) return 0;
174
175 if ((home = getenv("HOME"))) {
cc248aae 176 fn = alloca(strlen(home) + 20);
62402cb1
MP
177 strcpy(fn, home);
178 strcat(fn, "/.popt");
179 rc = poptReadConfigFile(con, fn);
180 if (rc) return rc;
181 }
182
183 return 0;
184}