~ubuntu-branches/ubuntu/oneiric/nis/oneiric-proposed

« back to all changes in this revision

Viewing changes to ypserv-2.18/lib/compat.c

  • Committer: Bazaar Package Importer
  • Author(s): Scott James Remnant
  • Date: 2005-11-16 23:42:06 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20051116234206-p00omaw5ji5q0qhr
Tags: 3.15-3ubuntu1
Resynchronise with Debian.  (me)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
#if defined(HAVE_CONFIG_H)
 
3
#include "config.h"
 
4
#endif
 
5
 
 
6
#include <stdio.h>
 
7
#include <stdlib.h>
 
8
#include <string.h>
 
9
#ifdef HAVE_GETOPT_H
 
10
#include <getopt.h>
 
11
#endif
 
12
#include "compat.h"
 
13
 
 
14
#ifndef HAVE_STPCPY
 
15
char *
 
16
stpcpy (char *s1, const char *s2)
 
17
{
 
18
  /* This is a naive implementation for platforms missing the
 
19
     function.  It should be rewritten. */
 
20
  strcpy (s1, s2);
 
21
  return s1 + strlen (s2);
 
22
}
 
23
#endif /* not HAVE_STPCPY */
 
24
 
 
25
#ifndef HAVE_STRNDUP
 
26
char *
 
27
strndup (const char *s, int size)
 
28
{
 
29
  int len = strlen (s) + 1;
 
30
  char *retval;
 
31
 
 
32
  len = len > size ? size : len;
 
33
  retval = malloc (len);
 
34
  strcpy (retval, s);
 
35
  retval[len - 1] = '\0';
 
36
 
 
37
  return retval;
 
38
}
 
39
#endif /* not HAVE_STRNDUP */
 
40
 
 
41
#ifndef HAVE_GETOPT_LONG
 
42
int
 
43
getopt_long (int argc, char *const *argv, const char *shortopts,
 
44
             const struct option *longopts, int *longind)
 
45
{
 
46
  return getopt (argc, argv, shortopts);
 
47
}
 
48
#endif /* not HAVE_GETOPT_LONG */
 
49
 
 
50
#if !defined(HAVE_GETDELIM) && !defined(HAVE_GETLINE)
 
51
/* copied from cvs 1.11.5 source */
 
52
/* getline.c -- Replacement for GNU C library function getline
 
53
 
 
54
Copyright (C) 1993 Free Software Foundation, Inc.
 
55
 
 
56
This program is free software; you can redistribute it and/or
 
57
modify it under the terms of the GNU General Public License as
 
58
published by the Free Software Foundation; either version 2 of the
 
59
License, or (at your option) any later version.
 
60
 
 
61
This program is distributed in the hope that it will be useful, but
 
62
WITHOUT ANY WARRANTY; without even the implied warranty of
 
63
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
64
General Public License for more details.  */
 
65
 
 
66
/* Written by Jan Brittenson, bson@gnu.ai.mit.edu.  */
 
67
 
 
68
#include <sys/types.h>
 
69
#include <stdio.h>
 
70
#include <assert.h>
 
71
#include <errno.h>
 
72
 
 
73
#define GETLINE_NO_LIMIT -1
 
74
 
 
75
#if STDC_HEADERS
 
76
#include <stdlib.h>
 
77
#else
 
78
char *malloc (), *realloc ();
 
79
#endif
 
80
 
 
81
/* Always add at least this many bytes when extending the buffer.  */
 
82
#define MIN_CHUNK 64
 
83
 
 
84
/* Read up to (and including) a TERMINATOR from STREAM into *LINEPTR
 
85
   + OFFSET (and null-terminate it).  If LIMIT is non-negative, then
 
86
   read no more than LIMIT chars.
 
87
 
 
88
   *LINEPTR is a pointer returned from malloc (or NULL), pointing to
 
89
   *N characters of space.  It is realloc'd as necessary.
 
90
 
 
91
   Return the number of characters read (not including the null
 
92
   terminator), or -1 on error or EOF.  On a -1 return, the caller
 
93
   should check feof(), if not then errno has been set to indicate the
 
94
   error.  */
 
