~cyphermox/ubuntu/precise/dnsmasq/dbus

« back to all changes in this revision

Viewing changes to src/option.c

  • Committer: Bazaar Package Importer
  • Author(s): Simon Kelley
  • Date: 2005-09-03 20:02:32 UTC
  • mfrom: (0.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20050903200232-76u3kbiz1hm4ok3u
Tags: 2.24-1
 * New upstream. (closes: #330422)
 * Fix typo and clean up dnsmasq.conf (closes: #326057) (closes: #304446)
 * Add build support for I18N and gettext.
 * Fixed manpage typos. (closes: #336413)
 * Create a dnsmasq-unique userid for the daemon to run as. (closes: #338353)

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
  int val;
22
22
};
23
23
 
24
 
#define OPTSTRING "yZDNLERKzowefnbvhdkqr:m:p:c:l:s:i:t:u:g:a:x:S:C:A:T:H:Q:I:B:F:G:O:M:X:V:U:j:P:J:W:Y:"
 
24
#define OPTSTRING "31yZDNLERKzowefnbvhdkqr:m:p:c:l:s:i:t:u:g:a:x:S:C:A:T:H:Q:I:B:F:G:O:M:X:V:U:j:P:J:W:Y:2:"
25
25
 
26
 
static struct myoption opts[] = { 
 
26
static const struct myoption opts[] = { 
27
27
  {"version", 0, 0, 'v'},
28
28
  {"no-hosts", 0, 0, 'h'},
29
29
  {"no-poll", 0, 0, 'n'},
65
65
  {"addn-hosts", 1, 0, 'H'},
66
66
  {"query-port", 1, 0, 'Q'},
67
67
  {"except-interface", 1, 0, 'I'},
 
68
  {"no-dhcp-interface", 1, 0, '2'},
68
69
  {"domain-needed", 0, 0, 'D'},
69
70
  {"dhcp-lease-max", 1, 0, 'X' },
70
71
  {"bind-interfaces", 0, 0, 'z'},
79
80
  {"srv-host", 1, 0, 'W'},
80
81
  {"localise-queries", 0, 0, 'y'},
81
82
  {"txt-record", 1, 0, 'Y'},
 
83
  {"enable-dbus", 0, 0, '1'},
 
84
  {"bootp-dynamic", 0, 0, '3'},
82
85
  {0, 0, 0, 0}
83
86
};
84
87
 
87
90
  unsigned int flag; 
88
91
};
89
92
 
90
 
static struct optflags optmap[] = {
 
93
static const struct optflags optmap[] = {
91
94
  { 'b', OPT_BOGUSPRIV },
92
95
  { 'f', OPT_FILTER },
93
96
  { 'q', OPT_LOG },
106
109
  { 'z', OPT_NOWILD },
107
110
  { 'Z', OPT_ETHERS },
108
111
  { 'y', OPT_LOCALISE },
 
112
  { '1', OPT_DBUS },
 
113
  { '3', OPT_BOOTP_DYNAMIC },
109
114
  { 'v', 0},
110
115
  { 'w', 0},
111
116
  { 0, 0 }
112
117
};
113
118
 
114
 
static char *usage =
115
 
"Usage: dnsmasq [options]\n\n"
116
 
#ifndef HAVE_GETOPT_LONG
117
 
"Use short options only on the command line.\n"
118
 
#endif
119
 
"Valid options are :\n"
120
 
"-a, --listen-address=ipaddr         Specify local address(es) to listen on.\n"
121
 
"-A, --address=/domain/ipaddr        Return ipaddr for all hosts in specified domains.\n"
122
 
"-b, --bogus-priv                    Fake reverse lookups for RFC1918 private address ranges.\n"
123
 
"-B, --bogus-nxdomain=ipaddr         Treat ipaddr as NXDOMAIN (defeats Verisign wildcard).\n" 
124
 
"-c, --cache-size=cachesize          Specify the size of the cache in entries (defaults to %d).\n"
125
 
"-C, --conf-file=path                Specify configuration file (defaults to " CONFFILE ").\n"
126
 
"-d, --no-daemon                     Do NOT fork into the background: run in debug mode.\n"
127
 
"-D, --domain-needed                 Do NOT forward queries with no domain part.\n" 
128
 
"-e, --selfmx                        Return self-pointing MX records for local hosts.\n"
129
 
"-E, --expand-hosts                  Expand simple names in /etc/hosts with domain-suffix.\n"
130
 
"-f, --filterwin2k                   Don't forward spurious DNS requests from Windows hosts.\n"
131
 
"-F, --dhcp-range=ipaddr,ipaddr,time Enable DHCP in the range given with lease duration.\n"
132
 
"-g, --group=groupname               Change to this group after startup (defaults to " CHGRP ").\n"
133
 
"-G, --dhcp-host=<hostspec>          Set address or hostname for a specified machine.\n"
134
 
"-h, --no-hosts                      Do NOT load " HOSTSFILE " file.\n"
135
 
"-H, --addn-hosts=path               Specify a hosts file to be read in addition to " HOSTSFILE ".\n"
136
 
"-i, --interface=interface           Specify interface(s) to listen on.\n"
137
 
"-I, --except-interface=int          Specify interface(s) NOT to listen on.\n"
138
 
"-j, --dhcp-userclass=<id>,<class>   Map DHCP user class to option set.\n"
139
 
"-J, --dhcp-ignore=<id>              Don't do DHCP for hosts in option set.\n"
140
 
"-k, --keep-in-foreground            Do NOT fork into the background, do NOT run in debug mode.\n"
141
 
"-K, --dhcp-authoritative            Assume we are the only DHCP server on the local network.\n"
142
 
"-l, --dhcp-leasefile=path           Specify where to store DHCP leases (defaults to " LEASEFILE ").\n"
143
 
"-L, --localmx                       Return MX records for local hosts.\n"
144
 
"-m, --mx-host=host_name,target,pref Specify an MX record.\n"
145
 
"-M, --dhcp-boot=<bootp opts>        Specify BOOTP options to DHCP server.\n"
146
 
"-n, --no-poll                       Do NOT poll " RESOLVFILE " file, reload only on SIGHUP.\n"
147
 
"-N, --no-negcache                   Do NOT cache failed search results.\n"
148
 
"-o, --strict-order                  Use nameservers strictly in the order given in " RESOLVFILE ".\n"
149
 
"-O, --dhcp-option=<optspec>         Set extra options to be set to DHCP clients.\n"
150
 
"-p, --port=number                   Specify port to listen for DNS requests on (defaults to 53).\n"
151
 
"-P, --edns-packet-max=<size>        Maximum supported UDP packet size for EDNS.0 (defaults to %d).\n"
152
 
"-q, --log-queries                   Log queries.\n"
153
 
"-Q, --query-port=number             Force the originating port for upstream queries.\n"
154
 
"-R, --no-resolv                     Do NOT read resolv.conf.\n"
155
 
"-r, --resolv-file=path              Specify path to resolv.conf (defaults to " RESOLVFILE ").\n"
156
 
"-S, --server=/domain/ipaddr         Specify address(es) of upstream servers with optional domains.\n"
157
 
"    --local=/domain/                Never forward queries to specified domains.\n"
158
 
"-s, --domain=domain                 Specify the domain to be assigned in DHCP leases.\n"
159
 
"-t, --mx-target=host_name           Specify default target in an MX record.\n"
160
 
"-T, --local-ttl=time                Specify time-to-live in seconds for replies from /etc/hosts.\n"
161
 
"-u, --user=username                 Change to this user after startup. (defaults to " CHUSER ").\n" 
162
 
"-U, --dhcp-vendorclass=<id>,<class> Map DHCP vendor class to option set.\n"
163
 
"-v, --version                       Display dnsmasq version and copyright information.\n"
164
 
"-V, --alias=addr,addr,mask          Translate IPv4 addresses from upstream servers.\n"
165
 
"-W, --srv-host=name,target,...      Specify a SRV record.\n"
166
 
"-w, --help                          Display this message.\n"
167
 
"-x, --pid-file=path                 Specify path of PID file. (defaults to " RUNFILE ").\n"
168
 
"-X, --dhcp-lease-max=number         Specify maximum number of DHCP leases (defaults to %d).\n"
169
 
"-y, --localise-queries              Answer DNS queries based on the interface a query was sent to.\n"
170
 
"-Y  --txt-record=name,txt....       Specify TXT DNS record.\n"
171
 
"-z, --bind-interfaces               Bind only to interfaces in use.\n"
172
 
"-Z, --read-ethers                   Read DHCP static host information from " ETHERSFILE ".\n"
173
 
"\n";
 
119
static const struct {
 
120
  char * const flag;
 
121
  char * const desc;
 
122
  char * const arg;
 
123
} usage[] = {
 
124
  { "-a, --listen-address=ipaddr",  gettext_noop("Specify local address(es) to listen on."), NULL },
 
125
  { "-A, --address=/domain/ipaddr", gettext_noop("Return ipaddr for all hosts in specified domains."), NULL },
 
126
  { "-b, --bogus-priv", gettext_noop("Fake reverse lookups for RFC1918 private address ranges."), NULL },
 
127
  { "-B, --bogus-nxdomain=ipaddr", gettext_noop("Treat ipaddr as NXDOMAIN (defeats Verisign wildcard)."), NULL }, 
 
128
  { "-c, --cache-size=cachesize", gettext_noop("Specify the size of the cache in entries (defaults to %s)."), "$" },
 
129
  { "-C, --conf-file=path", gettext_noop("Specify configuration file (defaults to %s)."), CONFFILE },
 
130
  { "-d, --no-daemon", gettext_noop("Do NOT fork into the background: run in debug mode."), NULL },
 
131
  { "-D, --domain-needed", gettext_noop("Do NOT forward queries with no domain part."), NULL }, 
 
132
  { "-e, --selfmx", gettext_noop("Return self-pointing MX records for local hosts."), NULL },
 
133
  { "-E, --expand-hosts", gettext_noop("Expand simple names in /etc/hosts with domain-suffix."), NULL },
 
134
  { "-f, --filterwin2k", gettext_noop("Don't forward spurious DNS requests from Windows hosts."), NULL },
 
135
  { "-F, --dhcp-range=ipaddr,ipaddr,time", gettext_noop("Enable DHCP in the range given with lease duration."), NULL },
 
136
  { "-g, --group=groupname", gettext_noop("Change to this group after startup (defaults to %s)."), CHGRP },
 
137
  { "-G, --dhcp-host=<hostspec>", gettext_noop("Set address or hostname for a specified machine."), NULL }, 
 
138
  { "-h, --no-hosts", gettext_noop("Do NOT load %s file."), HOSTSFILE },
 
139
  { "-H, --addn-hosts=path", gettext_noop("Specify a hosts file to be read in addition to %s."), HOSTSFILE },
 
140
  { "-i, --interface=interface", gettext_noop("Specify interface(s) to listen on."), NULL },
 
141
  { "-I, --except-interface=int", gettext_noop("Specify interface(s) NOT to listen on.") , NULL },
 
142
  { "-j, --dhcp-userclass=<id>,<class>", gettext_noop("Map DHCP user class to option set."), NULL },
 
143
  { "-J, --dhcp-ignore=<id>", gettext_noop("Don't do DHCP for hosts in option set."), NULL },
 
144
  { "-k, --keep-in-foreground", gettext_noop("Do NOT fork into the background, do NOT run in debug mode."), NULL },
 
145
  { "-K, --dhcp-authoritative", gettext_noop("Assume we are the only DHCP server on the local network."), NULL },
 
146
  { "-l, --dhcp-leasefile=path", gettext_noop("Specify where to store DHCP leases (defaults to %s)."), LEASEFILE },
 
147
  { "-L, --localmx", gettext_noop("Return MX records for local hosts."), NULL },
 
148
  { "-m, --mx-host=host_name,target,pref", gettext_noop("Specify an MX record."), NULL },
 
149
  { "-M, --dhcp-boot=<bootp opts>", gettext_noop("Specify BOOTP options to DHCP server."), NULL },
 
150
  { "-n, --no-poll", gettext_noop("Do NOT poll %s file, reload only on SIGHUP."), RESOLVFILE }, 
 
151
  { "-N, --no-negcache", gettext_noop("Do NOT cache failed search results."), NULL },
 
152
  { "-o, --strict-order", gettext_noop("Use nameservers strictly in the order given in %s."), RESOLVFILE },
 
153
  { "-O, --dhcp-option=<optspec>", gettext_noop("Set extra options to be set to DHCP clients."), NULL },
 
154
  { "-p, --port=number", gettext_noop("Specify port to listen for DNS requests on (defaults to 53)."), NULL },
 
155
  { "-P, --edns-packet-max=<size>", gettext_noop("Maximum supported UDP packet size for EDNS.0 (defaults to %s)."), "*" },
 
156
  { "-q, --log-queries", gettext_noop("Log queries."), NULL },
 
157
  { "-Q, --query-port=number", gettext_noop("Force the originating port for upstream queries."), NULL },
 
158
  { "-R, --no-resolv", gettext_noop("Do NOT read resolv.conf."), NULL },
 
159
  { "-r, --resolv-file=path", gettext_noop("Specify path to resolv.conf (defaults to %s)."), RESOLVFILE }, 
 
160
  { "-S, --server=/domain/ipaddr", gettext_noop("Specify address(es) of upstream servers with optional domains."), NULL },
 
161
  { "    --local=/domain/", gettext_noop("Never forward queries to specified domains."), NULL },
 
162
  { "-s, --domain=domain", gettext_noop("Specify the domain to be assigned in DHCP leases."), NULL },
 
163
  { "-t, --mx-target=host_name", gettext_noop("Specify default target in an MX record."), NULL },
 
164
  { "-T, --local-ttl=time", gettext_noop("Specify time-to-live in seconds for replies from /etc/hosts."), NULL },
 
165
  { "-u, --user=username", gettext_noop("Change to this user after startup. (defaults to %s)."), CHUSER }, 
 
166
  { "-U, --dhcp-vendorclass=<id>,<class>", gettext_noop("Map DHCP vendor class to option set."), NULL },
 
167
  { "-v, --version", gettext_noop("Display dnsmasq version and copyright information."), NULL },
 
168
  { "-V, --alias=addr,addr,mask", gettext_noop("Translate IPv4 addresses from upstream servers."), NULL },
 
169
  { "-W, --srv-host=name,target,...", gettext_noop("Specify a SRV record."), NULL },
 
170
  { "-w, --help", gettext_noop("Display this message."), NULL },
 
171
  { "-x, --pid-file=path", gettext_noop("Specify path of PID file. (defaults to %s)."), RUNFILE },
 
172
  { "-X, --dhcp-lease-max=number", gettext_noop("Specify maximum number of DHCP leases (defaults to %s)."), "&" },
 
173
  { "-y, --localise-queries", gettext_noop("Answer DNS queries based on the interface a query was sent to."), NULL },
 
174
  { "-Y  --txt-record=name,txt....", gettext_noop("Specify TXT DNS record."), NULL },
 
175
  { "-z, --bind-interfaces", gettext_noop("Bind only to interfaces in use."), NULL },
 
176
  { "-Z, --read-ethers", gettext_noop("Read DHCP static host information from %s."), ETHERSFILE },
 
177
  { "-1, --enable-dbus", gettext_noop("Enable the DBus interface for setting upstream servers, etc."), NULL },
 
178
  { "-2, --no-dhcp-interface=interface", gettext_noop("Do not provide DHCP on this interface, only provide DNS."), NULL },
 
179
  { "-3, --bootp-dynamic", gettext_noop("Enable dynamic address allocation for bootp."), NULL },
 
180
  { NULL, NULL, NULL }
 
181
}; 
 
182
 
 
183
/* We hide metacharaters in quoted strings by mapping them into the ASCII control
 
184
   character space. Note that the \0, \t \a \b \r  and \n characters are carefully placed in the
 
185
   following sequence so that they map to themselves: it is therefore possible to call
 
186
   unhide_metas repeatedly on string without breaking things.
 
187
   The transformation gets undone by opt_canonicalise, atoi_check and safe_string_alloc, and a 
 
188
   couple of other places. */
 
189
 
 
190
static const char meta[] = "\000123456\a\b\t\n78\r90abcdefABCDEF:,.";
 
191
 
 
192
static char hide_meta(char c)
 
193
{
 
194
  unsigned int i;
 
195
 
 
196
  for (i = 0; i < (sizeof(meta) - 1); i++)
 
197
    if (c == meta[i])
 
198
      return (char)i;
 
199
  
 
200
  return c;
 
201
}
 
202
 
 
203
static char unhide_meta(char cr)
 
204
 
205
  unsigned int c = cr;
 
206
  
 
207
  if (c < (sizeof(meta) - 1))
 
208
    cr = meta[c];
 
209
  
 
210
  return cr;
 
211
}
 
212
 
 
213
static void unhide_metas(char *cp)
 
214
{
 
215
  if (cp)
 
216
    for(; *cp; cp++)
 
217
      *cp = unhide_meta(*cp);
 
218
}
 
219
 
 
220
static char *safe_string_alloc(char *cp)
 
221
{
 
222
  char *ret = NULL;
 
223
  
 
224
  if (cp && strlen(cp) != 0)
 
225
    {
 
226
      ret = safe_malloc(strlen(cp)+1);
 
227
      strcpy(ret, cp); 
 
228
      
 
229
      /* restore hidden metachars */
 
230
      unhide_metas(ret);
 
231
    }
 
232
    
 
233
  return ret;
 
234
}
 
235
 
 
236
static char *safe_strchr(char *s, int c)
 
237
{
 
238
  if (!s) 
 
239
    return NULL;
 
240
 
 
241
  return strchr(s, c);
 
242
}
 
243
 
 
244
static int canonicalise_opt(char *s)
 
245
{
 
246
  if (!s)
 
247
    return 0;
 
248
 
 
249
  unhide_metas(s);
 
250
  return canonicalise(s);
 
251
}
 
252
 
 
253
static int atoi_check(char *a, int *res)
 
254
{
 
255
  char *p;
 
256
 
 
257
  if (!a)
 
258
    return 0;
 
259
 
 
260
  unhide_metas(a);
 
261
  
 
262
  for (p = a; *p; p++)
 
263
     if (*p < '0' || *p > '9')
 
264
       return 0;
 
265
 
 
266
  *res = atoi(a);
 
267
  return 1;
 
268
}
174
269
 
175
270
static void add_txt(struct daemon *daemon, char *name, char *txt)
176
271
{
187
282
  memcpy((r->txt)+1, txt, len);
188
283
}
189
284
 
190
 
/* filenames are OK with unquoted commas, restore them here. */
191
 
static char *safe_filename_alloc(char *filename)
192
 
{
193
 
  char *p, *ret = safe_string_alloc(filename);
194
 
  
195
 
  if (ret)
196
 
    for (p = ret; *p; p++)
197
 
      if (*p == '\001')
198
 
        *p = ',';
199
 
  
200
 
  return ret;
201
 
}
202
 
 
203
 
struct daemon *read_opts (int argc, char **argv)
 
285
struct daemon *read_opts (int argc, char **argv, char *compile_opts)
204
286
{
205
287
  struct daemon *daemon = safe_malloc(sizeof(struct daemon));
206
288
  char *problem = NULL, *buff = safe_malloc(MAXDNAME);
209
291
  char *p, *arg, *comma, *file_name_save = NULL, *conffile = CONFFILE;
210
292
  int hosts_index = 1, conffile_set = 0;
211
293
  int line_save = 0, lineno = 0;
 
294
    
212
295
  opterr = 0;
213
296
  
214
297
  memset(daemon, 0, sizeof(struct daemon));
248
331
              strncpy(buff, optarg, MAXDNAME);
249
332
              buff[MAXDNAME-1] = 0;
250
333
              arg = buff;
251
 
              for (p = arg; *p; p++)
252
 
                if (*p == ',')
253
 
                  *p = '\001';
254
334
            }
255
335
          else
256
336
            arg = NULL;
276
356
          else
277
357
            {
278
358
              int white;
 
359
              unsigned int lastquote;
279
360
              lineno++;
280
361
              
281
362
              /* Implement quotes, inside quotes we allow \\ \" \n and \t 
282
 
                 unquoted commas get changed to \001 also strip comments */
 
363
                 metacharacters get hidden also strip comments */
283
364
              
284
 
              for (white = 1, p = buff; *p; p++)
 
365
              for (white = 1, lastquote = 0, p = buff; *p; p++)
285
366
                {
286
367
                  if (*p == '"')
287
368
                    {
288
369
                      memmove(p, p+1, strlen(p+1)+1);
289
370
                      for(; *p && *p != '"'; p++)
290
 
                        if (*p == '\\' && 
291
 
                            (p[1] == '\\' || p[1] == '"' || p[1] == 'n' || p[1] == 't'))
292
 
                          {
293
 
                            if (p[1] == 't')
294
 
                              p[1] = '\t';
295
 
                            else if (p[1] == 'n')
296
 
                              p[1] = '\n';
297
 
                            memmove(p, p+1, strlen(p+1)+1);
298
 
                          }
 
371
                        {
 
372
                          if (*p == '\\' && strchr("\"tnabr\\", p[1]))
 
373
                            {
 
374
                              if (p[1] == 't')
 
375
                                p[1] = '\t';
 
376
                              else if (p[1] == 'n')
 
377
                                p[1] = '\n';
 
378
                              else if (p[1] == 'a')
 
379
                                p[1] = '\a';
 
380
                              else if (p[1] == 'b')
 
381
                                p[1] = '\b';
 
382
                              else if (p[1] == 'r')
 
383
                                p[1] = '\r';
 
384
                              memmove(p, p+1, strlen(p+1)+1);
 
385
                            }
 
386
                          *p = hide_meta(*p);
 
387
                        }
299
388
                      if (*p == '"') 
300
 
                        memmove(p, p+1, strlen(p+1)+1);
 
389
                        {
 
390
                          memmove(p, p+1, strlen(p+1)+1);
 
391
                          lastquote = p - buff;
 
392
                        }
301
393
                      else
302
 
                        complain("missing \"", lineno, conffile);
 
394
                        complain(_("missing \""), lineno, conffile);
303
395
                    }
304
396
 
305
397
                  if (white && *p == '#')
307
399
                      *p = 0;
308
400
                      break;
309
401
                    }
310
 
                  white = isspace(*p); 
311
 
                  if (*p == ',')
312
 
                    *p = '\001';
313
 
 
 
402
                  white = isspace(unhide_meta(*p)); 
314
403
                }
315
404
              /* fgets gets end of line char too. */
316
 
              while (strlen(buff) > 0 && isspace(buff[strlen(buff)-1]))
 
405
              while (strlen(buff) > lastquote && isspace(unhide_meta(buff[strlen(buff)-1])))
317
406
                buff[strlen(buff)-1] = 0;
318
407
              if (*buff == 0)
319
408
                continue; 
331
420
                  option = opts[i].val;
332
421
              if (!option)
333
422
                {
334
 
                  complain("bad option", lineno, conffile);
 
423
                  complain(_("bad option"), lineno, conffile);
335
424
                  continue;
336
425
                }
337
426
            }
348
437
              if (errno == ENOENT && !conffile_set)
349
438
                break; /* No conffile, all done. */
350
439
              else
351
 
                die("cannot read %s: %s", conffile);
 
440
                die(_("cannot read %s: %s"), conffile);
352
441
            }
353
442
        }
354
443
     
355
444
      if (!f && option == 'w')
356
445
        {
357
 
          printf (usage,  CACHESIZ, EDNS_PKTSZ, MAXLEASES);
 
446
          printf(_("Usage: dnsmasq [options]\n\n"));
 
447
#ifndef HAVE_GETOPT_LONG
 
448
          printf(_("Use short options only on the command line.\n"));
 
449
#endif
 
450
          printf(_("Valid options are :\n"));
 
451
          
 
452
          for (i = 0; usage[i].flag; i++)
 
453
            {
 
454
              if (usage[i].arg)
 
455
                {
 
456
                  if (strcmp(usage[i].arg, "$") == 0)
 
457
                    sprintf(buff, "%d", CACHESIZ);
 
458
                  else if (strcmp(usage[i].arg, "*") == 0)
 
459
                    sprintf(buff, "%d", EDNS_PKTSZ);
 
460
                  else if (strcmp(usage[i].arg, "&") == 0)
 
461
                    sprintf(buff, "%d", MAXLEASES);
 
462
                  else 
 
463
                    strcpy(buff, usage[i].arg);
 
464
                }
 
465
              printf("%-36.36s", usage[i].flag);
 
466
              printf(_(usage[i].desc), buff);
 
467
              printf("\n");
 
468
            }
 
469
 
358
470
          exit(0);
359
471
        }
360
472
 
361
473
      if (!f && option == 'v')
362
474
        {
363
 
          printf("Dnsmasq version %s  %s\n\n", VERSION, COPYRIGHT);
364
 
          printf("This software comes with ABSOLUTELY NO WARRANTY.\n");
365
 
          printf("Dnsmasq is free software, and you are welcome to redistribute it\n");
366
 
          printf("under the terms of the GNU General Public License, version 2.\n");
 
475
          printf(_("Dnsmasq version %s  %s\n"), VERSION, COPYRIGHT);
 
476
          printf(_("Compile time options %s\n\n"), compile_opts); 
 
477
          printf(_("This software comes with ABSOLUTELY NO WARRANTY.\n"));
 
478
          printf(_("Dnsmasq is free software, and you are welcome to redistribute it\n"));
 
479
          printf(_("under the terms of the GNU General Public License, version 2.\n"));
367
480
          exit(0);
368
481
        }
369
482
      
373
486
            daemon->options |= optmap[i].flag;
374
487
            option = 0;
375
488
            if (f && arg)
376
 
              complain("extraneous parameter", lineno, conffile);
 
489
              complain(_("extraneous parameter"), lineno, conffile);
377
490
            break;
378
491
          }
