res_mkquery.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:6k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*
  2.  * Copyright (c) 1985 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *   notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *   notice, this list of conditions and the following disclaimer in the
  12.  *   documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *   must display the following acknowledgement:
  15.  * This product includes software developed by the University of
  16.  * California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *   may be used to endorse or promote products derived from this software
  19.  *   without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33. #if defined(LIBC_SCCS) && !defined(lint)
  34. /*static char *sccsid = "from: @(#)res_mkquery.c 6.16 (Berkeley) 3/6/91";*/
  35. static char *rcsid = "$Id$";
  36. #endif /* LIBC_SCCS and not lint */
  37. #include <pthread.h>
  38. #include <sys/param.h>
  39. #include <sys/cdefs.h>
  40. #include <netinet/in.h>
  41. #include <resolv.h>
  42. #include <stdio.h>
  43. #include <string.h>
  44. /*
  45.  * Form all types of queries.
  46.  * Returns the size of the result or -1.
  47.  */
  48. res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
  49. int op; /* opcode of query */
  50. const char *dname; /* domain name */
  51. int class, type; /* class and type of query */
  52. const char *data; /* resource record data */
  53. int datalen; /* length of data */
  54. const char *newrr_in; /* new rr for modify or append */
  55. char *buf; /* buffer to put query */
  56. int buflen; /* size of buffer */
  57. {
  58. register HEADER *hp;
  59. register char *cp;
  60. register int n;
  61. struct rrec *newrr = (struct rrec *) newrr_in;
  62. char *dnptrs[10], **dpp, **lastdnptr;
  63. struct __res_state *_rs;
  64. /*
  65.  * Initialize header fields.
  66.  */
  67. _rs = _res_status();
  68. if (!_rs)
  69.         return -1;
  70. if ((buf == NULL) || (buflen < sizeof(HEADER)))
  71. return(-1);
  72. memset(buf, 0, sizeof(HEADER));
  73. hp = (HEADER *) buf;
  74. hp->id = htons(++_rs->id);
  75. hp->opcode = op;
  76. hp->pr = (_rs->options & RES_PRIMARY) != 0;
  77. hp->rd = (_rs->options & RES_RECURSE) != 0;
  78. hp->rcode = NOERROR;
  79. cp = buf + sizeof(HEADER);
  80. buflen -= sizeof(HEADER);
  81. dpp = dnptrs;
  82. *dpp++ = buf;
  83. *dpp++ = NULL;
  84. lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]);
  85. /*
  86.  * perform opcode specific processing
  87.  */
  88. switch (op) {
  89.   case QUERY:
  90. if ((buflen -= QFIXEDSZ) < 0)
  91. return(-1);
  92. if ((n = dn_comp((u_char *)dname, (u_char *)cp, buflen,
  93.  (u_char **)dnptrs, (u_char **)lastdnptr)) < 0)
  94. return (-1);
  95. cp += n;
  96. buflen -= n;
  97. __putshort(type, (u_char *)cp);
  98. cp += sizeof(u_short);
  99. __putshort(class, (u_char *)cp);
  100. cp += sizeof(u_short);
  101. hp->qdcount = htons(1);
  102. if (op == QUERY || data == NULL)
  103. break;
  104. /*
  105.  * Make an additional record for completion domain.
  106.  */
  107. buflen -= RRFIXEDSZ;
  108. if ((n = dn_comp((u_char *)data, (u_char *)cp, buflen,
  109.  (u_char **)dnptrs, (u_char **)lastdnptr)) < 0)
  110. return (-1);
  111. cp += n;
  112. buflen -= n;
  113. __putshort(T_NULL, (u_char *)cp);
  114. cp += sizeof(u_short);
  115. __putshort(class, (u_char *)cp);
  116. cp += sizeof(u_short);
  117. __putlong(0, (u_char *)cp);
  118. cp += sizeof(pthread_ipaddr_type);
  119. __putshort(0, (u_char *)cp);
  120. cp += sizeof(u_short);
  121. hp->arcount = htons(1);
  122. break;
  123.   case IQUERY:
  124. /*
  125.  * Initialize answer section
  126.  */
  127. if (buflen < 1 + RRFIXEDSZ + datalen)
  128. return (-1);
  129. *cp++ = ''; /* no domain name */
  130. __putshort(type, (u_char *)cp);
  131. cp += sizeof(u_short);
  132. __putshort(class, (u_char *)cp);
  133. cp += sizeof(u_short);
  134. __putlong(0, (u_char *)cp);
  135. cp += sizeof(pthread_ipaddr_type);
  136. __putshort(datalen, (u_char *)cp);
  137. cp += sizeof(u_short);
  138. if (datalen) {
  139. memcpy(cp, data, datalen);
  140. cp += datalen;
  141. }
  142. hp->ancount = htons(1);
  143. break;
  144. #ifdef ALLOW_UPDATES
  145. /*
  146.  * For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA
  147.  * (Record to be modified is followed by its replacement in msg.)
  148.  */
  149.   case UPDATEM:
  150.   case UPDATEMA:
  151.   case UPDATED:
  152. /*
  153.  * The res code for UPDATED and UPDATEDA is the same; user
  154.  * calls them differently: specifies data for UPDATED; server
  155.  * ignores data if specified for UPDATEDA.
  156.  */
  157.   case UPDATEDA:
  158. buflen -= RRFIXEDSZ + datalen;
  159. if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
  160. return (-1);
  161. cp += n;
  162. __putshort(type, cp);
  163. cp += sizeof(u_short);
  164. __putshort(class, cp);
  165. cp += sizeof(u_short);
  166. __putlong(0, cp);
  167. cp += sizeof(pthread_ipaddr_type);
  168. __putshort(datalen, cp);
  169. cp += sizeof(u_short);
  170. if (datalen) {
  171. memcpy(cp, data, datalen);
  172. cp += datalen;
  173. }
  174. if ( (op == UPDATED) || (op == UPDATEDA) ) {
  175. hp->ancount = htons(0);
  176. break;
  177. }
  178. /* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */
  179.   case UPDATEA: /* Add new resource record */
  180. buflen -= RRFIXEDSZ + datalen;
  181. if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
  182. return (-1);
  183. cp += n;
  184. __putshort(newrr->r_type, cp);
  185. cp += sizeof(u_short);
  186. __putshort(newrr->r_class, cp);
  187. cp += sizeof(u_short);
  188. __putlong(0, cp);
  189. cp += sizeof(pthread_ipaddr_type);
  190. __putshort(newrr->r_size, cp);
  191. cp += sizeof(u_short);
  192. if (newrr->r_size) {
  193. memcpy(cp, newrr->r_data, newrr->r_size);
  194. cp += newrr->r_size;
  195. }
  196. hp->ancount = htons(0);
  197. break;
  198. #endif /* ALLOW_UPDATES */
  199. }
  200. return (cp - buf);
  201. }