95
 
 
96
int
 
97
getstr (char **lineptr, size_t *n, FILE *stream, int terminator,
 
98
        int offset, int limit)
 
99
{
 
100
  int nchars_avail;             /* Allocated but unused chars in *LINEPTR.  */
 
101
  char *read_pos;               /* Where we're reading into *LINEPTR. */
 
102
  int ret;
 
103
 
 
104
  if (!lineptr || !n || !stream)
 
105
    {
 
106
      errno = EINVAL;
 
107
      return -1;
 
108
    }
 
109
 
 
110
  if (!*lineptr)
 
111
    {
 
112
      *n = MIN_CHUNK;
 
113
      *lineptr = malloc (*n);
 
114
      if (!*lineptr)
 
115
        {
 
116
          errno = ENOMEM;
 
117
          return -1;
 
118
        }
 
119
      *lineptr[0] = '\0';
 
120
    }
 
121
 
 
122
  nchars_avail = *n - offset;
 
123
  read_pos = *lineptr + offset;
 
124
 
 
125
  for (;;)
 
126
    {
 
127
      int save_errno;
 
128
      register int c;
 
129
 
 
130
      if (limit == 0)
 
131
          break;
 
132
      else
 
133
      {
 
134
          c = getc (stream);
 
135
 
 
136
          /* If limit is negative, then we shouldn't pay attention to
 
137
             it, so decrement only if positive. */
 
138
          if (limit > 0)
 
139
              limit--;
 
140
      }
 
141
 
 
142
      save_errno = errno;
 
143
 
 
144
      /* We always want at least one char left in the buffer, since we
 
145
         always (unless we get an error while reading the first char)
 
146
         NUL-terminate the line buffer.  */
 
147
 
 
148
      assert((*lineptr + *n) == (read_pos + nchars_avail));
 
149
      if (nchars_avail < 2)
 
150
        {
 
151
          if (*n > MIN_CHUNK)
 
152
            *n *= 2;
 
153
          else
 
154
            *n += MIN_CHUNK;
 
155
 
 
156
          nchars_avail = *n + *lineptr - read_pos;
 
157
          *lineptr = realloc (*lineptr, *n);
 
158
          if (!*lineptr)
 
159
            {
 
160
              errno = ENOMEM;
 
161
              return -1;
 
162
            }
 
163
          read_pos = *n - nchars_avail + *lineptr;
 
164
          assert((*lineptr + *n) == (read_pos + nchars_avail));
 
165
        }
 
166
 
 
167
      if (ferror (stream))
 
168
        {
 
169
          /* Might like to return partial line, but there is no
 
170
             place for us to store errno.  And we don't want to just
 
171
             lose errno.  */
 
172
          errno = save_errno;
 
173
          return -1;
 
174
        }
 
175
 
 
176
      if (c == EOF)
 
177
        {
 
178
          /* Return partial line, if any.  */
 
179
          if (read_pos == *lineptr)
 
180
            return -1;
 
181
          else
 
182
            break;
 
183
        }
 
184
 
 
185
      *read_pos++ = c;
 
186
      nchars_avail--;
 
187
 
 
188
      if (c == terminator)
 
189
        /* Return the line.  */
 
190
        break;
 
191
    }
 
192
 
 
193
  /* Done - NUL terminate and return the number of chars read.  */
 
194
  *read_pos = '\0';
 
195
 
 
196
  ret = read_pos - (*lineptr + offset);
 
197
  return ret;
 
198
}
 
199
 
 
200
ssize_t
 
201
getline (char **lineptr, size_t * n, FILE * stream)
 
202
{
 
203
  return getstr (lineptr, n, stream, '\n', 0, GETLINE_NO_LIMIT);
 
204
}
 
205
 
 
206
int
 
207
getline_safe (char **lineptr, size_t *n, FILE *stream, int limit)
 
208
{
 
209
  return getstr (lineptr, n, stream, '\n', 0, limit);
 
210
}
 
