00001
00005
00006
00007
00008
00009 #include "system.h"
00010 #include "poptint.h"
00011 #include <sys/stat.h>
00012 #include <glob.h>
00013
00014
00015
00016 static void configLine(poptContext con, char * line)
00017
00018 {
00019 size_t nameLength;
00020 const char * entryType;
00021 const char * opt;
00022 struct poptItem_s item_buf;
00023 poptItem item = &item_buf;
00024 int i, j;
00025
00026 if (con->appName == NULL)
00027 return;
00028 nameLength = strlen(con->appName);
00029
00030 memset(item, 0, sizeof(*item));
00031
00032 if (strncmp(line, con->appName, nameLength)) return;
00033
00034 line += nameLength;
00035 if (*line == '\0' || !_isspaceptr(line)) return;
00036
00037 while (*line != '\0' && _isspaceptr(line)) line++;
00038 entryType = line;
00039 while (*line == '\0' || !_isspaceptr(line)) line++;
00040 *line++ = '\0';
00041
00042 while (*line != '\0' && _isspaceptr(line)) line++;
00043 if (*line == '\0') return;
00044 opt = line;
00045 while (*line == '\0' || !_isspaceptr(line)) line++;
00046 *line++ = '\0';
00047
00048 while (*line != '\0' && _isspaceptr(line)) line++;
00049 if (*line == '\0') return;
00050
00051
00052 if (opt[0] == '-' && opt[1] == '-')
00053 item->option.longName = opt + 2;
00054 else if (opt[0] == '-' && opt[2] == '\0')
00055 item->option.shortName = opt[1];
00056
00057
00058 if (poptParseArgvString(line, &item->argc, &item->argv)) return;
00059
00060
00061 item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN;
00062 for (i = 0, j = 0; i < item->argc; i++, j++) {
00063 const char * f;
00064 if (!strncmp(item->argv[i], "--POPTdesc=", sizeof("--POPTdesc=")-1)) {
00065 f = item->argv[i] + sizeof("--POPTdesc=");
00066 if (f[0] == '$' && f[1] == '"') f++;
00067 item->option.descrip = f;
00068 item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
00069 j--;
00070 } else
00071 if (!strncmp(item->argv[i], "--POPTargs=", sizeof("--POPTargs=")-1)) {
00072 f = item->argv[i] + sizeof("--POPTargs=");
00073 if (f[0] == '$' && f[1] == '"') f++;
00074 item->option.argDescrip = f;
00075 item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
00076 item->option.argInfo |= POPT_ARG_STRING;
00077 j--;
00078 } else
00079 if (j != i)
00080 item->argv[j] = item->argv[i];
00081 }
00082 if (j != i) {
00083 item->argv[j] = NULL;
00084 item->argc = j;
00085 }
00086
00087
00088
00089 if (!strcmp(entryType, "alias"))
00090 (void) poptAddItem(con, item, 0);
00091 else if (!strcmp(entryType, "exec"))
00092 (void) poptAddItem(con, item, 1);
00093
00094 }
00095
00096
00097 int poptReadConfigFile(poptContext con, const char * fn)
00098 {
00099 char * file = NULL, * chptr, * end;
00100 char * buf = NULL;
00101 char * dst;
00102 int fd, rc;
00103 off_t fileLength;
00104
00105 fd = open(fn, O_RDONLY);
00106 if (fd < 0)
00107 return (errno == ENOENT ? 0 : POPT_ERROR_ERRNO);
00108
00109 fileLength = lseek(fd, 0, SEEK_END);
00110 if (fileLength == -1 || lseek(fd, 0, 0) == -1) {
00111 rc = errno;
00112 (void) close(fd);
00113 errno = rc;
00114 return POPT_ERROR_ERRNO;
00115 }
00116
00117 file = malloc(fileLength + 1);
00118 if (file == NULL || read(fd, (char *)file, fileLength) != fileLength) {
00119 rc = errno;
00120 (void) close(fd);
00121 errno = rc;
00122 if (file)
00123 free(file);
00124 return POPT_ERROR_ERRNO;
00125 }
00126 if (close(fd) == -1) {
00127 free(file);
00128 return POPT_ERROR_ERRNO;
00129 }
00130
00131 dst = buf = malloc(fileLength + 1);
00132 if (dst == NULL)
00133 return POPT_ERROR_ERRNO;
00134
00135 chptr = file;
00136 end = (file + fileLength);
00137
00138 while (chptr < end) {
00139 switch (*chptr) {
00140 case '\n':
00141 *dst = '\0';
00142 dst = buf;
00143 while (*dst && _isspaceptr(dst)) dst++;
00144 if (*dst && *dst != '#')
00145 configLine(con, dst);
00146 chptr++;
00147 break;
00148 case '\\':
00149 *dst++ = *chptr++;
00150 if (chptr < end) {
00151 if (*chptr == '\n')
00152 dst--, chptr++;
00153
00154 else
00155 *dst++ = *chptr++;
00156 }
00157 break;
00158 default:
00159 *dst++ = *chptr++;
00160 break;
00161 }
00162 }
00163
00164
00165 free(file);
00166 free(buf);
00167
00168 return 0;
00169 }
00170
00171 int poptReadDefaultConfig(poptContext con, int useEnv)
00172 {
00173 static const char _popt_sysconfdir[] = POPT_SYSCONFDIR "/popt";
00174 static const char _popt_etc[] = "/etc/popt";
00175 char * fn, * home;
00176 struct stat s;
00177 int rc;
00178
00179 if (con->appName == NULL) return 0;
00180
00181 if (strcmp(_popt_sysconfdir, _popt_etc)) {
00182 rc = poptReadConfigFile(con, _popt_sysconfdir);
00183 if (rc) return rc;
00184 }
00185
00186 rc = poptReadConfigFile(con, _popt_etc);
00187 if (rc) return rc;
00188
00189 if (!stat("/etc/popt.d", &s) && S_ISDIR(s.st_mode)) {
00190 glob_t g;
00191
00192 if (!glob("/etc/popt.d/*", 0, NULL, &g)) {
00193 int i;
00194 for (i=0; i<g.gl_pathc; i++) {
00195 char *f=g.gl_pathv[i];
00196 if (strstr(f, ".rpmnew") || strstr(f, ".rpmsave"))
00197 continue;
00198 if (!stat(f, &s)) {
00199 if (!S_ISREG(s.st_mode) && !S_ISLNK(s.st_mode))
00200 continue;
00201 }
00202 rc = poptReadConfigFile(con, f);
00203 if (rc) return rc;
00204 }
00205
00206 globfree(&g);
00207
00208 }
00209
00210 }
00211
00212 if ((home = getenv("HOME"))) {
00213 fn = malloc(strlen(home) + 20);
00214 if (fn != NULL) {
00215 strcpy(fn, home);
00216 strcat(fn, "/.popt");
00217 rc = poptReadConfigFile(con, fn);
00218 free(fn);
00219 } else
00220 rc = POPT_ERROR_ERRNO;
00221 if (rc) return rc;
00222 }
00223
00224 return 0;
00225 }