#include #include #include #include #include "wresolv.h" #ifndef SD_SEND #define SD_SEND 1 #endif MXDATA * allocMX(int c) { int i; MXDATA *mx; mx = (MXDATA *) malloc(c * sizeof(MXDATA)); if (mx) { memset(mx, 0, c * sizeof(MXDATA)); for (i = 0; i < c; i++) mx[i].cbMX = c; } return (mx); } MXDATA * freeMX(MXDATA * mx) { free(mx); return ((MXDATA *) NULL); } void sortMX(MXDATA * mx) { int i, k, done; MXDATA t; k = mx->cbMX; if (k < 2) return; done = 0; while (!done) { done = 1; for (i = 0; i < k - 1; i++) { if (mx[i].priority > mx[i + 1].priority) { memcpy(&t, &mx[i], sizeof(MXDATA)); memcpy(&mx[i], &mx[i + 1], sizeof(MXDATA)); memcpy(&mx[i + 1], &t, sizeof(MXDATA)); done = 0; } } } } int isIPLocal(MXDATA * mx, MXDATA * lmx) { return (strcmp(mx->hIP, lmx->hIP) == 0); } void setMX(MXDATA * mx, unsigned short *pri, char *hname, char *hip) { if (hname != NULL) strcpy(mx->hName, hname); if (hip != NULL) strcpy(mx->hIP, hip); if (pri != NULL) mx->priority = *pri; } /* * Since domain names CAN begin with a digit, I rolled this so that we can * see if we are looking at a dotted-quad IP address or a domain name. */ int isdotip(char *p) { int i = 0, k, ret = 1; k = strlen(p); for (i = 0; i < k; i++) { if ((p[i] != '.') && (isalpha(p[i]))) { ret = 0; break; } } return (ret); } void GetQName(char *pszHostName, unsigned char *p, char *pOrigBuf) { int i, j, k; unsigned short comp; for (i = 0; i < BUFSIZE; i++) { j = *p; if (j == 0) break; if (j & 0xc0) { comp = *(p + 1); GetQName(pszHostName, pOrigBuf + comp, pOrigBuf); return; } for (k = 1; k <= j; k++) { *pszHostName++ = *(p + k); } if (*(p + j + 1)) { *pszHostName++ = '.'; } p += j + 1; } *pszHostName = 0; } int PutQName(char *pszHostName, char *pQName) { int i, j = 0, k = 0; char c; for (i = 0; *(pszHostName + i); i++) { c = *(pszHostName + i); // printf("%c",c); if (c == '.') { *(pQName + j) = (unsigned char) k; // printf("%c", k+'0'); k = 0; j = i + 1; } else { *(pQName + i + 1) = c; k++; } } *(pQName + j) = (unsigned char) k; // printf("%c", k+'0'); *(pQName + i + 1) = 0; return (i + 1); } void stopTCP(SOCKET s) { int b; char buf[256]; shutdown(s, SD_SEND); while ((b = recv(s, buf, 256, 0)) != 0) if (b == SOCKET_ERROR) break; closesocket(s); } int getTCP(SOCKET s, char *buf, int *count) { int nRC; *buf = '\0'; nRC = recv(s, buf, *count, 0); if (nRC == SOCKET_ERROR) nRC = WSAGetLastError(); else { *count = nRC; buf[nRC] = 0; nRC = 0; } return (nRC); } int sendTCP(SOCKET s, char *buf, int count) { int nRC = 0; while (count) { nRC = send(s, buf, 1, 0); if (nRC == SOCKET_ERROR) { nRC = WSAGetLastError(); break; } else { count--; buf++; nRC = 0; } } return (nRC); } // waits for ack from receiver and returns status code.. int AckSend(SOCKET s) { char buf[1024]; int nRC, c = 1024; if ((nRC = getTCP(s, buf, &c)) != SOCKET_ERROR) { return (atoi(buf)); } else return SOCKET_ERROR; } // sends a string to socket and waits for ack from receiver.. int sendSMTP(SOCKET s, char *buf) { int nRC, c = strlen(buf); nRC = sendTCP(s, buf, c); if (nRC != SOCKET_ERROR) return (AckSend(s)); return (nRC); } MXDATA * fixMX(MXDATA * mx, char *tDomain) { struct hostent *ph; struct in_addr addr; int i; if (!mx) { // no MX records, create one with default // domain mx = (MXDATA *) malloc(sizeof(MXDATA)); if (mx) { memset(mx, 0, sizeof(MXDATA)); mx->cbMX = 1; strcpy(mx->hName, tDomain); ph = gethostbyname(tDomain); memcpy(&addr, ph->h_addr_list[0], sizeof(struct in_addr)); strcpy(mx->hIP, inet_ntoa(addr)); } } else { // else, make sure we have IPs for all MX // records for (i = 0; i < mx[0].cbMX; i++) { if (!strlen(mx[i].hIP)) { ph = gethostbyname(mx[i].hName); memcpy(&addr, ph->h_addr_list[0], sizeof(struct in_addr)); strcpy(mx[i].hIP, inet_ntoa(addr)); } } } return (mx); }