211
 
 
212
#endif /* not HAVE_GETDELIM and not HAVE_GETLINE */
 
213
 
 
214
#if !defined(HAVE_SVC_GETCALLER) && !defined(svc_getcaller)
 
215
const struct sockaddr_in *
 
216
svc_getcaller(const SVCXPRT *xprt)
 
217
{
 
218
#  ifdef HAVE_SVC_GETRPCCALLER
 
219
  const struct netbuf *addr;
 
220
  addr = svc_getrpccaller(xprt);
 
221
  log_msg ("warning: Bogus svc_getcaller() called");
 
222
  /* XXX find out how the result from svc_getrpccaller relates to
 
223
     svc_getcaller */
 
224
  assert(sizeof(struct sockaddr_in) == addr->len);
 
225
  return (const struct sockaddr_in *)addr->buf;
 
226
#  else /* not HAVE_SVC_GETRPCCALLER */
 
227
#    error "Missing both svc_getcaller() and svc_getrpccaller()"
 
228
#  endif /* not HAVE_SVC_GETRPCCALLER */
 
229
}
 
230
#endif /* not HAVE_SVC_GETCALLER */
 
231
 
 
232
 
 
233
#ifndef HAVE__RPC_DTABLESIZE
 
234
#  if HAVE_GETDTABLESIZE
 
235
int _rpc_dtablesize()
 
236
{
 
237
        static int size;
 
238
 
 
239
        if (size == 0) {
 
240
                size = getdtablesize();
 
241
        }
 
242
        return (size);
 
243
}
 
244
#  else
 
245
#  include <sys/resource.h>
 
246
int _rpc_dtablesize()
 
247
{
 
248
    static int size = 0;
 
249
    struct rlimit rlb;
 
250
 
 
251
    if (size == 0)
 
252
    {
 
253
        if (getrlimit(RLIMIT_NOFILE, &rlb) >= 0)
 
254
            size = rlb.rlim_cur;
 
255
    }
 
256
 
 
257
    return size;
 
258
}
 
259
#  endif /* not HAVE_GETDTABLESIZE */
 
260
#endif /* not HAVE__RPC_DTABLESIZE */
 
261
 
 
262
#ifndef HAVE_INET_ATON
 
263
/* Source: http://mail.gnu.org/archive/html/autoconf/2002-08/msg00036.html */
 
264
/*  $Id: compat.c,v 1.1.2.5 2005/05/19 12:12:06 kukuk Exp $
 
265
**
 
266
**  Replacement for a missing inet_aton.
 
267
**
 
268
**  Written by Russ Allbery <rra@bogus.example.com>
 
269
**  This work is hereby placed in the public domain by its author.
 
270
**
 
271
**  Provides the same functionality as the standard library routine
 
272
**  inet_aton for those platforms that don't have it.  inet_aton is
 
273
**  thread-safe.
 
274
*/
 
275
 
 
276
/* #include "config.h" */
 
277
/* #include "clibrary.h" */
 
278
#include <netinet/in.h>
 
279
 
 
280
/* If we're running the test suite, rename inet_ntoa to avoid conflicts with
 
281
   the system version. */
 
282
#if TESTING
 
283
# define inet_aton test_inet_aton
 
284
int test_inet_aton(const char *, struct in_addr *);
 
285
#endif
 
286
 
 
287
int
 
288
inet_aton(const char *s, struct in_addr *addr)
 
