00001
00005
00006
00007
00008
00009 #include "system.h"
00010 #include "poptint.h"
00011
00012
00013
00014 static void configLine(poptContext con, char * line)
00015
00016 {
00017 size_t nameLength;
00018 const char * entryType;
00019 const char * opt;
00020 struct poptItem_s item_buf;
00021 poptItem item = &item_buf;
00022 int i, j;
00023
00024 if (con->appName == NULL)
00025 return;
00026 nameLength = strlen(con->appName);
00027
00028
00029 memset(item, 0, sizeof(*item));
00030
00031 if (strncmp(line, con->appName, nameLength)) return;
00032
00033 line += nameLength;
00034 if (*line == '\0' || !isspace(*line)) return;
00035
00036 while (*line != '\0' && isspace(*line)) line++;
00037 entryType = line;
00038 while (*line == '\0' || !isspace(*line)) line++;
00039 *line++ = '\0';
00040
00041 while (*line != '\0' && isspace(*line)) line++;
00042 if (*line == '\0') return;
00043 opt = line;
00044 while (*line == '\0' || !isspace(*line)) line++;
00045 *line++ = '\0';
00046
00047 while (*line != '\0' && isspace(*line)) line++;
00048 if (*line == '\0') return;
00049
00050
00051 if (opt[0] == '-' && opt[1] == '-')
00052 item->option.longName = opt + 2;
00053 else if (opt[0] == '-' && opt[2] == '\0')
00054 item->option.shortName = opt[1];
00055
00056
00057 if (poptParseArgvString(line, &item->argc, &item->argv)) return;
00058
00059
00060 item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN;
00061 for (i = 0, j = 0; i < item->argc; i++, j++) {
00062 const char * f;
00063 if (!strncmp(item->argv[i], "--POPTdesc=", sizeof("--POPTdesc=")-1)) {
00064 f = item->argv[i] + sizeof("--POPTdesc=");
00065 if (f[0] == '$' && f[1] == '"') f++;
00066 item->option.descrip = f;
00067 item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
00068 j--;
00069 } else
00070 if (!strncmp(item->argv[i], "--POPTargs=", sizeof("--POPTargs=")-1)) {
00071 f = item->argv[i] + sizeof("--POPTargs=");
00072 if (f[0] == '$' && f[1] == '"') f++;
00073 item->option.argDescrip = f;
00074 item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
00075 item->option.argInfo |= POPT_ARG_STRING;
00076 j--;
00077 } else
00078 if (j != i)
00079 item->argv[j] = item->argv[i];
00080 }
00081 if (j != i) {
00082 item->argv[j] = NULL;
00083 item->argc = j;
00084 }
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 (read(fd, (char *)file, fileLength) != fileLength) {
00119 rc = errno;
00120 (void) close(fd);
00121 errno = rc;
00122 return POPT_ERROR_ERRNO;
00123 }
00124 if (close(fd) == -1) {
00125 free(file);
00126 return POPT_ERROR_ERRNO;
00127 }
00128
00129
00130 dst = buf = malloc(fileLength + 1);
00131
00132 chptr = file;
00133 end = (file + fileLength);
00134
00135 while (chptr < end) {
00136 switch (*chptr) {
00137 case '\n':
00138 *dst = '\0';
00139 dst = buf;
00140 while (*dst && isspace(*dst)) dst++;
00141 if (*dst && *dst != '#')
00142 configLine(con, dst);
00143 chptr++;
00144 break;
00145 case '\\':
00146 *dst++ = *chptr++;
00147 if (chptr < end) {
00148 if (*chptr == '\n')
00149 dst--, chptr++;
00150
00151 else
00152 *dst++ = *chptr++;
00153 }
00154 break;
00155 default:
00156 *dst++ = *chptr++;
00157 break;
00158 }
00159 }
00160
00161
00162
00163 free(file);
00164 free(buf);
00165
00166 return 0;
00167 }
00168
00169 int poptReadDefaultConfig(poptContext con, int useEnv)
00170 {
00171 char * fn, * home;
00172 int rc;
00173
00174 if (con->appName == NULL) return 0;
00175
00176 rc = poptReadConfigFile(con, POPT_SYSCONFDIR "/popt");
00177 if (rc) return rc;
00178
00179 rc = poptReadConfigFile(con, "/etc/popt");
00180 if (rc) return rc;
00181
00182 if ((home = getenv("HOME"))) {
00183 fn = malloc(strlen(home) + 20);
00184 strcpy(fn, home);
00185 strcat(fn, "/.popt");
00186 rc = poptReadConfigFile(con, fn);
00187 free(fn);
00188 if (rc) return rc;
00189 }
00190
00191 return 0;
00192 }