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