289
{
 
290
    unsigned long octet[4], address;
 
291
    const char *p;
 
292
    int base, i;
 
293
    int part = 0;
 
294
 
 
295
    if (s == NULL) return 0;
 
296
 
 
297
    /* Step through each period-separated part of the address.  If we see
 
298
       more than four parts, the address is invalid. */
 
299
    for (p = s; *p != 0; part++) {
 
300
        if (part > 3) return 0;
 
301
 
 
302
        /* Determine the base of the section we're looking at.  Numbers are
 
303
           represented the same as in C; octal starts with 0, hex starts
 
304
           with 0x, and anything else is decimal. */
 
305
        if (*p == '0') {
 
306
            p++;
 
307
            if (*p == 'x') {
 
308
                p++;
 
309
                base = 16;
 
310
            } else {
 
311
                base = 8;
 
312
            }
 
313
        } else {
 
314
            base = 10;
 
315
        }
 
316
 
 
317
        /* Make sure there's actually a number.  (A section of just "0"
 
318
           would set base to 8 and leave us pointing at a period; allow
 
319
           that.) */
 
320
        if (*p == '.' && base != 8) return 0;
 
321
        octet[part] = 0;
 
322
 
 
323
        /* Now, parse this segment of the address.  For each digit, multiply
 
324
           the result so far by the base and then add the value of the
 
325
           digit.  Be careful of arithmetic overflow in cases where an
 
326
           unsigned long is 32 bits; we need to detect it *before* we
 
327
           multiply by the base since otherwise we could overflow and wrap
 
328
           and then not detect the error. */
 
329
        for (; *p != 0 && *p != '.'; p++) {
 
330
            if (octet[part] > 0xffffffffUL / base) return 0;
 
331
 
 
332
            /* Use a switch statement to parse each digit rather than
 
333
               assuming ASCII.  Probably pointless portability.... */
 
334
            switch (*p) {
 
335
                case '0':           i = 0;  break;
 
336
                case '1':           i = 1;  break;
 
337
                case '2':           i = 2;  break;
 
338
                case '3':           i = 3;  break;
 
339
                case '4':           i = 4;  break;
 
340
                case '5':           i = 5;  break;
 
341
                case '6':           i = 6;  break;
 
342
                case '7':           i = 7;  break;
 
343
                case '8':           i = 8;  break;
 
344
                case '9':           i = 9;  break;
 
345
                case 'A': case 'a': i = 10; break;
 
346
                case 'B': case 'b': i = 11; break;
 
347
                case 'C': case 'c': i = 12; break;
 
348
                case 'D': case 'd': i = 13; break;
 
349
                case 'E': case 'e': i = 14; break;
 
350
                case 'F': case 'f': i = 15; break;
 
351
                default:            return 0;
 
352
            }
 
353
            if (i >= base) return 0;
 
354
            octet[part] = (octet[part] * base) + i;
 
355
        }
 
356
 
 
357
        /* Advance over periods; the top of the loop will increment the
 
358
           count of parts we've seen.  We need a check here to detect an
 
359
           illegal trailing period. */
 
360
        if (*p == '.') {
 
361
            p++;
 
362
            if (*p == 0) return 0;
 
363
        }
 
364
    }
 
365
    if (part == 0) return 0;
 
366
 
 
367
    /* IPv4 allows three types of address specification:
 
368
 
 
369
           a.b
 
370
           a.b.c
 
371
           a.b.c.d
 
372
 
 
373
       If there are fewer than four segments, the final segment accounts for
 
374
       all of the remaining portion of the address.  For example, in the a.b
 
375
       form, b is the final 24 bits of the address.  We also allow a simple
 
376
       number, which is interpreted as the 32-bit number corresponding to
 
377
       the full IPv4 address.
 
378
 
 
379
       The first for loop below ensures that any initial segments represent
 
380
       only 8 bits of the address and builds the upper portion of the IPv4
 
381
       address.  Then, the remaining segment is checked to make sure it's no
 
382
       bigger than the remaining space in the address and then is added into
 
383
       the result. */
 
384
    address = 0;
 
385
    for (i = 0; i < part - 1; i++) {
 
386
        if (octet[i] > 0xff) return 0;
 
387
        address |= octet[i] << (8 * (3 - i));
 
388
    }
 
389
    if (octet[i] > (0xffffffffUL >> (i * 8))) return 0;
 
390
    address |= octet[i];
 
391
    if (addr != NULL) addr->s_addr = htonl(address);
 
392
    return 1;
 
393
}
 
394
#endif /* not HAVE_INET_ATON */
 
395
 
 
396
 
 
397
#ifndef HAVE_INET_PTON
 
