popt  1.13
poptconfig.c
Go to the documentation of this file.
1 
5 /* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING
6  file accompanying popt source distributions, available from
7  ftp://ftp.rpm.org/pub/rpm/dist. */
8 
9 #include "system.h"
10 #include "poptint.h"
11 #include <sys/stat.h>
12 #include <glob.h>
13 /*@access poptContext @*/
14 
15 /*@-compmempass@*/ /* FIX: item->option.longName kept, not dependent. */
16 static void configLine(poptContext con, char * line)
17  /*@modifies con @*/
18 {
19  size_t nameLength;
20  const char * entryType;
21  const char * opt;
22  struct poptItem_s item_buf;
23  poptItem item = &item_buf;
24  int i, j;
25 
26  if (con->appName == NULL)
27  return;
28  nameLength = strlen(con->appName);
29 
30  memset(item, 0, sizeof(*item));
31 
32  if (strncmp(line, con->appName, nameLength)) return;
33 
34  line += nameLength;
35  if (*line == '\0' || !_isspaceptr(line)) return;
36 
37  while (*line != '\0' && _isspaceptr(line)) line++;
38  entryType = line;
39  while (*line == '\0' || !_isspaceptr(line)) line++;
40  *line++ = '\0';
41 
42  while (*line != '\0' && _isspaceptr(line)) line++;
43  if (*line == '\0') return;
44  opt = line;
45  while (*line == '\0' || !_isspaceptr(line)) line++;
46  *line++ = '\0';
47 
48  while (*line != '\0' && _isspaceptr(line)) line++;
49  if (*line == '\0') return;
50 
51 /*@-temptrans@*/ /* FIX: line alias is saved */
52  if (opt[0] == '-' && opt[1] == '-')
53  item->option.longName = opt + 2;
54  else if (opt[0] == '-' && opt[2] == '\0')
55  item->option.shortName = opt[1];
56 /*@=temptrans@*/
57 
58  if (poptParseArgvString(line, &item->argc, &item->argv)) return;
59 
60 /*@-modobserver@*/
61  item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN;
62  for (i = 0, j = 0; i < item->argc; i++, j++) {
63  const char * f;
64  if (!strncmp(item->argv[i], "--POPTdesc=", sizeof("--POPTdesc=")-1)) {
65  f = item->argv[i] + sizeof("--POPTdesc=");
66  if (f[0] == '$' && f[1] == '"') f++;
67  item->option.descrip = f;
68  item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
69  j--;
70  } else
71  if (!strncmp(item->argv[i], "--POPTargs=", sizeof("--POPTargs=")-1)) {
72  f = item->argv[i] + sizeof("--POPTargs=");
73  if (f[0] == '$' && f[1] == '"') f++;
74  item->option.argDescrip = f;
75  item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
76  item->option.argInfo |= POPT_ARG_STRING;
77  j--;
78  } else
79  if (j != i)
80  item->argv[j] = item->argv[i];
81  }
82  if (j != i) {
83  item->argv[j] = NULL;
84  item->argc = j;
85  }
86 /*@=modobserver@*/
87 
88 /*@-nullstate@*/ /* FIX: item->argv[] may be NULL */
89  if (!strcmp(entryType, "alias"))
90  (void) poptAddItem(con, item, 0);
91  else if (!strcmp(entryType, "exec"))
92  (void) poptAddItem(con, item, 1);
93 /*@=nullstate@*/
94 }
95 /*@=compmempass@*/
96 
97 int poptReadConfigFile(poptContext con, const char * fn)
98 {
99  char * file = NULL, * chptr, * end;
100  char * buf = NULL;
101 /*@dependent@*/ char * dst;
102  int fd, rc;
103  off_t fileLength;
104 
105  fd = open(fn, O_RDONLY);
106  if (fd < 0)
107  return (errno == ENOENT ? 0 : POPT_ERROR_ERRNO);
108 
109  fileLength = lseek(fd, 0, SEEK_END);
110  if (fileLength == -1 || lseek(fd, 0, 0) == -1) {
111  rc = errno;
112  (void) close(fd);
113  errno = rc;
114  return POPT_ERROR_ERRNO;
115  }
116 
117  file = malloc(fileLength + 1);
118  if (file == NULL || read(fd, (char *)file, fileLength) != fileLength) {
119  rc = errno;
120  (void) close(fd);
121  errno = rc;
122  if (file)
123  free(file);
124  return POPT_ERROR_ERRNO;
125  }
126  if (close(fd) == -1) {
127  free(file);
128  return POPT_ERROR_ERRNO;
129  }
130 
131  dst = buf = malloc(fileLength + 1);
132  if (dst == NULL)
133  return POPT_ERROR_ERRNO;
134 
135  chptr = file;
136  end = (file + fileLength);
137 /*@-infloops@*/ /* LCL: can't detect chptr++ */
138  while (chptr < end) {
139  switch (*chptr) {
140  case '\n':
141  *dst = '\0';
142  dst = buf;
143  while (*dst && _isspaceptr(dst)) dst++;
144  if (*dst && *dst != '#')
145  configLine(con, dst);
146  chptr++;
147  /*@switchbreak@*/ break;
148  case '\\':
149  *dst++ = *chptr++;
150  if (chptr < end) {
151  if (*chptr == '\n')
152  dst--, chptr++;
153  /* \ at the end of a line does not insert a \n */
154  else
155  *dst++ = *chptr++;
156  }
157  /*@switchbreak@*/ break;
158  default:
159  *dst++ = *chptr++;
160  /*@switchbreak@*/ break;
161  }
162  }
163 /*@=infloops@*/
164 
165  free(file);
166  free(buf);
167 
168  return 0;
169 }
170 
171 int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv)
172 {
173  static const char _popt_sysconfdir[] = POPT_SYSCONFDIR "/popt";
174  static const char _popt_etc[] = "/etc/popt";
175  char * fn, * home;
176  struct stat s;
177  int rc;
178 
179  if (con->appName == NULL) return 0;
180 
181  if (strcmp(_popt_sysconfdir, _popt_etc)) {
182  rc = poptReadConfigFile(con, _popt_sysconfdir);
183  if (rc) return rc;
184  }
185 
186  rc = poptReadConfigFile(con, _popt_etc);
187  if (rc) return rc;
188 
189  if (!stat("/etc/popt.d", &s) && S_ISDIR(s.st_mode)) {
190  glob_t g;
191 /*@-moduncon -nullpass -type @*/ /* FIX: annotations for glob/globfree */
192  if (!glob("/etc/popt.d/*", 0, NULL, &g)) {
193  int i;
194  for (i=0; i<g.gl_pathc; i++) {
195  char *f=g.gl_pathv[i];
196  if (strstr(f, ".rpmnew") || strstr(f, ".rpmsave"))
197  continue;
198  if (!stat(f, &s)) {
199  if (!S_ISREG(s.st_mode) && !S_ISLNK(s.st_mode))
200  continue;
201  }
202  rc = poptReadConfigFile(con, f);
203  if (rc) return rc;
204  }
205 /*@-noeffectuncon@*/
206  globfree(&g);
207 /*@=noeffectuncon@*/
208  }
209 /*@=moduncon =nullpass =type @*/
210  }
211 
212  if ((home = getenv("HOME"))) {
213  fn = malloc(strlen(home) + 20);
214  if (fn != NULL) {
215  strcpy(fn, home);
216  strcat(fn, "/.popt");
217  rc = poptReadConfigFile(con, fn);
218  free(fn);
219  } else
220  rc = POPT_ERROR_ERRNO;
221  if (rc) return rc;
222  }
223 
224  return 0;
225 }

Generated for popt by  doxygen 1.8.1.2