379
492
      
381
494
        {
382
495
          if (f && !arg)
383
496
            {
384
 
              complain("missing parameter", lineno, conffile);
 
497
              complain(_("missing parameter"), lineno, conffile);
385
498
              continue;
386
499
            }
387
500
                  
390
503
             case 'C': 
391
504
               if (!f)
392
505
                 {
393
 
                   conffile = safe_filename_alloc(arg);
 
506
                   conffile = safe_string_alloc(arg);
394
507
                   conffile_set = 1;
395
508
                   break;
396
509
                 }
398
511
               /* nest conffiles one deep */
399
512
               if (file_save)
400
513
                 {
401
 
                   complain("nested includes not allowed", lineno, conffile);
 
514
                   complain(_("nested includes not allowed"), lineno, conffile);
402
515
                   continue;
403
516
                 }
404
517
               file_name_save = conffile;
405
518
               file_save = f;
406
519
               line_save = lineno;
407
 
               conffile = safe_filename_alloc(arg);
 
520
               conffile = safe_string_alloc(arg);
408
521
               conffile_set = 1;
409
522
               lineno = 0;
410
523
               goto fileopen;
411
524
              
412
525
            case 'x': 
413
 
              daemon->runfile = safe_filename_alloc(arg);
 
526
              daemon->runfile = safe_string_alloc(arg);
414
527
              break;
415
528
              
416
529
            case 'r':
417
530
              {
418
 
                char *name = safe_filename_alloc(arg);
 
531
                char *name = safe_string_alloc(arg);
419
532
                struct resolvc *new, *list = daemon->resolv_files;
420
533
                
421
534
                if (list && list->is_default)
448
561
                int pref = 1;
449
562
                struct mx_srv_record *new;
450
563
 
451
 
                if ((comma = strchr(arg, '\001')))
 
564
                if ((comma = safe_strchr(arg, ',')))
452
565
                  {
453
566
                    char *prefstr;
454
567
                    *(comma++) = 0;
455
 
                    if ((prefstr=strchr(comma, '\001')))
 
568
                    if ((prefstr=strchr(comma, ',')))
456
569
                      {
457
570
                        *(prefstr++) = 0;
458
571
                        if (!atoi_check(prefstr, &pref))
459
572
                          {
460
573
                            option = '?';
461
 
                            problem = "bad MX preference";
 
574
                            problem = _("bad MX preference");
462
575
                            break;
463
576
                          }
464
577
                      }
465
578
                  }
466
579
 
467
 
                if (!canonicalise(arg) || (comma && !canonicalise(comma)))
 
580
                if (!canonicalise_opt(arg) || (comma && !canonicalise_opt(comma)))
468
581
                  {
469
582
                    option = '?';
470
 
                    problem = "bad MX name";
 
583
                    problem = _("bad MX name");
471
584
                    break;
472
585
                  }
473
586
 
482
595
              }
483
596
 
484
597
            case 't':
485
 
              if (!canonicalise(arg))
 
598
              if (!canonicalise_opt(arg))
486
599
                {
487
600
                  option = '?';
488
 
                  problem = "bad MX target";
 
601
                  problem = _("bad MX target");
489
602
                }
490
603
              else
491
604
                daemon->mxtarget = safe_string_alloc(arg);
492
605
              break;
493
606
              
494
607
            case 'l':
495
 
              daemon->lease_file = safe_filename_alloc(arg);
 
608
              daemon->lease_file = safe_string_alloc(arg);
496
609
              break;
497
610
              
498
611
            case 'H':
499
612
              {
500
613
                struct hostsfile *new = safe_malloc(sizeof(struct hostsfile));
501
 
                new->fname = safe_filename_alloc(arg);
 
614
                new->fname = safe_string_alloc(arg);
502
615
                new->index = hosts_index++;
503
616
                new->next = daemon->addn_hosts;
504
617
                daemon->addn_hosts = new;
508
621
            case 's':
509
622
              if (strcmp (arg, "#") == 0)
510
623
                daemon->options |= OPT_RESOLV_DOMAIN;
511
 
              else if (!canonicalise(arg))
 
624
              else if (!canonicalise_opt(arg))
512
625
                option = '?';
513
626
              else
514
627
                daemon->domain_suffix = safe_string_alloc(arg);
525
638
            case 'i':
526
639
              do {
527
640
                struct iname *new = safe_malloc(sizeof(struct iname));
528
 
                if ((comma = strchr(arg, '\001')))
 
641
                if ((comma = safe_strchr(arg, ',')))
529
642
                  *comma++ = 0;
530
643
                new->next = daemon->if_names;
531
644
                daemon->if_names = new;
533
646
                   "interface=" to disable all interfaces except loop. */
534
647
                new->name = safe_string_alloc(arg);
535
648
                new->isloop = new->used = 0;
536
 
                if (strchr(arg, ':'))
 
649
                if (safe_strchr(new->name, ':'))
537
650
                  daemon->options |= OPT_NOWILD;
538
651
                arg = comma;
539
652
              } while (arg);
540
653
              break;
541
654
            
542
655
            case 'I':
 
656
            case '2':
543
657
              do {
544
658
                struct iname *new = safe_malloc(sizeof(struct iname));
545
 
                if ((comma = strchr(arg, '\001')))
 
659
                if ((comma = safe_strchr(arg, ',')))
546
660
                  *comma++ = 0;
547
 
                new->next = daemon->if_except;
548
 
                daemon->if_except = new;
549
661
                new->name = safe_string_alloc(arg);
550
 
                if (strchr(arg, ':'))
551
 
                  daemon->options |= OPT_NOWILD;
 
662
                if (option == 'I')
 
663
                  {
 
664
                    new->next = daemon->if_except;
 
665
                    daemon->if_except = new;
 
666
                    if (safe_strchr(new->name, ':'))
 
667
                      daemon->options |= OPT_NOWILD;
 
668
                  }
 
669
                else
 
670
                  {
 
671
                    new->next = daemon->dhcp_except;
 
672
                    daemon->dhcp_except = new;
 
673
                  }
552
674
                arg = comma;
553
675
              } while (arg);
554
676
              break;
555
 
                      
 
677
              
556
678
            case 'B':
557
679
              {
558
680
                struct in_addr addr;
559
 
                if ((addr.s_addr = inet_addr(arg)) != (in_addr_t)-1)
 
681
                unhide_metas(arg);
 
682
                if (arg && (addr.s_addr = inet_addr(arg)) != (in_addr_t)-1)
560
683
                  {
561
684
                    struct bogus_addr *baddr = safe_malloc(sizeof(struct bogus_addr));
562
685
                    baddr->next = daemon->bogus_addr;
571
694
            case 'a':
572
695
              do {
573
696
                struct iname *new = safe_malloc(sizeof(struct iname));
574
 
                if ((comma = strchr(arg, '\001')))
 
697
                if ((comma = safe_strchr(arg, ',')))
575
698
                  *comma++ = 0;
 
699
                unhide_metas(arg);
576
700
                new->next = daemon->if_addrs;
577
 
#ifdef HAVE_IPV6
578
 
                if (inet_pton(AF_INET, arg, &new->addr.in.sin_addr))
 
701
                if (arg && (new->addr.in.sin_addr.s_addr = inet_addr(arg)) != (in_addr_t)-1)
579
702
                  {
580
703
                    new->addr.sa.sa_family = AF_INET;
581
704
#ifdef HAVE_SOCKADDR_SA_LEN
582
705
                    new->addr.in.sin_len = sizeof(struct sockaddr_in);
583
706
#endif
584
707
                  }
585
 
                else if (inet_pton(AF_INET6, arg, &new->addr.in6.sin6_addr))
 
708
#ifdef HAVE_IPV6
 
709
                else if (arg && inet_pton(AF_INET6, arg, &new->addr.in6.sin6_addr) > 0)
586
710
                  {
587
711
                    new->addr.sa.sa_family = AF_INET6;
588
712
                    new->addr.in6.sin6_flowinfo = htonl(0);
590
714
                    new->addr.in6.sin6_len = sizeof(struct sockaddr_in6);
591
715
#endif
592
716
                  }
593
 
#else
594
 
                if ((new->addr.in.sin_addr.s_addr = inet_addr(arg)) != (in_addr_t)-1)
595
 
                  {
596
 
                    new->addr.sa.sa_family = AF_INET;
597
 
#ifdef HAVE_SOCKADDR_SA_LEN
598
 
                    new->addr.in.sin_len = sizeof(struct sockaddr_in);
599
 
#endif
600
 
                  }
601
717
#endif
602
718
                else
603
719
                  {
616
732
              {
617
733
                struct server *serv, *newlist = NULL;
618
734
                
619
 
                if (*arg == '/')
 
735
                unhide_metas(arg);
 
736
 
 
737
                if (arg && *arg == '/')
620
738
                  {
621
739
                    char *end;
622
740
                    arg++;
627
745
                        /* # matches everything and becomes a zero length domain string */
628
746
                        if (strcmp(arg, "#") == 0)
629
747
                          domain = "";
630
 
                        else if (!canonicalise(arg) && strlen(arg) != 0)
 
748
                        else if (!canonicalise_opt(arg) && strlen(arg) != 0)
631
749
                          option = '?';
632
750
                        else
633
751
                          domain = safe_string_alloc(arg); /* NULL if strlen is zero */
662
780
                      option = '?';
663
781
                  }
664
782
                
665
 
                if (!*arg)
 
783
                if (!arg || !*arg)
666
784
                  {
667
785
                    newlist->flags |= SERV_NO_ADDR; /* no server */
668
786
                    if (newlist->flags & SERV_LITERAL_ADDRESS)
682
800
                            if (!atoi_check(portno+1, &source_port))
683
801
                              {
684
802
                                option = '?';
685
 
                                problem = "bad port";
 
803
                                problem = _("bad port");
686
804
                              }
687
805
                          }
688
806
                      }
693
811
                        if (!atoi_check(portno+1, &serv_port))
694
812
                          {
695
813
                            option = '?';
696
 
                            problem = "bad port";
 
814
                            problem = _("bad port");
697
815
                          }
698
816
                      }
699
817
 
700
 
#ifdef HAVE_IPV6
701
 
                    if (inet_pton(AF_INET, arg, &newlist->addr.in.sin_addr))
702
 
#else
703
818
                    if ((newlist->addr.in.sin_addr.s_addr = inet_addr(arg)) != (in_addr_t) -1)
704
 
#endif
705
819
                      {
706
820
                        newlist->addr.in.sin_port = htons(serv_port);   
707
821
                        newlist->source_addr.in.sin_port = htons(source_port); 
711
825
#endif
712
826
                        if (source)
713
827
                          {
714
 
#ifdef HAVE_IPV6
715
 
                            if (inet_pton(AF_INET, source+1, &newlist->source_addr.in.sin_addr))
716
 
#else
717
828
                            if ((newlist->source_addr.in.sin_addr.s_addr = inet_addr(source+1)) != (in_addr_t) -1)
718
 
#endif
719
829
                                newlist->flags |= SERV_HAS_SOURCE;
720
830
                            else
721
831
                              option = '?'; /* error */
724
834
                          newlist->source_addr.in.sin_addr.s_addr = INADDR_ANY;
725
835
                      }
726
836
#ifdef HAVE_IPV6
727
 
                    else if (inet_pton(AF_INET6, arg, &newlist->addr.in6.sin6_addr))
 
837
                    else if (inet_pton(AF_INET6, arg, &newlist->addr.in6.sin6_addr) > 0)
728
838
                      {
729
839
                        newlist->addr.in6.sin6_port = htons(serv_port);
730
840
                        newlist->source_addr.in6.sin6_port = htons(source_port);
735
845
#endif
736
846
                        if (source)
737
847
                          {
738
 
                            if (inet_pton(AF_INET6, source+1, &newlist->source_addr.in6.sin6_addr))
 
848
                            if (inet_pton(AF_INET6, source+1, &newlist->source_addr.in6.sin6_addr) > 0)
739
849
                              newlist->flags |= SERV_HAS_SOURCE;
740
850
                            else
741
851
                              option = '?'; /* error */
775
885
            case 'c':
776
886
              {
777
887
                int size;
 
888
                
778
889
                if (!atoi_check(arg, &size))
779
890
                  option = '?';
780
891
                else
840
951
                new->netid.net = NULL;
841
952
                new->flags = 0;
842
953
                
843
 
                problem = "bad dhcp-range";
 
954
                problem = _("bad dhcp-range");
844
955
 
 
956
                if (!arg)
 
957
                  {
 
958
                    option = '?';
 
959
                    break;
 
960
                  }
 
961
                
845
962
                for (cp = arg; *cp; cp++)
846
963
                  if (!(*cp == ' ' || *cp == '.' ||  (*cp >='0' && *cp <= '9')))
847
964
                    break;
848
965
 
849
 
                if (*cp != '\001' && (comma = strchr(arg, '\001')))
 
966
                if (*cp != ',' && (comma = strchr(arg, ',')))
850
967
                  {
851
968
                    *comma = 0;
852
969
                    if (strstr(arg, "net:") == arg)
865
982
                
866
983
                for (k = 1; k < 5; k++)
867
984
                  {
868
 
                    if (!(a[k] = strchr(a[k-1], '\001')))
 
985
                    if (!(a[k] = strchr(a[k-1], ',')))
869
986
                      break;
870
987
                    *(a[k]++) = 0;
871
988
                  }
894
1011
                    leasepos = 3;
895
1012
                    if (!is_same_net(new->start, new->end, new->netmask))
896
1013
                      {
897
 
                        problem = "inconsistent DHCP range";
 
1014
                        problem = _("inconsistent DHCP range");
898
1015
                        option = '?';
899
1016
                      }
900
1017
                  }
925
1042
                          {
926
1043
                            switch (a[leasepos][strlen(a[leasepos]) - 1])
927
1044
                              {
 
1045
                              case 'd':
 
1046
                              case 'D':
 
1047
                                fac *= 24;
 
1048
                                /* fall though */
928
1049
                              case 'h':
929
1050
                              case 'H':
930
1051
                                fac *= 60;
963
1084
                new->flags = 0;           
964
1085
                
965
1086
                
966
 
                a[0] = arg;
967
 
                for (k = 1; k < 6; k++)
968
 
                  {
969
 
                    if (!(a[k] = strchr(a[k-1], '\001')))
970
 
                      break;
971
 
                    *(a[k]++) = 0;
972
 
                  }
 
1087
                if ((a[0] = arg))
 
1088
                  for (k = 1; k < 6; k++)
 
1089
                    {
 
1090
                      if (!(a[k] = strchr(a[k-1], ',')))
 
1091
                        break;
 
1092
                      *(a[k]++) = 0;
 
1093
                    }
 
1094
                else
 
1095
                  k = 0;
973
1096
                   
974
 
                for(j = 0; j < k; j++)
 
1097
                for (j = 0; j < k; j++)
975
1098
                  if (strchr(a[j], ':')) /* ethernet address, netid or binary CLID */
976
1099
                    {
977
1100
                      char *arg = a[j];
987
1110
                              int len;
988
1111
                              arg += 3; /* dump id: */
989
1112
                              if (strchr(arg, ':'))
990
 
                                len = parse_hex(arg, arg, -1, NULL);
 
1113
                                len = parse_hex(arg, (unsigned char *)arg, -1, NULL);
991
1114
                              else
992
1115
                                len = (int) strlen(arg);
993
1116
                              
1023
1146
                          last = *lastp;
1024
1147
                          switch (last)
1025
1148
                            {
 
1149
                            case 'd':
 
1150
                            case 'D':
 
1151
                              fac *= 24;
 
1152
                              /* fall through */
1026
1153
                            case 'h':
1027
1154
                            case 'H':
1028
1155
                              fac *= 60;
1071
1198
 
1072
1199
                if (option == '?')
1073
1200
                  {
1074
 
                    problem = "bad dhcp-host";
 
1201
                    problem = _("bad dhcp-host");
1075
1202
                    if (new->flags & CONFIG_NAME)
1076
1203
                      free(new->hostname);
1077
1204
                    if (new->flags & CONFIG_CLID)
1101
1228
                new->val = NULL;
1102
1229
                new->vendor_class = NULL;
1103
1230
                                
1104
 
                if ((comma = strchr(arg, '\001')))
 
1231
                if ((comma = safe_strchr(arg, ',')))
1105
1232
                  {
1106
1233
                    struct dhcp_netid *np = NULL;
1107
1234
                    *comma++ = 0;
1114
1241
                        break;
1115
1242
                      
1116
1243
                      if (strstr(arg, "vendor:") == arg)
1117
 
                        new->vendor_class = safe_string_alloc(arg+7);
 
1244
                        new->vendor_class = (unsigned char *)safe_string_alloc(arg+7);
1118
1245
                      else
1119
1246
                        {
1120
1247
                          new->netid = safe_malloc(sizeof (struct dhcp_netid));
1123
1250
                          np = new->netid;
1124
1251
                        }
1125
1252
                      arg = comma;
1126
 
                      if ((comma = strchr(arg, '\001')))
 
1253
                      if ((comma = safe_strchr(arg, ',')))
1127
1254
                        *comma++ = 0;
1128
1255
                    } while (arg);
1129
1256
                  }
1131
1258
                if (!arg || (new->opt = atoi(arg)) == 0)
1132
1259
                  {
1133
1260
                    option = '?';
1134
 
                    problem = "bad dhcp-option";
 
1261
                    problem = _("bad dhcp-option");
1135
1262
                  }
1136
1263
                else if (comma && new->opt == 119 && !new->vendor_class)
1137
1264
                  {
1141
1268
                    size_t newlen, len = 0;
1142
1269
                    
1143
1270
                    arg = comma;
1144
 
                    if ((comma = strchr(arg, '\001')))
 
1271
                    if ((comma = safe_strchr(arg, ',')))
1145
1272
                      *(comma++) = 0;
1146
1273
 
1147
1274
                    while (arg && *arg)
1148
1275
                      {
1149
 
                        if (!canonicalise(arg))
 
1276
                        if (!canonicalise_opt(arg))
1150
1277
                          {
1151
1278
                            option = '?';
1152
 
                            problem = "bad domain in dhcp-option";
 
1279
                            problem = _("bad domain in dhcp-option");
1153
1280
                            break;
1154
1281
                          }
1155
1282
                        
1156
1283
                        if (!(p = realloc(p, len + strlen(arg) + 2)))
1157
 
                          die("could not get memory", NULL);
 
1284
                          die(_("could not get memory"), NULL);
1158
1285
                        q = p + len;
1159
1286
                        
1160
1287
                        /* add string on the end in RFC1035 format */
1161
1288
                        while (*arg) 
1162
1289
                          {
1163
 
                            char *cp = q++;
 
1290
                            unsigned char *cp = q++;
1164
1291
                            int j;
1165
1292
                            for (j = 0; *arg && (*arg != '.'); arg++, j++)
1166
1293
                              *q++ = *arg;
1174
1301
                        newlen = q - p;
1175
1302
                        for (tail = p + len; *tail; tail += (*tail) + 1)
1176
1303
                          for (r = p; r - p < (int)len; r += (*r) + 1)
1177
 
                            if (strcmp(r, tail) == 0)
 
1304
                            if (strcmp((char *)r, (char *)tail) == 0)
1178
1305
                              {
1179
1306
                                PUTSHORT((r - p) | 0xc000, tail); 
1180
1307
                                newlen = tail - p;
1184
1311
                        len = newlen;
1185
1312
                    
1186
1313
                        arg = comma;
1187
 
                        if (arg && (comma = strchr(arg, '\001')))
 
1314
                        if ((comma = safe_strchr(arg, ',')))
1188
1315
                          *(comma++) = 0;
1189
1316
                      }
1190
1317
 
1198
1325
                    is_addr = is_hex = is_dec = 1;
1199
1326
                    addrs = digs = 1;
1200
1327
                    for (cp = comma; *cp; cp++)
1201
 
                      if (*cp == '\001')
 
1328
                      if (*cp == ',')
1202
1329
                        {
1203
1330
                          addrs++;
1204
1331
                          is_dec = is_hex = 0;
1276
1403
                        while (addrs--) 
1277
1404
                          {
1278
1405
                            cp = comma;
1279
 
                            if ((comma = strchr(cp, '\001')))
 
1406
                            if ((comma = strchr(cp, ',')))
1280
1407
                              *comma++ = 0;
1281
1408
                            in.s_addr = inet_addr(cp);
1282
1409
                            memcpy(op, &in, INADDRSZ);
1288
1415
                        /* text arg */
1289
1416
                        new->len = strlen(comma);
1290
1417
                        /* keep terminating zero on string */
1291
 
                        new->val = safe_string_alloc(comma);
 
1418
                        new->val = (unsigned char *)safe_string_alloc(comma);
1292
1419
                      }
1293
1420
                  }
1294
1421
 
1295
1422
                if (new->len > 255)
1296
1423
                  {
1297
1424
                    option = '?';
1298
 
                    problem = "dhcp-option too long";
 
1425
                    problem = _("dhcp-option too long");
1299
1426
                  }
1300
1427
 
1301
1428
                if (option == '?')
1329
1456
                    struct dhcp_netid *newid = safe_malloc(sizeof(struct dhcp_netid));
1330
1457
                    newid->next = id;
1331
1458
                    id = newid;
1332
 
                    if ((comma = strchr(arg, '\001')))
 
1459
                    if ((comma = strchr(arg, ',')))
1333
1460
                      *comma++ = 0;
1334
1461
                    newid->net = safe_string_alloc(arg+4);
1335
1462
                    arg = comma;
1341
1468
                  {
1342
1469
                    char *dhcp_file, *dhcp_sname = NULL;
1343
1470
                    struct in_addr dhcp_next_server;
1344
 
                    if ((comma = strchr(arg, '\001')))
 
1471
                    if ((comma = strchr(arg, ',')))
1345
1472
                      *comma++ = 0;
1346
1473
                    dhcp_file = safe_string_alloc(arg);
1347
1474
                    dhcp_next_server.s_addr = 0;
1348
1475
                    if (comma)
1349
1476
                      {
1350
1477
                        arg = comma;
1351
 
                        if ((comma = strchr(arg, '\001')))
 
1478
                        if ((comma = strchr(arg, ',')))
1352
1479
                          *comma++ = 0;
1353
1480
                        dhcp_sname = safe_string_alloc(arg);
1354
 
                        if (comma && (dhcp_next_server.s_addr = inet_addr(comma)) == (in_addr_t)-1)
1355
 
                          option = '?';
 
1481
                        if (comma)
 
1482
                          {
 
1483
                            unhide_metas(comma);
 
1484
                            if ((dhcp_next_server.s_addr = inet_addr(comma)) == (in_addr_t)-1)
 
1485
                              option = '?';
 
1486
                          }
1356
1487
                      }
1357
1488
                    if (option != '?')
1358
1489
                      {
1381
1512
            case 'U':
1382
1513
            case 'j':
1383
1514
              {
1384
 
                if (!(comma = strchr(arg, '\001')))
 
1515
                if (!(comma = safe_strchr(arg, ',')))
1385
1516
                  option = '?';
1386
1517
                else
1387
1518
                  {
1388
1519
                    struct dhcp_vendor *new = safe_malloc(sizeof(struct dhcp_vendor));
1389
1520
                    *comma = 0;
1390
1521
                    new->netid.net = safe_string_alloc(arg);
 
1522
                    unhide_metas(comma+1);
1391
1523
                    new->len = strlen(comma+1);
1392
1524
                    new->data = safe_malloc(new->len);
1393
1525
                    memcpy(new->data, comma+1, new->len);
1406
1538
                daemon->dhcp_ignore = new;
1407
1539
                do {
1408
1540
                  struct dhcp_netid *member = safe_malloc(sizeof(struct dhcp_netid));
1409
 
                  if ((comma = strchr(arg, '\001')))
 
1541
                  if ((comma = safe_strchr(arg, ',')))
1410
1542
                    *comma++ = 0;
1411
1543
                  member->next = list;
1412
1544
                  list = member;
1427
1559
 
1428
1560
                mask.s_addr = 0xffffffff;
1429
1561
                
1430
 
                a[0] = arg;
1431
 
                for (k = 1; k < 4; k++)
1432
 
                  {
1433
 
                    if (!(a[k] = strchr(a[k-1], '\001')))
1434
 
                      break;
1435
 
                    *(a[k]++) = 0;
1436
 
                  }
 
1562
                if ((a[0] = arg))
 
1563
                  for (k = 1; k < 3; k++)
 
1564
                    {
 
1565
                      if (!(a[k] = strchr(a[k-1], ',')))
 
1566
                        break;
 
1567
                      *(a[k]++) = 0;
 
1568
                      unhide_metas(a[k]);
 
1569
                    }
 
1570
                else
 
1571
                  k = 0;
1437
1572
 
1438
 
                if ((k < 2) ||
 
1573
                if ((k < 2) || 
1439
1574
                    ((in.s_addr = inet_addr(a[0])) == (in_addr_t)-1) ||
1440
1575
                    ((out.s_addr = inet_addr(a[1])) == (in_addr_t)-1))
1441
1576
                  {
1461
1596
                struct txt_record *new;
1462
1597
                unsigned char *p, *q;
1463
1598
 
1464
 
                if ((comma = strchr(arg, '\001')))
 
1599
                if ((comma = safe_strchr(arg, ',')))
1465
1600
                  *(comma) = 0;
1466
1601
 
1467
 
                if (!canonicalise(arg))
 
1602
                if (!canonicalise_opt(arg))
1468
1603
                  {
1469
1604
                    option = '?';
1470
 
                    problem = "bad TXT record";
 
1605
                    problem = _("bad TXT record");
1471
1606
                    break;
1472
1607
                  }
1473
1608
                                  
1474
 
                if ((q = comma))
 
1609
                if ((q = (unsigned char *)comma))
1475
1610
                  while (1)
1476
1611
                    {
1477
1612
                      size_t len;
1478
 
                      if ((p = strchr(q+1, '\001')))
 
1613
                      if ((p = (unsigned char *)strchr((char*)q+1, ',')))
1479
1614
                        {
1480
1615
                          if ((len = p - q - 1) > 255)
1481
1616
                            { 
1483
1618
                              break;
1484
1619
                            }
1485
1620
                          *q = len;
1486
 
                          q = p;
 
1621
                          for (q = q+1; q < p; q++)
 
1622
                            *q = unhide_meta(*q);
1487
1623
                        }
1488
1624
                      else
1489
1625
                        {
1490
 
                          if ((len = strlen(q+1)) > 255)
 
1626
                          if ((len = strlen((char *)q+1)) > 255)
1491
1627
                            option = '?';
1492
1628
                          *q = len;
 
1629
                          for (q = q+1; *q; q++)
 
1630
                            *q = unhide_meta(*q);
1493
1631
                          break;
1494
1632
                        }
1495
1633
                    }
1496
1634
                
1497
1635
                if (option == '?')
1498
1636
                  {
1499
 
                    problem = "TXT record string too long";
 
1637
                    problem = _("TXT record string too long");
1500
1638
                    break;
1501
1639
                  }
1502
1640
 
1506
1644
                new->class = C_IN;
1507
1645
                if (comma)
1508
1646
                  {
1509
 
                    new->len = q - ((unsigned char *)comma) + *q + 1;
 
1647
                    new->len = q - ((unsigned char *)comma);
1510
1648
                    new->txt = safe_malloc(new->len);
1511
1649
                    memcpy(new->txt, comma, new->len);
1512
1650
                  }
1529
1667
                char *name, *target = NULL;
1530
1668
                struct mx_srv_record *new;
1531
1669
                
1532
 
                if ((comma = strchr(arg, '\001')))
 
1670
                if ((comma = safe_strchr(arg, ',')))
1533
1671
                  *(comma++) = 0;
1534
1672
 
1535
 
                if (!canonicalise(arg))
 
1673
                if (!canonicalise_opt(arg))
1536
1674
                  {
1537
1675
                    option = '?';
1538
 
                    problem = "bad SRV record";
 
1676
                    problem = _("bad SRV record");
1539
1677
                    break;
1540
1678
                  }
1541
1679
                name = safe_string_alloc(arg);
1543
1681
                if (comma)
1544
1682
                  {
1545
1683
                    arg = comma;
1546
 
                    if ((comma = strchr(arg, '\001')))
 
1684
                    if ((comma = strchr(arg, ',')))
1547
1685
                      *(comma++) = 0;
1548
 
                    if (!canonicalise(arg))
 
1686
                    if (!canonicalise_opt(arg))
1549
1687
                      {
1550
1688
                        option = '?';
1551
 
                        problem = "bad SRV target";
 
1689
                        problem = _("bad SRV target");
1552
1690
                        break;
1553
1691
                      }
1554
1692
                    target = safe_string_alloc(arg);
1555
1693
                    if (comma)
1556
1694
                      {
1557
1695
                        arg = comma;
1558
 
                        if ((comma = strchr(arg, '\001')))
 
1696
                        if ((comma = strchr(arg, ',')))
1559
1697
                          *(comma++) = 0;
1560
1698
                        if (!atoi_check(arg, &port))
1561
1699
                          {
1562
1700
                            option = '?';
1563
 
                            problem = "invalid port number";
 
1701
                            problem = _("invalid port number");
1564
1702
                            break;
1565
1703
                          }
1566
1704
                        if (comma)
1567
1705
                          {
1568
1706
                            arg = comma;
1569
 
                            if ((comma = strchr(arg, '\001')))
 
1707
                            if ((comma = strchr(arg, ',')))
1570
1708
                              *(comma++) = 0;
1571
1709
                            if (!atoi_check(arg, &priority))
1572
1710
                              {
1573
1711
                                option = '?';
1574
 
                                problem = "invalid priority";
 
1712
                                problem = _("invalid priority");
1575
1713
                                break;
1576
1714
                              }
1577
1715
                            if (comma)
1578
1716
                              {
1579
1717
                                arg = comma;
1580
 
                                if ((comma = strchr(arg, '\001')))
 
1718
                                if ((comma = strchr(arg, ',')))
1581
1719
                                  *(comma++) = 0;
1582
1720
                                if (!atoi_check(arg, &weight))
1583
1721
                                  {
1584
1722
                                    option = '?';
1585
 
                                    problem = "invalid weight";
 
1723
                                    problem = _("invalid weight");
1586
1724
                                    break;
1587
1725
                                  }
1588
1726
                              }
1607
1745
      if (option == '?')
1608
1746
        {
1609
1747
          if (f)
1610
 
            complain( problem ? problem : "error", lineno, conffile);
 
1748
            complain( problem ? problem : _("error"), lineno, conffile);
1611
1749
          else
 
1750
            die(_("bad command line options: %s."),
1612
1751
#ifdef HAVE_GETOPT_LONG
1613
 
            die("bad command line options: %s.", problem ? problem : "try --help");
 
1752
                problem ? problem : "try --help"
1614
1753
#else
1615
 
            die("bad command line options: %s.", problem ? problem : "try -w");
 
1754
                problem ? problem : "try -w"
1616
1755
#endif
 
1756
                );
1617
1757
        }
1618
1758
    }
1619
1759
      
1651
1791
      struct mx_srv_record *mx;
1652
1792
      
1653
1793
      if (gethostname(buff, MAXDNAME) == -1)
1654
 
        die("cannot get host-name: %s", NULL);
 
1794
        die(_("cannot get host-name: %s"), NULL);
1655
1795
      
1656
1796
      for (mx = daemon->mxnames; mx; mx = mx->next)
1657
1797
        if (!mx->issrv && hostname_isequal(mx->name, buff))
1675
1815
          mx->target = daemon->mxtarget;
1676
1816
    }
1677
1817
 
1678
 
  if (daemon->domain_suffix)
1679
 
    {
1680
 
       /* add domain for any srv record without one. */
1681
 
      struct mx_srv_record *srv;
1682
 
      
1683
 
      for (srv = daemon->mxnames; srv; srv = srv->next)
1684
 
        if (srv->issrv &&
1685
 
            strchr(srv->name, '.') && 
1686
 
            strchr(srv->name, '.') == strrchr(srv->name, '.'))
1687
 
          {
1688
 
            strcpy(buff, srv->name);
1689
 
            strcat(buff, ".");
1690
 
            strcat(buff, daemon->domain_suffix);
1691
 
            free(srv->name);
1692
 
            srv->name = safe_string_alloc(buff);
1693
 
          }
1694
 
    }
1695
 
  
1696
1818
  if (daemon->options & OPT_NO_RESOLV)
1697
1819
    daemon->resolv_files = 0;
1698
 
  else if (daemon->resolv_files && (daemon->resolv_files)->next && (daemon->options & OPT_NO_POLL))
1699
 
    die("only one resolv.conf file allowed in no-poll mode.", NULL);
 
1820
  else if (daemon->resolv_files && 
 
1821
           (daemon->resolv_files)->next && 
 
1822
           (daemon->options & OPT_NO_POLL))
 
1823
    die(_("only one resolv.conf file allowed in no-poll mode."), NULL);
1700
1824
  
1701
1825
  if (daemon->options & OPT_RESOLV_DOMAIN)
1702
1826
    {
1703
1827
      char *line;
1704
1828
      
1705
1829
      if (!daemon->resolv_files || (daemon->resolv_files)->next)
1706
 
        die("must have exactly one resolv.conf to read domain from.", NULL);
 
1830
        die(_("must have exactly one resolv.conf to read domain from."), NULL);
1707
1831
      
1708
1832
      if (!(f = fopen((daemon->resolv_files)->name, "r")))
1709
 
        die("failed to read %s: %m", (daemon->resolv_files)->name);
 
1833
        die(_("failed to read %s: %m"), (daemon->resolv_files)->name);
1710
1834
      
1711
1835
      while ((line = fgets(buff, MAXDNAME, f)))
1712
1836
        {
1716
1840
            continue;
1717
1841
          
1718
1842
          if ((token = strtok(NULL, " \t\n\r")) &&  
1719
 
              canonicalise(token) &&
 
1843
              canonicalise_opt(token) &&
1720
1844
              (daemon->domain_suffix = safe_string_alloc(token)))
1721
1845
            break;
1722
1846
        }
1724
1848
      fclose(f);
1725
1849
 
1726
1850
      if (!daemon->domain_suffix)
1727
 
        die("no search directive found in %s", (daemon->resolv_files)->name);
 
1851
        die(_("no search directive found in %s"), (daemon->resolv_files)->name);
1728
1852
    }
 
1853
 
 
1854
  if (daemon->domain_suffix)
 
1855
    {
 
1856
       /* add domain for any srv record without one. */
 
1857
      struct mx_srv_record *srv;
1729
1858
      
 
1859
      for (srv = daemon->mxnames; srv; srv = srv->next)
 
1860
        if (srv->issrv &&
 
1861
            strchr(srv->name, '.') && 
 
1862
            strchr(srv->name, '.') == strrchr(srv->name, '.'))
 
1863
          {
 
1864
            strcpy(buff, srv->name);
 
1865
            strcat(buff, ".");
 
1866
            strcat(buff, daemon->domain_suffix);
 
1867
            free(srv->name);
 
1868
            srv->name = safe_string_alloc(buff);
 
1869
          }
 
1870
    }
 
1871
     
1730
1872
  return daemon;
1731
1873
}
1732
1874