398
#include <arpa/inet.h>
 
399
#include <sys/socket.h>
 
400
int
 
401
inet_pton(int af, const char *src, void *dst)
 
402
{
 
403
  switch (af) {
 
404
  case AF_INET:
 
405
    return inet_aton(src, (struct in_addr *)dst);
 
406
    break;
 
407
#ifdef AF_INET6
 
408
  case AF_INET6:
 
409
#endif /* AF_INET6 */
 
410
  default:
 
411
    fprintf(stderr, "warning: Bogus inet_pton() called\n");
 
412
    errno = EAFNOSUPPORT;
 
413
    return -1;
 
414
    break;
 
415
  }
 
416
}
 
417
#endif /* not HAVE_INET_PTON */
 
418
 
 
419
#ifndef HAVE_XDR_YPXFRSTAT
 
420
#include <rpc/rpc.h>
 
421
#include "yp.h"
 
422
bool_t
 
423
xdr_ypxfrstat(XDR *xdrs, ypxfrstat *objp)
 
424
{
 
425
    if (!xdr_enum(xdrs, (enum_t *)objp))
 
426
        return FALSE;
 
427
 
 
428
    return TRUE;
 
429
}
 
430
#endif /* not HAVE_XDR_YPXFRSTAT */
 
431
 
 
432
#ifndef HAVE_XDR_DOMAINNAME
 
433
#include <rpc/rpc.h>
 
434
bool_t
 
435
xdr_domainname(XDR *xdrs, domainname *objp)
 
436
{
 
437
    if (!xdr_string(xdrs, objp, YPMAXDOMAIN))
 
438
        return FALSE;
 
439
 
 
440
    return TRUE;
 
441
}
 
442
#endif /* not HAVE_XDR_DOMAINNAME */
 
443
 
 
444
#ifndef HAVE_XDR_YPRESP_XFR
 
445
#include <rpc/rpc.h>
 
446
bool_t
 
447
xdr_ypresp_xfr(XDR *xdrs, ypresp_xfr *objp)
 
448
{
 
449
    if (!xdr_u_int(xdrs, &objp->transid))
 
450
        return FALSE;
 
451
 
 
452
    if (!xdr_ypxfrstat(xdrs, &objp->xfrstat))
 
453
        return FALSE;
 
454
 
 
455
    return TRUE;
 
456
}
 
457
#endif /* not HAVE_XDR_YPRESP_XFR */
 
458
 
 
459
#ifndef HAVE_XDR_YPMAP_PARMS
 
460
bool_t
 
461
xdr_ypmap_parms(XDR *xdrs, ypmap_parms *objp)
 
462
{
 
463
  if (!xdr_domainname(xdrs, &objp->domain))
 
464
    return (FALSE);
 
465
  if (!xdr_mapname(xdrs, &objp->map))
 
466
    return (FALSE);
 
467
  if (!xdr_u_int(xdrs, &objp->ordernum))
 
468
    return (FALSE);
 
469
  if (!xdr_peername(xdrs, &objp->peer))
 
470
    return (FALSE);
 
471
  return (TRUE);
 
472
}
 
473
#endif /* not HAVE_XDR_YPMAP_PARMS */
 
474
 
 
475
 
 
476
#ifndef HAVE_XDR_YPREQ_XFR
 
477
bool_t
 
478
xdr_ypreq_xfr(XDR *xdrs, ypreq_xfr *objp)
 
479
{
 
480
  if (!xdr_ypmap_parms(xdrs, &objp->map_parms))
 
481
    return (FALSE);
 
482
  if (!xdr_u_int(xdrs, &objp->transid))
 
483
    return (FALSE);
 
484
  if (!xdr_u_int(xdrs, &objp->prog))
 
485
    return (FALSE);
 
486
  if (!xdr_u_int(xdrs, &objp->port))
 
487
    return (FALSE);
 
488
  return (TRUE);
 
489
}
 
490
#endif /* not HAVE_XDR_YPREQ_XFR */
 
