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

操作系统开发

开发平台:

C/C++

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