Split code out into separate files and remove some global variables to
[rsync/rsync.git] / popt / 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
b348deae 5#include "system.h"
62402cb1
MP
6#include "poptint.h"
7
8static void configLine(poptContext con, char * line) {
9 int nameLength = strlen(con->appName);
10 char * opt;
11 struct poptAlias alias;
12 char * entryType;
13 char * longName = NULL;
14 char shortName = '\0';
15
16 if (strncmp(line, con->appName, nameLength)) return;
17 line += nameLength;
18 if (!*line || !isspace(*line)) return;
19 while (*line && isspace(*line)) line++;
20 entryType = line;
21
22 while (!*line || !isspace(*line)) line++;
23 *line++ = '\0';
24 while (*line && isspace(*line)) line++;
25 if (!*line) return;
26 opt = line;
27
28 while (!*line || !isspace(*line)) line++;
29 *line++ = '\0';
30 while (*line && isspace(*line)) line++;
31 if (!*line) return;
32
33 if (opt[0] == '-' && opt[1] == '-')
34 longName = opt + 2;
35 else if (opt[0] == '-' && !opt[2])
36 shortName = opt[1];
37
38 if (!strcmp(entryType, "alias")) {
39 if (poptParseArgvString(line, &alias.argc, &alias.argv)) return;
40 alias.longName = longName, alias.shortName = shortName;
41 poptAddAlias(con, alias, 0);
42 } else if (!strcmp(entryType, "exec")) {
b348deae 43 con->execs = realloc(con->execs,
62402cb1
MP
44 sizeof(*con->execs) * (con->numExecs + 1));
45 if (longName)
b348deae 46 con->execs[con->numExecs].longName = xstrdup(longName);
62402cb1
MP
47 else
48 con->execs[con->numExecs].longName = NULL;
49
50 con->execs[con->numExecs].shortName = shortName;
b348deae 51 con->execs[con->numExecs].script = xstrdup(line);
62402cb1
MP
52
53 con->numExecs++;
54 }
55}
56
b348deae 57int poptReadConfigFile(poptContext con, const char * fn) {
6afe7f23
AT
58 char * file=NULL, * chptr, * end;
59 char * buf=NULL, * dst;
62402cb1
MP
60 int fd, rc;
61 int fileLength;
62
63 fd = open(fn, O_RDONLY);
64 if (fd < 0) {
65 if (errno == ENOENT)
66 return 0;
67 else
68 return POPT_ERROR_ERRNO;
69 }
70
71 fileLength = lseek(fd, 0, SEEK_END);
b348deae 72 (void) lseek(fd, 0, 0);
62402cb1 73
6afe7f23 74 file = malloc(fileLength + 1);
b348deae 75 if (read(fd, file, fileLength) != fileLength) {
62402cb1
MP
76 rc = errno;
77 close(fd);
78 errno = rc;
6afe7f23 79 if (file) free(file);
62402cb1
MP
80 return POPT_ERROR_ERRNO;
81 }
82 close(fd);
83
6afe7f23 84 dst = buf = malloc(fileLength + 1);
62402cb1
MP
85
86 chptr = file;
87 end = (file + fileLength);
88 while (chptr < end) {
89 switch (*chptr) {
90 case '\n':
91 *dst = '\0';
92 dst = buf;
93 while (*dst && isspace(*dst)) dst++;
94 if (*dst && *dst != '#') {
95 configLine(con, dst);
96 }
97 chptr++;
98 break;
99 case '\\':
100 *dst++ = *chptr++;
101 if (chptr < end) {
102 if (*chptr == '\n')
103 dst--, chptr++;
104 /* \ at the end of a line does not insert a \n */
105 else
106 *dst++ = *chptr++;
107 }
108 break;
109 default:
110 *dst++ = *chptr++;
b348deae 111 break;
62402cb1
MP
112 }
113 }
114
6afe7f23
AT
115 free(file);
116 free(buf);
117
62402cb1
MP
118 return 0;
119}
120
b348deae 121int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv) {
62402cb1
MP
122 char * fn, * home;
123 int rc;
124
125 if (!con->appName) return 0;
126
127 rc = poptReadConfigFile(con, "/etc/popt");
128 if (rc) return rc;
129 if (getuid() != geteuid()) return 0;
130
131 if ((home = getenv("HOME"))) {
6afe7f23 132 fn = malloc(strlen(home) + 20);
62402cb1
MP
133 strcpy(fn, home);
134 strcat(fn, "/.popt");
135 rc = poptReadConfigFile(con, fn);
6afe7f23 136 free(fn);
62402cb1
MP
137 if (rc) return rc;
138 }
139
140 return 0;
141}
142