LIB.TXT
上传用户:datang2001
上传日期:2007-02-01
资源大小:53269k
文件大小:979k
源码类别:

操作系统开发

开发平台:

C/C++

  1. 26645                 }
  2. 26646                 break;
  3. 26647         }
  4. 26648         return (cp - comp_dn);
  5. 26649 }
  6. 26651 /*
  7. 26652  * Search for expanded name from a list of previously compressed names.
  8. 26653  * Return the offset from msg if found or -1.
  9. 26654  * dnptrs is the pointer to the first name on the list,
  10. 26655  * not the pointer to the start of the message.
  11. 26656  */
  12. 26657 static int
  13. 26658 dn_find(exp_dn, msg, dnptrs, lastdnptr)
  14. 26659         CONST u_char *exp_dn, *msg;
  15. 26660         u_char **dnptrs, **lastdnptr;
  16. 26661 {
  17. 26662         CONST register u_char *dn, *cp;
  18. 26663         register u_char **cpp;
  19. 26664         register int n;
  20. 26665         CONST u_char *sp;
  21. 26666
  22. 26667         for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
  23. 26668                 dn = exp_dn;
  24. 26669                 sp = cp = *cpp;
  25. 26670                 while (n = *cp++) {
  26. 26671                         /*
  27. 26672                          * check for indirection
  28. 26673                          */
  29. 26674                         switch (n & INDIR_MASK) {
  30. 26675                         case 0:         /* normal case, n == len */
  31. 26676                                 while (--n >= 0) {
  32. 26677                                         if (*dn == '.')
  33. 26678                                                 goto next;
  34. 26679                                         if (*dn == '\')
  35. 26680                                                 dn++;
  36. 26681                                         if (*dn++ != *cp++)
  37. 26682                                                 goto next;
  38. 26683                                 }
  39. 26684                                 if ((n = *dn++) == '' && *cp == '')
  40. 26685                                         return (sp - msg);
  41. 26686                                 if (n == '.')
  42. 26687                                         continue;
  43. 26688                                 goto next;
  44. 26689
  45. 26690                         default:        /* illegal type */
  46. 26691                                 return (-1);
  47. 26692
  48. 26693                         case INDIR_MASK:        /* indirection */
  49. 26694                                 cp = msg + (((n & 0x3f) << 8) | *cp);
  50. 26695                         }
  51. 26696                 }
  52. 26697                 if (*dn == '')
  53. 26698                         return (sp - msg);
  54. 26699         next:   ;
  55. 26700         }
  56. 26701         return (-1);
  57. 26702 }
  58. 26704 /*
  59. 26705  * Routines to insert/extract short/long's. Must account for byte
  60. 26706  * order and non-alignment problems. This code at least has the
  61. 26707  * advantage of being portable.
  62. 26708  *
  63. 26709  * used by sendmail.
  64. 26710  */
  65. 26711
  66. 26712 u16_t
  67. 26713 getshort(msgp)
  68. 26714         CONST u8_t *msgp;
  69. 26715 {
  70. 26716         return ((msgp[0] << 8) | (msgp[1] << 0));
  71. 26717 }
  72. 26719 u32_t
  73. 26720 getlong(msgp)
  74. 26721         CONST u8_t *msgp;
  75. 26722 {
  76. 26723         return (  ((u32_t) msgp[0] << 24)
  77. 26724                 | ((u32_t) msgp[1] << 16)
  78. 26725                 | ((u32_t) msgp[2] <<  8)
  79. 26726                 | ((u32_t) msgp[3] <<  0));
  80. 26727 }
  81. 26730 void
  82. 26731 putshort(s, msgp)
  83. 26732         register U16_t s;
  84. 26733         register u8_t *msgp;
  85. 26734 {
  86. 26735
  87. 26736         msgp[1] = s;
  88. 26737         msgp[0] = s >> 8;
  89. 26738 }
  90. 26740 void
  91. 26741 putlong(l, msgp)
  92. 26742         register u32_t l;
  93. 26743         register u8_t *msgp;
  94. 26744 {
  95. 26745
  96. 26746         msgp[3] = l;
  97. 26747         msgp[2] = (l >>= 8);
  98. 26748         msgp[1] = (l >>= 8);
  99. 26749         msgp[0] = l >> 8;
  100. 26750 }
  101. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  102. src/lib/ip/res_init.c    
  103. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  104. 26800 /*-
  105. 26801  * Copyright (c) 1985, 1989 Regents of the University of California.
  106. 26802  * All rights reserved.
  107. 26803  *
  108. 26804  * Redistribution and use in source and binary forms are permitted provided
  109. 26805  * that: (1) source distributions retain this entire copyright notice and
  110. 26806  * comment, and (2) distributions including binaries display the following
  111. 26807  * acknowledgement:  ``This product includes software developed by the
  112. 26808  * University of California, Berkeley and its contributors'' in the
  113. 26809  * documentation or other materials provided with the distribution and in
  114. 26810  * all advertising materials mentioning features or use of this software.
  115. 26811  * Neither the name of the University nor the names of its contributors may
  116. 26812  * be used to endorse or promote products derived from this software without
  117. 26813  * specific prior written permission.
  118. 26814  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  119. 26815  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  120. 26816  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  121. 26817  */
  122. 26818
  123. 26819 #if defined(LIBC_SCCS) && !defined(lint)
  124. 26820 static char sccsid[] = "@(#)res_init.c  6.14 (Berkeley) 6/27/90";
  125. 26821 #endif /* LIBC_SCCS and not lint */
  126. 26822
  127. 26823 #if _MINIX
  128. 26824 #include <sys/types.h>
  129. 26825 #include <stdio.h>
  130. 26826 #include <stdlib.h>
  131. 26827 #include <string.h>
  132. 26828 #include <unistd.h>
  133. 26829
  134. 26830 #include <net/hton.h>
  135. 26831 #include <net/gen/in.h>
  136. 26832 #include <net/gen/inet.h>
  137. 26833 #include <net/gen/nameser.h>
  138. 26834 #include <net/gen/netdb.h>
  139. 26835 #include <net/gen/resolv.h>
  140. 26836 #include <net/gen/socket.h>
  141. 26837
  142. 26838 #define index(s,c) strchr(s,c)
  143. 26839 #else
  144. 26840 #include <sys/types.h>
  145. 26841 #include <sys/socket.h>
  146. 26842 #include <netinet/in.h>
  147. 26843 #include <stdio.h>
  148. 26844 #include <arpa/nameser.h>
  149. 26845 #include <resolv.h>
  150. 26846 #endif
  151. 26847
  152. 26848 /*
  153. 26849  * Resolver state
  154. 26850  */
  155. 26851 struct state _res;
  156. 26852
  157. 26853 /*
  158. 26854  * Set up default settings.  If the configuration file exist, the values
  159. 26855  * there will have precedence.  Otherwise, the server address is set to
  160. 26856  * 127.0.0.1 (localhost) and the default domain name comes from gethostname().
  161. 26857  *
  162. 26858  * The configuration file should only be used if you want to redefine your
  163. 26859  * domain or run without a server on your machine.
  164. 26860  *
  165. 26861  * Return 0 if completes successfully, -1 on error
  166. 26862  */
  167. 26863 int
  168. 26864 res_init()
  169. 26865 {
  170. 26866         register FILE *fp;
  171. 26867         register char *cp, **pp;
  172. 26868         register int n;
  173. 26869         char buf[BUFSIZ];
  174. 26870         int haveenv = 0;
  175. 26871         int havesearch = 0;
  176. 26872         struct servent* servent;
  177. 26873         u16_t nameserver_port;
  178. 26874
  179. 26875         /* Resolver state default settings */
  180. 26876         _res.retrans = RES_TIMEOUT;     /* retransmition time interval */
  181. 26877         _res.retry = 4;                 /* number of times to retransmit */
  182. 26878         _res.options = RES_DEFAULT;     /* options flags */
  183. 26879         _res.nscount = 0;               /* number of name servers */
  184. 26880
  185. 26881         servent= getservbyname("domain", NULL);
  186. 26882         if (!servent)
  187. 26883         {
  188. 26884                 h_errno= NO_RECOVERY;
  189. 26885                 return -1;
  190. 26886         }
  191. 26887         nameserver_port= servent->s_port;
  192. 26888
  193. 26889         /* Allow user to override the local domain definition */
  194. 26890         if ((cp = getenv("LOCALDOMAIN")) != NULL) {
  195. 26891                 (void)strncpy(_res.defdname, cp, sizeof(_res.defdname));
  196. 26892                 haveenv++;
  197. 26893         }
  198. 26894
  199. 26895         if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
  200. 26896             /* read the config file */
  201. 26897             while (fgets(buf, sizeof(buf), fp) != NULL) {
  202. 26898                 /* read default domain name */
  203. 26899                 if (!strncmp(buf, "domain", sizeof("domain") - 1)) {
  204. 26900                     if (haveenv)        /* skip if have from environ */
  205. 26901                             continue;
  206. 26902                     cp = buf + sizeof("domain") - 1;
  207. 26903                     while (*cp == ' ' || *cp == 't')
  208. 26904                             cp++;
  209. 26905                     if ((*cp == '') || (*cp == 'n'))
  210. 26906                             continue;
  211. 26907                     (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
  212. 26908                     if ((cp = index(_res.defdname, 'n')) != NULL)
  213. 26909                             *cp = '';
  214. 26910                     havesearch = 0;
  215. 26911                     continue;
  216. 26912                 }
  217. 26913                 /* set search list */
  218. 26914                 if (!strncmp(buf, "search", sizeof("search") - 1)) {
  219. 26915                     if (haveenv)        /* skip if have from environ */
  220. 26916                             continue;
  221. 26917                     cp = buf + sizeof("search") - 1;
  222. 26918                     while (*cp == ' ' || *cp == 't')
  223. 26919                             cp++;
  224. 26920                     if ((*cp == '') || (*cp == 'n'))
  225. 26921                             continue;
  226. 26922                     (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
  227. 26923                     if ((cp = index(_res.defdname, 'n')) != NULL)
  228. 26924                             *cp = '';
  229. 26925                     /*
  230. 26926                      * Set search list to be blank-separated strings
  231. 26927                      * on rest of line.
  232. 26928                      */
  233. 26929                     cp = _res.defdname;
  234. 26930                     pp = _res.dnsrch;
  235. 26931                     *pp++ = cp;
  236. 26932                     for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
  237. 26933                             if (*cp == ' ' || *cp == 't') {
  238. 26934                                     *cp = 0;
  239. 26935                                     n = 1;
  240. 26936                             } else if (n) {
  241. 26937                                     *pp++ = cp;
  242. 26938                                     n = 0;
  243. 26939                             }
  244. 26940                     }
  245. 26941                     /* null terminate last domain if there are excess */
  246. 26942                     while (*cp != '' && *cp != ' ' && *cp != 't')
  247. 26943                             cp++;
  248. 26944                     *cp = '';
  249. 26945                     *pp++ = 0;
  250. 26946                     havesearch = 1;
  251. 26947                     continue;
  252. 26948                 }
  253. 26949                 /* read nameservers to query */
  254. 26950                 if (!strncmp(buf, "nameserver", sizeof("nameserver") - 1) &&
  255. 26951                    _res.nscount < MAXNS) {
  256. 26952                     cp = buf + sizeof("nameserver") - 1;
  257. 26953                     while (*cp == ' ' || *cp == 't')
  258. 26954                             cp++;
  259. 26955                     if ((*cp == '') || (*cp == 'n'))
  260. 26956                             continue;
  261. 26957                     if (!inet_aton(cp, &_res.nsaddr_list[_res.nscount]))
  262. 26958                             continue;
  263. 26959                     _res.nsport_list[_res.nscount]= nameserver_port;
  264. 26960                     _res.nscount++;
  265. 26961                     continue;
  266. 26962                 }
  267. 26963             }
  268. 26964             (void) fclose(fp);
  269. 26965         }
  270. 26966         if (_res.nscount == 0) {
  271. 26967                 /* "localhost" is the default nameserver. */
  272. 26968                 _res.nsaddr_list[0]= HTONL(0x7F000001);
  273. 26969                 _res.nsport_list[0]= nameserver_port;
  274. 26970                 _res.nscount= 1;
  275. 26971         }
  276. 26972         if (_res.defdname[0] == 0) {
  277. 26973                 if (gethostname(buf, sizeof(_res.defdname)) == 0 &&
  278. 26974                    (cp = index(buf, '.')))
  279. 26975                         (void)strcpy(_res.defdname, cp + 1);
  280. 26976         }
  281. 26977
  282. 26978         /* find components of local domain that might be searched */
  283. 26979         if (havesearch == 0) {
  284. 26980                 pp = _res.dnsrch;
  285. 26981                 *pp++ = _res.defdname;
  286. 26982                 for (cp = _res.defdname, n = 0; *cp; cp++)
  287. 26983                         if (*cp == '.')
  288. 26984                                 n++;
  289. 26985                 cp = _res.defdname;
  290. 26986                 for (; n >= LOCALDOMAINPARTS && pp < _res.dnsrch + MAXDFLSRCH;
  291. 26987                     n--) {
  292. 26988                         cp = index(cp, '.');
  293. 26989                         *pp++ = ++cp;
  294. 26990                 }
  295. 26991                 *pp++ = 0;
  296. 26992         }
  297. 26993         _res.options |= RES_INIT;
  298. 26994         return (0);
  299. 26995 }
  300. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  301. src/lib/ip/res_mkquery.c    
  302. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  303. 27000 /*
  304. 27001  * Copyright (c) 1985 Regents of the University of California.
  305. 27002  * All rights reserved.
  306. 27003  *
  307. 27004  * Redistribution and use in source and binary forms are permitted
  308. 27005  * provided that: (1) source distributions retain this entire copyright
  309. 27006  * notice and comment, and (2) distributions including binaries display
  310. 27007  * the following acknowledgement:  ``This product includes software
  311. 27008  * developed by the University of California, Berkeley and its contributors''
  312. 27009  * in the documentation or other materials provided with the distribution
  313. 27010  * and in all advertising materials mentioning features or use of this
  314. 27011  * software. Neither the name of the University nor the names of its
  315. 27012  * contributors may be used to endorse or promote products derived
  316. 27013  * from this software without specific prior written permission.
  317. 27014  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  318. 27015  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  319. 27016  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  320. 27017  */
  321. 27018
  322. 27019 #if defined(LIBC_SCCS) && !defined(lint)
  323. 27020 static char sccsid[] = "@(#)res_mkquery.c       6.12 (Berkeley) 6/1/90";
  324. 27021 #endif /* LIBC_SCCS and not lint */
  325. 27022
  326. 27023 #if _MINIX
  327. 27024 #include <sys/types.h>
  328. 27025 #include <stdio.h>
  329. 27026 #include <stdlib.h>
  330. 27027 #include <string.h>
  331. 27028
  332. 27029 #include <net/hton.h>
  333. 27030 #include <net/gen/in.h>
  334. 27031 #include <net/gen/nameser.h>
  335. 27032 #include <net/gen/resolv.h>
  336. 27033
  337. 27034 typedef u16_t u_short;
  338. 27035 typedef unsigned u_int;
  339. 27036 typedef u32_t u_long;
  340. 27037
  341. 27038 #define bzero(b,l) memset(b,0,l)
  342. 27039 #define bcopy(s,d,l) memcpy(d,s,l)
  343. 27040
  344. 27041 #define putshort __putshort
  345. 27042 #define putlong __putlong
  346. 27043 #else
  347. 27044 #include <stdio.h>
  348. 27045 #include <sys/types.h>
  349. 27046 #include <netinet/in.h>
  350. 27047 #include <arpa/nameser.h>
  351. 27048 #include <resolv.h>
  352. 27049 #endif
  353. 27050
  354. 27051 #ifdef __STDC__
  355. 27052 #define _CONST  const
  356. 27053 #else
  357. 27054 #define _CONST
  358. 27055 #endif
  359. 27056
  360. 27057 /*
  361. 27058  * Form all types of queries.
  362. 27059  * Returns the size of the result or -1.
  363. 27060  */
  364. 27061 res_mkquery(op, dname, class, type, data, datalen, newrr, buf, buflen)
  365. 27062         int op;                 /* opcode of query */
  366. 27063         _CONST char *dname;     /* domain name */
  367. 27064         int class, type;        /* class and type of query */
  368. 27065         _CONST char *data;      /* resource record data */
  369. 27066         int datalen;            /* length of data */
  370. 27067         _CONST struct rrec *newrr; /* new rr for modify or append */
  371. 27068         char *buf;              /* buffer to put query */
  372. 27069         int buflen;             /* size of buffer */
  373. 27070 {
  374. 27071         register dns_hdr_t *hp;
  375. 27072         register char *cp;
  376. 27073         register int n;
  377. 27074         char *dnptrs[10], **dpp, **lastdnptr;
  378. 27075
  379. 27076 #ifdef DEBUG
  380. 27077         if (_res.options & RES_DEBUG)
  381. 27078                 printf("res_mkquery(%d, %s, %d, %d)n", op, dname, class, type);
  382. 27079 #endif /* DEBUG */
  383. 27080         /*
  384. 27081          * Initialize header fields.
  385. 27082          */
  386. 27083         if ((buf == NULL) || (buflen < sizeof(dns_hdr_t)))
  387. 27084                 return(-1);
  388. 27085         bzero(buf, sizeof(dns_hdr_t));
  389. 27086         hp = (dns_hdr_t *) buf;
  390. 27087         hp->dh_id = htons(++_res.id);
  391. 27088         hp->dh_flag1= 0;
  392. 27089         hp->dh_flag2= 0;
  393. 27090         hp->dh_flag1 |= (op << 3) & DHF_OPCODE;
  394. 27091         hp->dh_flag2 |= ((_res.options & RES_PRIMARY) != 0 ? 1 : 0) << 6;
  395. 27092         hp->dh_flag1 |= (_res.options & RES_RECURSE) != 0 ? 1 : 0;
  396. 27093         hp->dh_flag2 |= NOERROR & DHF_RCODE;
  397. 27094         cp = buf + sizeof(dns_hdr_t);
  398. 27095         buflen -= sizeof(dns_hdr_t);
  399. 27096         dpp = dnptrs;
  400. 27097         *dpp++ = buf;
  401. 27098         *dpp++ = NULL;
  402. 27099         lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]);
  403. 27100         /*
  404. 27101          * perform opcode specific processing
  405. 27102          */
  406. 27103         switch (op) {
  407. 27104         case QUERY:
  408. 27105                 if ((buflen -= QFIXEDSZ) < 0)
  409. 27106                         return(-1);
  410. 27107                 if ((n = dn_comp((u8_t *)dname, (u8_t *)cp, buflen, 
  411. 27108                         (u8_t **)dnptrs, (u8_t **)lastdnptr)) < 0)
  412. 27109                         return (-1);
  413. 27110                 cp += n;
  414. 27111                 buflen -= n;
  415. 27112                 putshort(type, (u8_t *)cp);
  416. 27113                 cp += sizeof(u_short);
  417. 27114                 putshort(class, (u8_t *)cp);
  418. 27115                 cp += sizeof(u_short);
  419. 27116                 hp->dh_qdcount = htons(1);
  420. 27117                 if (op == QUERY || data == NULL)
  421. 27118                         break;
  422. 27119                 /*
  423. 27120                  * Make an additional record for completion domain.
  424. 27121                  */
  425. 27122                 buflen -= RRFIXEDSZ;
  426. 27123                 if ((n = dn_comp((u8_t *)data, (u8_t *)cp, buflen, 
  427. 27124                         (u8_t **)dnptrs, (u8_t **)lastdnptr)) < 0)
  428. 27125                         return (-1);
  429. 27126                 cp += n;
  430. 27127                 buflen -= n;
  431. 27128                 putshort(T_NULL, (u8_t *)cp);
  432. 27129                 cp += sizeof(u_short);
  433. 27130                 putshort(class, (u8_t *)cp);
  434. 27131                 cp += sizeof(u_short);
  435. 27132                 putlong(0, (u8_t *)cp);
  436. 27133                 cp += sizeof(u_long);
  437. 27134                 putshort(0, (u8_t *)cp);
  438. 27135                 cp += sizeof(u_short);
  439. 27136                 hp->dh_arcount = htons(1);
  440. 27137                 break;
  441. 27138
  442. 27139         case IQUERY:
  443. 27140                 /*
  444. 27141                  * Initialize answer section
  445. 27142                  */
  446. 27143                 if (buflen < 1 + RRFIXEDSZ + datalen)
  447. 27144                         return (-1);
  448. 27145                 *cp++ = '';   /* no domain name */
  449. 27146                 putshort(type, (u8_t *)cp);
  450. 27147                 cp += sizeof(u_short);
  451. 27148                 putshort(class, (u8_t *)cp);
  452. 27149                 cp += sizeof(u_short);
  453. 27150                 putlong(0, (u8_t *)cp);
  454. 27151                 cp += sizeof(u_long);
  455. 27152                 putshort(datalen, (u8_t *)cp);
  456. 27153                 cp += sizeof(u_short);
  457. 27154                 if (datalen) {
  458. 27155                         bcopy(data, cp, datalen);
  459. 27156                         cp += datalen;
  460. 27157                 }
  461. 27158                 hp->dh_ancount = htons(1);
  462. 27159                 break;
  463. 27160
  464. 27161 #ifdef ALLOW_UPDATES
  465. 27162         /*
  466. 27163          * For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA
  467. 27164          * (Record to be modified is followed by its replacement in msg.)
  468. 27165          */
  469. 27166         case UPDATEM:
  470. 27167         case UPDATEMA:
  471. 27168
  472. 27169         case UPDATED:
  473. 27170                 /*
  474. 27171                  * The res code for UPDATED and UPDATEDA is the same; user
  475. 27172                  * calls them differently: specifies data for UPDATED; server
  476. 27173                  * ignores data if specified for UPDATEDA.
  477. 27174                  */
  478. 27175         case UPDATEDA:
  479. 27176                 buflen -= RRFIXEDSZ + datalen;
  480. 27177                 if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
  481. 27178                         return (-1);
  482. 27179                 cp += n;
  483. 27180                 putshort(type, cp);
  484. 27181                 cp += sizeof(u_short);
  485. 27182                 putshort(class, cp);
  486. 27183                 cp += sizeof(u_short);
  487. 27184                 putlong(0, cp);
  488. 27185                 cp += sizeof(u_long);
  489. 27186                 putshort(datalen, cp);
  490. 27187                 cp += sizeof(u_short);
  491. 27188                 if (datalen) {
  492. 27189                         bcopy(data, cp, datalen);
  493. 27190                         cp += datalen;
  494. 27191                 }
  495. 27192                 if ( (op == UPDATED) || (op == UPDATEDA) ) {
  496. 27193                         hp->ancount = htons(0);
  497. 27194                         break;
  498. 27195                 }
  499. 27196                 /* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */
  500. 27197
  501. 27198         case UPDATEA:   /* Add new resource record */
  502. 27199                 buflen -= RRFIXEDSZ + datalen;
  503. 27200                 if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
  504. 27201                         return (-1);
  505. 27202                 cp += n;
  506. 27203                 putshort(newrr->r_type, cp);
  507. 27204                 cp += sizeof(u_short);
  508. 27205                 putshort(newrr->r_class, cp);
  509. 27206                 cp += sizeof(u_short);
  510. 27207                 putlong(0, cp);
  511. 27208                 cp += sizeof(u_long);
  512. 27209                 putshort(newrr->r_size, cp);
  513. 27210                 cp += sizeof(u_short);
  514. 27211                 if (newrr->r_size) {
  515. 27212                         bcopy(newrr->r_data, cp, newrr->r_size);
  516. 27213                         cp += newrr->r_size;
  517. 27214                 }
  518. 27215                 hp->ancount = htons(0);
  519. 27216                 break;
  520. 27217
  521. 27218 #endif /* ALLOW_UPDATES */
  522. 27219         }
  523. 27220         return (cp - buf);
  524. 27221 }
  525. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  526. src/lib/ip/res_query.c    
  527. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  528. 27300 /*
  529. 27301  * Copyright (c) 1988 Regents of the University of California.
  530. 27302  * All rights reserved.
  531. 27303  *
  532. 27304  * Redistribution and use in source and binary forms are permitted
  533. 27305  * provided that: (1) source distributions retain this entire copyright
  534. 27306  * notice and comment, and (2) distributions including binaries display
  535. 27307  * the following acknowledgement:  ``This product includes software
  536. 27308  * developed by the University of California, Berkeley and its contributors''
  537. 27309  * in the documentation or other materials provided with the distribution
  538. 27310  * and in all advertising materials mentioning features or use of this
  539. 27311  * software. Neither the name of the University nor the names of its
  540. 27312  * contributors may be used to endorse or promote products derived
  541. 27313  * from this software without specific prior written permission.
  542. 27314  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  543. 27315  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  544. 27316  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  545. 27317  */
  546. 27318
  547. 27319 #if defined(LIBC_SCCS) && !defined(lint)
  548. 27320 static char sccsid[] = "@(#)res_query.c 5.7 (Berkeley) 6/1/90";
  549. 27321 #endif /* LIBC_SCCS and not lint */
  550. 27322
  551. 27323 #if _MINIX
  552. 27324 #include <sys/types.h>
  553. 27325 #include <ctype.h>
  554. 27326 #include <errno.h>
  555. 27327 #include <stdio.h>
  556. 27328 #include <stdlib.h>
  557. 27329 #include <string.h>
  558. 27330
  559. 27331 #include <net/hton.h>
  560. 27332 #include <net/gen/in.h>
  561. 27333 #include <net/gen/nameser.h>
  562. 27334 #include <net/gen/netdb.h>
  563. 27335 #include <net/gen/resolv.h>
  564. 27336
  565. 27337 typedef u8_t u_char;
  566. 27338
  567. 27339 #define bcopy(s,d,l) memcpy(d,s,l)
  568. 27340
  569. 27341 #define hostalias __hostalias
  570. 27342 #else
  571. 27343 #include <sys/param.h>
  572. 27344 #include <sys/socket.h>
  573. 27345 #include <netinet/in.h>
  574. 27346 #include <ctype.h>
  575. 27347 #include <netdb.h>
  576. 27348 #include <stdio.h>
  577. 27349 #include <errno.h>
  578. 27350 #include <string.h>
  579. 27351 #include <arpa/inet.h>
  580. 27352 #include <arpa/nameser.h>
  581. 27353 #include <resolv.h>
  582. 27354
  583. 27355 extern int errno;
  584. 27356 #endif
  585. 27357
  586. 27358 #if __STDC__
  587. 27359 #define CONST   const
  588. 27360 #else
  589. 27361 #define CONST
  590. 27362 #endif
  591. 27363
  592. 27364 #if PACKETSZ > 1024
  593. 27365 #define MAXPACKET       PACKETSZ
  594. 27366 #else
  595. 27367 #define MAXPACKET       1024
  596. 27368 #endif
  597. 27369
  598. 27370 int h_errno;
  599. 27371
  600. 27372 /*
  601. 27373  * Formulate a normal query, send, and await answer.
  602. 27374  * Returned answer is placed in supplied buffer "answer".
  603. 27375  * Perform preliminary check of answer, returning success only
  604. 27376  * if no error is indicated and the answer count is nonzero.
  605. 27377  * Return the size of the response on success, -1 on error.
  606. 27378  * Error number is left in h_errno.
  607. 27379  * Caller must parse answer and determine whether it answers the question.
  608. 27380  */
  609. 27381 int
  610. 27382 res_query(name, class, type, answer, anslen)
  611. 27383         char *name;             /* domain name */
  612. 27384         int class, type;        /* class and type of query */
  613. 27385         u_char *answer;         /* buffer to put answer */
  614. 27386         int anslen;             /* size of answer buffer */
  615. 27387 {
  616. 27388         char buf[MAXPACKET];
  617. 27389         dns_hdr_t *hp;
  618. 27390         int n;
  619. 27391
  620. 27392         if ((_res.options & RES_INIT) == 0 && res_init() == -1)
  621. 27393                 return (-1);
  622. 27394 #ifdef DEBUG
  623. 27395         if (_res.options & RES_DEBUG)
  624. 27396                 printf("res_query(%s, %d, %d)n", name, class, type);
  625. 27397 #endif
  626. 27398         n = res_mkquery(QUERY, name, class, type, (char *)NULL, 0, NULL,
  627. 27399             buf, sizeof(buf));
  628. 27400
  629. 27401         if (n <= 0) {
  630. 27402 #ifdef DEBUG
  631. 27403                 if (_res.options & RES_DEBUG)
  632. 27404                         printf("res_query: mkquery failedn");
  633. 27405 #endif
  634. 27406                 h_errno = NO_RECOVERY;
  635. 27407                 return (n);
  636. 27408         }
  637. 27409         n = res_send(buf, n, (char *)answer, anslen);
  638. 27410         if (n < 0) {
  639. 27411 #ifdef DEBUG
  640. 27412                 if (_res.options & RES_DEBUG)
  641. 27413                         printf("res_query: send error(%d)n", errno);
  642. 27414 #endif
  643. 27415                 h_errno = TRY_AGAIN;
  644. 27416                 return(n);
  645. 27417         }
  646. 27418
  647. 27419         hp = (dns_hdr_t *) answer;
  648. 27420         if ((hp->dh_flag2 & DHF_RCODE) != NOERROR || 
  649. 27421                 ntohs(hp->dh_ancount) == 0) {
  650. 27422 #ifdef DEBUG
  651. 27423                 if (_res.options & RES_DEBUG)
  652. 27424                         printf("rcode = %d, ancount=%dn", 
  653. 27425                                 hp->dh_flag2 & DHF_RCODE,
  654. 27426                             ntohs(hp->dh_ancount));
  655. 27427 #endif
  656. 27428                 switch (hp->dh_flag2 & DHF_RCODE) {
  657. 27429                         case NXDOMAIN:
  658. 27430                                 h_errno = HOST_NOT_FOUND;
  659. 27431                                 break;
  660. 27432                         case SERVFAIL:
  661. 27433                                 h_errno = TRY_AGAIN;
  662. 27434                                 break;
  663. 27435                         case NOERROR:
  664. 27436                                 h_errno = NO_DATA;
  665. 27437                                 break;
  666. 27438                         case FORMERR:
  667. 27439                         case NOTIMP:
  668. 27440                         case REFUSED:
  669. 27441                         default:
  670. 27442                                 h_errno = NO_RECOVERY;
  671. 27443                                 break;
  672. 27444                 }
  673. 27445                 return (-1);
  674. 27446         }
  675. 27447         return(n);
  676. 27448 }
  677. 27450 /*
  678. 27451  * Formulate a normal query, send, and retrieve answer in supplied buffer.
  679. 27452  * Return the size of the response on success, -1 on error.
  680. 27453  * If enabled, implement search rules until answer or unrecoverable failure
  681. 27454  * is detected.  Error number is left in h_errno.
  682. 27455  * Only useful for queries in the same name hierarchy as the local host
  683. 27456  * (not, for example, for host address-to-name lookups in domain in-addr.arpa).
  684. 27457  */
  685. 27458 res_search(name, class, type, answer, anslen)
  686. 27459         char *name;             /* domain name */
  687. 27460         int class, type;        /* class and type of query */
  688. 27461         u_char *answer;         /* buffer to put answer */
  689. 27462         int anslen;             /* size of answer */
  690. 27463 {
  691. 27464         register char *cp, **domain;
  692. 27465         int n, ret, got_nodata = 0;
  693. 27466
  694. 27467         if ((_res.options & RES_INIT) == 0 && res_init() == -1)
  695. 27468                 return (-1);
  696. 27469
  697. 27470         errno = 0;
  698. 27471         h_errno = HOST_NOT_FOUND;               /* default, if we never query */
  699. 27472         for (cp = name, n = 0; *cp; cp++)
  700. 27473                 if (*cp == '.')
  701. 27474                         n++;
  702. 27475         if (n == 0 && (cp = hostalias(name)))
  703. 27476                 return (res_query(cp, class, type, answer, anslen));
  704. 27477
  705. 27478         /*
  706. 27479          * We do at least one level of search if
  707. 27480          *      - there is no dot and RES_DEFNAME is set, or
  708. 27481          *      - there is at least one dot, there is no trailing dot,
  709. 27482          *        and RES_DNSRCH is set.
  710. 27483          */
  711. 27484         if ((n == 0 && _res.options & RES_DEFNAMES) ||
  712. 27485            (n != 0 && *--cp != '.' && _res.options & RES_DNSRCH))
  713. 27486              for (domain = _res.dnsrch; *domain; domain++) {
  714. 27487                 ret = res_querydomain(name, *domain, class, type,
  715. 27488                     answer, anslen);
  716. 27489                 if (ret > 0)
  717. 27490                         return (ret);
  718. 27491                 /*
  719. 27492                  * If no server present, give up.
  720. 27493                  * If name isn't found in this domain,
  721. 27494                  * keep trying higher domains in the search list
  722. 27495                  * (if that's enabled).
  723. 27496                  * On a NO_DATA error, keep trying, otherwise
  724. 27497                  * a wildcard entry of another type could keep us
  725. 27498                  * from finding this entry higher in the domain.
  726. 27499                  * If we get some other error (negative answer or
  727. 27500                  * server failure), then stop searching up,
  728. 27501                  * but try the input name below in case it's fully-qualified.
  729. 27502                  */
  730. 27503                 if (errno == ECONNREFUSED) {
  731. 27504                         h_errno = TRY_AGAIN;
  732. 27505                         return (-1);
  733. 27506                 }
  734. 27507                 if (h_errno == NO_DATA)
  735. 27508                         got_nodata++;
  736. 27509                 if ((h_errno != HOST_NOT_FOUND && h_errno != NO_DATA) ||
  737. 27510                     (_res.options & RES_DNSRCH) == 0)
  738. 27511                         break;
  739. 27512         }
  740. 27513         /*
  741. 27514          * If the search/default failed, try the name as fully-qualified,
  742. 27515          * but only if it contained at least one dot (even trailing).
  743. 27516          * This is purely a heuristic; we assume that any reasonable query
  744. 27517          * about a top-level domain (for servers, SOA, etc) will not use
  745. 27518          * res_search.
  746. 27519          */
  747. 27520         if (n && (ret = res_querydomain(name, (char *)NULL, class, type,
  748. 27521             answer, anslen)) > 0)
  749. 27522                 return (ret);
  750. 27523         if (got_nodata)
  751. 27524                 h_errno = NO_DATA;
  752. 27525         return (-1);
  753. 27526 }
  754. 27528 /*
  755. 27529  * Perform a call on res_query on the concatenation of name and domain,
  756. 27530  * removing a trailing dot from name if domain is NULL.
  757. 27531  */
  758. 27532 int
  759. 27533 res_querydomain(name, domain, class, type, answer, anslen)
  760. 27534         char *name, *domain;
  761. 27535         int class, type;        /* class and type of query */
  762. 27536         u_char *answer;         /* buffer to put answer */
  763. 27537         int anslen;             /* size of answer */
  764. 27538 {
  765. 27539         char nbuf[2*MAXDNAME+2];
  766. 27540         char *longname = nbuf;
  767. 27541         int n;
  768. 27542
  769. 27543 #ifdef DEBUG
  770. 27544         if (_res.options & RES_DEBUG)
  771. 27545                 printf("res_querydomain(%s, %s, %d, %d)n",
  772. 27546                     name, domain, class, type);
  773. 27547 #endif
  774. 27548         if (domain == NULL) {
  775. 27549                 /*
  776. 27550                  * Check for trailing '.';
  777. 27551                  * copy without '.' if present.
  778. 27552                  */
  779. 27553                 n = strlen(name) - 1;
  780. 27554                 if (name[n] == '.' && n < sizeof(nbuf) - 1) {
  781. 27555                         bcopy(name, nbuf, n);
  782. 27556                         nbuf[n] = '';
  783. 27557                 } else
  784. 27558                         longname = name;
  785. 27559         } else
  786. 27560                 (void)sprintf(nbuf, "%.*s.%.*s",
  787. 27561                     MAXDNAME, name, MAXDNAME, domain);
  788. 27562
  789. 27563         return (res_query(longname, class, type, answer, anslen));
  790. 27564 }
  791. 27566 char *
  792. 27567 hostalias(name)
  793. 27568         register CONST char *name;
  794. 27569 {
  795. 27570         register char *C1, *C2;
  796. 27571         FILE *fp;
  797. 27572         char *file;
  798. 27573         char buf[BUFSIZ];
  799. 27574         static char abuf[MAXDNAME];
  800. 27575
  801. 27576         file = getenv("HOSTALIASES");
  802. 27577         if (file == NULL || (fp = fopen(file, "r")) == NULL)
  803. 27578                 return (NULL);
  804. 27579         buf[sizeof(buf) - 1] = '';
  805. 27580         while (fgets(buf, sizeof(buf), fp)) {
  806. 27581                 for (C1 = buf; *C1 && !isspace(*C1); ++C1);
  807. 27582                 if (!*C1)
  808. 27583                         break;
  809. 27584                 *C1 = '';
  810. 27585                 if (!strcasecmp(buf, name)) {
  811. 27586                         while (isspace(*++C1));
  812. 27587                         if (!*C1)
  813. 27588                                 break;
  814. 27589                         for (C2 = C1 + 1; *C2 && !isspace(*C2); ++C2);
  815. 27590                         abuf[sizeof(abuf) - 1] = *C2 = '';
  816. 27591                         (void)strncpy(abuf, C1, sizeof(abuf) - 1);
  817. 27592                         fclose(fp);
  818. 27593                         return (abuf);
  819. 27594                 }
  820. 27595         }
  821. 27596         fclose(fp);
  822. 27597         return (NULL);
  823. 27598 }
  824. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  825. src/lib/ip/res_send.c    
  826. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  827. 27600 /*
  828. 27601  * Copyright (c) 1985, 1989 Regents of the University of California.
  829. 27602  * All rights reserved.
  830. 27603  *
  831. 27604  * Redistribution and use in source and binary forms, with or without
  832. 27605  * modification, are permitted provided that the following conditions
  833. 27606  * are met:
  834. 27607  * 1. Redistributions of source code must retain the above copyright
  835. 27608  *    notice, this list of conditions and the following disclaimer.
  836. 27609  * 2. Redistributions in binary form must reproduce the above copyright
  837. 27610  *    notice, this list of conditions and the following disclaimer in the
  838. 27611  *    documentation and/or other materials provided with the distribution.
  839. 27612  * 3. All advertising materials mentioning features or use of this software
  840. 27613  *    must display the following acknowledgement:
  841. 27614  *      This product includes software developed by the University of
  842. 27615  *      California, Berkeley and its contributors.
  843. 27616  * 4. Neither the name of the University nor the names of its contributors
  844. 27617  *    may be used to endorse or promote products derived from this software
  845. 27618  *    without specific prior written permission.
  846. 27619  *
  847. 27620  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  848. 27621  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  849. 27622  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  850. 27623  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  851. 27624  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  852. 27625  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  853. 27626  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  854. 27627  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  855. 27628  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  856. 27629  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  857. 27630  * SUCH DAMAGE.
  858. 27631  */
  859. 27632
  860. 27633 #if defined(LIBC_SCCS) && !defined(lint)
  861. 27634 static char sccsid[] = "@(#)res_send.c  6.27 (Berkeley) 2/24/91";
  862. 27635 #endif /* LIBC_SCCS and not lint */
  863. 27636
  864. 27637 /*
  865. 27638  * Send query to name server and wait for reply.
  866. 27639  */
  867. 27640
  868. 27641 #if !_MINIX
  869. 27642 #include <sys/param.h>
  870. 27643 #include <sys/time.h>
  871. 27644 #include <sys/socket.h>
  872. 27645 #include <sys/uio.h>
  873. 27646 #include <netinet/in.h>
  874. 27647 #include <arpa/nameser.h>
  875. 27648 #include <stdio.h>
  876. 27649 #include <errno.h>
  877. 27650 #include <resolv.h>
  878. 27651 #include <unistd.h>
  879. 27652 #include <string.h>
  880. 27653
  881. 27654 #else /* _MINIX */
  882. 27655
  883. 27656 #include <sys/types.h>
  884. 27657 #include <sys/ioctl.h>
  885. 27658 #include <sys/stat.h>
  886. 27659 #include <assert.h>
  887. 27660 #include <errno.h>
  888. 27661 #include <fcntl.h>
  889. 27662 #include <signal.h>
  890. 27663 #include <stdio.h>
  891. 27664 #include <stdlib.h>
  892. 27665 #include <string.h>
  893. 27666 #include <unistd.h>
  894. 27667
  895. 27668 #include <net/hton.h>
  896. 27669
  897. 27670 #include <net/netlib.h>
  898. 27671 #include <net/gen/in.h>
  899. 27672 #include <net/gen/inet.h>
  900. 27673 #include <net/gen/netdb.h>
  901. 27674 #include <net/gen/nameser.h>
  902. 27675 #include <net/gen/resolv.h>
  903. 27676 #include <net/gen/tcp.h>
  904. 27677 #include <net/gen/tcp_io.h>
  905. 27678 #include <net/gen/udp.h>
  906. 27679 #include <net/gen/udp_hdr.h>
  907. 27680 #include <net/gen/udp_io.h>
  908. 27681
  909. 27682 typedef u16_t u_short;
  910. 27683
  911. 27684 static int tcp_connect _ARGS(( ipaddr_t host, Tcpport_t port, int *terrno ));
  912. 27685 static int tcpip_writeall _ARGS(( int fd, const char *buf, size_t siz ));
  913. 27686 static int udp_connect _ARGS(( void ));
  914. 27687 static int udp_sendto _ARGS(( int fd, const char *buf, unsigned buflen,
  915. 27688                                 ipaddr_t addr, Udpport_t port ));
  916. 27689 static int udp_receive _ARGS(( int fd, char *buf, unsigned buflen,
  917. 27690                                 time_t timeout ));
  918. 27691 static void alarm_handler _ARGS(( int sig ));
  919. 27692
  920. 27693 #endif /* !_MINIX */
  921. 27694
  922. 27695 static int s = -1;      /* socket used for communications */
  923. 27696 #if !_MINIX
  924. 27697 static struct sockaddr no_addr;
  925. 27698
  926. 27699 #ifndef FD_SET
  927. 27700 #define NFDBITS         32
  928. 27701 #define FD_SETSIZE      32
  929. 27702 #define FD_SET(n, p)    ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
  930. 27703 #define FD_CLR(n, p)    ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
  931. 27704 #define FD_ISSET(n, p)  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
  932. 27705 #define FD_ZERO(p)      bzero((char *)(p), sizeof(*(p)))
  933. 27706 #endif /* FD_SET */
  934. 27707 #endif /* _MINIX */
  935. 27708
  936. 27709 res_send(buf, buflen, answer, anslen)
  937. 27710         const char *buf;
  938. 27711         int buflen;
  939. 27712         char *answer;
  940. 27713         int anslen;
  941. 27714 {
  942. 27715         register int n;
  943. 27716         int try, v_circuit, resplen, ns;
  944. 27717         int gotsomewhere = 0, connected = 0;
  945. 27718         int connreset = 0;
  946. 27719 #if !_MINIX
  947. 27720         u_short id, len;
  948. 27721 #else /* _MINIX */
  949. 27722         u16_t id, len;
  950. 27723 #endif /* !_MINIX */
  951. 27724         char *cp;
  952. 27725 #if !_MINIX
  953. 27726         fd_set dsmask;
  954. 27727         struct timeval timeout;
  955. 27728         HEADER *hp = (HEADER *) buf;
  956. 27729         HEADER *anhp = (HEADER *) answer;
  957. 27730         struct iovec iov[2];
  958. 27731 #else /* _MINIX */
  959. 27732         time_t timeout;
  960. 27733         dns_hdr_t *hp = (dns_hdr_t *) buf;
  961. 27734         dns_hdr_t *anhp = (dns_hdr_t *) answer;
  962. 27735 #endif /* !_MINIX */
  963. 27736         int terrno = ETIMEDOUT;
  964. 27737         char junk[512];
  965. 27738
  966. 27739 #ifdef DEBUG
  967. 27740         if (_res.options & RES_DEBUG) {
  968. 27741                 printf("res_send()n");
  969. 27742                 __p_query(buf);
  970. 27743         }
  971. 27744 #endif /* DEBUG */
  972. 27745         if (!(_res.options & RES_INIT))
  973. 27746                 if (res_init() == -1) {
  974. 27747                         return(-1);
  975. 27748                 }
  976. 27749
  977. 27750         v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
  978. 27751 #if !_MINIX
  979. 27752         id = hp->id;
  980. 27753 #else /* _MINIX */
  981. 27754         id = hp->dh_id;
  982. 27755 #endif /* !_MINIX */
  983. 27756         /*
  984. 27757          * Send request, RETRY times, or until successful
  985. 27758          */
  986. 27759         for (try = 0; try < _res.retry; try++) {
  987. 27760            for (ns = 0; ns < _res.nscount; ns++) {
  988. 27761 #ifdef DEBUG
  989. 27762 #if !_MINIX
  990. 27763                 if (_res.options & RES_DEBUG)
  991. 27764                         printf("Querying server (# %d) address = %sn", ns+1,
  992. 27765                               inet_ntoa(_res.nsaddr_list[ns].sin_addr));
  993. 27766 #else /* _MINIX */
  994. 27767                 if (_res.options & RES_DEBUG)
  995. 27768                         printf("Querying server (# %d) address = %sn", ns+1,
  996. 27769                               inet_ntoa(_res.nsaddr_list[ns]));
  997. 27770 #endif /* !_MINIX */
  998. 27771 #endif /* DEBUG */
  999. 27772         usevc:
  1000. 27773                 if (v_circuit) {
  1001. 27774 #if !_MINIX
  1002. 27775                         int truncated = 0;
  1003. 27776
  1004. 27777                         /*
  1005. 27778                          * Use virtual circuit;
  1006. 27779                          * at most one attempt per server.
  1007. 27780                          */
  1008. 27781                         try = _res.retry;
  1009. 27782                         if (s < 0) {
  1010. 27783                                 s = socket(AF_INET, SOCK_STREAM, 0);
  1011. 27784                                 if (s < 0) {
  1012. 27785                                         terrno = errno;
  1013. 27786 #ifdef DEBUG
  1014. 27787                                         if (_res.options & RES_DEBUG)
  1015. 27788                                             perror("socket (vc) failed");
  1016. 27789 #endif /* DEBUG */
  1017. 27790                                         continue;
  1018. 27791                                 }
  1019. 27792                                 if (connect(s,
  1020. 27793                                     (struct sockaddr *)&(_res.nsaddr_list[ns]),
  1021. 27794                                     sizeof(struct sockaddr)) < 0) {
  1022. 27795                                         terrno = errno;
  1023. 27796 #ifdef DEBUG
  1024. 27797                                         if (_res.options & RES_DEBUG)
  1025. 27798                                             perror("connect failed");
  1026. 27799 #endif /* DEBUG */
  1027. 27800                                         (void) close(s);
  1028. 27801                                         s = -1;
  1029. 27802                                         continue;
  1030. 27803                                 }
  1031. 27804                         }
  1032. 27805                         /*
  1033. 27806                          * Send length & message
  1034. 27807                          */
  1035. 27808                         len = htons((u_short)buflen);
  1036. 27809                         iov[0].iov_base = (caddr_t)&len;
  1037. 27810                         iov[0].iov_len = sizeof(len);
  1038. 27811                         iov[1].iov_base = (char *)buf;
  1039. 27812                         iov[1].iov_len = buflen;
  1040. 27813                         if (writev(s, iov, 2) != sizeof(len) + buflen) {
  1041. 27814                                 terrno = errno;
  1042. 27815 #ifdef DEBUG
  1043. 27816                                 if (_res.options & RES_DEBUG)
  1044. 27817                                         perror("write failed");
  1045. 27818 #endif /* DEBUG */
  1046. 27819                                 (void) close(s);
  1047. 27820                                 s = -1;
  1048. 27821                                 continue;
  1049. 27822                         }
  1050. 27823                         /*
  1051. 27824                          * Receive length & response
  1052. 27825                          */
  1053. 27826                         cp = answer;
  1054. 27827                         len = sizeof(short);
  1055. 27828                         while (len != 0 &&
  1056. 27829                             (n = read(s, (char *)cp, (int)len)) > 0) {
  1057. 27830                                 cp += n;
  1058. 27831                                 len -= n;
  1059. 27832                         }
  1060. 27833                         if (n <= 0) {
  1061. 27834                                 terrno = errno;
  1062. 27835 #ifdef DEBUG
  1063. 27836                                 if (_res.options & RES_DEBUG)
  1064. 27837                                         perror("read failed");
  1065. 27838 #endif /* DEBUG */
  1066. 27839                                 (void) close(s);
  1067. 27840                                 s = -1;
  1068. 27841                                 /*
  1069. 27842                                  * A long running process might get its TCP
  1070. 27843                                  * connection reset if the remote server was
  1071. 27844                                  * restarted.  Requery the server instead of
  1072. 27845                                  * trying a new one.  When there is only one
  1073. 27846                                  * server, this means that a query might work
  1074. 27847                                  * instead of failing.  We only allow one reset
  1075. 27848                                  * per query to prevent looping.
  1076. 27849                                  */
  1077. 27850                                 if (terrno == ECONNRESET && !connreset) {
  1078. 27851                                         connreset = 1;
  1079. 27852                                         ns--;
  1080. 27853                                 }
  1081. 27854                                 continue;
  1082. 27855                         }
  1083. 27856                         cp = answer;
  1084. 27857                         if ((resplen = ntohs(*(u_short *)cp)) > anslen) {
  1085. 27858 #ifdef DEBUG
  1086. 27859                                 if (_res.options & RES_DEBUG)
  1087. 27860                                         fprintf(stderr, "response truncatedn");
  1088. 27861 #endif /* DEBUG */
  1089. 27862                                 len = anslen;
  1090. 27863                                 truncated = 1;
  1091. 27864                         } else
  1092. 27865                                 len = resplen;
  1093. 27866                         while (len != 0 &&
  1094. 27867                            (n = read(s, (char *)cp, (int)len)) > 0) {
  1095. 27868                                 cp += n;
  1096. 27869                                 len -= n;
  1097. 27870                         }
  1098. 27871                         if (n <= 0) {
  1099. 27872                                 terrno = errno;
  1100. 27873 #ifdef DEBUG
  1101. 27874                                 if (_res.options & RES_DEBUG)
  1102. 27875                                         perror("read failed");
  1103. 27876 #endif /* DEBUG */
  1104. 27877                                 (void) close(s);
  1105. 27878                                 s = -1;
  1106. 27879                                 continue;
  1107. 27880                         }
  1108. 27881                         if (truncated) {
  1109. 27882                                 /*
  1110. 27883                                  * Flush rest of answer
  1111. 27884                                  * so connection stays in synch.
  1112. 27885                                  */
  1113. 27886                                 anhp->tc = 1;
  1114. 27887                                 len = resplen - anslen;
  1115. 27888                                 while (len != 0) {
  1116. 27889                                         n = (len > sizeof(junk) ?
  1117. 27890                                             sizeof(junk) : len);
  1118. 27891                                         if ((n = read(s, junk, n)) > 0)
  1119. 27892                                                 len -= n;
  1120. 27893                                         else
  1121. 27894                                                 break;
  1122. 27895                                 }
  1123. 27896                         }
  1124. 27897 #else /* _MINIX */
  1125. 27898                         int truncated = 0;
  1126. 27899                         int nbytes;
  1127. 27900
  1128. 27901                         /*
  1129. 27902                          * Use virtual circuit;
  1130. 27903                          * at most one attempt per server.
  1131. 27904                          */
  1132. 27905                         try = _res.retry;
  1133. 27906                         if (s < 0) 
  1134. 27907                         {
  1135. 27908                                 s= tcp_connect(_res.nsaddr_list[ns],
  1136. 27909                                         _res.nsport_list[ns], &terrno);
  1137. 27910                                 if (s == -1)
  1138. 27911                                         continue;
  1139. 27912                         }
  1140. 27913                         /*
  1141. 27914                          * Send length & message
  1142. 27915                          */
  1143. 27916                         len = htons((u_short)buflen);
  1144. 27917                         nbytes= tcpip_writeall(s, (char *)&len, 
  1145. 27918                                 sizeof(len));
  1146. 27919                         if (nbytes != sizeof(len))
  1147. 27920                         {
  1148. 27921                                 terrno= errno;
  1149. 27922 #ifdef DEBUG
  1150. 27923                                 if (_res.options & RES_DEBUG)
  1151. 27924                                         fprintf(stderr, "write failed: %sn",
  1152. 27925                                         strerror(terrno));
  1153. 27926 #endif /* DEBUG */
  1154. 27927                                 close(s);
  1155. 27928                                 s= -1;
  1156. 27929                                 continue;
  1157. 27930                         }
  1158. 27931                         nbytes= tcpip_writeall(s, buf, buflen);
  1159. 27932                         if (nbytes != buflen)
  1160. 27933                         {
  1161. 27934                                 terrno= errno;
  1162. 27935 #ifdef DEBUG
  1163. 27936                                 if (_res.options & RES_DEBUG)
  1164. 27937                                         fprintf(stderr, "write failed: %sn",
  1165. 27938                                         strerror(terrno));
  1166. 27939 #endif /* DEBUG */
  1167. 27940                                 close(s);
  1168. 27941                                 s= -1;
  1169. 27942                                 continue;
  1170. 27943                         }
  1171. 27944                         /*
  1172. 27945                          * Receive length & response
  1173. 27946                          */
  1174. 27947                         cp = answer;
  1175. 27948                         len = sizeof(short);
  1176. 27949                         while (len != 0)
  1177. 27950                         {
  1178. 27951                                 n = read(s, (char *)cp, (int)len);
  1179. 27952                                 if (n <= 0)
  1180. 27953                                         break;
  1181. 27954                                 cp += n;
  1182. 27955                                 assert(len >= n);
  1183. 27956                                 len -= n;
  1184. 27957                         }
  1185. 27958                         if (len) {
  1186. 27959                                 terrno = errno;
  1187. 27960 #ifdef DEBUG
  1188. 27961                                 if (_res.options & RES_DEBUG)
  1189. 27962                                         fprintf(stderr, "read failed: %sn",
  1190. 27963                                                 strerror(terrno));
  1191. 27964 #endif /* DEBUG */
  1192. 27965                                 close(s);
  1193. 27966                                 s= -1;
  1194. 27967                                 /*
  1195. 27968                                  * A long running process might get its TCP
  1196. 27969                                  * connection reset if the remote server was
  1197. 27970                                  * restarted.  Requery the server instead of
  1198. 27971                                  * trying a new one.  When there is only one
  1199. 27972                                  * server, this means that a query might work
  1200. 27973                                  * instead of failing.  We only allow one reset
  1201. 27974                                  * per query to prevent looping.
  1202. 27975                                  */
  1203. 27976                                 if (terrno == ECONNRESET && !connreset) {
  1204. 27977                                         connreset = 1;
  1205. 27978                                         ns--;
  1206. 27979                                 }
  1207. 27980                                 continue;
  1208. 27981                         }
  1209. 27982                         cp = answer;
  1210. 27983                         if ((resplen = ntohs(*(u_short *)cp)) > anslen) {
  1211. 27984 #ifdef DEBUG
  1212. 27985                                 if (_res.options & RES_DEBUG)
  1213. 27986                                         fprintf(stderr, "response truncatedn");
  1214. 27987 #endif /* DEBUG */
  1215. 27988                                 len = anslen;
  1216. 27989                                 truncated = 1;
  1217. 27990                         } else
  1218. 27991                                 len = resplen;
  1219. 27992                         while (len != 0)
  1220. 27993                         {
  1221. 27994                                 n= read(s, (char *)cp, (int)len);
  1222. 27995                                 if (n <= 0)
  1223. 27996                                         break;
  1224. 27997                                 cp += n;
  1225. 27998                                 assert(len >= n);
  1226. 27999                                 len -= n;
  1227. 28000                         }
  1228. 28001                         if (len) {
  1229. 28002                                 terrno = errno;
  1230. 28003 #ifdef DEBUG
  1231. 28004                                 if (_res.options & RES_DEBUG)
  1232. 28005                                         fprintf(stderr, "read failed: %sn",
  1233. 28006                                                 strerror(terrno));
  1234. 28007 #endif /* DEBUG */
  1235. 28008                                 close(s);
  1236. 28009                                 s= -1;
  1237. 28010                                 continue;
  1238. 28011                         }
  1239. 28012                         if (truncated) {
  1240. 28013                                 /*
  1241. 28014                                  * Flush rest of answer
  1242. 28015                                  * so connection stays in synch.
  1243. 28016                                  */
  1244. 28017                                 anhp->dh_flag1 |= DHF_TC;
  1245. 28018                                 len = resplen - anslen;
  1246. 28019                                 while (len != 0) {
  1247. 28020                                         n = (len > sizeof(junk) ?
  1248. 28021                                             sizeof(junk) : len);
  1249. 28022                                         n = read(s, junk, n);
  1250. 28023                                         if (n <= 0)
  1251. 28024                                         {
  1252. 28025                                                 assert(len >= n);
  1253. 28026                                                 len -= n;
  1254. 28027                                         }
  1255. 28028                                         else
  1256. 28029                                                 break;
  1257. 28030                                 }
  1258. 28031                         }
  1259. 28032 #endif /* _MINIX */
  1260. 28033                 } else {
  1261. 28034 #if !_MINIX
  1262. 28035                         /*
  1263. 28036                          * Use datagrams.
  1264. 28037                          */
  1265. 28038                         if (s < 0) {
  1266. 28039                                 s = socket(AF_INET, SOCK_DGRAM, 0);
  1267. 28040                                 if (s < 0) {
  1268. 28041                                         terrno = errno;
  1269. 28042 #ifdef DEBUG
  1270. 28043                                         if (_res.options & RES_DEBUG)
  1271. 28044                                             perror("socket (dg) failed");
  1272. 28045 #endif /* DEBUG */
  1273. 28046                                         continue;
  1274. 28047                                 }
  1275. 28048                         }
  1276. 28049 #if     BSD >= 43
  1277. 28050                         /*
  1278. 28051                          * I'm tired of answering this question, so:
  1279. 28052                          * On a 4.3BSD+ machine (client and server,
  1280. 28053                          * actually), sending to a nameserver datagram
  1281. 28054                          * port with no nameserver will cause an
  1282. 28055                          * ICMP port unreachable message to be returned.
  1283. 28056                          * If our datagram socket is "connected" to the
  1284. 28057                          * server, we get an ECONNREFUSED error on the next
  1285. 28058                          * socket operation, and select returns if the
  1286. 28059                          * error message is received.  We can thus detect
  1287. 28060                          * the absence of a nameserver without timing out.
  1288. 28061                          * If we have sent queries to at least two servers,
  1289. 28062                          * however, we don't want to remain connected,
  1290. 28063                          * as we wish to receive answers from the first
  1291. 28064                          * server to respond.
  1292. 28065                          */
  1293. 28066                         if (_res.nscount == 1 || (try == 0 && ns == 0)) {
  1294. 28067                                 /*
  1295. 28068                                  * Don't use connect if we might
  1296. 28069                                  * still receive a response
  1297. 28070                                  * from another server.
  1298. 28071                                  */
  1299. 28072                                 if (connected == 0) {
  1300. 28073                         if (connect(s, (struct sockaddr *)&_res.nsaddr_list[ns],
  1301. 28074                                             sizeof(struct sockaddr)) < 0) {
  1302. 28075 #ifdef DEBUG
  1303. 28076                                                 if (_res.options & RES_DEBUG)
  1304. 28077                                                         perror("connect");
  1305. 28078 #endif /* DEBUG */
  1306. 28079                                                 continue;
  1307. 28080                                         }
  1308. 28081                                         connected = 1;
  1309. 28082                                 }
  1310. 28083                                 if (send(s, buf, buflen, 0) != buflen) {
  1311. 28084 #ifdef DEBUG
  1312. 28085                                         if (_res.options & RES_DEBUG)
  1313. 28086                                                 perror("send");
  1314. 28087 #endif /* DEBUG */
  1315. 28088                                         continue;
  1316. 28089                                 }
  1317. 28090                         } else {
  1318. 28091                                 /*
  1319. 28092                                  * Disconnect if we want to listen
  1320. 28093                                  * for responses from more than one server.
  1321. 28094                                  */
  1322. 28095                                 if (connected) {
  1323. 28096                                         (void) connect(s, &no_addr,
  1324. 28097                                             sizeof(no_addr));
  1325. 28098                                         connected = 0;
  1326. 28099                                 }
  1327. 28100 #endif /* BSD */
  1328. 28101                                 if (sendto(s, buf, buflen, 0,
  1329. 28102                                     (struct sockaddr *)&_res.nsaddr_list[ns],
  1330. 28103                                     sizeof(struct sockaddr)) != buflen) {
  1331. 28104 #ifdef DEBUG
  1332. 28105                                         if (_res.options & RES_DEBUG)
  1333. 28106                                                 perror("sendto");
  1334. 28107 #endif /* DEBUG */
  1335. 28108                                         continue;
  1336. 28109                                 }
  1337. 28110 #if     BSD >= 43
  1338. 28111                         }
  1339. 28112 #endif /* BSD */
  1340. 28113
  1341. 28114                         /*
  1342. 28115                          * Wait for reply
  1343. 28116                          */
  1344. 28117                         timeout.tv_sec = (_res.retrans << try);
  1345. 28118                         if (try > 0)
  1346. 28119                                 timeout.tv_sec /= _res.nscount;
  1347. 28120                         if (timeout.tv_sec <= 0)
  1348. 28121                                 timeout.tv_sec = 1;
  1349. 28122                         timeout.tv_usec = 0;
  1350. 28123 wait:
  1351. 28124                         FD_ZERO(&dsmask);
  1352. 28125                         FD_SET(s, &dsmask);
  1353. 28126                         n = select(s+1, &dsmask, (fd_set *)NULL,
  1354. 28127                                 (fd_set *)NULL, &timeout);
  1355. 28128                         if (n < 0) {
  1356. 28129 #ifdef DEBUG
  1357. 28130                                 if (_res.options & RES_DEBUG)
  1358. 28131                                         perror("select");
  1359. 28132 #endif /* DEBUG */
  1360. 28133                                 continue;
  1361. 28134                         }
  1362. 28135                         if (n == 0) {
  1363. 28136                                 /*
  1364. 28137                                  * timeout
  1365. 28138                                  */
  1366. 28139 #ifdef DEBUG
  1367. 28140                                 if (_res.options & RES_DEBUG)
  1368. 28141                                         printf("timeoutn");
  1369. 28142 #endif /* DEBUG */
  1370. 28143 #if BSD >= 43
  1371. 28144                                 gotsomewhere = 1;
  1372. 28145 #endif
  1373. 28146                                 continue;
  1374. 28147                         }
  1375. 28148                         if ((resplen = recv(s, answer, anslen, 0)) <= 0) {
  1376. 28149 #ifdef DEBUG
  1377. 28150                                 if (_res.options & RES_DEBUG)
  1378. 28151                                         perror("recvfrom");
  1379. 28152 #endif /* DEBUG */
  1380. 28153                                 continue;
  1381. 28154                         }
  1382. 28155                         gotsomewhere = 1;
  1383. 28156                         if (id != anhp->id) {
  1384. 28157                                 /*
  1385. 28158                                  * response from old query, ignore it
  1386. 28159                                  */
  1387. 28160 #ifdef DEBUG
  1388. 28161                                 if (_res.options & RES_DEBUG) {
  1389. 28162                                         printf("old answer:n");
  1390. 28163                                         __p_query(answer);
  1391. 28164                                 }
  1392. 28165 #endif /* DEBUG */
  1393. 28166                                 goto wait;
  1394. 28167                         }
  1395. 28168                         if (!(_res.options & RES_IGNTC) && anhp->tc) {
  1396. 28169                                 /*
  1397. 28170                                  * get rest of answer;
  1398. 28171                                  * use TCP with same server.
  1399. 28172                                  */
  1400. 28173 #ifdef DEBUG
  1401. 28174                                 if (_res.options & RES_DEBUG)
  1402. 28175                                         printf("truncated answern");
  1403. 28176 #endif /* DEBUG */
  1404. 28177                                 (void) close(s);
  1405. 28178                                 s = -1;
  1406. 28179                                 v_circuit = 1;
  1407. 28180                                 goto usevc;
  1408. 28181                         }
  1409. 28182 #else /* _MINIX */
  1410. 28183                         /*
  1411. 28184                          * Use datagrams.
  1412. 28185                          */
  1413. 28186                         if (s < 0) {
  1414. 28187                                 s = udp_connect();
  1415. 28188                                 if (s < 0) {
  1416. 28189                                         terrno = errno;
  1417. 28190 #ifdef DEBUG
  1418. 28191                                         if (_res.options & RES_DEBUG)
  1419. 28192                                             perror("udp_connect failed");
  1420. 28193 #endif /* DEBUG */
  1421. 28194                                         continue;
  1422. 28195                                 }
  1423. 28196                         }
  1424. 28197                         if (udp_sendto(s, buf, buflen, _res.nsaddr_list[ns],
  1425. 28198                                 _res.nsport_list[ns]) != buflen) {
  1426. 28199 #ifdef DEBUG
  1427. 28200                                 if (_res.options & RES_DEBUG)
  1428. 28201                                         perror("sendto");
  1429. 28202 #endif /* DEBUG */
  1430. 28203                                 continue;
  1431. 28204                         }
  1432. 28205
  1433. 28206                         /*
  1434. 28207                          * Wait for reply
  1435. 28208                          */
  1436. 28209                         timeout= (_res.retrans << try);
  1437. 28210                         if (try > 0)
  1438. 28211                                 timeout /= _res.nscount;
  1439. 28212                         if (timeout <= 0)
  1440. 28213                                 timeout= 1;
  1441. 28214 wait:
  1442. 28215                         if ((resplen= udp_receive(s, answer, anslen, timeout))
  1443. 28216                                 == -1)
  1444. 28217                         {
  1445. 28218                                 if (errno == EINTR)
  1446. 28219                                 {
  1447. 28220                                 /*
  1448. 28221                                  * timeout
  1449. 28222                                  */
  1450. 28223 #ifdef DEBUG
  1451. 28224                                         if (_res.options & RES_DEBUG)
  1452. 28225                                                 printf("timeoutn");
  1453. 28226 #endif /* DEBUG */
  1454. 28227                                         gotsomewhere = 1;
  1455. 28228                                 }
  1456. 28229                                 else
  1457. 28230                                 {
  1458. 28231 #ifdef DEBUG
  1459. 28232                                 if (_res.options & RES_DEBUG)
  1460. 28233                                         perror("udp_receive");
  1461. 28234 #endif /* DEBUG */
  1462. 28235                                 }
  1463. 28236                                 continue;
  1464. 28237                         }
  1465. 28238                         gotsomewhere = 1;
  1466. 28239                         if (id != anhp->dh_id) {
  1467. 28240                                 /*
  1468. 28241                                  * response from old query, ignore it
  1469. 28242                                  */
  1470. 28243 #ifdef DEBUG
  1471. 28244                                 if (_res.options & RES_DEBUG) {
  1472. 28245                                         printf("old answer:n");
  1473. 28246                                         __p_query(answer);
  1474. 28247                                 }
  1475. 28248 #endif /* DEBUG */
  1476. 28249                                 goto wait;
  1477. 28250                         }
  1478. 28251                         if (!(_res.options & RES_IGNTC) &&
  1479. 28252                                 (anhp->dh_flag1 & DHF_TC)) {
  1480. 28253                                 /*
  1481. 28254                                  * get rest of answer;
  1482. 28255                                  * use TCP with same server.
  1483. 28256                                  */
  1484. 28257 #ifdef DEBUG
  1485. 28258                                 if (_res.options & RES_DEBUG)
  1486. 28259                                         printf("truncated answern");
  1487. 28260 #endif /* DEBUG */
  1488. 28261                                 (void) close(s);
  1489. 28262                                 s = -1;
  1490. 28263                                 v_circuit = 1;
  1491. 28264                                 goto usevc;
  1492. 28265                         }
  1493. 28266 #endif /* !_MINIX */
  1494. 28267                 }
  1495. 28268 #ifdef DEBUG
  1496. 28269                 if (_res.options & RES_DEBUG) {
  1497. 28270                         printf("got answer:n");
  1498. 28271                         __p_query(answer);
  1499. 28272                 }
  1500. 28273 #endif /* DEBUG */
  1501. 28274                 /*
  1502. 28275                  * If using virtual circuits, we assume that the first server
  1503. 28276                  * is preferred * over the rest (i.e. it is on the local
  1504. 28277                  * machine) and only keep that one open.
  1505. 28278                  * If we have temporarily opened a virtual circuit,
  1506. 28279                  * or if we haven't been asked to keep a socket open,
  1507. 28280                  * close the socket.
  1508. 28281                  */
  1509. 28282                 if ((v_circuit &&
  1510. 28283                     ((_res.options & RES_USEVC) == 0 || ns != 0)) ||
  1511. 28284                     (_res.options & RES_STAYOPEN) == 0) {
  1512. 28285                         (void) close(s);
  1513. 28286                         s = -1;
  1514. 28287                 }
  1515. 28288                 return (resplen);
  1516. 28289            }
  1517. 28290         }
  1518. 28291         if (s >= 0) {
  1519. 28292                 (void) close(s);
  1520. 28293                 s = -1;
  1521. 28294         }
  1522. 28295         if (v_circuit == 0)
  1523. 28296                 if (gotsomewhere == 0)
  1524. 28297                         errno = ECONNREFUSED;   /* no nameservers found */
  1525. 28298                 else
  1526. 28299                         errno = ETIMEDOUT;      /* no answer obtained */
  1527. 28300         else
  1528. 28301                 errno = terrno;
  1529. 28302         return (-1);
  1530. 28303 }
  1531. 28305 /*
  1532. 28306  * This routine is for closing the socket if a virtual circuit is used and
  1533. 28307  * the program wants to close it.  This provides support for endhostent()
  1534. 28308  * which expects to close the socket.
  1535. 28309  *
  1536. 28310  * This routine is not expected to be user visible.
  1537. 28311  */
  1538. 28312 void
  1539. 28313 _res_close()
  1540. 28314 {
  1541. 28315         if (s != -1) {
  1542. 28316                 (void) close(s);
  1543. 28317                 s = -1;
  1544. 28318         }
  1545. 28319 }
  1546. 28321 #if _MINIX
  1547. 28322 static int tcp_connect(host, port, terrno)
  1548. 28323 ipaddr_t host;
  1549. 28324 tcpport_t port;
  1550. 28325 int *terrno;
  1551. 28326 {
  1552. 28327         char *dev_name;
  1553. 28328         int fd;
  1554. 28329         int error;
  1555. 28330         nwio_tcpconf_t tcpconf;
  1556. 28331         nwio_tcpcl_t clopt;
  1557. 28332
  1558. 28333         dev_name= getenv("TCP_DEVICE");
  1559. 28334         if (!dev_name)
  1560. 28335                 dev_name= TCP_DEVICE;
  1561. 28336         fd= open(dev_name, O_RDWR);
  1562. 28337         if (fd == -1)
  1563. 28338         {
  1564. 28339                 *terrno= errno;
  1565. 28340                 return -1;
  1566. 28341         }
  1567. 28342         tcpconf.nwtc_flags= NWTC_EXCL | NWTC_LP_SEL | NWTC_SET_RA | NWTC_SET_RP;
  1568. 28343         tcpconf.nwtc_remaddr= host;
  1569. 28344         tcpconf.nwtc_remport= port;
  1570. 28345         error= ioctl(fd, NWIOSTCPCONF, &tcpconf);
  1571. 28346         if (error == -1)
  1572. 28347         {
  1573. 28348                 *terrno= errno;
  1574. 28349                 close(fd);
  1575. 28350                 return -1;
  1576. 28351         }
  1577. 28352         clopt.nwtcl_flags= 0;
  1578. 28353         error= ioctl(fd, NWIOTCPCONN, &clopt);
  1579. 28354         if (error == -1)
  1580. 28355         {
  1581. 28356                 *terrno= errno;
  1582. 28357                 close(fd);
  1583. 28358                 return -1;
  1584. 28359         }
  1585. 28360         *terrno= 0;
  1586. 28361         return fd;
  1587. 28362 }
  1588. 28364 static int tcpip_writeall(fd, buf, siz)
  1589. 28365 int fd;
  1590. 28366 const char *buf;
  1591. 28367 size_t siz;
  1592. 28368 {
  1593. 28369         size_t siz_org;
  1594. 28370         int nbytes;
  1595. 28371
  1596. 28372         siz_org= siz;
  1597. 28373
  1598. 28374         while (siz)
  1599. 28375         {
  1600. 28376                 nbytes= write(fd, buf, siz);
  1601. 28377                 if (nbytes <= 0)
  1602. 28378                         return siz_org-siz;
  1603. 28379                 assert(siz >= nbytes);
  1604. 28380                 buf += nbytes;
  1605. 28381                 siz -= nbytes;
  1606. 28382         }
  1607. 28383         return siz_org;
  1608. 28384 }
  1609. 28387 static int udp_connect()
  1610. 28388 {
  1611. 28389         nwio_udpopt_t udpopt;
  1612. 28390         char *dev_name;
  1613. 28391         int fd, r, terrno;
  1614. 28392
  1615. 28393         dev_name= getenv("UDP_DEVICE");
  1616. 28394         if (!dev_name)
  1617. 28395                 dev_name= UDP_DEVICE;
  1618. 28396         fd= open(dev_name, O_RDWR);
  1619. 28397         if (fd == -1)
  1620. 28398                 return -1;
  1621. 28399
  1622. 28400         udpopt.nwuo_flags= NWUO_COPY | NWUO_LP_SEL | NWUO_EN_LOC |
  1623. 28401                 NWUO_EN_BROAD | NWUO_RP_ANY | NWUO_RA_ANY | NWUO_RWDATALL |
  1624. 28402                 NWUO_DI_IPOPT;
  1625. 28403         r= ioctl(fd, NWIOSUDPOPT, &udpopt);
  1626. 28404         if (r == -1)
  1627. 28405         {
  1628. 28406                 terrno= errno;
  1629. 28407                 close(fd);
  1630. 28408                 errno= terrno;
  1631. 28409                 return -1;
  1632. 28410         }
  1633. 28411         return fd;
  1634. 28412 }
  1635. 28414 static int udp_sendto(fd, buf, buflen, addr, port)
  1636. 28415 int fd;
  1637. 28416 const char *buf;
  1638. 28417 unsigned buflen;
  1639. 28418 ipaddr_t addr;
  1640. 28419 udpport_t port;
  1641. 28420 {
  1642. 28421         char *newbuf;
  1643. 28422         udp_io_hdr_t *udp_io_hdr;
  1644. 28423         int r, terrno;
  1645. 28424
  1646. 28425         newbuf= malloc(sizeof(*udp_io_hdr) + buflen);
  1647. 28426         if (newbuf == NULL)
  1648. 28427         {
  1649. 28428                 errno= ENOMEM;
  1650. 28429                 return -1;
  1651. 28430         }
  1652. 28431         udp_io_hdr= (udp_io_hdr_t *)newbuf;
  1653. 28432         udp_io_hdr->uih_dst_addr= addr;
  1654. 28433         udp_io_hdr->uih_dst_port= port;
  1655. 28434         udp_io_hdr->uih_ip_opt_len= 0;
  1656. 28435         udp_io_hdr->uih_data_len= buflen;
  1657. 28436
  1658. 28437         memcpy(newbuf + sizeof(*udp_io_hdr), buf, buflen);
  1659. 28438         r= write(fd, newbuf, sizeof(*udp_io_hdr) + buflen);
  1660. 28439         terrno= errno;
  1661. 28440         free(newbuf);
  1662. 28441         if (r >= sizeof(*udp_io_hdr))
  1663. 28442                 r -= sizeof(*udp_io_hdr);
  1664. 28443         errno= terrno;
  1665. 28444         return r;
  1666. 28445 }
  1667. 28447 static void alarm_handler(sig)
  1668. 28448 int sig;
  1669. 28449 {
  1670. 28450         signal(SIGALRM, alarm_handler);
  1671. 28451         alarm(1);
  1672. 28452 }
  1673. 28454 static int udp_receive(fd, buf, buflen, timeout)
  1674. 28455 int fd;
  1675. 28456 char *buf;
  1676. 28457 unsigned buflen;
  1677. 28458 time_t timeout;
  1678. 28459 {
  1679. 28460         char *newbuf;
  1680. 28461         udp_io_hdr_t *udp_io_hdr;
  1681. 28462         int r, terrno;
  1682. 28463         void (*u_handler) _ARGS(( int sig ));
  1683. 28464         time_t u_timeout;
  1684. 28465
  1685. 28466         newbuf= malloc(sizeof(*udp_io_hdr) + buflen);
  1686. 28467         if (newbuf == NULL)
  1687. 28468         {
  1688. 28469                 errno= ENOMEM;
  1689. 28470                 return -1;
  1690. 28471         }
  1691. 28472
  1692. 28473         u_handler= signal(SIGALRM, alarm_handler);
  1693. 28474         u_timeout= alarm(timeout);
  1694. 28475
  1695. 28476         r= read(fd, newbuf, sizeof(*udp_io_hdr) + buflen);
  1696. 28477         terrno= errno;
  1697. 28478
  1698. 28479         if (r < 0 || r <= sizeof(*udp_io_hdr))
  1699. 28480         {
  1700. 28481                 if (r > 0)
  1701. 28482                         r= 0;
  1702. 28483                 free(newbuf);
  1703. 28484
  1704. 28485
  1705. 28486                 alarm(0);
  1706. 28487                 signal(SIGALRM, u_handler);
  1707. 28488                 alarm(u_timeout);
  1708. 28489
  1709. 28490                 errno= terrno;
  1710. 28491                 return r;
  1711. 28492         }
  1712. 28493
  1713. 28494         memcpy(buf, newbuf + sizeof(*udp_io_hdr), r - sizeof(*udp_io_hdr));
  1714. 28495         free(newbuf);
  1715. 28496
  1716. 28497         alarm(0);
  1717. 28498         signal(SIGALRM, u_handler);
  1718. 28499         alarm(u_timeout);
  1719. 28500
  1720. 28501         return r-sizeof(*udp_io_hdr);
  1721. 28502 }
  1722. 28504 #endif
  1723. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1724. src/lib/ip/strcasecmp.c    
  1725. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1726. 28600 /*
  1727. 28601 strcasecmp.c
  1728. 28602
  1729. 28603 Created Oct 14, 1991 by Philip Homburg
  1730. 28604 */
  1731. 28605
  1732. 28606 #include <ctype.h>
  1733. 28607 #include <string.h>
  1734. 28608
  1735. 28609 #ifdef __STDC__
  1736. 28610 #define _CONST  const
  1737. 28611 #else
  1738. 28612 #define _CONST
  1739. 28613 #endif
  1740. 28614
  1741. 28615 int
  1742. 28616 strcasecmp(s1, s2)
  1743. 28617 _CONST char *s1, *s2;
  1744. 28618 {
  1745. 28619         int c1, c2;
  1746. 28620         while (c1= toupper(*s1++), c2= toupper(*s2++), c1 == c2 && (c1 & c2))
  1747. 28621                 ;
  1748. 28622         if (c1 & c2)
  1749. 28623                 return c1 < c2 ? -1 : 1;
  1750. 28624         return c1 ? 1 : (c2 ? -1 : 0);
  1751. 28625 }
  1752. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1753. src/lib/liby/main.c    
  1754. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1755. 28700 /*-
  1756. 28701  * Copyright (c) 1990 The Regents of the University of California.
  1757. 28702  * All rights reserved.
  1758. 28703  *
  1759. 28704  * Redistribution and use in source and binary forms, with or without
  1760. 28705  * modification, are permitted provided that the following conditions
  1761. 28706  * are met:
  1762. 28707  * 1. Redistributions of source code must retain the above copyright
  1763. 28708  *    notice, this list of conditions and the following disclaimer.
  1764. 28709  * 2. Redistributions in binary form must reproduce the above copyright
  1765. 28710  *    notice, this list of conditions and the following disclaimer in the
  1766. 28711  *    documentation and/or other materials provided with the distribution.
  1767. 28712  * 3. All advertising materials mentioning features or use of this software
  1768. 28713  *    must display the following acknowledgement:
  1769. 28714  *      This product includes software developed by the University of
  1770. 28715  *      California, Berkeley and its contributors.
  1771. 28716  * 4. Neither the name of the University nor the names of its contributors
  1772. 28717  *    may be used to endorse or promote products derived from this software
  1773. 28718  *    without specific prior written permission.
  1774. 28719  *
  1775. 28720  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  1776. 28721  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  1777. 28722  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  1778. 28723  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  1779. 28724  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  1780. 28725  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  1781. 28726  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  1782. 28727  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1783. 28728  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  1784. 28729  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  1785. 28730  * SUCH DAMAGE.
  1786. 28731  */
  1787. 28732
  1788. 28733 #if defined(LIBC_SCCS) && !defined(lint)
  1789. 28734 static char sccsid[] = "@(#)main.c      5.3 (Berkeley) 1/13/91";
  1790. 28735 #endif /* not lint */
  1791. 28736
  1792. 28737 main()
  1793. 28738 {
  1794. 28739         exit(yyparse());
  1795. 28740 }
  1796. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1797. src/lib/liby/yyerror.c    
  1798. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1799. 28800 /*-
  1800. 28801  * Copyright (c) 1990 The Regents of the University of California.
  1801. 28802  * All rights reserved.
  1802. 28803  *
  1803. 28804  * Redistribution and use in source and binary forms, with or without
  1804. 28805  * modification, are permitted provided that the following conditions
  1805. 28806  * are met:
  1806. 28807  * 1. Redistributions of source code must retain the above copyright
  1807. 28808  *    notice, this list of conditions and the following disclaimer.
  1808. 28809  * 2. Redistributions in binary form must reproduce the above copyright
  1809. 28810  *    notice, this list of conditions and the following disclaimer in the
  1810. 28811  *    documentation and/or other materials provided with the distribution.
  1811. 28812  * 3. All advertising materials mentioning features or use of this software
  1812. 28813  *    must display the following acknowledgement:
  1813. 28814  *      This product includes software developed by the University of
  1814. 28815  *      California, Berkeley and its contributors.
  1815. 28816  * 4. Neither the name of the University nor the names of its contributors
  1816. 28817  *    may be used to endorse or promote products derived from this software
  1817. 28818  *    without specific prior written permission.
  1818. 28819  *
  1819. 28820  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  1820. 28821  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  1821. 28822  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  1822. 28823  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  1823. 28824  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  1824. 28825  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  1825. 28826  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  1826. 28827  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1827. 28828  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  1828. 28829  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  1829. 28830  * SUCH DAMAGE.
  1830. 28831  */
  1831. 28832
  1832. 28833 #if defined(LIBC_SCCS) && !defined(lint)
  1833. 28834 static char sccsid[] = "@(#)yyerror.c   5.2 (Berkeley) 5/15/90";
  1834. 28835 #endif /* not lint */
  1835. 28836
  1836. 28837 #include <stdio.h>
  1837. 28838
  1838. 28839 yyerror(msg)
  1839. 28840 char *msg;
  1840. 28841 {
  1841. 28842         (void)fprintf(stderr, "%sn", msg);
  1842. 28843         return(0);
  1843. 28844 }
  1844. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1845. src/lib/math/localmath.h    
  1846. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1847. 28900 /*
  1848. 28901  * localmath.h - This header is used by the mathematical library.
  1849. 28902  */
  1850. 28903 /* $Header: localmath.h,v 1.2 89/12/18 15:43:05 eck Exp $ */
  1851. 28904
  1852. 28905 /* some constants (Hart & Cheney) */
  1853. 28906 #define M_PI            3.14159265358979323846264338327950288
  1854. 28907 #define M_2PI           6.28318530717958647692528676655900576
  1855. 28908 #define M_3PI_4         2.35619449019234492884698253745962716
  1856. 28909 #define M_PI_2          1.57079632679489661923132169163975144
  1857. 28910 #define M_3PI_8         1.17809724509617246442349126872981358
  1858. 28911 #define M_PI_4          0.78539816339744830961566084581987572
  1859. 28912 #define M_PI_8          0.39269908169872415480783042290993786
  1860. 28913 #define M_1_PI          0.31830988618379067153776752674502872
  1861. 28914 #define M_2_PI          0.63661977236758134307553505349005744
  1862. 28915 #define M_4_PI          1.27323954473516268615107010698011488
  1863. 28916 #define M_E             2.71828182845904523536028747135266250
  1864. 28917 #define M_LOG2E         1.44269504088896340735992468100189213
  1865. 28918 #define M_LOG10E        0.43429448190325182765112891891660508
  1866. 28919 #define M_LN2           0.69314718055994530941723212145817657
  1867. 28920 #define M_LN10          2.30258509299404568401799145468436421
  1868. 28921 #define M_SQRT2         1.41421356237309504880168872420969808
  1869. 28922 #define M_1_SQRT2       0.70710678118654752440084436210484904
  1870. 28923 #define M_EULER         0.57721566490153286060651209008240243
  1871. 28924
  1872. 28925 /* macros for constructing polynomials */
  1873. 28926 #define POLYNOM1(x, a)  ((a)[1]*(x)+(a)[0])
  1874. 28927 #define POLYNOM2(x, a)  (POLYNOM1((x),(a)+1)*(x)+(a)[0])
  1875. 28928 #define POLYNOM3(x, a)  (POLYNOM2((x),(a)+1)*(x)+(a)[0])
  1876. 28929 #define POLYNOM4(x, a)  (POLYNOM3((x),(a)+1)*(x)+(a)[0])
  1877. 28930 #define POLYNOM5(x, a)  (POLYNOM4((x),(a)+1)*(x)+(a)[0])
  1878. 28931 #define POLYNOM6(x, a)  (POLYNOM5((x),(a)+1)*(x)+(a)[0])
  1879. 28932 #define POLYNOM7(x, a)  (POLYNOM6((x),(a)+1)*(x)+(a)[0])
  1880. 28933 #define POLYNOM8(x, a)  (POLYNOM7((x),(a)+1)*(x)+(a)[0])
  1881. 28934 #define POLYNOM9(x, a)  (POLYNOM8((x),(a)+1)*(x)+(a)[0])
  1882. 28935 #define POLYNOM10(x, a) (POLYNOM9((x),(a)+1)*(x)+(a)[0])
  1883. 28936 #define POLYNOM11(x, a) (POLYNOM10((x),(a)+1)*(x)+(a)[0])
  1884. 28937 #define POLYNOM12(x, a) (POLYNOM11((x),(a)+1)*(x)+(a)[0])
  1885. 28938 #define POLYNOM13(x, a) (POLYNOM12((x),(a)+1)*(x)+(a)[0])
  1886. 28939
  1887. 28940 #define M_LN_MAX_D      (M_LN2 * DBL_MAX_EXP)
  1888. 28941 #define M_LN_MIN_D      (M_LN2 * (DBL_MIN_EXP - 1))
  1889. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1890. src/lib/math/asin.c    
  1891. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1892. 29000 /*
  1893. 29001  * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  1894. 29002  * See the copyright notice in the ACK home directory, in the file "Copyright".
  1895. 29003  *
  1896. 29004  * Author: Ceriel J.H. Jacobs
  1897. 29005  */
  1898. 29006 /* $Header: asin.c,v 1.3 91/03/19 16:38:12 ceriel Exp $ */
  1899. 29007
  1900. 29008 #include        <math.h>
  1901. 29009 #include        <errno.h>
  1902. 29010 #include        "localmath.h"
  1903. 29011
  1904. 29012 static double
  1905. 29013 asin_acos(double x, int cosfl)
  1906. 29014 {
  1907. 29015         int negative = x < 0;
  1908. 29016         int     i;
  1909. 29017         double  g;
  1910. 29018         static double p[] = {
  1911. 29019                 -0.27368494524164255994e+2,
  1912. 29020                  0.57208227877891731407e+2,
  1913. 29021                 -0.39688862997540877339e+2,
  1914. 29022                  0.10152522233806463645e+2,
  1915. 29023                 -0.69674573447350646411e+0
  1916. 29024         };
  1917. 29025         static double q[] = {
  1918. 29026                 -0.16421096714498560795e+3,
  1919. 29027                  0.41714430248260412556e+3,
  1920. 29028                 -0.38186303361750149284e+3,
  1921. 29029                  0.15095270841030604719e+3,
  1922. 29030                 -0.23823859153670238830e+2,
  1923. 29031                  1.0
  1924. 29032         };
  1925. 29033
  1926. 29034         if (__IsNan(x)) {
  1927. 29035                 errno = EDOM;
  1928. 29036                 return x;
  1929. 29037         }
  1930. 29038
  1931. 29039         if (negative) {
  1932. 29040                 x = -x;
  1933. 29041         }
  1934. 29042         if (x > 0.5) {
  1935. 29043                 i = 1;
  1936. 29044                 if (x > 1) {
  1937. 29045                         errno = EDOM;
  1938. 29046                         return 0;
  1939. 29047                 }
  1940. 29048                 g = 0.5 - 0.5 * x;
  1941. 29049                 x = - sqrt(g);
  1942. 29050                 x += x;
  1943. 29051         }
  1944. 29052         else {
  1945. 29053                 /* ??? avoid underflow ??? */
  1946. 29054                 i = 0;
  1947. 29055                 g = x * x;
  1948. 29056         }
  1949. 29057         x += x * g * POLYNOM4(g, p) / POLYNOM5(g, q);
  1950. 29058         if (cosfl) {
  1951. 29059                 if (! negative) x = -x;
  1952. 29060         }
  1953. 29061         if ((cosfl == 0) == (i == 1)) {
  1954. 29062                 x = (x + M_PI_4) + M_PI_4;
  1955. 29063         }
  1956. 29064         else if (cosfl && negative && i == 1) {
  1957. 29065                 x = (x + M_PI_2) + M_PI_2;
  1958. 29066         }
  1959. 29067         if (! cosfl && negative) x = -x;
  1960. 29068         return x;
  1961. 29069 }
  1962. 29071 double
  1963. 29072 asin(double x)
  1964. 29073 {
  1965. 29074         return asin_acos(x, 0);
  1966. 29075 }
  1967. 29077 double
  1968. 29078 acos(double x)
  1969. 29079 {
  1970. 29080         return asin_acos(x, 1);
  1971. 29081 }
  1972. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1973. src/lib/math/atan.c    
  1974. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1975. 29100 /*
  1976. 29101  * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  1977. 29102  * See the copyright notice in the ACK home directory, in the file "Copyright".
  1978. 29103  *
  1979. 29104  * Author: Ceriel J.H. Jacobs
  1980. 29105  */
  1981. 29106 /* $Header: atan.c,v 1.3 91/03/19 16:38:21 ceriel Exp $ */
  1982. 29107
  1983. 29108 #include        <float.h>
  1984. 29109 #include        <math.h>
  1985. 29110 #include        <errno.h>
  1986. 29111 #include        "localmath.h"
  1987. 29112
  1988. 29113 double
  1989. 29114 atan(double x)
  1990. 29115 {
  1991. 29116         /*      Algorithm and coefficients from:
  1992. 29117                         "Software manual for the elementary functions"
  1993. 29118                         by W.J. Cody and W. Waite, Prentice-Hall, 1980
  1994. 29119         */
  1995. 29120
  1996. 29121         static double p[] = {
  1997. 29122                 -0.13688768894191926929e+2,
  1998. 29123                 -0.20505855195861651981e+2,
  1999. 29124                 -0.84946240351320683534e+1,
  2000. 29125                 -0.83758299368150059274e+0
  2001. 29126         };
  2002. 29127         static double q[] = {
  2003. 29128                  0.41066306682575781263e+2,
  2004. 29129                  0.86157349597130242515e+2,
  2005. 29130                  0.59578436142597344465e+2,
  2006. 29131                  0.15024001160028576121e+2,
  2007. 29132                  1.0
  2008. 29133         };
  2009. 29134         static double a[] = {
  2010. 29135                 0.0,
  2011. 29136                 0.52359877559829887307710723554658381,  /* pi/6 */
  2012. 29137                 M_PI_2,
  2013. 29138                 1.04719755119659774615421446109316763   /* pi/3 */
  2014. 29139         };
  2015. 29140
  2016. 29141         int     neg = x < 0;
  2017. 29142         int     n;
  2018. 29143         double  g;
  2019. 29144
  2020. 29145         if (__IsNan(x)) {
  2021. 29146                 errno = EDOM;
  2022. 29147                 return x;
  2023. 29148         }
  2024. 29149         if (neg) {
  2025. 29150                 x = -x;
  2026. 29151         }
  2027. 29152         if (x > 1.0) {
  2028. 29153                 x = 1.0/x;
  2029. 29154                 n = 2;
  2030. 29155         }
  2031. 29156         else    n = 0;
  2032. 29157
  2033. 29158         if (x > 0.26794919243112270647) {       /* 2-sqtr(3) */
  2034. 29159                 n = n + 1;
  2035. 29160                 x = (((0.73205080756887729353*x-0.5)-0.5)+x)/
  2036. 29161                         (1.73205080756887729353+x);
  2037. 29162         }
  2038. 29163
  2039. 29164         /* ??? avoid underflow ??? */
  2040. 29165
  2041. 29166         g = x * x;
  2042. 29167         x += x * g * POLYNOM3(g, p) / POLYNOM4(g, q);
  2043. 29168         if (n > 1) x = -x;
  2044. 29169         x += a[n];
  2045. 29170         return neg ? -x : x;
  2046. 29171 }
  2047. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2048. src/lib/math/atan2.c    
  2049. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2050. 29200 /*
  2051. 29201  * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2052. 29202  * See the copyright notice in the ACK home directory, in the file "Copyright".
  2053. 29203  *
  2054. 29204  * Author: Ceriel J.H. Jacobs
  2055. 29205  */
  2056. 29206 /* $Header: atan2.c,v 1.2 89/12/18 15:42:35 eck Exp $ */
  2057. 29207
  2058. 29208 #include        <math.h>
  2059. 29209 #include        <errno.h>
  2060. 29210 #include        "localmath.h"
  2061. 29211
  2062. 29212 double
  2063. 29213 atan2(double y, double x)
  2064. 29214 {
  2065. 29215         double absx, absy, val;
  2066. 29216
  2067. 29217         if (x == 0 && y == 0) {
  2068. 29218                 errno = EDOM;
  2069. 29219                 return 0;
  2070. 29220         }
  2071. 29221         absy = y < 0 ? -y : y;
  2072. 29222         absx = x < 0 ? -x : x;
  2073. 29223         if (absy - absx == absy) {
  2074. 29224                 /* x negligible compared to y */
  2075. 29225                 return y < 0 ? -M_PI_2 : M_PI_2;
  2076. 29226         }
  2077. 29227         if (absx - absy == absx) {
  2078. 29228                 /* y negligible compared to x */
  2079. 29229                 val = 0.0;
  2080. 29230         }
  2081. 29231         else    val = atan(y/x);
  2082. 29232         if (x > 0) {
  2083. 29233                 /* first or fourth quadrant; already correct */
  2084. 29234                 return val;
  2085. 29235         }
  2086. 29236         if (y < 0) {
  2087. 29237                 /* third quadrant */
  2088. 29238                 return val - M_PI;
  2089. 29239         }
  2090. 29240         return val + M_PI;
  2091. 29241 }
  2092. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2093. src/lib/math/ceil.c    
  2094. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2095. 29300 /*
  2096. 29301  * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2097. 29302  * See the copyright notice in the ACK home directory, in the file "Copyright".
  2098. 29303  *
  2099. 29304  * Author: Ceriel J.H. Jacobs
  2100. 29305  */
  2101. 29306 /* $Header: ceil.c,v 1.1 89/05/10 16:00:46 eck Exp $ */
  2102. 29307
  2103. 29308 #include        <math.h>
  2104. 29309
  2105. 29310 double
  2106. 29311 ceil(double x)
  2107. 29312 {
  2108. 29313         double val;
  2109. 29314
  2110. 29315         return modf(x, &val) > 0 ? val + 1.0 : val ;
  2111. 29316         /*      this also works if modf always returns a positive
  2112. 29317                 fractional part
  2113. 29318         */
  2114. 29319 }
  2115. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2116. src/lib/math/exp.c    
  2117. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2118. 29400 /*
  2119. 29401  * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2120. 29402  * See the copyright notice in the ACK home directory, in the file "Copyright".
  2121. 29403  *
  2122. 29404  * Author: Ceriel J.H. Jacobs
  2123. 29405  */
  2124. 29406 /* $Header: exp.c,v 1.5 91/03/19 16:38:29 ceriel Exp $ */
  2125. 29407
  2126. 29408 #include        <math.h>
  2127. 29409 #include        <float.h>
  2128. 29410 #include        <errno.h>
  2129. 29411 #include        "localmath.h"
  2130. 29412
  2131. 29413
  2132. 29414 double
  2133. 29415 exp(double x)
  2134. 29416 {
  2135. 29417         /*      Algorithm and coefficients from:
  2136. 29418                         "Software manual for the elementary functions"
  2137. 29419                         by W.J. Cody and W. Waite, Prentice-Hall, 1980
  2138. 29420         */
  2139. 29421
  2140. 29422         static double p[] = {
  2141. 29423                 0.25000000000000000000e+0,
  2142. 29424                 0.75753180159422776666e-2,
  2143. 29425                 0.31555192765684646356e-4
  2144. 29426         };
  2145. 29427
  2146. 29428         static double q[] = {
  2147. 29429                 0.50000000000000000000e+0,
  2148. 29430                 0.56817302698551221787e-1,
  2149. 29431                 0.63121894374398503557e-3,
  2150. 29432                 0.75104028399870046114e-6
  2151. 29433         };
  2152. 29434         double  xn, g;
  2153. 29435         int     n;
  2154. 29436         int     negative = x < 0;
  2155. 29437
  2156. 29438         if (__IsNan(x)) {
  2157. 29439                 errno = EDOM;
  2158. 29440                 return x;
  2159. 29441         }
  2160. 29442         if (x < M_LN_MIN_D) {
  2161. 29443                 errno = ERANGE;
  2162. 29444                 return 0.0;
  2163. 29445         }
  2164. 29446         if (x > M_LN_MAX_D) {
  2165. 29447                 errno = ERANGE;
  2166. 29448                 return HUGE_VAL;
  2167. 29449         }
  2168. 29450
  2169. 29451         if (negative) x = -x;
  2170. 29452  
  2171. 29453         /* ??? avoid underflow ??? */
  2172. 29454
  2173. 29455         n = x * M_LOG2E + 0.5;  /* 1/ln(2) = log2(e), 0.5 added for rounding */
  2174. 29456         xn = n;
  2175. 29457         {
  2176. 29458                 double  x1 = (long) x;
  2177. 29459                 double  x2 = x - x1;
  2178. 29460
  2179. 29461                 g = ((x1-xn*0.693359375)+x2) - xn*(-2.1219444005469058277e-4);
  2180. 29462         }
  2181. 29463         if (negative) {
  2182. 29464                 g = -g;
  2183. 29465                 n = -n;
  2184. 29466         }
  2185. 29467         xn = g * g;
  2186. 29468         x = g * POLYNOM2(xn, p);
  2187. 29469         n += 1;
  2188. 29470         return (ldexp(0.5 + x/(POLYNOM3(xn, q) - x), n));
  2189. 29471 }
  2190. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2191. src/lib/math/fabs.c    
  2192. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2193. 29500 /*
  2194. 29501  * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2195. 29502  * See the copyright notice in the ACK home directory, in the file "Copyright".
  2196. 29503  *
  2197. 29504  * Author: Ceriel J.H. Jacobs
  2198. 29505  */
  2199. 29506 /* $Header: fabs.c,v 1.1 89/05/10 16:01:17 eck Exp $ */
  2200. 29507
  2201. 29508 double
  2202. 29509 fabs(double x)
  2203. 29510 {
  2204. 29511         return  x < 0 ? -x : x;
  2205. 29512 }
  2206. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2207. src/lib/math/floor.c    
  2208. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2209. 29600 /*
  2210. 29601  * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2211. 29602  * See the copyright notice in the ACK home directory, in the file "Copyright".
  2212. 29603  *
  2213. 29604  * Author: Ceriel J.H. Jacobs
  2214. 29605  */
  2215. 29606 /* $Header: floor.c,v 1.1 89/05/10 16:01:29 eck Exp $ */
  2216. 29607
  2217. 29608 #include        <math.h>
  2218. 29609
  2219. 29610 double
  2220. 29611 floor(double x)
  2221. 29612 {
  2222. 29613         double val;
  2223. 29614
  2224. 29615         return modf(x, &val) < 0 ? val - 1.0 : val ;
  2225. 29616         /*      this also works if modf always returns a positive
  2226. 29617                 fractional part
  2227. 29618         */
  2228. 29619 }
  2229. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2230. src/lib/math/fmod.c    
  2231. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2232. 29700 /*
  2233. 29701  * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2234. 29702  * See the copyright notice in the ACK home directory, in the file "Copyright".
  2235. 29703  *
  2236. 29704  * Author: Hans van Eck
  2237. 29705  */
  2238. 29706 /* $Header: fmod.c,v 1.1 89/12/18 15:41:53 eck Exp $ */
  2239. 29707
  2240. 29708 #include        <math.h>
  2241. 29709 #include        <errno.h>
  2242. 29710
  2243. 29711 double
  2244. 29712 fmod(double x, double y)
  2245. 29713 {
  2246. 29714         long    i;
  2247. 29715         double val;
  2248. 29716         double frac;
  2249. 29717
  2250. 29718         if (y == 0) {
  2251. 29719                 errno = EDOM;
  2252. 29720                 return 0;
  2253. 29721         }
  2254. 29722         frac = modf( x / y, &val);
  2255. 29723
  2256. 29724         return frac * y;
  2257. 29725
  2258. 29726 /*
  2259. 29727         val = x / y;
  2260. 29728         if (val > LONG_MIN && val < LONG_MAX) {
  2261. 29729                 i = val;
  2262. 29730                 return x - i * y;
  2263. 29731         }
  2264. 29732 */
  2265. 29733 }
  2266. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2267. src/lib/math/frexp.s    
  2268. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2269. 29800 #
  2270. 29801 .sect .text; .sect .rom; .sect .data; .sect .bss
  2271. 29802 .extern _frexp
  2272. 29803 .sect .text
  2273. 29804 _frexp:
  2274. 29805 #if __i386
  2275. 29806         push    ebp
  2276. 29807         mov     ebp, esp
  2277. 29808         push    12(ebp)
  2278. 29809         push    8(ebp)
  2279. 29810         mov     eax, esp
  2280. 29811         add     eax, -4
  2281. 29812         push    eax
  2282. 29813         call    .fef8
  2283. 29814         mov     eax, 16(ebp)
  2284. 29815         pop     (eax)
  2285. 29816         pop     eax
  2286. 29817         pop     edx
  2287. 29818         leave
  2288. 29819         ret
  2289. 29820 #else /* i86 */
  2290. 29821         push    bp
  2291. 29822         mov     bp, sp
  2292. 29823         lea     bx, 4(bp)
  2293. 29824         mov     cx, #8
  2294. 29825         call    .loi
  2295. 29826         mov     ax, sp
  2296. 29827         add     ax, #-2
  2297. 29828         push    ax
  2298. 29829         call    .fef8
  2299. 29830         mov     bx, 12(bp)
  2300. 29831         pop     (bx)
  2301. 29832         call    .ret8
  2302. 29833         jmp     .cret
  2303. 29834 #endif
  2304. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2305. src/lib/math/hugeval.c    
  2306. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2307. 29900 /*
  2308. 29901  * (c) copyright 1990 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2309. 29902  * See the copyright notice in the ACK home directory, in the file "Copyright".
  2310. 29903  *
  2311. 29904  * Author: Hans van Eck
  2312. 29905  */
  2313. 29906 /* $Header: hugeval.c,v 1.1 90/10/24 14:29:42 eck Exp $ */
  2314. 29907 #include        <math.h>
  2315. 29908
  2316. 29909 double
  2317. 29910 __huge_val(void)
  2318. 29911 {
  2319. 29912         return 1.0e+1000;       /* This will generate a warning */
  2320. 29913 }
  2321. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2322. src/lib/math/isnan.c    
  2323. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2324. 30000 int __IsNan(double d)
  2325. 30001 {
  2326. 30002 #if defined(vax) || defined(pdp)
  2327. 30003 #else
  2328. 30004         float f = d;
  2329. 30005
  2330. 30006         if ((*((long *) &f) & 0x7f800000) == 0x7f800000 &&
  2331. 30007             (*((long *) &f) & 0x007fffff) != 0) return 1;
  2332. 30008 #endif
  2333. 30009         return 0;
  2334. 30010 }
  2335. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2336. src/lib/math/ldexp.c    
  2337. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2338. 30100 /*
  2339. 30101  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2340. 30102  * See the copyright notice in the ACK home directory, in the file "Copyright".
  2341. 30103  */
  2342. 30104 /* $Header: ldexp.c,v 1.5 91/03/19 16:38:37 ceriel Exp $ */
  2343. 30105
  2344. 30106 #include        <math.h>
  2345. 30107 #include        <float.h>
  2346. 30108 #include        <errno.h>
  2347. 30109
  2348. 30110 double
  2349. 30111 ldexp(double fl, int exp)
  2350. 30112 {
  2351. 30113         int sign = 1;
  2352. 30114         int currexp;
  2353. 30115
  2354. 30116         if (__IsNan(fl)) {
  2355. 30117                 errno = EDOM;
  2356. 30118                 return fl;
  2357. 30119         }
  2358. 30120         if (fl == 0.0) return 0.0;
  2359. 30121         if (fl<0) {
  2360. 30122                 fl = -fl;
  2361. 30123                 sign = -1;
  2362. 30124         }
  2363. 30125         if (fl > DBL_MAX) {             /* for infinity */
  2364. 30126                 errno = ERANGE;
  2365. 30127                 return sign * fl;
  2366. 30128         }
  2367. 30129         fl = frexp(fl,&currexp);
  2368. 30130         exp += currexp;
  2369. 30131         if (exp > 0) {
  2370. 30132                 if (exp > DBL_MAX_EXP) {
  2371. 30133                         errno = ERANGE;
  2372. 30134                         return sign * HUGE_VAL;
  2373. 30135                 }
  2374. 30136                 while (exp>30) {
  2375. 30137                         fl *= (double) (1L << 30);
  2376. 30138                         exp -= 30;
  2377. 30139                 }
  2378. 30140                 fl *= (double) (1L << exp);
  2379. 30141         }
  2380. 30142         else    {
  2381. 30143                 /* number need not be normalized */
  2382. 30144                 if (exp < DBL_MIN_EXP - DBL_MANT_DIG) {
  2383. 30145                         return 0.0;
  2384. 30146                 }
  2385. 30147                 while (exp<-30) {
  2386. 30148                         fl /= (double) (1L << 30);
  2387. 30149                         exp += 30;
  2388. 30150                 }
  2389. 30151                 fl /= (double) (1L << -exp);
  2390. 30152         }
  2391. 30153         return sign * fl;
  2392. 30154 }
  2393. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2394. src/lib/math/log.c    
  2395. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2396. 30200 /*
  2397. 30201  * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2398. 30202  * See the copyright notice in the ACK home directory, in the file "Copyright".
  2399. 30203  *
  2400. 30204  * Author: Ceriel J.H. Jacobs
  2401. 30205  */
  2402. 30206 /* $Header: log.c,v 1.3 91/03/19 16:38:45 ceriel Exp $ */
  2403. 30207
  2404. 30208 #include        <math.h>
  2405. 30209 #include        <float.h>
  2406. 30210 #include        <errno.h>
  2407. 30211 #include        "localmath.h"
  2408. 30212
  2409. 30213 double
  2410. 30214 log(double x)
  2411. 30215 {
  2412. 30216         /*      Algorithm and coefficients from:
  2413. 30217                         "Software manual for the elementary functions"
  2414. 30218                         by W.J. Cody and W. Waite, Prentice-Hall, 1980
  2415. 30219         */
  2416. 30220         static double a[] = {
  2417. 30221                 -0.64124943423745581147e2,
  2418. 30222                  0.16383943563021534222e2,
  2419. 30223                 -0.78956112887491257267e0
  2420. 30224         };
  2421. 30225         static double b[] = {
  2422. 30226                 -0.76949932108494879777e3,
  2423. 30227                  0.31203222091924532844e3,
  2424. 30228                 -0.35667977739034646171e2,
  2425. 30229                  1.0
  2426. 30230         };
  2427. 30231
  2428. 30232         double  znum, zden, z, w;
  2429. 30233         int     exponent;
  2430. 30234
  2431. 30235         if (__IsNan(x)) {
  2432. 30236                 errno = EDOM;
  2433. 30237                 return x;
  2434. 30238         }
  2435. 30239         if (x < 0) {
  2436. 30240                 errno = EDOM;
  2437. 30241                 return -HUGE_VAL;
  2438. 30242         }
  2439. 30243         else if (x == 0) {
  2440. 30244                 errno = ERANGE;
  2441. 30245                 return -HUGE_VAL;
  2442. 30246         }
  2443. 30247
  2444. 30248         if (x <= DBL_MAX) {
  2445. 30249         }
  2446. 30250         else return x;  /* for infinity and Nan */
  2447. 30251         x = frexp(x, &exponent);
  2448. 30252         if (x > M_1_SQRT2) {
  2449. 30253                 znum = (x - 0.5) - 0.5;
  2450. 30254                 zden = x * 0.5 + 0.5;
  2451. 30255         }
  2452. 30256         else {
  2453. 30257                 znum = x - 0.5;
  2454. 30258                 zden = znum * 0.5 + 0.5;
  2455. 30259                 exponent--;
  2456. 30260         }
  2457. 30261         z = znum/zden; w = z * z;
  2458. 30262         x = z + z * w * (POLYNOM2(w,a)/POLYNOM3(w,b));
  2459. 30263         z = exponent;
  2460. 30264         x += z * (-2.121944400546905827679e-4);
  2461. 30265         return x + z * 0.693359375;
  2462. 30266 }
  2463. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2464. src/lib/math/log10.c    
  2465. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2466. 30300 /*
  2467. 30301  * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2468. 30302  * See the copyright notice in the ACK home directory, in the file "Copyright".
  2469. 30303  *
  2470. 30304  * Author: Ceriel J.H. Jacobs
  2471. 30305  */
  2472. 30306 /* $Header: log10.c,v 1.3 91/03/19 16:38:55 ceriel Exp $ */
  2473. 30307
  2474. 30308 #include        <math.h>
  2475. 30309 #include        <errno.h>
  2476. 30310 #include        "localmath.h"
  2477. 30311
  2478. 30312 double
  2479. 30313 log10(double x)
  2480. 30314 {
  2481. 30315         if (__IsNan(x)) {
  2482. 30316                 errno = EDOM;
  2483. 30317                 return x;
  2484. 30318         }
  2485. 30319         if (x < 0) {
  2486. 30320                 errno = EDOM;
  2487. 30321                 return -HUGE_VAL;
  2488. 30322         }
  2489. 30323         else if (x == 0) {
  2490. 30324                 errno = ERANGE;
  2491. 30325                 return -HUGE_VAL;
  2492. 30326         }
  2493. 30327
  2494. 30328         return log(x) / M_LN10;
  2495. 30329 }
  2496. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2497. src/lib/math/modf.s    
  2498. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2499. 30400 #
  2500. 30401 .sect .text; .sect .rom; .sect .data; .sect .bss
  2501. 30402 .extern _modf
  2502. 30403 .sect .text
  2503. 30404 _modf:
  2504. 30405 #if __i386
  2505. 30406         push    ebp
  2506. 30407         mov     ebp, esp
  2507. 30408         push    12(ebp)
  2508. 30409         push    8(ebp)
  2509. 30410         push    1
  2510. 30411         push    4
  2511. 30412         call    .cif8
  2512. 30413         mov     eax, esp
  2513. 30414         push    eax
  2514. 30415         call    .fif8
  2515. 30416         pop     ecx
  2516. 30417         mov     edx, 16(ebp)
  2517. 30418         pop     ecx
  2518. 30419         pop     ebx
  2519. 30420         mov     0(edx), ecx
  2520. 30421         mov     4(edx), ebx
  2521. 30422         pop     eax
  2522. 30423         pop     edx
  2523. 30424         leave
  2524. 30425         ret
  2525. 30426 #else /* i86 */
  2526. 30427         push    bp
  2527. 30428         mov     bp, sp
  2528. 30429         lea     bx, 4(bp)
  2529. 30430         mov     cx, #8
  2530. 30431         call    .loi
  2531. 30432         mov     dx, #1
  2532. 30433         push    dx
  2533. 30434         push    dx
  2534. 30435         push    dx
  2535. 30436         mov     ax, #2
  2536. 30437         push    ax
  2537. 30438         call    .cif8
  2538. 30439         mov     ax, sp
  2539. 30440         push    ax
  2540. 30441         call    .fif8
  2541. 30442         pop     bx
  2542. 30443         mov     bx, 12(bp)
  2543. 30444         mov     cx, #8
  2544. 30445         call    .sti
  2545. 30446         call    .ret8
  2546. 30447         jmp     .cret
  2547. 30448 #endif
  2548. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2549. src/lib/math/pow.c    
  2550. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2551. 30500 /*
  2552. 30501  * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2553. 30502  * See the copyright notice in the ACK home directory, in the file "Copyright".
  2554. 30503  *
  2555. 30504  * Author: Ceriel J.H. Jacobs
  2556. 30505  */
  2557. 30506 /* $Header: pow.c,v 1.3 90/08/28 13:59:36 eck Exp $ */
  2558. 30507
  2559. 30508 #include        <math.h>
  2560. 30509 #include        <float.h>
  2561. 30510 #include        <errno.h>
  2562. 30511 #include        "localmath.h"
  2563. 30512
  2564. 30513 double
  2565. 30514 pow(double x, double y)
  2566. 30515 {
  2567. 30516         /*      Simple version for now. The Cody and Waite book has
  2568. 30517                 a very complicated, much more precise version, but
  2569. 30518                 this version has machine-dependent arrays A1 and A2,
  2570. 30519                 and I don't know yet how to solve this ???
  2571. 30520         */
  2572. 30521         double dummy;
  2573. 30522         int     result_neg = 0;
  2574. 30523
  2575. 30524         if ((x == 0 && y == 0) ||
  2576. 30525             (x < 0 && modf(y, &dummy) != 0)) {
  2577. 30526                 errno = EDOM;
  2578. 30527                 return 0;
  2579. 30528         }
  2580. 30529
  2581. 30530         if (x == 0) return x;
  2582. 30531
  2583. 30532         if (x < 0) {
  2584. 30533                 if (modf(y/2.0, &dummy) != 0) {
  2585. 30534                         /* y was odd */
  2586. 30535                         result_neg = 1;
  2587. 30536                 }
  2588. 30537                 x = -x;
  2589. 30538         }
  2590. 30539         x = log(x);
  2591. 30540
  2592. 30541         if (x < 0) {
  2593. 30542                 x = -x;
  2594. 30543                 y = -y;
  2595. 30544         }
  2596. 30545         /* Beware of overflow in the multiplication */
  2597. 30546         if (x > 1.0 && y > DBL_MAX/x) {
  2598. 30547                 errno = ERANGE;
  2599. 30548                 return result_neg ? -HUGE_VAL : HUGE_VAL;
  2600. 30549         }
  2601. 30550
  2602. 30551         x = exp(x * y);
  2603. 30552         return result_neg ? -x : x;
  2604. 30553 }
  2605. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2606. src/lib/math/sin.c    
  2607. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2608. 30600 /*
  2609. 30601  * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2610. 30602  * See the copyright notice in the ACK home directory, in the file "Copyright".
  2611. 30603  *
  2612. 30604  * Author: Ceriel J.H. Jacobs
  2613. 30605  */
  2614. 30606 /* $Header: sin.c,v 1.3 91/03/19 16:39:04 ceriel Exp $ */
  2615. 30607
  2616. 30608 #include        <math.h>
  2617. 30609 #include        <float.h>
  2618. 30610 #include        <errno.h>
  2619. 30611 #include        "localmath.h"
  2620. 30612
  2621. 30613 static double
  2622. 30614 sinus(double x, int cos_flag)
  2623. 30615 {
  2624. 30616         /*      Algorithm and coefficients from:
  2625. 30617                         "Software manual for the elementary functions"
  2626. 30618                         by W.J. Cody and W. Waite, Prentice-Hall, 1980
  2627. 30619         */
  2628. 30620
  2629. 30621         static double r[] = {
  2630. 30622                 -0.16666666666666665052e+0,
  2631. 30623                  0.83333333333331650314e-2,
  2632. 30624                 -0.19841269841201840457e-3,
  2633. 30625                  0.27557319210152756119e-5,
  2634. 30626                 -0.25052106798274584544e-7,
  2635. 30627                  0.16058936490371589114e-9,
  2636. 30628                 -0.76429178068910467734e-12,
  2637. 30629                  0.27204790957888846175e-14
  2638. 30630         };
  2639. 30631
  2640. 30632         double  y;
  2641. 30633         int     neg = 1;
  2642. 30634
  2643. 30635         if (__IsNan(x)) {
  2644. 30636                 errno = EDOM;
  2645. 30637                 return x;
  2646. 30638         }
  2647. 30639         if (x < 0) {
  2648. 30640                 x = -x;
  2649. 30641                 neg = -1;
  2650. 30642         }
  2651. 30643         if (cos_flag) {
  2652. 30644                 neg = 1;
  2653. 30645                 y = M_PI_2 + x;
  2654. 30646         }
  2655. 30647         else    y = x;
  2656. 30648
  2657. 30649         /* ??? avoid loss of significance, if y is too large, error ??? */
  2658. 30650
  2659. 30651         y = y * M_1_PI + 0.5;
  2660. 30652
  2661. 30653         if (y >= DBL_MAX/M_PI) return 0.0;
  2662. 30654
  2663. 30655         /*      Use extended precision to calculate reduced argument.
  2664. 30656                 Here we used 12 bits of the mantissa for a1.
  2665. 30657                 Also split x in integer part x1 and fraction part x2.
  2666. 30658         */
  2667. 30659 #define A1 3.1416015625
  2668. 30660 #define A2 -8.908910206761537356617e-6
  2669. 30661         {
  2670. 30662                 double x1, x2;
  2671. 30663
  2672. 30664                 modf(y, &y);
  2673. 30665                 if (modf(0.5*y, &x1)) neg = -neg;
  2674. 30666                 if (cos_flag) y -= 0.5;
  2675. 30667                 x2 = modf(x, &x1);
  2676. 30668                 x = x1 - y * A1;
  2677. 30669                 x += x2;
  2678. 30670                 x -= y * A2;
  2679. 30671 #undef A1
  2680. 30672 #undef A2
  2681. 30673         }
  2682. 30674  
  2683. 30675         if (x < 0) {
  2684. 30676                 neg = -neg;
  2685. 30677                 x = -x;
  2686. 30678         }
  2687. 30679
  2688. 30680         /* ??? avoid underflow ??? */
  2689. 30681
  2690. 30682         y = x * x;
  2691. 30683         x += x * y * POLYNOM7(y, r);
  2692. 30684         return neg==-1 ? -x : x;
  2693. 30685 }
  2694. 30687 double
  2695. 30688 sin(double x)
  2696. 30689 {
  2697. 30690         return sinus(x, 0);
  2698. 30691 }
  2699. 30693 double
  2700. 30694 cos(double x)
  2701. 30695 {
  2702. 30696         if (x < 0) x = -x;
  2703. 30697         return sinus(x, 1);
  2704. 30698 }
  2705. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2706. src/lib/math/sinh.c    
  2707. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2708. 30700 /*
  2709. 30701  * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2710. 30702  * See the copyright notice in the ACK home directory, in the file "Copyright".
  2711. 30703  *
  2712. 30704  * Author: Ceriel J.H. Jacobs
  2713. 30705  */
  2714. 30706 /* $Header: sinh.c,v 1.3 91/03/19 16:39:12 ceriel Exp $ */
  2715. 30707
  2716. 30708 #include        <math.h>
  2717. 30709 #include        <float.h>
  2718. 30710 #include        <errno.h>
  2719. 30711 #include        "localmath.h"
  2720. 30712
  2721. 30713 static double
  2722. 30714 sinh_cosh(double x, int cosh_flag)
  2723. 30715 {
  2724. 30716         /*      Algorithm and coefficients from:
  2725. 30717                         "Software manual for the elementary functions"
  2726. 30718                         by W.J. Cody and W. Waite, Prentice-Hall, 1980
  2727. 30719         */
  2728. 30720
  2729. 30721         static double p[] = {
  2730. 30722                 -0.35181283430177117881e+6,
  2731. 30723                 -0.11563521196851768270e+5,
  2732. 30724                 -0.16375798202630751372e+3,
  2733. 30725                 -0.78966127417357099479e+0
  2734. 30726         };
  2735. 30727         static double q[] = {
  2736. 30728                 -0.21108770058106271242e+7,
  2737. 30729                  0.36162723109421836460e+5,
  2738. 30730                 -0.27773523119650701167e+3,
  2739. 30731                  1.0
  2740. 30732         };
  2741. 30733         int     negative = x < 0;
  2742. 30734         double  y = negative ? -x : x;
  2743. 30735
  2744. 30736         if (__IsNan(x)) {
  2745. 30737                 errno = EDOM;
  2746. 30738                 return x;
  2747. 30739         }
  2748. 30740         if (! cosh_flag && y <= 1.0) {
  2749. 30741                 /* ??? check for underflow ??? */
  2750. 30742                 y = y * y;
  2751. 30743                 return x + x * y * POLYNOM3(y, p)/POLYNOM3(y,q);
  2752. 30744         }
  2753. 30745
  2754. 30746         if (y >= M_LN_MAX_D) {
  2755. 30747                 /* exp(y) would cause overflow */
  2756. 30748 #define LNV     0.69316101074218750000e+0
  2757. 30749 #define VD2M1   0.52820835025874852469e-4
  2758. 30750                 double  w = y - LNV;
  2759. 30751                 
  2760. 30752                 if (w < M_LN_MAX_D+M_LN2-LNV) {
  2761. 30753                         x = exp(w);
  2762. 30754                         x += VD2M1 * x;
  2763. 30755                 }
  2764. 30756                 else {
  2765. 30757                         errno = ERANGE;
  2766. 30758                         x = HUGE_VAL;
  2767. 30759                 }
  2768. 30760         }
  2769. 30761         else {
  2770. 30762                 double  z = exp(y);
  2771. 30763                 
  2772. 30764                 x = 0.5 * (z + (cosh_flag ? 1.0 : -1.0)/z);
  2773. 30765         }
  2774. 30766         return negative ? -x : x;
  2775. 30767 }
  2776. 30769 double
  2777. 30770 sinh(double x)
  2778. 30771 {
  2779. 30772         return sinh_cosh(x, 0);
  2780. 30773 }
  2781. 30775 double
  2782. 30776 cosh(double x)
  2783. 30777 {
  2784. 30778         if (x < 0) x = -x;
  2785. 30779         return sinh_cosh(x, 1);
  2786. 30780 }
  2787. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2788. src/lib/math/sqrt.c    
  2789. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2790. 30800 /*
  2791. 30801  * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2792. 30802  * See the copyright notice in the ACK home directory, in the file "Copyright".
  2793. 30803  *
  2794. 30804  * Author: Ceriel J.H. Jacobs
  2795. 30805  */
  2796. 30806 /* $Header: sqrt.c,v 1.3 91/03/19 16:39:21 ceriel Exp $ */
  2797. 30807
  2798. 30808 #include        <math.h>
  2799. 30809 #include        <float.h>
  2800. 30810 #include        <errno.h>
  2801. 30811
  2802. 30812 #define NITER   5
  2803. 30813
  2804. 30814 double
  2805. 30815 sqrt(double x)
  2806. 30816 {
  2807. 30817         int exponent;
  2808. 30818         double val;
  2809. 30819
  2810. 30820         if (__IsNan(x)) {
  2811. 30821                 errno = EDOM;
  2812. 30822                 return x;
  2813. 30823         }
  2814. 30824         if (x <= 0) {
  2815. 30825                 if (x < 0) errno = EDOM;
  2816. 30826                 return 0;
  2817. 30827         }
  2818. 30828
  2819. 30829         if (x > DBL_MAX) return x;      /* for infinity */
  2820. 30830
  2821. 30831         val = frexp(x, &exponent);
  2822. 30832         if (exponent & 1) {
  2823. 30833                 exponent--;
  2824. 30834                 val *= 2;
  2825. 30835         }
  2826. 30836         val = ldexp(val + 1.0, exponent/2 - 1);
  2827. 30837         /* was: val = (val + 1.0)/2.0; val = ldexp(val, exponent/2); */
  2828. 30838         for (exponent = NITER - 1; exponent >= 0; exponent--) {
  2829. 30839                 val = (val + x / val) / 2.0;
  2830. 30840         }
  2831. 30841         return val;
  2832. 30842 }
  2833. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2834. src/lib/math/tan.c    
  2835. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2836. 30900 /*
  2837. 30901  * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2838. 30902  * See the copyright notice in the ACK home directory, in the file "Copyright".
  2839. 30903  *
  2840. 30904  * Author: Ceriel J.H. Jacobs
  2841. 30905  */
  2842. 30906 /* $Header: tan.c,v 1.3 91/03/19 16:39:30 ceriel Exp $ */
  2843. 30907
  2844. 30908 #include        <math.h>
  2845. 30909 #include        <float.h>
  2846. 30910 #include        <errno.h>
  2847. 30911 #include        "localmath.h"
  2848. 30912
  2849. 30913 double
  2850. 30914 tan(double x)
  2851. 30915 {
  2852. 30916         /*      Algorithm and coefficients from:
  2853. 30917                         "Software manual for the elementary functions"
  2854. 30918                         by W.J. Cody and W. Waite, Prentice-Hall, 1980
  2855. 30919         */
  2856. 30920
  2857. 30921         int negative = x < 0;
  2858. 30922         int invert = 0;
  2859. 30923         double  y;
  2860. 30924         static double   p[] = {
  2861. 30925                  1.0,
  2862. 30926                 -0.13338350006421960681e+0,
  2863. 30927                  0.34248878235890589960e-2,
  2864. 30928                 -0.17861707342254426711e-4
  2865. 30929         };
  2866. 30930         static double   q[] = {
  2867. 30931                  1.0,
  2868. 30932                 -0.46671683339755294240e+0,
  2869. 30933                  0.25663832289440112864e-1,
  2870. 30934                 -0.31181531907010027307e-3,
  2871. 30935                  0.49819433993786512270e-6
  2872. 30936         };
  2873. 30937
  2874. 30938         if (__IsNan(x)) {
  2875. 30939                 errno = EDOM;
  2876. 30940                 return x;
  2877. 30941         }
  2878. 30942         if (negative) x = -x;
  2879. 30943  
  2880. 30944         /* ??? avoid loss of significance, error if x is too large ??? */
  2881. 30945
  2882. 30946         y = x * M_2_PI + 0.5;
  2883. 30947
  2884. 30948         if (y >= DBL_MAX/M_PI_2) return 0.0;
  2885. 30949
  2886. 30950         /*      Use extended precision to calculate reduced argument.
  2887. 30951                 Here we used 12 bits of the mantissa for a1.
  2888. 30952                 Also split x in integer part x1 and fraction part x2.
  2889. 30953         */
  2890. 30954     #define A1 1.57080078125
  2891. 30955     #define A2 -4.454455103380768678308e-6
  2892. 30956         {
  2893. 30957                 double x1, x2;
  2894. 30958
  2895. 30959                 modf(y, &y);
  2896. 30960                 if (modf(0.5*y, &x1)) invert = 1;
  2897. 30961                 x2 = modf(x, &x1);
  2898. 30962                 x = x1 - y * A1;
  2899. 30963                 x += x2;
  2900. 30964                 x -= y * A2;
  2901. 30965     #undef A1
  2902. 30966     #undef A2
  2903. 30967         }
  2904. 30968
  2905. 30969         /* ??? avoid underflow ??? */
  2906. 30970         y = x * x;
  2907. 30971         x += x * y * POLYNOM2(y, p+1);
  2908. 30972         y = POLYNOM4(y, q);
  2909. 30973         if (negative) x = -x;
  2910. 30974         return invert ? -y/x : x/y;
  2911. 30975 }
  2912. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2913. src/lib/math/tanh.c    
  2914. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2915. 31000 /*
  2916. 31001  * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2917. 31002  * See the copyright notice in the ACK home directory, in the file "Copyright".
  2918. 31003  *
  2919. 31004  * Author: Ceriel J.H. Jacobs
  2920. 31005  */
  2921. 31006 /* $Header: tanh.c,v 1.3 91/03/19 16:39:40 ceriel Exp $ */
  2922. 31007
  2923. 31008 #include        <float.h>
  2924. 31009 #include        <math.h>
  2925. 31010 #include        <errno.h>
  2926. 31011 #include        "localmath.h"
  2927. 31012
  2928. 31013 double
  2929. 31014 tanh(double x)
  2930. 31015 {
  2931. 31016         /*      Algorithm and coefficients from:
  2932. 31017                         "Software manual for the elementary functions"
  2933. 31018                         by W.J. Cody and W. Waite, Prentice-Hall, 1980
  2934. 31019         */
  2935. 31020
  2936. 31021         static double p[] = {
  2937. 31022                 -0.16134119023996228053e+4,
  2938. 31023                 -0.99225929672236083313e+2,
  2939. 31024                 -0.96437492777225469787e+0
  2940. 31025         };
  2941. 31026         static double q[] = {
  2942. 31027                  0.48402357071988688686e+4,
  2943. 31028                  0.22337720718962312926e+4,
  2944. 31029                  0.11274474380534949335e+3,
  2945. 31030                  1.0
  2946. 31031         };
  2947. 31032         int     negative = x < 0;
  2948. 31033
  2949. 31034         if (__IsNan(x)) {
  2950. 31035                 errno = EDOM;
  2951. 31036                 return x;
  2952. 31037         }
  2953. 31038         if (negative) x = -x;
  2954. 31039
  2955. 31040         if (x >= 0.5*M_LN_MAX_D) {
  2956. 31041                 x = 1.0;
  2957. 31042         }
  2958. 31043 #define LN3D2   0.54930614433405484570e+0       /* ln(3)/2 */
  2959. 31044         else if (x > LN3D2) {
  2960. 31045                 x = 0.5 - 1.0/(exp(x+x)+1.0);
  2961. 31046                 x += x;
  2962. 31047         }
  2963. 31048         else {
  2964. 31049                 /* ??? avoid underflow ??? */
  2965. 31050                 double g = x*x;
  2966. 31051                 x += x * g * POLYNOM2(g, p)/POLYNOM3(g, q);
  2967. 31052         }
  2968. 31053         return negative ? -x : x;
  2969. 31054 }
  2970. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2971. src/lib/other/_brk.c    
  2972. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2973. 31100 #include <lib.h>
  2974. 31101 #define brk     _brk
  2975. 31102 #define sbrk    _sbrk
  2976. 31103 #include <unistd.h>
  2977. 31104
  2978. 31105 extern char *_brksize;
  2979. 31106
  2980. 31107 /* Both OSF/1 and SYSVR4 man pages specify that brk(2) returns int.
  2981. 31108  * However, BSD4.3 specifies that brk() returns char*.  POSIX omits
  2982. 31109  * brk() on the grounds that it imposes a memory model on an architecture.
  2983. 31110  * For this reason, brk() and sbrk() are not in the lib/posix directory.
  2984. 31111  * On the other hand, they are so crucial to correct operation of so many
  2985. 31112  * parts of the system, that we have chosen to hide the name brk using _brk,
  2986. 31113  * as with system calls.  In this way, if a user inadvertently defines a
  2987. 31114  * procedure brk, MINIX may continue to work because the true call is _brk.
  2988. 31115  */
  2989. 31116 PUBLIC int brk(addr)
  2990. 31117 char *addr;
  2991. 31118 {
  2992. 31119   message m;
  2993. 31120
  2994. 31121   m.m1_p1 = addr;
  2995. 31122   if (_syscall(MM, BRK, &m) < 0) return(-1);
  2996. 31123   _brksize = m.m2_p1;
  2997. 31124   return(0);
  2998. 31125 }
  2999. 31128 PUBLIC char *sbrk(incr)
  3000. 31129 int incr;
  3001. 31130 {
  3002. 31131   char *newsize, *oldsize;
  3003. 31132
  3004. 31133   oldsize = _brksize;
  3005. 31134   newsize = _brksize + incr;
  3006. 31135   if (incr > 0 && newsize < oldsize || incr < 0 && newsize > oldsize)
  3007. 31136         return( (char *) -1);
  3008. 31137   if (brk(newsize) == 0)
  3009. 31138         return(oldsize);
  3010. 31139   else
  3011. 31140         return( (char *) -1);
  3012. 31141 }
  3013. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3014. src/lib/other/_longjerr.c    
  3015. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3016. 31200 #include <lib.h>
  3017. 31201 #define longjerr        _longjerr
  3018. 31202 #define write           _write
  3019. 31203 #include <minix/minlib.h>
  3020. 31204 #include <stdlib.h>
  3021. 31205 #include <string.h>
  3022. 31206 #include <unistd.h>
  3023. 31207
  3024. 31208
  3025. 31209 _PROTOTYPE( void longjerr, (void));
  3026. 31210
  3027. 31211 PUBLIC void longjerr()
  3028. 31212 {
  3029. 31213   static char errmsg[] = "longj errorn";
  3030. 31214
  3031. 31215   write(2, errmsg, strlen(errmsg));     /* hope it's stderr */
  3032. 31216   while(1) abort();             /* XXX - maybe just exit */
  3033. 31217 }
  3034. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3035. src/lib/other/_reboot.c    
  3036. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3037. 31300 /* reboot.c - Systemcall interface to mm/signal.c::do_reboot()
  3038. 31301
  3039. 31302    author: Edvard Tuinder  v892231@si.hhs.NL
  3040. 31303  */
  3041. 31304
  3042. 31305 #include <lib.h>
  3043. 31306 #define reboot  _reboot
  3044. 31307 #include <unistd.h>
  3045. 31308 #include <stdarg.h>
  3046. 31309
  3047. 31310 int reboot(int how, ...)
  3048. 31311 {
  3049. 31312   message m;
  3050. 31313   va_list ap;
  3051. 31314
  3052. 31315   va_start(ap, how);
  3053. 31316   if ((m.m1_i1 = how) == RBT_MONITOR) {
  3054. 31317         m.m1_p1 = va_arg(ap, char *);
  3055. 31318         m.m1_i2 = va_arg(ap, size_t);
  3056. 31319   }
  3057. 31320   va_end(ap);
  3058. 31321
  3059. 31322   return _syscall(MM, REBOOT, &m);
  3060. 31323 }
  3061. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3062. src/lib/other/_seekdir.c    
  3063. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3064. 31400 /*      seekdir()                                       Author: Kees J. Bot
  3065. 31401  *                                                              24 Apr 1989
  3066. 31402  */
  3067. 31403 #define nil 0
  3068. 31404 #include <lib.h>
  3069. 31405 #define lseek   _lseek
  3070. 31406 #define readdir _readdir
  3071. 31407 #define seekdir _seekdir
  3072. 31408 #include <sys/types.h>
  3073. 31409 #include <dirent.h>
  3074. 31410 #include <unistd.h>
  3075. 31411 #include <errno.h>
  3076. 31412
  3077. 31413 int seekdir(DIR *dp, off_t pos)
  3078. 31414 /* Seek to position pos in a directory. */
  3079. 31415 {
  3080. 31416         int off;
  3081. 31417
  3082. 31418         if (dp == nil) { errno= EBADF; return -1; }
  3083. 31419
  3084. 31420         dp->_count= 0;
  3085. 31421         dp->_ptr= dp->_buf;
  3086. 31422
  3087. 31423         off= pos & (sizeof(dp->_buf) - 1);
  3088. 31424         dp->_pos= pos - off;
  3089. 31425
  3090. 31426         if (lseek(dp->_fd, dp->_pos, SEEK_SET) == -1) return -1;
  3091. 31427
  3092. 31428         while (dp->_pos < pos && readdir(dp) != nil) {}
  3093. 31429
  3094. 31430         return 0;
  3095. 31431 }
  3096. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3097. src/lib/other/asynchio.c    
  3098. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3099. 31500 /*      asyn_init(), asyn_read(), asyn_write(), asyn_ioctl(),
  3100. 31501  *      asyn_wait(), asyn_synch(), asyn_close()
  3101. 31502  *                                                      Author: Kees J. Bot
  3102. 31503  *                                                              26 Jan 1995
  3103. 31504  * Thise are just stub routines that are call compatible with
  3104. 31505  * the asynchio(3) library of Minix-vmd.  See asynchio.h.
  3105. 31506  */
  3106. 31507 #define nil 0
  3107. 31508 #define alarm   _alarm
  3108. 31509 #define ioctl   _ioctl
  3109. 31510 #define read    _read
  3110. 31511 #define sigaction _sigaction
  3111. 31512 #define sigfillset _sigfillset
  3112. 31513 #define time    _time
  3113. 31514 #define write   _write
  3114. 31515 #include <lib.h>
  3115. 31516 #include <sys/ioctl.h>
  3116. 31517 #include <sys/asynchio.h>
  3117. 31518 #include <stdlib.h>
  3118. 31519 #include <unistd.h>
  3119. 31520 #include <string.h>
  3120. 31521 #include <time.h>
  3121. 31522 #include <signal.h>
  3122. 31523
  3123. 31524 #define IDLE            0
  3124. 31525 #define INPROGRESS      1
  3125. 31526 #define RESULT          2
  3126. 31527
  3127. 31528 #define OP_READ         0
  3128. 31529 #define OP_WRITE        1
  3129. 31530 #define OP_IOCTL        2
  3130. 31531
  3131. 31532 static int *asyn_current;
  3132. 31533 static int asyn_op;
  3133. 31534 static int asyn_fd;
  3134. 31535 static int asyn_req;
  3135. 31536 static void *asyn_data;
  3136. 31537 static ssize_t asyn_count;
  3137. 31538 static int asyn_errno;
  3138. 31539
  3139. 31540 void asyn_init(asynchio_t *asyn)
  3140. 31541 {
  3141. 31542         *asyn= IDLE;
  3142. 31543 }
  3143. 31545 static ssize_t operation(int op, asynchio_t *asyn, int fd, int req,
  3144. 31546                                                 void *data, ssize_t count)
  3145. 31547 {
  3146. 31548         switch (*asyn) {
  3147. 31549         case INPROGRESS:
  3148. 31550                 if (asyn_current != asyn && asyn_op != op) abort();
  3149. 31551                 /*FALL THROUGH*/
  3150. 31552         case IDLE:
  3151. 31553                 asyn_current= asyn;
  3152. 31554                 asyn_op= op;
  3153. 31555                 asyn_fd= fd;
  3154. 31556                 asyn_req= req;
  3155. 31557                 asyn_data= data;
  3156. 31558                 asyn_count= count;
  3157. 31559                 *asyn= INPROGRESS;
  3158. 31560                 errno= EINPROGRESS;
  3159. 31561                 return -1;
  3160. 31562         case RESULT:
  3161. 31563                 if (asyn_current != asyn && asyn_op != op) abort();
  3162. 31564                 *asyn= IDLE;
  3163. 31565                 errno= asyn_errno;
  3164. 31566                 return asyn_count;
  3165. 31567         }
  3166. 31568 }
  3167. 31570 ssize_t asyn_read(asynchio_t *asyn, int fd, void *buf, size_t len)
  3168. 31571 {
  3169. 31572         return operation(OP_READ, asyn, fd, 0, buf, len);
  3170. 31573 }
  3171. 31575 ssize_t asyn_write(asynchio_t *asyn, int fd, const void *buf, size_t len)
  3172. 31576 {
  3173. 31577         return operation(OP_WRITE, asyn, fd, 0, (void *) buf, len);
  3174. 31578 }
  3175. 31580 int asyn_ioctl(asynchio_t *asyn, int fd, unsigned long request, void *data)
  3176. 31581 {
  3177. 31582         return operation(OP_IOCTL, asyn, fd, request, data, 0);
  3178. 31583 }
  3179. 31585 static void time_out(int sig)
  3180. 31586 {
  3181. 31587         alarm(1);
  3182. 31588 }
  3183. 31590 int asyn_wait(asynchio_t *asyn, int flags, struct timeval *to)
  3184. 31591 {
  3185. 31592         time_t now;
  3186. 31593         unsigned old_timer, new_timer;
  3187. 31594         struct sigaction old_sa, new_sa;
  3188. 31595
  3189. 31596         if (*asyn == IDLE) return 0;
  3190. 31597         if (asyn_current != asyn || *asyn != INPROGRESS) abort();
  3191. 31598         if (flags & ASYN_NONBLOCK) abort();
  3192. 31599
  3193. 31600         if (to != nil) {
  3194. 31601                 now= time(nil);
  3195. 31602                 if (to->tv_sec <= now) { errno= EINTR; return -1; }
  3196. 31603                 old_timer= alarm(0);
  3197. 31604                 new_sa.sa_handler= time_out;
  3198. 31605                 sigfillset(&new_sa.sa_mask);
  3199. 31606                 new_sa.sa_flags= 0;
  3200. 31607                 sigaction(SIGALRM, &new_sa, &old_sa);
  3201. 31608                 new_timer= to->tv_sec - now;
  3202. 31609                 if (new_timer < old_timer) {
  3203. 31610                         new_timer= old_timer;
  3204. 31611                 }
  3205. 31612                 alarm(new_timer);
  3206. 31613         }
  3207. 31614         switch (asyn_op) {
  3208. 31615         case OP_READ:
  3209. 31616                 asyn_count= read(asyn_fd, asyn_data, asyn_count);
  3210. 31617                 asyn_errno= errno;
  3211. 31618                 break;
  3212. 31619         case OP_WRITE:
  3213. 31620                 asyn_count= write(asyn_fd, asyn_data, asyn_count);
  3214. 31621                 asyn_errno= errno;
  3215. 31622                 break;
  3216. 31623         case OP_IOCTL:
  3217. 31624                 asyn_count= ioctl(asyn_fd, asyn_req, asyn_data);
  3218. 31625                 asyn_errno= errno;
  3219. 31626                 break;
  3220. 31627         }
  3221. 31628         if (to != nil) {
  3222. 31629                 alarm(0);
  3223. 31630                 sigaction(SIGALRM, &old_sa, (struct sigaction *)0);
  3224. 31631                 alarm(old_timer);
  3225. 31632         }
  3226. 31633
  3227. 31634         if (asyn_count == -1 && asyn_errno == EINTR) {
  3228. 31635                 errno= EINTR;
  3229. 31636                 return -1;
  3230. 31637         } else {
  3231. 31638                 *asyn= RESULT;
  3232. 31639                 return 0;
  3233. 31640         }
  3234. 31641 }
  3235. 31643 int asyn_synch(asynchio_t *asyn, int fd)
  3236. 31644 {
  3237. 31645 }
  3238. 31647 int asyn_close(asynchio_t *asyn, int fd)
  3239. 31648 {
  3240. 31649         *asyn= IDLE;
  3241. 31650 }
  3242. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3243. src/lib/other/bcmp.c    
  3244. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3245. 31700 #include <lib.h>
  3246. 31701 /* bcmp - Berklix equivalent of memcmp  */
  3247. 31702
  3248. 31703 #include <string.h>
  3249. 31704
  3250. 31705 int bcmp(s1, s2, length)        /* == 0 or != 0 for equality and inequality */ 
  3251. 31706 _CONST void *s1;
  3252. 31707 _CONST void *s2;
  3253. 31708 int length;
  3254. 31709 {
  3255. 31710   return(memcmp((_CONST _VOIDSTAR) s1, (_CONST _VOIDSTAR) s2, (_SIZET) length));
  3256. 31711 }
  3257. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3258. src/lib/other/bcopy.c    
  3259. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3260. 31800 #include <lib.h>
  3261. 31801 /* bcopy - Berklix equivalent of memcpy  */
  3262. 31802
  3263. 31803 #include <string.h>
  3264. 31804
  3265. 31805 void bcopy(src, dst, length)
  3266. 31806 _CONST void *src;
  3267. 31807 void *dst;
  3268. 31808 int length;
  3269. 31809 {
  3270. 31810   (void) memcpy((_VOIDSTAR) dst, (_CONST _VOIDSTAR) src, (_SIZET) length);
  3271. 31811 }
  3272. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3273. src/lib/other/bzero.c    
  3274. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3275. 31900 #include <lib.h>
  3276. 31901 /* bzero - Berklix subset of memset  */
  3277. 31902
  3278. 31903 #include <string.h>
  3279. 31904
  3280. 31905 void bzero(dst, length)
  3281. 31906 void *dst;
  3282. 31907 int length;
  3283. 31908 {
  3284. 31909   (void) memset((_VOIDSTAR) dst, 0, (_SIZET) length);
  3285. 31910 }
  3286. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3287. src/lib/other/crypt.c    
  3288. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3289. 32000 /*      crypt() - one-way password encryption function  Author: Kees J. Bot
  3290. 32001  *                                                              7 Feb 1994
  3291. 32002  * This routine does not encrypt anything, it uses the pwdauth
  3292. 32003  * program to do the hard work.
  3293. 32004  */
  3294. 32005 #define nil 0
  3295. 32006 #define pipe _pipe
  3296. 32007 #define fork _fork
  3297. 32008 #define close _close
  3298. 32009 #define dup2 _dup2
  3299. 32010 #define execl _execl
  3300. 32011 #define read _read
  3301. 32012 #define _exit __exit
  3302. 32013 #define write _write
  3303. 32014 #define waitpid _waitpid
  3304. 32015 #include <sys/types.h>
  3305. 32016 #include <unistd.h>
  3306. 32017 #include <string.h>
  3307. 32018 #include <stdio.h>
  3308. 32019 #include <sys/wait.h>
  3309. 32020
  3310. 32021 /* Set-uid root program to read /etc/shadow or encrypt passwords. */
  3311. 32022 static char PWDAUTH[] = "/usr/lib/pwdauth";
  3312. 32023 #define LEN     1024
  3313. 32024
  3314. 32025 char *crypt(const char *key, const char *salt)
  3315. 32026 {
  3316. 32027         pid_t pid;
  3317. 32028         int status;
  3318. 32029         int pfd[2];
  3319. 32030         static char pwdata[LEN];
  3320. 32031         char *p= pwdata;
  3321. 32032         const char *k= key;
  3322. 32033         const char *s= salt;
  3323. 32034         int n;
  3324. 32035
  3325. 32036         /* Fill pwdata[] with the key and salt. */
  3326. 32037         while ((*p++ = *k++) != 0) if (p == pwdata+LEN-1) goto fail;
  3327. 32038         while ((*p++ = *s++) != 0) if (p == pwdata+LEN-0) goto fail;
  3328. 32039
  3329. 32040         if (pipe(pfd) < 0) goto fail;
  3330. 32041
  3331. 32042         /* Prefill the pipe. */
  3332. 32043         (void) write(pfd[1], pwdata, p - pwdata);
  3333. 32044
  3334. 32045         switch ((pid= fork())) {
  3335. 32046         case -1:
  3336. 32047                 close(pfd[0]);
  3337. 32048                 close(pfd[1]);
  3338. 32049                 goto fail;
  3339. 32050         case 0:
  3340. 32051                 /* Connect both input and output to the pipe. */
  3341. 32052                 if (pfd[0] != 0) {
  3342. 32053                         dup2(pfd[0], 0);
  3343. 32054                         close(pfd[0]);
  3344. 32055                 }
  3345. 32056                 if (pfd[1] != 1) {
  3346. 32057                         dup2(pfd[1], 1);
  3347. 32058                         close(pfd[1]);
  3348. 32059                 }
  3349. 32060
  3350. 32061                 execl(PWDAUTH, PWDAUTH, (char *) nil);
  3351. 32062
  3352. 32063                 /* No pwdauth?  Fail! */
  3353. 32064                 (void) read(0, pwdata, LEN);
  3354. 32065                 _exit(1);
  3355. 32066         }
  3356. 32067         close(pfd[1]);
  3357. 32068
  3358. 32069         if (waitpid(pid, &status, 0) < 0 || status != 0) {
  3359. 32070                 close(pfd[0]);
  3360. 32071                 goto fail;
  3361. 32072         }
  3362. 32073
  3363. 32074         /* Read and return the result.  Check if it contains exactly one
  3364. 32075          * string.
  3365. 32076          */
  3366. 32077         n= read(pfd[0], pwdata, LEN);
  3367. 32078         close(pfd[0]);
  3368. 32079         if (n < 0) goto fail;
  3369. 32080         p = pwdata + n;
  3370. 32081         n = 0;
  3371. 32082         while (p > pwdata) if (*--p == 0) n++;
  3372. 32083         if (n != 1) goto fail;
  3373. 32084         return pwdata;
  3374. 32085
  3375. 32086 fail:
  3376. 32087         pwdata[0] = salt[0] ^ 1;                /* make result != salt */
  3377. 32088         pwdata[1] = 0;
  3378. 32089         return pwdata;
  3379. 32090 }
  3380. 32092 /*
  3381. 32093  * $PchHeader: /mount/hd2/minix/lib/misc/RCS/crypt.c,v 1.3 1994/12/22 13:51:49 philip Exp $
  3382. 32094  */
  3383. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3384. src/lib/other/ctermid.c    
  3385. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3386. 32100 /*  ctermid(3)