491
 
 
492
#ifndef HAVE_XDR_MAPNAME
 
493
bool_t
 
494
xdr_mapname (XDR *xdrs, mapname *objp)
 
495
{
 
496
  if (!xdr_string (xdrs, objp, YPMAXMAP))
 
497
    return FALSE;
 
498
 
 
499
  return TRUE;
 
500
}
 
501
#endif /* not HAVE_XDR_MAPNAME */
 
502
 
 
503
#ifndef HAVE_XDR_PEERNAME
 
504
bool_t
 
505
xdr_peername (XDR *xdrs, peername *objp)
 
506
{
 
507
  if (!xdr_string (xdrs, objp, YPMAXPEER))
 
508
    return (FALSE);
 
509
  return (TRUE);
 
510
}
 
511
#endif /* not HAVE_XDR_PEERNAME */
 
512
 
 
513
#ifndef HAVE_XDR_YPSTAT
 
514
bool_t
 
515
xdr_ypstat (XDR *xdrs, ypstat *objp)
 
516
{
 
517
  if (!xdr_enum (xdrs, (enum_t *) objp))
 
518
    return FALSE;
 
519
 
 
520
  return TRUE;
 
521
}
 
522
#endif /* not HAVE_XDR_YPSTAT */
 
523
 
 
524
#ifndef HAVE_XDR_YPRESP_MASTER
 
525
bool_t
 
526
xdr_ypresp_master (XDR *xdrs, ypresp_master *objp)
 
527
{
 
528
  if (!xdr_ypstat (xdrs, &objp->stat))
 
529
    return FALSE;
 
530
  if (!xdr_peername (xdrs, &objp->peer))
 
531
    return FALSE;
 
532
  return TRUE;
 
533
}
 
534
#endif /* not HAVE_XDR_YPRESP_MASTER */
 
535
 
 
536
#ifndef HAVE_XDR_YPBIND_BINDING
 
537
bool_t
 
538
xdr_ypbind_binding (XDR *xdrs, ypbind_binding *objp)
 
539
{
 
540
  if (!xdr_opaque (xdrs, objp->ypbind_binding_addr, 4))
 
541
    return FALSE;
 
542
  if (!xdr_opaque (xdrs, objp->ypbind_binding_port, 2))
 
543
    return FALSE;
 
544
  return TRUE;
 
545
}
 
546
#endif /* not HAVE_XDR_YPBIND_BINDING */
 
547
 
 
548
#ifndef HAVE_XDR_YPREQ_NOKEY
 
549
bool_t
 
550
xdr_ypreq_nokey (XDR *xdrs, ypreq_nokey *objp)
 
551
{
 
552
  if (!xdr_domainname (xdrs, &objp->domain))
 
553
    return FALSE;
 
554
 
 
555
  if (!xdr_mapname (xdrs, &objp->map))
 
556
    return FALSE;
 
557
 
 
558
  return TRUE;
 
559
}
 
560
#endif /* not HAVE_XDR_YPREQ_NOKEY */
 
561
 
 
562
#ifndef HAVE_XDR_YPPUSH_STATUS
 
563
bool_t
 
564
xdr_yppush_status(XDR *xdrs, yppush_status *objp)
 
565
{
 
566
  if (!xdr_enum(xdrs, (enum_t *)objp))
 
567
    return (FALSE);
 
568
  return (TRUE);
 
569
}
 
570
#endif /* not HAVE_XDR_YPPUSH_STATUS */
 
571
 
 
572
#ifndef HAVE_XDR_YPPUSHRESP_XFR
 
573
bool_t
 
574
xdr_yppushresp_xfr(XDR *xdrs, yppushresp_xfr *objp)
 
575
{
 
576
  if (!xdr_u_int(xdrs, &objp->transid))
 
577
    return (FALSE);
 
578
  if (!xdr_yppush_status(xdrs, &objp->status))
 
579
    return (FALSE);
 
580
  return (TRUE);
 
581
}
 
582
#endif /* not HAVE_XDR_YPPUSHRESP_XFR */