*** qmail-remote.c.orig Fri Mar 21 15:01:14 2003 --- qmail-remote.c Fri Mar 21 15:02:08 2003 *************** *** 1,3 **** --- 1,5 ---- + #include + #include #include #include #include *************** *** 48,53 **** --- 50,62 ---- struct ip_address partner; + struct relay { + stralloc host; + unsigned long port; + unsigned long weight; + struct relay *next; + }; + #ifdef TLS # include # include "tls.h" *************** *** 655,666 **** { static ipalloc ip = {0}; int i; ! unsigned long random; char **recips; unsigned long prefme; int flagallaliases; int flagalias; char *relayhost; sig_pipeignore(); if (argc < 4) perm_usage(); --- 664,686 ---- { static ipalloc ip = {0}; int i; ! unsigned long randomval; char **recips; unsigned long prefme; int flagallaliases; int flagalias; char *relayhost; + struct relay *relay_list = NULL, *relay_list_head = NULL, *tmp; + short done = 0; + char temp; + char *pos; + unsigned long weight; + unsigned long totalweight = 0; + long randomweight; + int slashpos; + /* + FILE *outfile; + */ sig_pipeignore(); if (argc < 4) perm_usage(); *************** *** 678,689 **** --- 698,869 ---- if (relayhost && !*relayhost) relayhost = 0; if (relayhost) { + /* + outfile = fopen("/tmp/debug", "a"); + */ + pos = relayhost; + while (!done) { + if (host.s != NULL) { + alloc_free(host.s); + host.s = 0; + } + port = PORT_SMTP; + slashpos = str_chr(pos, '/'); + i = str_chr(pos, ':'); + if (pos[i] && (!pos[slashpos] || i < slashpos)) { + /* + fprintf(outfile, "found :\n"); + fflush(outfile); + */ + scan_ulong(pos + i + 1, &port); + /* + fprintf(outfile, "found port %ul\n", port); + fflush(outfile); + */ + temp = pos[i]; + pos[i] = 0; + if (!stralloc_copys(&host,pos)) temp_nomem(); + /* + fprintf(outfile, "found host: %s\n", host.s); + fflush(outfile); + */ + pos[i] = temp; + pos = pos + i + 1; + } + slashpos = str_chr(pos, '/'); + i = str_chr(pos, '@'); + if (pos[i] && (!pos[slashpos] || i < slashpos)) { + /* + fprintf(outfile, "found @\n"); + fflush(outfile); + */ + if (host.s == NULL) { + temp = pos[i]; + pos[i] = 0; + if (!stralloc_copys(&host,pos)) temp_nomem(); + /* + fprintf(outfile, "found host: %s\n", host.s); + fflush(outfile); + */ + pos[i] = temp; + } + scan_ulong(pos + i + 1, &weight); + pos = pos + i + 1; + /* + fprintf(outfile, "found weight %ul\n", weight); + fflush(outfile); + */ + totalweight = totalweight + weight; + } else { + weight = 1; + totalweight = totalweight + 1; + } + + if (host.s == NULL) { + if (pos[slashpos]) { + temp = pos[slashpos]; + pos[slashpos] = 0; + if (!stralloc_copys(&host,pos)) temp_nomem(); + /* + fprintf(outfile, "found host: %s\n", host.s); + fflush(outfile); + */ + pos[slashpos] = temp; + } else { + if (!stralloc_copys(&host,pos)) temp_nomem(); + /* + fprintf(outfile, "found host: %s\n", host.s); + fflush(outfile); + */ + } + } + + + if (relay_list_head == NULL) { + relay_list_head = (struct relay *) alloc(sizeof(struct relay)); + relay_list = relay_list_head; + relay_list->next = NULL; + } else { + relay_list->next = (struct relay *) alloc(sizeof(struct relay)); + relay_list = relay_list->next; + relay_list->next = NULL; + } + relay_list->host.s = 0; + relay_list->next = NULL; + if (!stralloc_copy(&(relay_list->host), &(host))) temp_nomem(); + relay_list->port = port; + relay_list->weight = weight; + i = str_chr(pos, '/'); + if (pos[i]) { + /* + fprintf(outfile, "found /\n"); + fflush(outfile); + */ + pos = pos + i + 1; + } else { + done = 1; + } + } + if (relay_list_head != NULL) { + if (relay_list_head->next == NULL) { + if (relay_list_head->host.s != NULL) alloc_free(relay_list_head->host.s); + alloc_free(relay_list_head); + } else { + srandomdev(); + randomweight = (long) (((float) (random()) / LONG_MAX) * totalweight); + /* + fprintf(outfile, "%ul\n", randomweight); + fflush(outfile); + */ + relay_list = relay_list_head; + done = 0; + totalweight = 0; + while (!done) { + if (randomweight <= totalweight + relay_list->weight) { + if (!stralloc_copy(&host, &(relay_list->host))) temp_nomem(); + /* + fprintf(outfile, "chose %s\n", relay_list->host); + fflush(outfile); + */ + port = relay_list->port; + while (relay_list != NULL) { + tmp = relay_list; + relay_list = relay_list->next; + if (tmp->host.s != NULL) alloc_free(tmp->host.s); + alloc_free(tmp); + } + done = 1; + } else if (relay_list->next == NULL) { + if (!stralloc_copy(&host, &(relay_list->host))) temp_nomem(); + /* + fprintf(outfile, "chose %s\n", relay_list->host); + fflush(outfile); + */ + port = relay_list->port; + if (relay_list->host.s != NULL) alloc_free(relay_list->host.s); + alloc_free(relay_list); + done = 1; + } else { + totalweight = totalweight + relay_list->weight; + tmp = relay_list; + relay_list = relay_list->next; + if (tmp->host.s != NULL) alloc_free(tmp->host.s); + alloc_free(tmp); + } + } + } + } + /* + fclose(outfile); + */ + /* i = str_chr(relayhost,':'); if (relayhost[i]) { scan_ulong(relayhost + i + 1,&port); relayhost[i] = 0; } if (!stralloc_copys(&host,relayhost)) temp_nomem(); + */ } *************** *** 704,711 **** } ! random = now() + (getpid() << 16); ! switch (relayhost ? dns_ip(&ip,&host) : dns_mxip(&ip,&host,random)) { case DNS_MEM: temp_nomem(); case DNS_SOFT: temp_dns(); case DNS_HARD: perm_dns(); --- 884,891 ---- } ! randomval = now() + (getpid() << 16); ! switch (relayhost ? dns_ip(&ip,&host) : dns_mxip(&ip,&host,randomval)) { case DNS_MEM: temp_nomem(); case DNS_SOFT: temp_dns(); case DNS_HARD: perm_dns();