Back to index

citadel  8.12
Classes | Defines | Functions
domain.h File Reference
#include "typesize.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  mx

Defines

#define HFIXEDSZ   12 /* I hope! */
#define INT16SZ   sizeof(cit_int16_t)
#define INT32SZ   sizeof(cit_int32_t)

Functions

int getmx (char *mxbuf, char *dest)
int get_hosts (char *mxbuf, char *rectype)

Class Documentation

struct mx

Definition at line 13 of file domain.h.

Class Members
char host
int pref

Define Documentation

#define HFIXEDSZ   12 /* I hope! */

Definition at line 27 of file domain.h.

#define INT16SZ   sizeof(cit_int16_t)

Definition at line 30 of file domain.h.

#define INT32SZ   sizeof(cit_int32_t)

Definition at line 33 of file domain.h.


Function Documentation

int get_hosts ( char *  mxbuf,
char *  rectype 
)

Definition at line 51 of file domain.c.

                                          {
       int config_lines;
       int i;
       char buf[256];
       char host[256], type[256];
       int total_smarthosts = 0;

       if (inetcfg == NULL) return(0);
       strcpy(mxbuf, "");

       config_lines = num_tokens(inetcfg, '\n');
       for (i=0; i<config_lines; ++i) {
              extract_token(buf, inetcfg, i, '\n', sizeof buf);
              extract_token(host, buf, 0, '|', sizeof host);
              extract_token(type, buf, 1, '|', sizeof type);

              if (!strcasecmp(type, rectype)) {
                     strcat(mxbuf, host);
                     strcat(mxbuf, "|");
                     ++total_smarthosts;
              }
       }

       return(total_smarthosts);
}

Here is the caller graph for this function:

int getmx ( char *  mxbuf,
char *  dest 
)

Definition at line 112 of file domain.c.

                                   {

#ifdef HAVE_RESOLV_H
       union {
                     u_char bytes[1024];
                     HEADER header;
    } answer;
#endif

       int ret;
       unsigned char *startptr, *endptr, *ptr;
       char expanded_buf[1024];
       unsigned short pref, type;
       int n = 0;
       int qdcount;

       struct mx *mxrecs = NULL;
       int num_mxrecs = 0;
       
       /* If we're configured to send all mail to a smart-host, then our
        * job here is really easy.
        */
       n = get_hosts(mxbuf, "smarthost");
       if (n > 0) return(n);

       /*
        * No smart-host?  Look up the best MX for a site.
        * Make a call to the resolver library.
        */

       ret = res_query(
              dest,
              C_IN, T_MX, (unsigned char *)answer.bytes, sizeof(answer)  );

       if (ret < 0) {
              mxrecs = malloc(sizeof(struct mx));
              mxrecs[0].pref = 0;
              strcpy(mxrecs[0].host, dest);
              num_mxrecs = 1;
       }
       else {

              /* If we had to truncate, shrink the number to avoid fireworks */
              if (ret > sizeof(answer))
                     ret = sizeof(answer);
       
              startptr = &answer.bytes[0];              /* start and end of buffer */
              endptr = &answer.bytes[ret];
              ptr = startptr + HFIXEDSZ;  /* advance past header */
       
              for (qdcount = ntohs(answer.header.qdcount); qdcount--; ptr += ret + QFIXEDSZ) {
                     if ((ret = dn_skipname(ptr, endptr)) < 0) {
                            syslog(LOG_DEBUG, "dn_skipname error\n");
                            return(0);
                     }
              }
       
              while(1) {
                     memset(expanded_buf, 0, sizeof(expanded_buf));
                     ret = dn_expand(startptr,
                                   endptr,
                                   ptr,
                                   expanded_buf,
                                   sizeof(expanded_buf)
                                   );
                     if (ret < 0) break;
                     ptr += ret;
       
                     GETSHORT(type, ptr);
                     ptr += INT16SZ + INT32SZ;
                     GETSHORT(n, ptr);
       
                     if (type != T_MX) {
                            ptr += n;
                     }
       
                     else {
                            GETSHORT(pref, ptr);
                            ret = dn_expand(startptr,
                                          endptr,
                                          ptr,
                                          expanded_buf,
                                          sizeof(expanded_buf)
                                          );
                            ptr += ret;
       
                            ++num_mxrecs;
                            if (mxrecs == NULL) {
                                   mxrecs = malloc(sizeof(struct mx));
                            }
                            else {
                                   mxrecs = realloc(mxrecs,
                                       (sizeof(struct mx) * num_mxrecs) );
                            }
       
                            mxrecs[num_mxrecs - 1].pref = pref;
                            strcpy(mxrecs[num_mxrecs - 1].host,
                                   expanded_buf);
                     }
              }
       }

       /* Sort the MX records by preference */
       if (num_mxrecs > 1) {
              qsort(mxrecs, num_mxrecs, sizeof(struct mx), mx_compare_pref);
       }

       strcpy(mxbuf, "");
       for (n=0; n<num_mxrecs; ++n) {
              strcat(mxbuf, mxrecs[n].host);
              strcat(mxbuf, "|");
       }
       free(mxrecs);

       /* Append any fallback smart hosts we have configured.
        */
       num_mxrecs += get_hosts(&mxbuf[strlen(mxbuf)], "fallbackhost");
       return(num_mxrecs);
}

Here is the call graph for this function:

Here is the caller graph for this function: