let ipkg fail when a package file to be installed is not found
[openwrt.git] / openwrt / package / mtr / patches / 501-dns.patch
1 diff -Naur mtr-0.69.old/dns.c mtr-0.69.new/dns.c
2 --- mtr-0.69.old/dns.c  2005-01-11 09:32:42.000000000 +0100
3 +++ mtr-0.69.new/dns.c  2005-10-03 21:31:27.000000000 +0200
4 @@ -853,6 +853,507 @@
5    fputs("\r",stderr);
6  }
7  
8 +#ifdef __UCLIBC__
9 +
10 +static const char       digits[] = "0123456789";
11 +#define __set_errno(e) (errno = (e))
12 +
13 +#define NS_PUT16(s, cp) do { \
14 +        register u_int16_t t_s = (u_int16_t)(s); \
15 +        register u_char *t_cp = (u_char *)(cp); \
16 +        *t_cp++ = t_s >> 8; \
17 +        *t_cp   = t_s; \
18 +        (cp) += NS_INT16SZ; \
19 +} while (0)
20 +
21 +
22 +
23 +#define NS_PUT32(l, cp) do { \
24 +        register u_int32_t t_l = (u_int32_t)(l); \
25 +        register u_char *t_cp = (u_char *)(cp); \
26 +        *t_cp++ = t_l >> 24; \
27 +        *t_cp++ = t_l >> 16; \
28 +        *t_cp++ = t_l >> 8; \
29 +        *t_cp   = t_l; \
30 +        (cp) += NS_INT32SZ; \
31 +} while (0)
32 +
33 +
34 +void
35 +ns_put16(u_int src, u_char *dst) {
36 +        NS_PUT16(src, dst);
37 +}
38 +
39 +void
40 +ns_put32(u_long src, u_char *dst) {
41 +        NS_PUT32(src, dst);
42 +}
43 +
44 +void __putshort(u_int16_t src, u_char *dst) { ns_put16(src, dst); }
45 +void __putlong(u_int32_t src, u_char *dst) { ns_put32(src, dst); }
46 +
47 +int
48 +mklower(int ch) {
49 +        if (ch >= 0x41 && ch <= 0x5A)
50 +                return (ch + 0x20);
51 +        return (ch);
52 +}
53 +
54 +
55 +static int
56 +dn_find(const u_char *domain, const u_char *msg,
57 +        const u_char * const *dnptrs,
58 +        const u_char * const *lastdnptr)
59 +{
60 +        const u_char *dn, *cp, *sp;
61 +        const u_char * const *cpp;
62 +        u_int n;
63 +
64 +        for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
65 +                sp = *cpp;
66 +                /*
67 +                 * terminate search on:
68 +                 * root label
69 +                 * compression pointer
70 +                 * unusable offset
71 +                 */
72 +                while (*sp != 0 && (*sp & NS_CMPRSFLGS) == 0 &&
73 +                       (sp - msg) < 0x4000) {
74 +                        dn = domain;
75 +                        cp = sp;
76 +                        while ((n = *cp++) != 0) {
77 +                                /*
78 +                                 * check for indirection
79 +                                 */
80 +                                switch (n & NS_CMPRSFLGS) {
81 +                                case 0:         /* normal case, n == len */
82 +                                        if (n != *dn++)
83 +                                                goto next;
84 +                                        for ((void)NULL; n > 0; n--)
85 +                                                if (mklower(*dn++) !=
86 +                                                    mklower(*cp++))
87 +                                                        goto next;
88 +                                        /* Is next root for both ? */
89 +                                        if (*dn == '\0' && *cp == '\0')
90 +                                                return (sp - msg);
91 +                                        if (*dn)
92 +                                                continue;
93 +                                        goto next;
94 +
95 +                                case NS_CMPRSFLGS:      /* indirection */
96 +                                        cp = msg + (((n & 0x3f) << 8) | *cp);
97 +                                        break;
98 +
99 +                                default:        /* illegal type */
100 +                                        __set_errno (EMSGSIZE);
101 +                                        return (-1);
102 +                                }
103 +                        }
104 + next:
105 +                        sp += *sp + 1;
106 +                }
107 +        }
108 +        __set_errno (ENOENT);
109 +        return (-1);
110 +}
111 +
112 +
113 +int
114 +ns_name_pack(const u_char *src, u_char *dst, int dstsiz,
115 +             const u_char **dnptrs, const u_char **lastdnptr)
116 +{
117 +        u_char *dstp;
118 +        const u_char **cpp, **lpp, *eob, *msg;
119 +        const u_char *srcp;
120 +        int n, l, first = 1;
121 +
122 +        srcp = src;
123 +        dstp = dst;
124 +        eob = dstp + dstsiz;
125 +        lpp = cpp = NULL;
126 +        if (dnptrs != NULL) {
127 +                if ((msg = *dnptrs++) != NULL) {
128 +                        for (cpp = dnptrs; *cpp != NULL; cpp++)
129 +                                (void)NULL;
130 +                        lpp = cpp;      /* end of list to search */
131 +                }
132 +        } else
133 +                msg = NULL;
134 +
135 +        /* make sure the domain we are about to add is legal */
136 +        l = 0;
137 +        do {
138 +                n = *srcp;
139 +                if ((n & NS_CMPRSFLGS) != 0 && n != 0x41) {
140 +                        __set_errno (EMSGSIZE);
141 +                        return (-1);
142 +                }
143 +                if (n == 0x41)
144 +                        n = *++srcp / 8;
145 +                l += n + 1;
146 +                if (l > MAXCDNAME) {
147 +                        __set_errno (EMSGSIZE);
148 +                        return (-1);
149 +                }
150 +                srcp += n + 1;
151 +        } while (n != 0);
152 +
153 +        /* from here on we need to reset compression pointer array on error */
154 +        srcp = src;
155 +        do {
156 +                /* Look to see if we can use pointers. */
157 +                n = *srcp;
158 +                if (n != 0 && n != 0x41 && msg != NULL) {
159 +                        l = dn_find(srcp, msg, (const u_char * const *)dnptrs,
160 +                                    (const u_char * const *)lpp);
161 +                        if (l >= 0) {
162 +                                if (dstp + 1 >= eob) {
163 +                                        goto cleanup;
164 +                                }
165 +                                *dstp++ = (l >> 8) | NS_CMPRSFLGS;
166 +                                *dstp++ = l % 256;
167 +                                return (dstp - dst);
168 +                        }
169 +                        /* Not found, save it. */
170 +                        if (lastdnptr != NULL && cpp < lastdnptr - 1 &&
171 +                            (dstp - msg) < 0x4000 && first) {
172 +                                *cpp++ = dstp;
173 +                                *cpp = NULL;
174 +                                first = 0;
175 +                        }
176 +                }
177 +                /* copy label to buffer */
178 +                if ((n & NS_CMPRSFLGS) != 0 && n != 0x41) {             /* Should not happen. */
179 +                        goto cleanup;
180 +                }
181 +                if (n == 0x41) {
182 +                        n = *++srcp / 8;
183 +                        if (dstp + 1 >= eob)
184 +                                goto cleanup;
185 +                        *dstp++ = 0x41;
186 +                }
187 +                if (dstp + 1 + n >= eob) {
188 +                        goto cleanup;
189 +                }
190 +                memcpy(dstp, srcp, n + 1);
191 +                srcp += n + 1;
192 +                dstp += n + 1;
193 +        } while (n != 0);
194 +
195 +        if (dstp > eob) {
196 +cleanup:
197 +                if (msg != NULL)
198 +                        *lpp = NULL;
199 +                __set_errno (EMSGSIZE);
200 +                return (-1);
201 +        }
202 +        return (dstp - dst);
203 +}
204 +
205 +
206 +int
207 +ns_name_pton(const char *src, u_char *dst, size_t dstsiz) {
208 +        u_char *label, *bp, *eom;
209 +        int c, n, escaped;
210 +        char *cp;
211 +
212 +        escaped = 0;
213 +        bp = dst;
214 +        eom = dst + dstsiz;
215 +        label = bp++;
216 +
217 +        while ((c = *src++) != 0) {
218 +                if (escaped) {
219 +                        if ((cp = strchr(digits, c)) != NULL) {
220 +                                n = (cp - digits) * 100;
221 +                                if ((c = *src++) == 0 ||
222 +                                    (cp = strchr(digits, c)) == NULL) {
223 +                                        __set_errno (EMSGSIZE);
224 +                                        return (-1);
225 +                                }
226 +                                n += (cp - digits) * 10;
227 +                                if ((c = *src++) == 0 ||
228 +                                    (cp = strchr(digits, c)) == NULL) {
229 +                                        __set_errno (EMSGSIZE);
230 +                                        return (-1);
231 +                                }
232 +                                n += (cp - digits);
233 +                                if (n > 255) {
234 +                                        __set_errno (EMSGSIZE);
235 +                                        return (-1);
236 +                                }
237 +                                c = n;
238 +                        } else if (c == '[' && label == bp - 1 && *src == 'x') {
239 +                                /* Theoretically we would have to handle \[o
240 +                                   as well but we do not since we do not need
241 +                                   it internally.  */
242 +                                *label = 0x41;
243 +                                label = bp++;
244 +                                ++src;
245 +                                while (isxdigit (*src)) {
246 +                                        n = *src > '9' ? *src - 'a' + 10 : *src - '0';
247 +                                        ++src;
248 +                                        if (! isxdigit(*src)) {
249 +                                                __set_errno (EMSGSIZE);
250 +                                                return (-1);
251 +                                        }
252 +                                        n <<= 4;
253 +                                        n += *src > '9' ? *src - 'a' + 10 : *src - '0';
254 +                                        if (bp + 1 >= eom) {
255 +                                                __set_errno (EMSGSIZE);
256 +                                                return (-1);
257 +                                        }
258 +                                        *bp++ = n;
259 +                                        ++src;
260 +                                }
261 +                                *label = (bp - label - 1) * 8;
262 +                                if (*src++ != ']' || *src++ != '.') {
263 +                                        __set_errno (EMSGSIZE);
264 +                                        return (-1);
265 +                                }
266 +                                escaped = 0;
267 +                                label = bp++;
268 +                                if (bp >= eom) {
269 +                                        __set_errno (EMSGSIZE);
270 +                                        return (-1);
271 +                                }
272 +                                continue;
273 +                        }
274 +                        escaped = 0;
275 +                } else if (c == '\\') {
276 +                        escaped = 1;
277 +                        continue;
278 +                } else if (c == '.') {
279 +                        c = (bp - label - 1);
280 +                        if ((c & NS_CMPRSFLGS) != 0) {  /* Label too big. */
281 +                                __set_errno (EMSGSIZE);
282 +                                return (-1);
283 +                        }
284 +                        if (label >= eom) {
285 +                                __set_errno (EMSGSIZE);
286 +                                return (-1);
287 +                        }
288 +                        *label = c;
289 +                        /* Fully qualified ? */
290 +                        if (*src == '\0') {
291 +                                if (c != 0) {
292 +                                        if (bp >= eom) {
293 +                                                __set_errno (EMSGSIZE);
294 +                                                return (-1);
295 +                                        }
296 +                                        *bp++ = '\0';
297 +                                }
298 +                                if ((bp - dst) > MAXCDNAME) {
299 +                                        __set_errno (EMSGSIZE);
300 +                                        return (-1);
301 +                                }
302 +                                return (1);
303 +                        }
304 +                        if (c == 0 || *src == '.') {
305 +                                __set_errno (EMSGSIZE);
306 +                                return (-1);
307 +                        }
308 +                        label = bp++;
309 +                        continue;
310 +                }
311 +                if (bp >= eom) {
312 +                        __set_errno (EMSGSIZE);
313 +                        return (-1);
314 +                }
315 +                *bp++ = (u_char)c;
316 +        }
317 +        c = (bp - label - 1);
318 +        if ((c & NS_CMPRSFLGS) != 0) {          /* Label too big. */
319 +                __set_errno (EMSGSIZE);
320 +                return (-1);
321 +        }
322 +        if (label >= eom) {
323 +                __set_errno (EMSGSIZE);
324 +                return (-1);
325 +        }
326 +        *label = c;
327 +        if (c != 0) {
328 +                if (bp >= eom) {
329 +                        __set_errno (EMSGSIZE);
330 +                        return (-1);
331 +                }
332 +                *bp++ = 0;
333 +        }
334 +        if ((bp - dst) > MAXCDNAME) {   /* src too big */
335 +                __set_errno (EMSGSIZE);
336 +                return (-1);
337 +        }
338 +        return (0);
339 +}
340 +
341 +
342 +
343 +int
344 +ns_name_compress(const char *src, u_char *dst, size_t dstsiz,
345 +                 const u_char **dnptrs, const u_char **lastdnptr)
346 +{
347 +        u_char tmp[NS_MAXCDNAME];
348 +
349 +        if (ns_name_pton(src, tmp, sizeof tmp) == -1)
350 +                return (-1);
351 +        return (ns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr));
352 +}
353 +
354 +
355 +int
356 +dn_comp(const char *src, u_char *dst, int dstsiz,
357 +        u_char **dnptrs, u_char **lastdnptr)
358 +{
359 +        return (ns_name_compress(src, dst, (size_t)dstsiz,
360 +                                 (const u_char **)dnptrs,
361 +                                 (const u_char **)lastdnptr));
362 +}
363 +
364 +
365 +
366 +
367 +int
368 +res_nmkquery(res_state statp,
369 +             int op,                    /* opcode of query */
370 +             const char *dname,         /* domain name */
371 +             int class, int type,       /* class and type of query */
372 +             const u_char *data,        /* resource record data */
373 +             int datalen,               /* length of data */
374 +             const u_char *newrr_in,    /* new rr for modify or append */
375 +             u_char *buf,               /* buffer to put query */
376 +             int buflen)                /* size of buffer */
377 +{
378 +        register HEADER *hp;
379 +        register u_char *cp;
380 +        register int n;
381 +        u_char *dnptrs[20], **dpp, **lastdnptr;
382 +
383 +#ifdef DEBUG
384 +        if (statp->options & RES_DEBUG)
385 +                printf(";; res_nmkquery(%s, %s, %s, %s)\n",
386 +                       _res_opcodes[op], dname, p_class(class), p_type(type));
387 +#endif
388 +        /*
389 +         * Initialize header fields.
390 +         */
391 +        if ((buf == NULL) || (buflen < HFIXEDSZ))
392 +                return (-1);
393 +        memset(buf, 0, HFIXEDSZ);
394 +        hp = (HEADER *) buf;
395 +        /* We randomize the IDs every time.  The old code just
396 +           incremented by one after the initial randomization which
397 +           still predictable if the application does multiple
398 +           requests.  */
399 +#if 0
400 +        hp->id = htons(++statp->id);
401 +#else
402 +        hp->id = htons(statp->id);
403 +        int randombits;
404 +        do
405 +          {
406 +#ifdef RANDOM_BITS
407 +            RANDOM_BITS (randombits);
408 +#else
409 +            struct timeval tv;
410 +            gettimeofday (&tv, NULL);
411 +            randombits = (tv.tv_sec << 8) ^ tv.tv_usec;
412 +#endif
413 +          }
414 +        while ((randombits & 0xffff) == 0);
415 +        statp->id = (statp->id + randombits) & 0xffff;
416 +#endif
417 +        hp->opcode = op;
418 +        hp->rd = (statp->options & RES_RECURSE) != 0;
419 +        hp->rcode = NOERROR;
420 +        cp = buf + HFIXEDSZ;
421 +        buflen -= HFIXEDSZ;
422 +        dpp = dnptrs;
423 +        *dpp++ = buf;
424 +        *dpp++ = NULL;
425 +        lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
426 +        /*
427 +         * perform opcode specific processing
428 +         */
429 +        switch (op) {
430 +        case QUERY:     /*FALLTHROUGH*/
431 +        case NS_NOTIFY_OP:
432 +                if ((buflen -= QFIXEDSZ) < 0)
433 +                        return (-1);
434 +                if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
435 +                        return (-1);
436 +                cp += n;
437 +                buflen -= n;
438 +                __putshort(type, cp);
439 +                cp += INT16SZ;
440 +                __putshort(class, cp);
441 +                cp += INT16SZ;
442 +                hp->qdcount = htons(1);
443 +                if (op == QUERY || data == NULL)
444 +                        break;
445 +                /*
446 +                 * Make an additional record for completion domain.
447 +                 */
448 +                buflen -= RRFIXEDSZ;
449 +                n = dn_comp((char *)data, cp, buflen, dnptrs, lastdnptr);
450 +                if (n < 0)
451 +                        return (-1);
452 +                cp += n;
453 +                buflen -= n;
454 +                __putshort(T_NULL, cp);
455 +                cp += INT16SZ;
456 +                __putshort(class, cp);
457 +                cp += INT16SZ;
458 +                __putlong(0, cp);
459 +                cp += INT32SZ;
460 +                __putshort(0, cp);
461 +                cp += INT16SZ;
462 +                hp->arcount = htons(1);
463 +                break;
464 +
465 +        case IQUERY:
466 +                /*
467 +                 * Initialize answer section
468 +                 */
469 +                if (buflen < 1 + RRFIXEDSZ + datalen)
470 +                        return (-1);
471 +                *cp++ = '\0';   /* no domain name */
472 +                __putshort(type, cp);
473 +                cp += INT16SZ;
474 +                __putshort(class, cp);
475 +                cp += INT16SZ;
476 +                __putlong(0, cp);
477 +                cp += INT32SZ;
478 +                __putshort(datalen, cp);
479 +                cp += INT16SZ;
480 +                if (datalen) {
481 +                        memcpy(cp, data, datalen);
482 +                        cp += datalen;
483 +                }
484 +                hp->ancount = htons(1);
485 +                break;
486 +
487 +        default:
488 +                return (-1);
489 +        }
490 +        return (cp - buf);
491 +}
492 +
493 +int
494 +res_mkquery(int op,                     /* opcode of query */
495 +            const char *dname,          /* domain name */
496 +            int class, int type,        /* class and type of query */
497 +            const u_char *data,         /* resource record data */
498 +            int datalen,                /* length of data */
499 +            const u_char *newrr_in,     /* new rr for modify or append */
500 +            u_char *buf,                /* buffer to put query */
501 +            int buflen)                 /* size of buffer */
502 +{
503 +        return (res_nmkquery(&_res, op, dname, class, type,
504 +                             data, datalen,
505 +                             newrr_in, buf, buflen));
506 +}
507 +
508 +#endif
509  
510  void dorequest(char *s,int type,word id)
511  {