2
* libdpkg - Debian packaging suite library routines
3
* myopt.c - my very own option parsing
5
* Copyright © 1994,1995 Ian Jackson <ian@chiark.greenend.org.uk>
6
* Copyright © 2000,2002 Wichert Akkerman <wichert@deephackmode.org>
7
* Copyright © 2008,2009 Guillem Jover <guillem@debian.org>
9
* This is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as
11
* published by the Free Software Foundation; either version 2,
12
* or (at your option) any later version.
14
* This is distributed in the hope that it will be useful, but
15
* WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* You should have received a copy of the GNU General Public
20
* License along with this file; if not, write to the Free Software
21
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26
#include <dpkg/i18n.h>
35
#include <dpkg/dpkg.h>
36
#include <dpkg/string.h>
37
#include <dpkg/myopt.h>
40
badusage(const char *fmt, ...)
46
vsnprintf(buf, sizeof(buf), fmt, al);
49
ohshit("%s\n\n%s", buf, gettext(printforhelp));
53
config_error(const char *file_name, int line_num, const char *fmt, ...)
59
vsnprintf(buf, sizeof(buf), fmt, al);
62
ohshit(_("configuration error: %s:%d: %s"), file_name, line_num, buf);
65
void myfileopt(const char* fn, const struct cmdinfo* cmdinfos) {
68
char linebuf[MAX_CONFIG_LINE];
74
warning(_("failed to open configuration file '%.255s' for reading: %s"),
79
while (fgets(linebuf, sizeof(linebuf), file)) {
81
const struct cmdinfo *cip;
86
if ((linebuf[0] == '#') || (linebuf[0] == '\n') || (linebuf[0] == '\0'))
89
if (linebuf[l - 1] == '\n')
90
linebuf[l - 1] = '\0';
91
for (opt=linebuf;isalnum(*opt)||*opt=='-';opt++) ;
97
while (isspace(*opt)) opt++;
99
opt = str_strip_quotes(opt);
101
config_error(fn, line_num, _("unbalanced quotes in '%s'"), linebuf);
104
for (cip=cmdinfos; cip->olong || cip->oshort; cip++) {
106
if (!cip->olong) continue;
107
if (!strcmp(cip->olong,linebuf)) break;
108
l=strlen(cip->olong);
109
if ((cip->takesvalue==2) && (linebuf[l]=='-') &&
110
!opt && !strncmp(linebuf,cip->olong,l)) {
117
config_error(fn, line_num, _("unknown option '%s'"), linebuf);
119
if (cip->takesvalue) {
121
config_error(fn, line_num, _("'%s' needs a value"), linebuf);
122
if (cip->call) cip->call(cip,opt);
124
*cip->sassignto = m_strdup(opt);
127
config_error(fn, line_num, _("'%s' does not take a value"), linebuf);
128
if (cip->call) cip->call(cip,NULL);
129
else *cip->iassignto= cip->arg;
132
if (ferror(file)) ohshite(_("read error in configuration file `%.255s'"), fn);
133
if (fclose(file)) ohshite(_("error closing configuration file `%.255s'"), fn);
137
valid_config_filename(const struct dirent *dent)
141
if (dent->d_name[0] == '.')
144
for (c = dent->d_name; *c; c++)
145
if (!isalnum(*c) && *c != '_' && *c != '-')
155
load_config_dir(const char *prog, const struct cmdinfo* cmdinfos)
158
struct dirent **dlist;
161
dirname = m_malloc(strlen(CONFIGDIR "/.cfg.d") + strlen(prog) + 1);
162
sprintf(dirname, "%s/%s.cfg.d", CONFIGDIR, prog);
164
dlist_n = scandir(dirname, &dlist, valid_config_filename, alphasort);
166
if (errno == ENOENT) {
170
ohshite(_("error opening configuration directory '%s'"), dirname);
173
for (i = 0; i < dlist_n; i++) {
176
filename = m_malloc(strlen(dirname) + 1 + strlen(dlist[i]->d_name) + 1);
177
sprintf(filename, "%s/%s", dirname, dlist[i]->d_name);
179
myfileopt(filename, cmdinfos);
188
void loadcfgfile(const char *prog, const struct cmdinfo* cmdinfos) {
192
load_config_dir(prog, cmdinfos);
194
l1 = strlen(CONFIGDIR "/.cfg") + strlen(prog);
195
file = m_malloc(l1 + 1);
196
sprintf(file, CONFIGDIR "/%s.cfg", prog);
197
myfileopt(file, cmdinfos);
198
if ((home = getenv("HOME")) != NULL) {
199
l2 = strlen(home) + 1 + strlen("/.cfg") + strlen(prog);
202
file = m_malloc(l2 + 1);
204
sprintf(file, "%s/.%s.cfg", home, prog);
205
myfileopt(file, cmdinfos);
210
void myopt(const char *const **argvp, const struct cmdinfo *cmdinfos) {
211
const struct cmdinfo *cip;
212
const char *p, *value;
216
while ((p= **argvp) && *p == '-') {
218
if (!strcmp(p,"--")) break;
222
cip->olong || cip->oshort;
224
if (!cip->olong) continue;
225
if (!strcmp(p,cip->olong)) break;
226
l= strlen(cip->olong);
227
if (!strncmp(p,cip->olong,l) &&
228
(p[l]== ((cip->takesvalue==2) ? '-' : '='))) { value=p+l+1; break; }
230
if (!cip->olong) badusage(_("unknown option --%s"),p);
231
if (cip->takesvalue) {
234
if (!value) badusage(_("--%s option takes a value"),cip->olong);
236
if (cip->call) cip->call(cip,value);
237
else *cip->sassignto= value;
239
if (value) badusage(_("--%s option does not take a value"),cip->olong);
240
if (cip->call) cip->call(cip,NULL);
241
else *cip->iassignto= cip->arg;
245
for (cip= cmdinfos; (cip->olong || cip->oshort) && *p != cip->oshort; cip++);
246
if (!cip->oshort) badusage(_("unknown option -%c"),*p);
248
if (cip->takesvalue) {
251
if (!value) badusage(_("-%c option takes a value"),cip->oshort);
254
if (*value == '=') value++;
256
if (cip->call) cip->call(cip,value);
257
else *cip->sassignto= value;
259
if (*p == '=') badusage(_("-%c option does not take a value"),cip->oshort);
260
if (cip->call) cip->call(cip,NULL);
261
else *cip->iassignto= cip->arg;