Doc.
[rsync/rsync.git] / popt-1.2 / poptconfig.c
CommitLineData
62402cb1
MP
1/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
2 file accompanying popt source distributions, available from
3 ftp://ftp.redhat.com/pub/code/popt */
4
5#ifdef HAVE_CONFIG_H
6#include "config.h"
7#endif
8
9#include <ctype.h>
10#include <errno.h>
11#include <fcntl.h>
12#include <stdlib.h>
13#include <string.h>
14#include <unistd.h>
15
16#if HAVE_ALLOCA_H
17# include <alloca.h>
18#endif
19
20#include "popt.h"
21#include "poptint.h"
22
23static void configLine(poptContext con, char * line) {
24 int nameLength = strlen(con->appName);
25 char * opt;
26 struct poptAlias alias;
27 char * entryType;
28 char * longName = NULL;
29 char shortName = '\0';
30
31 if (strncmp(line, con->appName, nameLength)) return;
32 line += nameLength;
33 if (!*line || !isspace(*line)) return;
34 while (*line && isspace(*line)) line++;
35 entryType = line;
36
37 while (!*line || !isspace(*line)) line++;
38 *line++ = '\0';
39 while (*line && isspace(*line)) line++;
40 if (!*line) return;
41 opt = line;
42
43 while (!*line || !isspace(*line)) line++;
44 *line++ = '\0';
45 while (*line && isspace(*line)) line++;
46 if (!*line) return;
47
48 if (opt[0] == '-' && opt[1] == '-')
49 longName = opt + 2;
50 else if (opt[0] == '-' && !opt[2])
51 shortName = opt[1];
52
53 if (!strcmp(entryType, "alias")) {
54 if (poptParseArgvString(line, &alias.argc, &alias.argv)) return;
55 alias.longName = longName, alias.shortName = shortName;
56 poptAddAlias(con, alias, 0);
57 } else if (!strcmp(entryType, "exec")) {
58 con->execs = realloc(con->execs,
59 sizeof(*con->execs) * (con->numExecs + 1));
60 if (longName)
61 con->execs[con->numExecs].longName = strdup(longName);
62 else
63 con->execs[con->numExecs].longName = NULL;
64
65 con->execs[con->numExecs].shortName = shortName;
66 con->execs[con->numExecs].script = strdup(line);
67
68 con->numExecs++;
69 }
70}
71
72int poptReadConfigFile(poptContext con, char * fn) {
73 char * file, * chptr, * end;
74 char * buf, * dst;
75 int fd, rc;
76 int fileLength;
77
78 fd = open(fn, O_RDONLY);
79 if (fd < 0) {
80 if (errno == ENOENT)
81 return 0;
82 else
83 return POPT_ERROR_ERRNO;
84 }
85
86 fileLength = lseek(fd, 0, SEEK_END);
87 lseek(fd, 0, 0);
88
89 file = alloca(fileLength + 1);
90 if ((fd = read(fd, file, fileLength)) != fileLength) {
91 rc = errno;
92 close(fd);
93 errno = rc;
94 return POPT_ERROR_ERRNO;
95 }
96 close(fd);
97
98 dst = buf = alloca(fileLength + 1);
99
100 chptr = file;
101 end = (file + fileLength);
102 while (chptr < end) {
103 switch (*chptr) {
104 case '\n':
105 *dst = '\0';
106 dst = buf;
107 while (*dst && isspace(*dst)) dst++;
108 if (*dst && *dst != '#') {
109 configLine(con, dst);
110 }
111 chptr++;
112 break;
113 case '\\':
114 *dst++ = *chptr++;
115 if (chptr < end) {
116 if (*chptr == '\n')
117 dst--, chptr++;
118 /* \ at the end of a line does not insert a \n */
119 else
120 *dst++ = *chptr++;
121 }
122 break;
123 default:
124 *dst++ = *chptr++;
125 }
126 }
127
128 return 0;
129}
130
131int poptReadDefaultConfig(poptContext con, int useEnv) {
132 char * fn, * home;
133 int rc;
134
135 if (!con->appName) return 0;
136
137 rc = poptReadConfigFile(con, "/etc/popt");
138 if (rc) return rc;
139 if (getuid() != geteuid()) return 0;
140
141 if ((home = getenv("HOME"))) {
142 fn = alloca(strlen(home) + 20);
143 strcpy(fn, home);
144 strcat(fn, "/.popt");
145 rc = poptReadConfigFile(con, fn);
146 if (rc) return rc;
147 }
148
149 return 0;
150}
151