Years ago I used to run a hockey server. On that server I had some custom code that would obscure the host of the player. The idea was that security-wise it is not a good idea to list IP addresses to all game players, given that there are often heated arguments and an IP address is a good start for any kind of network attack. However, IP addresses are useful for players to recognise other players (like "player foo always plays from bar.isp"), and also to report problem players to an administrator. So what I did was to "x" out the hostname for a string address, or the last two fields for a numeric address. For example: 127.0.0.1 --> 127.0.x.x foo.bar.com --> x.bar.com I'm offering the patch here, in case somebody thinks it's a good idea and wants to apply it. However, note: This code is years old. Some work will have to be done to apply it, though not much, I think. I don't play netrek any more or run a server, so I have no interest in doing this work myself. I have attached the original main.c from years ago and the patched main.c. I've also included the diff. -Jeff -------------- next part -------------- A non-text attachment was scrubbed... Name: main.c Type: text/x-csrc Size: 23862 bytes Desc: not available Url : http://mailman.us.netrek.org/pipermail/netrek-dev/attachments/20060601/4924f502/attachment-0001.c -------------- next part -------------- A non-text attachment was scrubbed... Name: main.c.diff Type: text/x-patch Size: 2844 bytes Desc: not available Url : http://mailman.us.netrek.org/pipermail/netrek-dev/attachments/20060601/4924f502/attachment-0001.bin -------------- next part -------------- /* * main.c */ #include "copyright.h" #include <stdio.h> #include <math.h> #include <stdlib.h> #include <ctype.h> #include <time.h> #include <signal.h> #include <pwd.h> #include <sys/time.h> #include <fcntl.h> #include <string.h> #include <sys/types.h> #include "defs.h" #include INC_STRINGS #include INC_UNISTD #include INC_SYS_WAIT #include "struct.h" #include "data.h" #include "packets.h" #include "../patchlevel.h" #define SVERS #include "../version.h" #ifdef SENDFLAGS #include "../cflags.h" #endif #include "proto.h" #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif /* file scope prototypes */ static void reaper(int); static void printUsage(char *prog); static void sendMotd(void); static void sendConfigMsg(void); static void printStats(void); static int checkbanned(char *login, char *host); int ignored[MAXPLAYER]; /* change 7/24/91 TC */ int indie = 0; /* always be indie 8/28/91 TC */ int living = 1; /* our ship is living, reset by death */ int main(int argc, char **argv) { int team, s_type, w_queue = 0; int pno; int usage = 0; int err = 0; char *name, *ptr; struct passwd *pwent; int callHost=0; time_t starttime; int i; register struct player *j; /* for traipsing through the playerlist */ extern void forceShutdown (); char pseudo[PSEUDOSIZE]; /* Was a global - MK 9/30/94 */ getpath(); /* added 11/6/92 DRG */ errors = open(Error_File, O_WRONLY | O_APPEND | O_CREAT, 0644); dup2(errors,2); setbuf(stderr, NULL); dup2(errors,1); setbuf(stdout, NULL); name = *argv++; argc--; if ((ptr = RINDEX(name,'/')) != NULL) name = ptr + 1; while (*argv) { if (**argv == '-') ++*argv; else break; argc--; ptr = *argv++; while (*ptr) { switch (*ptr) { case 'u': usage++; break; case 'i': indie++; break; /* 8/28/91 TC */ case 'q': w_queue=atoi(*argv); argv++; argc--; break; case 's': xtrekPort=atoi(*argv); callHost=1; argv++; argc--; break; #ifdef OBSERVERS case 'O': Observer = 1; clueVerified = 1; break; #endif case 'd': host = *argv; argc--; argv++; break; default: ERROR(1,("%s: unknown option '%c'\n", name, *ptr)); err++; break; } ptr++; } } if (usage || err) { printUsage(name); exit(err); } /* accept host name from newstartd */ if (argc > 0) host = argv[0]; srandom((int)getpid() * time((time_t *) 0)); /* avoid having daemon (started by openmem) inherit our socket */ fcntl(0, F_SETFD, FD_CLOEXEC); /* this finds the shared memory information */ openmem(1); readsysdefaults(); #ifdef FEATURE_PACKETS readFeatures(); #endif me = NULL; /* UDP fix (?) */ if (callHost) { if (!connectToClient(host,xtrekPort)) { exit(0); } } else { sock=0; /* newstartd gives us our connection on 0 */ checkSocket(); setNoDelay(sock); initClientData(); /* "normally" called by connectToClient() */ } starttime=time(NULL); while (userVersion==0) { time_t t; /* Waiting for user to send his version number. * We give him thirty seconds to do so... */ if (isClientDead()) { ERROR(2,("ntserv/main.c: disconnect waiting for version packet from %s\n", host)); exit(1); } if (starttime+30 < time(&t)) { ERROR(2,("ntserv/main.c: no version packet received from %s\n", host)); exit(1); } socketPause(starttime+30-t); readFromClient(); } if (!checkVersion()) { ERROR(2,("ntserv/main.c: bad version packet from %s\n", host)); exit(1); } SIGNAL(SIGALRM, SIG_IGN); SIGNAL(SIGTERM, forceShutdown); SIGNAL(SIGPIPE, SIG_IGN); sendMotd(); pno = findslot(w_queue); if (pno < 0) { /* trigger client's "Sorry, but you cannot play xtrek now. Try again later." */ struct badversion_spacket packet; packet.type = SP_BADVERSION; packet.why = 1; sendClientPacket (&packet); flushSockBuf (); ERROR(2,("ntserv/main.c: Quitting: No slot available on queue %d\n",w_queue)); /* print some appropriate message */ exit(1); } me = &players[pno]; me->p_process = getpid (); me->p_timerdelay = defskip; me->p_mapchars[0] = 'X'; me->p_mapchars[1] = shipnos[pno]; me->p_mapchars[2] = '\0'; me->p_whydead=KLOGIN; myship = &me->p_ship; mystats = &me->p_stats; lastm = mctl->mc_current; SIGNAL(SIGINT, SIG_IGN); (void) SIGNAL(SIGCHLD, reaper); /* erase prior slot login identity */ me->p_login[0] = '\0'; /* We set these so we won't bother updating him on the location of the * other players in the galaxy which he is not near. There is no * real harm to doing this, except that he would then get more information * than he deserves. * It is kind of a hack, but should be harmless. */ me->p_x= -100000; me->p_y= -100000; me->p_team=0; updateSelf(FALSE); /* so he gets info on who he is */ /* updateSelf(TRUE) shouldn't be necessary */ updateShips(); updatePlanets(); flushSockBuf(); /* Get login name */ if ((pwent = getpwuid(getuid())) != NULL) STRNCPY(login, pwent->pw_name, NAME_LEN); else STRNCPY(login, "Bozo", NAME_LEN); login[NAME_LEN - 1] = '\0'; strcpy(pseudo, "Guest"); strcpy(me->p_name, pseudo); me->p_team=ALLTEAM; getname(); strcpy(pseudo, me->p_name); ERROR(7,("%s: is %s@%s as %s\n", me->p_mapchars, login, host, pseudo)); keeppeace = (me->p_stats.st_flags / ST_KEEPPEACE) & 1; /* showgalactic = 1 + (me->p_stats.st_flags / ST_GALFREQUENT) & 1;*/ /* Set p_hostile to hostile, so if keeppeace is on, the guy starts off hating everyone (like a good fighter should) */ me->p_hostile = (FED|ROM|KLI|ORI); me->p_war = me->p_hostile; s_type = CRUISER; me->p_planets=0; me->p_genoplanets=0; me->p_armsbomb=0; me->p_genoarmsbomb=0; STRNCPY(me->p_login, login, NAME_LEN); me->p_login[NAME_LEN - 1] = '\0'; { int i; for (i = 0; i < MAXPLAYER; i++) ignored[i] = 0; } #ifdef REVERSED_HOSTNAMES if (strlen(host) >= NAME_LEN) { STRNCPY(me->p_monitor, host + (strlen(host) - NAME_LEN + 1), NAME_LEN); /* The # denotes truncation */ me->p_monitor[0] = '#'; } else #endif STRNCPY(me->p_monitor, host, NAME_LEN); me->p_monitor[NAME_LEN - 1] = '\0'; #ifdef FULL_HOSTNAMES /* assume this is only place p_monitor is set, and mirror accordingly */ /* 4/13/92 TC */ STRNCPY(me->p_full_hostname, host, sizeof(me->p_full_hostname)); me->p_full_hostname[sizeof(me->p_full_hostname) - 1] = '\0'; #endif logEntry(); /* moved down to get login/monitor 2/12/92 TMC */ #ifdef PING /* 0 might just be legit for a local player */ me->p_avrt = -1; me->p_stdv = -1; me->p_pkls_c_s = -1; me->p_pkls_s_c = -1; #endif #ifdef LTD_STATS startTkills = ltd_kills(me, LTD_TOTAL); startTlosses = ltd_deaths(me, LTD_TOTAL); startTarms = ltd_armies_bombed(me, LTD_TOTAL); startTplanets = ltd_planets_taken(me, LTD_TOTAL); startTticks = ltd_ticks(me, LTD_TOTAL); startSBkills = ltd_kills(me, LTD_SB); startSBlosses = ltd_deaths(me, LTD_SB); startSBticks = ltd_ticks(me, LTD_SB); #else startTkills = me->p_stats.st_tkills; startTlosses = me->p_stats.st_tlosses; startTarms = me->p_stats.st_tarmsbomb; startTplanets = me->p_stats.st_tplanets; startTticks = me->p_stats.st_tticks; startSBkills = me->p_stats.st_sbkills; startSBlosses = me->p_stats.st_sblosses; startSBticks = me->p_stats.st_sbticks; #endif /* LTD_STATS */ for (;;) { /* give the player the motd and find out which team he wants */ if (me->p_status != PALIVE) { me->p_x= -100000; me->p_y= -100000; updateSelf(FALSE); /* updateSelf(TRUE) isn't necessary */ updateShips(); teamPick= -1; flushSockBuf(); getEntry(&team, &s_type); repCount=0; /* Make sure he gets an update immediately */ } if (team == -1) { exitGame(); } if(CheckBypass(login,host,Bypass_File)==TRUE) bypassed=1; else bypassed=0; if (indie) team = 4; /* force to independent 8/28/91 TC */ redrawall = 1; for (i = 0; i <= MAX_CP_PACKETS; i++) FD_SET (i, &inputMask); /* Allow all input now */ enter(team, 0, pno, s_type, pseudo); #ifndef DEBUG for (i = 1; i < NSIG; i++) { SIGNAL(i, SIG_IGN); } #endif /* +++ 2.6pl2 kantner at hot.caltech.edu 22-NOV-1994 09:46:00.74 */ /* ** The daemon sends ntserv a SIGTERM after the slot is freed during a ** ghostbust. Without this line the SIGTERM does nothing. The slot is ** marked free, but really isn't. Someone else joins the slot, and a ** copilot is formed. */ SIGNAL(SIGTERM, forceShutdown); /* --- */ SIGNAL(SIGILL, SIG_DFL); /* since illegal instruction is so rare this is an useful one to use to make core files for debugging ie. kill -SIGILL <process #> */ #ifdef OBSERVERS if (Observer) { me->p_status = POBSERV; /* put observer in game */ new_warning(UNDEF,"Lock onto a teammate or planet to see the action."); pmessage(me->p_no, MINDIV, addr_mess(me->p_no,MINDIV), "Lock onto a teammate or planet to see the action."); } else #endif me->p_status = PALIVE; /* Put player in game */ me->p_ghostbuster = 0; if (checkbanned(login, host) == TRUE) { FILE *logfile; time_t curtime; pmessage(0, MALL, "GOD->ALL","%s (%s@%s) is banned from the game.", me->p_name, me->p_login, host); new_warning(UNDEF,"You are banned from the game."); me->p_explode=100; me->p_status=PEXPLODE; me->p_whydead=KQUIT; /* make him self destruct */ me->p_whodead=0; logfile=fopen(LogFileName, "a"); if (logfile) { curtime=time(NULL); fprintf(logfile, "Banned and exiting: %s (%s@%s), (%c), %s", me->p_name, me->p_login, host, shipnos[me->p_no], ctime(&curtime) ); fclose(logfile); } } #ifdef VOTING /* reset eject voting to avoid inheriting this slot's last occupant's */ /* escaped fate just in case the last vote comes through after the */ /* old guy quit and the new guy joined -Villalpando req. by Cameron */ for (i = 0, j = &players[i]; i < MAXPLAYER; i++, j++) j->voting[me->p_no] = -1; #endif /* Get input until the player quits or dies */ living++; while (living) input(); } } void exitGame(void) { char addrbuf[20]; if (me != NULL && me->p_team != ALLTEAM) { sprintf(addrbuf, " %c%c->ALL", teamlet[me->p_team], shipnos[me->p_no]); #ifndef FULL_HOSTNAMES /* old-style leaving message 4/13/92 TC */ pmessage2(0, MALL | MLEAVE, addrbuf, me->p_no, "%s %s (%s) leaving the game (%.16s@%.16s)", ranks[me->p_stats.st_rank].name, me->p_name, me->p_mapchars, me->p_login, me->p_monitor); #else /* new-style leaving message 4/13/92 TC */ pmessage2(0, MALL | MLEAVE, addrbuf, me->p_no, "%s %s (%s) leaving game (%.16s@%.32s)", ranks[me->p_stats.st_rank].name, me->p_name, me->p_mapchars, me->p_login, me->p_full_hostname); #endif me->p_stats.st_flags &= ~ST_CYBORG; /* clear this flag 8/27/91 TC */ savestats(); printStats(); } if (me) { if(me->p_process != getpid()){ ERROR(1,( "main/exitGame: process exiting from co-pilot!\n")); ERROR(1,( "%d != pid: %d\n", (int) me->p_process, (int) getpid())); fflush(stderr); exit(0); } freeslot(me); } exit(0); } static void printUsage(char *prog) { char *text = "\ Usage: %s [-u] [-q n] [-i] [-O] [-s n] [-d a]\n\ -u displays program usage\n\ -q n specifies queue number to join\n\ -i player is to be independant\n\ -O player is to be an observer\n\ \n\ Manual Connection\n\ -s n call client on socket number 'n'\n\ -d a call client on machine address 'a'\n"; ERROR(1,(text,prog)); } static void sendMotd(void) { FILE *motd; char buf[100]; /* big enough... */ char motd_file[255]; time_t curtime; struct tm *tmstruct; int hour; #ifdef SENDPATCHLEVEL sprintf(buf, "Welcome to %s, patchlevel %d", serv_version, PATCHLEVEL); sendMotdLine(buf); #endif #ifdef SENDFLAGS sendMotdLine("Compiler option flags used for this server:"); sendMotdLine(cflags); sendMotdLine(" "); #endif time(&curtime); tmstruct = localtime(&curtime); if (!(hour = tmstruct->tm_hour%12)) hour = 12; sprintf(buf,"Connection to server established at %d:%02d%s.", hour, tmstruct->tm_min, tmstruct->tm_hour >= 12 ? "pm" : "am"); if (!time_access()) { strcat(buf, " WE'RE CLOSED. SEE HOURS BELOW."); sendMotdLine(buf); sendMotdLine(" "); } strcpy(motd_file,Motd_Path); if (clue) /* added 2/6/93 NBT */ strcat(motd_file,N_MOTD_CLUE); else strcat(motd_file,Motd); /* the following will read a motd */ if ((motd = fopen(motd_file, "r")) != NULL) { while (fgets(buf, sizeof (buf), motd) != NULL) { buf[strlen(buf)-1] = '\0'; sendMotdLine(buf); } (void) fclose(motd); } if (show_sysdef) sendConfigMsg(); } static void sendConfigMsg(void) { register int i, flag; char buf[100]; /* big enough... */ extern char *shiptypes[]; /* ATM: send current configuration info as well */ sendMotdLine(STATUS_TOKEN); /* indicate start of config info */ if (clue) sendMotdLine("Clue verification enabled"); sprintf(buf, "%-30s: ", "Binary Verification"); switch (binconfirm) { case 0: strcat(buf, "disabled"); break; case 1: strcat(buf, "enabled, RSA only"); break; case 2: strcat(buf, "enabled, RSA and reserved.c"); break; } sendMotdLine(buf); if (tournplayers > 8) sprintf(buf, "%-30s: disabled", "Tournament Mode"); else sprintf(buf, "%-30s: %d players / side","Tournament Mode",tournplayers); sendMotdLine(buf); sprintf(buf, "%-30s: ", "Ships Allowed"); for (i = 0; i < NUM_TYPES; i++) { if (i == ATT) continue; if (shipsallowed[i]) { strcat(buf, shiptypes[i]); strcat(buf, " "); } } sendMotdLine(buf); sprintf(buf, "%-30s: %s", "Tractor/Pressor Beams", weaponsallowed[WP_TRACTOR] ? "enabled" : "disabled"); sendMotdLine(buf); sprintf(buf, "%-30s: %s", "Plasma Torpedoes", weaponsallowed[WP_PLASMA] ? "enabled" : "disabled"); sendMotdLine(buf); if (weaponsallowed[WP_PLASMA]) { sprintf(buf, "%-30s: %d", "Kills Required for Plasma", plkills); sendMotdLine(buf); } #ifdef nodef sprintf(buf, "%-30s: %s", "Scanning Beams", weaponsallowed[WP_SCANNER] ? "enabled" : "disabled"); sendMotdLine(buf); #endif if (shipsallowed[STARBASE]) { sprintf(buf, "%-30s: %s (%d)", "Rank Required for SB", ranks[sbrank].name, sbrank); sendMotdLine(buf); } sprintf(buf, "%-30s: %d", "Planets Required for SB", sbplanets); sendMotdLine(buf); sprintf(buf, "%-30s: ", "Hidden Mode"); switch (hiddenenemy) { case 0: strcat(buf, "inactive"); break; case 1: strcat(buf, "tournament only"); break; case 2: strcat(buf, "active"); break; } sendMotdLine(buf); flag = 0; /* see if non-home worlds are allowable entry points */ for (i = 0; i < MAXPLANETS; i++) { if (startplanets[i] && (i % 10)) { flag = 1; break; } } sprintf(buf, "%-30s: %s", "Multiple Entry Planets", flag ? "yes" : "no"); sendMotdLine(buf); sprintf(buf, "%-30s: %s", "Chaos Mode", chaos ? "enabled" : "disabled"); sendMotdLine(buf); #ifdef TORPCONFIG sprintf(buf, "%-30s: %s", "Vector Torps", vectortorps ? "yes" : "no"); sendMotdLine(buf); #endif sprintf(buf,"%-30s: ", "Hunter Killer"); if (killer) strcat(buf, "Yes"); else strcat(buf, "No"); sendMotdLine(buf); #ifdef CHECKMESG sprintf(buf, "%-30s: ", "Message to GOD Log"); if(loggod) strcat(buf, "Yes"); else strcat(buf, "No"); sendMotdLine(buf); #endif #ifdef SB_TRANSWARP sprintf(buf, "%-30s: ", "SB Transwarp"); if (twarpMode) strcat(buf, "Yes"); else strcat(buf, "No"); sendMotdLine(buf); #else sprintf(buf, "%-30s: No", "SB Transwarp"); sendMotdLine(buf); #endif sprintf(buf, "%-30s: %d", "Surrender Counter", surrenderStart); sendMotdLine(buf); } int CheckBypass(char *login, char *host, char *file) { FILE *bypassfile; char log_buf[64], host_buf[64], line_buf[160]; char *position; int num1; int Hits=0; if ((bypassfile = fopen(file, "r")) == NULL) { ERROR(1,( "No bypass file %s\n", file)); fflush(stderr); return(FALSE); } while(fgets(line_buf, 160, bypassfile) != NULL) { /* Split line up */ if((*line_buf=='#')||(*line_buf=='\n')) continue; if ((position = (char *) RINDEX(line_buf, '@')) == 0) { ERROR(1,( "Bad line in bypass file\n")); fflush(stderr); continue; } num1 = position - line_buf; STRNCPY(log_buf, line_buf, num1); /* copy login name into log_buf */ log_buf[num1] = '\0'; STRNCPY(host_buf, position + 1, 64); /* copy host name into host_buf */ /* Cut off any extra spaces on the host buffer */ position = host_buf; while (!isspace((int) (*position))) position++; *position = '\0'; /* ERROR(1,( "Login: <%s>; host: <%s>\n", login, host)); ERROR(1,(" Checking Bypass <%s> and <%s>.\n",log_buf,host_buf)); */ if (*log_buf=='*') Hits=1; else if (!strcasecmp(login, log_buf)){ Hits=1; } if(Hits==1) { if (*host_buf == '*'){ /* Bypass any host */ Hits++; break; /* break out now. otherwise Hits will get reset to one */ } else if (!strcasecmp(host,host_buf) || /* Bypass subdomains */ (strstr(host,host_buf)!=NULL)) { /* (eg, "*@usc.edu" */ Hits++; break; /* break out now. otherwise Hits will get reset to one */ } } } fclose(bypassfile); if(Hits>=2) { /* ERROR(1,("Bypassing %s@%s\n",login,host)); fflush(stderr); */ return(TRUE); } else{ /* ERROR(1,("NOT Bypassing %s@%s\n",login,host)); */ return(FALSE); } } /*ARGSUSED*/ /* some systems pass the signal when caught */ static void reaper(int sig) { WAIT_TYPE stat=0; static int pid; MZERO( &stat, sizeof(WAIT_TYPE) ); while ((pid = WAIT3(&stat, WNOHANG, 0)) > 0) ; HANDLE_SIG(SIGCHLD,reaper); /* added the below code to catch the reason for a child dying - NBT 9/28/92 */ if (!WIFEXITED(stat)) ERROR(1,("Process # %d signal caught\n",pid)); if (WEXITSTATUS(stat)) ERROR(1,("exited with state %d\n",stat)); if (WIFSIGNALED(stat)) ERROR(1,("exited because of signal\n")); if (WTERMSIG(stat)) ERROR(1,("signal state %d\n",stat)); #ifdef WCOREDUMP if (WCOREDUMP(stat)) ERROR(1,("core image made\n")); #endif if (WIFSTOPPED(stat)) ERROR(1,("stopped\n")); if (WSTOPSIG(stat)) ERROR(1,("stop signal was %d\n",stat)); } static void printStats(void) { FILE *logfile; time_t curtime; logfile=fopen(LogFileName, "a"); if (!logfile) return; curtime=time(NULL); fprintf(logfile, "Leaving: %-16s (%c%c) %3dP %3dA %3dW/%3dL %3dmin %2d\n\t<%s@%s> %s", me->p_name, teamlet[me->p_team], shipnos[me->p_no], #ifdef LTD_STATS ltd_planets_taken(me, LTD_TOTAL) - startTplanets, ltd_armies_bombed(me, LTD_TOTAL) - startTarms, ltd_kills(me, LTD_TOTAL) - startTkills, ltd_deaths(me, LTD_TOTAL) - startTlosses, (ltd_ticks(me, LTD_TOTAL) - startTticks)/600, #else me->p_stats.st_tplanets - startTplanets, me->p_stats.st_tarmsbomb - startTarms, me->p_stats.st_tkills - startTkills, me->p_stats.st_tlosses - startTlosses, (me->p_stats.st_tticks - startTticks)/600, #endif /* LTD_STATS */ numPlanets(me->p_team), me->p_login, #ifndef FULL_HOSTNAMES me->p_monitor, #else me->p_full_hostname, #endif ctime(&curtime)); fclose(logfile); } static int checkbanned(char *login, char *host) { FILE *bannedfile; char log_buf[64], host_buf[64], line_buf[160]; char *position; int num1; int Hits=0; /* Hits==2 means we're banned */ if ((bannedfile = fopen(Banned_File, "r")) == NULL) { ERROR(1,( "No banned file %s\n", Banned_File)); fflush(stderr); return(FALSE); } while(fgets(line_buf, 160, bannedfile) != NULL) { /* Split line up */ if((*line_buf=='#')||(*line_buf=='\n')) continue; if ((position = (char *) RINDEX(line_buf, '@')) == 0) { ERROR(1,( "Bad line in banned file\n")); fflush(stderr); continue; } num1 = position - line_buf; STRNCPY(log_buf, line_buf, num1); /* copy login name into log_buf */ log_buf[num1] = '\0'; STRNCPY(host_buf, position + 1, 64); /* copy host name into host_buf */ /* Cut off any extra spaces on the host buffer */ position = host_buf; while (!isspace(*position)) position++; *position = '\0'; /* ERROR(1,( "Login: <%s>; host: <%s>\n", login, host)); ERROR(1,(" Checking Banned <%s> and <%s>.\n",log_buf,host_buf)); */ if(*log_buf=='*') Hits=1; else if (!strcmp(login, log_buf)) Hits=1; if(Hits==1) { if (*host_buf == '*'){ /* Lock out any host */ Hits++; break; /* break out now. otherwise Hits will get reset to one */ } else if(strstr(host,host_buf)!=NULL){ /* Lock out subdomains (eg, "*@usc .edu" */ Hits++; break; /* break out now. otherwise Hits will get reset to one */ } else if (!strcmp(host, host_buf)){ /* Lock out specific host */ Hits++; break; /* break out now. otherwise Hits will get reset to one */ } } } fclose(bannedfile); if(Hits>=2) return(TRUE); else return(FALSE); } /* ARGSUSED */ void message_flag(struct message *cur, char *address) { /* This is to prevent false sending with SP_S_WARNING */ cur->args[0] = DINVALID; }