Exemple #1
0
void
checkmail (void)
{
  int i;
  int gold, taxes;

  if (readboard () < 0)
    return;			/* can't find scoreboard */
  for (i = 0; i < SCORESIZE; i++)	/* search through winners scoreboard */
    if (strcmp (winr[i].who, logname) == 0 && winr[i].score > 0
	&& winr[i].hasmail)
      {
	winr[i].hasmail = 0;
	gold = taxes = winr[i].taxes;
	writeboard ();

	/* Intuit the amount of gold -- should have changed
	 * the score file, but ...  TAXRATE is an fraction.
	 */
	while ((gold * TAXRATE) < taxes)
	  gold += taxes;
	readmail (gold);
      }
}
//Client-Handle
void * runclient(void *arg)
{

	args *arg2 = arg; //Argumente casten

	int new_socket = arg2->socket; //Socket
	struct sockaddr_in client = arg2->address; //IP und Port

	short attempt = 0; //Login-Versuche
	char buffer[BUF];
	char *username = NULL; //Benutzername	
	 int quit = 0;
	 int size = 0;


	     //Client mit Server verbunden, Willkommennachricht senden
	     if (new_socket > 0)
	     {
	        printf ("Client connected from %s:%d...\n", inet_ntoa (client.sin_addr),ntohs(client.sin_port));
	        strcpy(buffer,"Welcome to our Mail-Server, Please enter your command:\n");
	        send(new_socket, buffer, strlen(buffer),0);
	     }
	     do
	     {

	        size = readline(new_socket, buffer, BUF-1);

	        if( size > 0)
	        {
	           buffer[size] = '\0';

	           switch(findcom(buffer)) //Auswahl welcher Befehl eingegeben wurde
	           {
		           case 0: //QUIT
		           		free(username);
		           		quit = 1;
		           		break;

		           case 1: //SEND
		           		if(sendmail(new_socket, spool, username) == 0)
		           		    strcpy(buffer,"OK\n");
		           		else
			           		strcpy(buffer,"ERR\n");
		           		send(new_socket, buffer, strlen(buffer),0);
		           		break;

		           case 2: //LIST
		           		if(listmail(new_socket, spool, username) == 0)
		           		    strcpy(buffer,"OK\n");
		           		else
			           		strcpy(buffer,"ERR\n");
		           		send(new_socket, buffer, strlen(buffer),0);
		           		break;

		           case 3: //READ
		           		if(readmail(new_socket, spool, username) == 0)
		           		    strcpy(buffer,"OK\n");
		           		else
			           		strcpy(buffer,"ERR\n");;
		           		send(new_socket, buffer, strlen(buffer),0);
		           		break;

		           case 4: //DEL
		           		if(delmail(new_socket, spool, username) == 0)
		           		    strcpy(buffer,"OK\n");
		           		else
			           		strcpy(buffer,"ERR\n");
		           		send(new_socket, buffer, strlen(buffer),0);
		           		break;


		           case 5: //LOGIN
		           		if(loginuser(new_socket, &username) == 0)
		           		{
		           		    strcpy(buffer,"OK\n");
		           		}
		           		else
		           		{
			           		attempt++;
			           		strcpy(buffer,"ERR\n");
		           		}
		           		send(new_socket, buffer, strlen(buffer),0);
		           		break;

		           default: //Andere Eingabe -> Fehler
		           		strcpy(buffer,"Server: Undefinded command\n");
	        			send(new_socket, buffer, strlen(buffer),0);
		           		break;
	           }

		   //Client in Liste speichern
		   if(attempt >= 3)
	           {
		           struct host *tmp;

		           if(locked == NULL)
		           {
			           locked = malloc(sizeof(struct host));
			           locked->ip = strdup(inet_ntoa (client.sin_addr));
			           locked->time = time(NULL);
			           locked->next = NULL;
		           }
		           else
		           {
			           tmp = locked;
			           while(tmp->next != NULL)
			           		tmp = tmp->next;
			           tmp->next = malloc(sizeof(struct host));
			           tmp = tmp->next;
			           tmp->ip = strdup(inet_ntoa (client.sin_addr));
			           tmp->time = time(NULL);
			           tmp->next = NULL;
		           }

		           //Nachricht an Server senden
		           strcpy(buffer, "lock\n");
		           send(new_socket, buffer, strlen(buffer),0);	
			   printf("Client locked\n");		   
		           quit = 1;
	           }

	        }
	        else if (size == 0)
	        {
	           printf("Client closed remote socket\n");
	           free(username);
	           break;
	        }
	        else
	        {
	           perror("recv error");
	           free(username);
	           return EXIT_FAILURE;
	        }

	     } while (quit == 0);

	     close (new_socket);
}
Exemple #3
0
int
doread()
{
	struct obj *scroll;
	boolean confused = (Confusion != 0);
	boolean known = FALSE;

	scroll = getobj("?", "read");
	if(!scroll) return(0);
	if(!scroll->dknown && Blind) {
	    pline("Being blind, you cannot read the formula on the scroll.");
	    return(0);
	}
	if(Blind)
	  pline("As you pronounce the formula on it, the scroll disappears.");
	else
	  pline("As you read the scroll, it disappears.");
	if(confused)
	  pline("Being confused, you mispronounce the magic words ... ");

	switch(scroll->otyp) {
#ifdef MAIL
	case SCR_MAIL:
		readmail(/* scroll */);
		break;
#endif /* MAIL */
	case SCR_ENCHANT_ARMOR:
	    {	struct obj *otmp = some_armor();
		if(!otmp) {
			strange_feeling(scroll,"Your skin glows then fades.");
			return(1);
		}
		if(confused) {
			pline("Your %s glows silver for a moment.",
				objects[otmp->otyp].oc_name);
			otmp->rustfree = 1;
			break;
		}
		if(otmp->spe > 3 && rn2(otmp->spe)) {
	pline("Your %s glows violently green for a while, then evaporates.",
			objects[otmp->otyp].oc_name);
			useup(otmp);
			break;
		}
		pline("Your %s glows green for a moment.",
			objects[otmp->otyp].oc_name);
		otmp->cursed = 0;
		otmp->spe++;
		break;
	    }
	case SCR_DESTROY_ARMOR:
		if(confused) {
			struct obj *otmp = some_armor();
			if(!otmp) {
				strange_feeling(scroll,"Your bones itch.");
				return(1);
			}
			pline("Your %s glows purple for a moment.",
				objects[otmp->otyp].oc_name);
			otmp->rustfree = 0;
			break;
		}
		if(uarm) {
		    pline("Your armor turns to dust and falls to the floor!");
		    useup(uarm);
		} else if(uarmh) {
		    pline("Your helmet turns to dust and is blown away!");
		    useup(uarmh);
		} else if(uarmg) {
			pline("Your gloves vanish!");
			useup(uarmg);
			selftouch("You");
		} else {
			strange_feeling(scroll,"Your skin itches.");
			return(1);
		}
		break;
	case SCR_CONFUSE_MONSTER:
		if(confused) {
			pline("Your hands begin to glow purple.");
			Confusion += rnd(100);
		} else {
			pline("Your hands begin to glow blue.");
			u.umconf = 1;
		}
		break;
	case SCR_SCARE_MONSTER:
	    {	int ct = 0;
		struct monst *mtmp;

		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
			if(cansee(mtmp->mx,mtmp->my)) {
				if(confused)
					mtmp->mflee = mtmp->mfroz =
					mtmp->msleep = 0;
				else
					mtmp->mflee = 1;
				ct++;
			}
		if(!ct) {
		    if(confused)
			pline("You hear sad wailing in the distance.");
		    else
			pline("You hear maniacal laughter in the distance.");
		}
		break;
	    }
	case SCR_BLANK_PAPER:
		if(confused)
		    pline("You see strange patterns on this scroll.");
		else
		    pline("This scroll seems to be blank.");
		break;
	case SCR_REMOVE_CURSE:
	    {	struct obj *obj;
		if(confused)
		  pline("You feel like you need some help.");
		else
		  pline("You feel like someone is helping you.");
		for(obj = invent; obj ; obj = obj->nobj)
			if(obj->owornmask)
				obj->cursed = confused;
		if(Punished && !confused) {
			Punished = 0;
			freeobj(uchain);
			unpobj(uchain);
			free(uchain);
			uball->spe = 0;
			uball->owornmask &= ~W_BALL;
			uchain = uball = (struct obj *) 0;
		}
		break;
	    }
	case SCR_CREATE_MONSTER:
	    {	int cnt = 1;

		if(!rn2(73)) cnt += rnd(4);
		if(confused) cnt += 12;
		while(cnt--)
		    (void) makemon(confused ? PM_ACID_BLOB :
			(struct permonst *) 0, u.ux, u.uy);
		break;
	    }
	case SCR_ENCHANT_WEAPON:
		if(uwep && confused) {
			pline("Your %s glows silver for a moment.",
				objects[uwep->otyp].oc_name);
			uwep->rustfree = 1;
		} else
			if(!chwepon(scroll, 1))		/* tests for !uwep */
				return(1);
		break;
	case SCR_DAMAGE_WEAPON:
		if(uwep && confused) {
			pline("Your %s glows purple for a moment.",
				objects[uwep->otyp].oc_name);
			uwep->rustfree = 0;
		} else
			if(!chwepon(scroll, -1))	/* tests for !uwep */
				return(1);
		break;
	case SCR_TAMING:
	    {	int i,j;
		int bd = confused ? 5 : 1;
		struct monst *mtmp;

		for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++)
		if ((mtmp = m_at(u.ux+i, u.uy+j)))
			(void) tamedog(mtmp, NULL);
		break;
	    }
	case SCR_GENOCIDE:
	    {	extern char genocided[], fut_geno[];
		char buf[BUFSZ];
		struct monst *mtmp, *mtmp2;

		pline("You have found a scroll of genocide!");
		known = TRUE;
		if(confused)
			*buf = u.usym;
		else do {
	    pline("What monster do you want to genocide (Type the letter)? ");
			getlin(buf);
		} while(strlen(buf) != 1 || !monstersym(*buf));
		if(!strchr(fut_geno, *buf))
			charcat(fut_geno, *buf);
		if(!strchr(genocided, *buf))
			charcat(genocided, *buf);
		else {
			pline("Such monsters do not exist in this world.");
			break;
		}
		for(mtmp = fmon; mtmp; mtmp = mtmp2){
			mtmp2 = mtmp->nmon;
			if(mtmp->data->mlet == *buf)
				mondead(mtmp);
		}
		pline("Wiped out all %c's.", *buf);
		if(*buf == u.usym) {
			killer = "scroll of genocide";
			u.uhp = -1;
		}
		break;
		}
	case SCR_LIGHT:
		if(!Blind) known = TRUE;
		litroom(!confused);
		break;
	case SCR_TELEPORTATION:
		if(confused)
			level_tele();
		else {
#ifdef QUEST
			int oux = u.ux, ouy = u.uy;
			tele();
			if(dist(oux, ouy) > 100) known = TRUE;
#else /* QUEST */
			int uroom = inroom(u.ux, u.uy);
			tele();
			if(uroom != inroom(u.ux, u.uy)) known = TRUE;
#endif /* QUEST */
		}
		break;
	case SCR_GOLD_DETECTION:
	    /* Unfortunately this code has become slightly less elegant,
	       now that gold and traps no longer are of the same type. */
	    if(confused) {
		struct trap *ttmp;

		if(!ftrap) {
			strange_feeling(scroll, "Your toes stop itching.");
			return(1);
		} else {
			for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
				if(ttmp->tx != u.ux || ttmp->ty != u.uy)
					goto outtrapmap;
			/* only under me - no separate display required */
			pline("Your toes itch!");
			break;
		outtrapmap:
			cls();
			for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
				at(ttmp->tx, ttmp->ty, '$');
			prme();
			pline("You feel very greedy!");
		}
	    } else {
		struct gold *gtmp;

		if(!fgold) {
			strange_feeling(scroll, "You feel materially poor.");
			return(1);
		} else {
			known = TRUE;
			for(gtmp = fgold; gtmp; gtmp = gtmp->ngold)
				if(gtmp->gx != u.ux || gtmp->gy != u.uy)
					goto outgoldmap;
			/* only under me - no separate display required */
			pline("You notice some gold between your feet.");
			break;
		outgoldmap:
			cls();
			for(gtmp = fgold; gtmp; gtmp = gtmp->ngold)
				at(gtmp->gx, gtmp->gy, '$');
			prme();
			pline("You feel very greedy, and sense gold!");
		}
	    }
		/* common sequel */
		more();
		docrt();
		break;
	case SCR_FOOD_DETECTION:
	    {	int ct = 0, ctu = 0;
		struct obj *obj;
		char foodsym = confused ? POTION_SYM : FOOD_SYM;

		for(obj = fobj; obj; obj = obj->nobj)
			if(obj->olet == FOOD_SYM) {
				if(obj->ox == u.ux && obj->oy == u.uy) ctu++;
				else ct++;
			}
		if(!ct && !ctu) {
			strange_feeling(scroll,"Your nose twitches.");
			return(1);
		} else if(!ct) {
			known = TRUE;
			pline("You smell %s close nearby.",
				confused ? "something" : "food");
			
		} else {
			known = TRUE;
			cls();
			for(obj = fobj; obj; obj = obj->nobj)
			    if(obj->olet == foodsym)
				at(obj->ox, obj->oy, FOOD_SYM);
			prme();
			pline("Your nose tingles and you smell %s!",
				confused ? "something" : "food");
			more();
			docrt();
		}
		break;
	    }
	case SCR_IDENTIFY:
		/* known = TRUE; */
		if(confused)
			pline("You identify this as an identify scroll.");
		else
			pline("This is an identify scroll.");
		useup(scroll);
		objects[SCR_IDENTIFY].oc_name_known = 1;
		if(!confused)
		    while(
			!ggetobj("identify", identify, rn2(5) ? 1 : rn2(5))
			&& invent
		    );
		return(1);
	case SCR_MAGIC_MAPPING:
	    {	struct rm *lev;
		int num, zx, zy;

		known = TRUE;
		pline("On this scroll %s a map!",
			confused ? "was" : "is");
		for(zy = 0; zy < ROWNO; zy++)
			for(zx = 0; zx < COLNO; zx++) {
				if(confused && rn2(7)) continue;
				lev = &(levl[zx][zy]);
				if((num = lev->typ) == 0)
					continue;
				if(num == SCORR) {
					lev->typ = CORR;
					lev->scrsym = CORR_SYM;
				} else
				if(num == SDOOR) {
					lev->typ = DOOR;
					lev->scrsym = '+';
					/* do sth in doors ? */
				} else if(lev->seen) continue;
#ifndef QUEST
				if(num != ROOM)
#endif /* QUEST */
				{
				  lev->seen = lev->new = 1;
				  if(lev->scrsym == ' ' || !lev->scrsym)
				    newsym(zx,zy);
				  else
				    on_scr(zx,zy);
				}
			}
		break;
	    }
	case SCR_AMNESIA:
	    {	int zx, zy;

		known = TRUE;
		for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++)
		    if(!confused || rn2(7))
			if(!cansee(zx,zy))
			    levl[zx][zy].seen = 0;
		docrt();
		pline("Thinking of Maud you forget everything else.");
		break;
	    }
	case SCR_FIRE:
	    {	int num;
		struct monst *mtmp;

		known = TRUE;
		if(confused) {
		    pline("The scroll catches fire and you burn your hands.");
		    losehp(1, "scroll of fire");
		} else {
		    pline("The scroll erupts in a tower of flame!");
		    if(Fire_resistance)
			pline("You are uninjured.");
		    else {
			num = rnd(6);
			u.uhpmax -= num;
			losehp(num, "scroll of fire");
		    }
		}
		num = (2*num + 1)/3;
		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
		    if(dist(mtmp->mx,mtmp->my) < 3) {
			mtmp->mhp -= num;
			if(strchr("FY", mtmp->data->mlet))
			    mtmp->mhp -= 3*num;	/* this might well kill 'F's */
			if(mtmp->mhp < 1) {
			    killed(mtmp);
			    break;		/* primitive */
			}
		    }
		}
		break;
	    }
	case SCR_PUNISHMENT:
		known = TRUE;
		if(confused) {
			pline("You feel guilty.");
			break;
		}
		pline("You are being punished for your misbehaviour!");
		if(Punished){
			pline("Your iron ball gets heavier.");
			uball->owt += 15;
			break;
		}
		Punished = INTRINSIC;
		setworn(mkobj_at(CHAIN_SYM, u.ux, u.uy), W_CHAIN);
		setworn(mkobj_at(BALL_SYM, u.ux, u.uy), W_BALL);
		uball->spe = 1;		/* special ball (see save) */
		break;
	default:
		impossible("What weird language is this written in? (%u)",
			scroll->otyp);
	}
Exemple #4
0
bool sbbs_t::logon()
{
	char	str[256],c;
	char 	tmp[512];
	int 	file;
	uint	i,j,mailw;
	long	kmode;
	ulong	totallogons;
	node_t	node;
	struct	tm	tm;

	now=time(NULL);
	if(localtime_r(&now,&tm)==NULL)
		return(false);

	if(!useron.number)
		return(false);

	client.user=useron.alias;
	client_on(client_socket,&client,TRUE /* update */);

#ifdef JAVASCRIPT
	js_create_user_objects();
#endif

	if(useron.rest&FLAG('Q'))
		qwklogon=1;
	if(SYSOP && !(cfg.sys_misc&SM_R_SYSOP))
		return(false);

	if(useron.rest&FLAG('G')) {     /* Guest account */
		useron.misc=(cfg.new_misc&(~ASK_NSCAN));
		useron.rows=0;
		useron.misc&=~(ANSI|RIP|WIP|NO_EXASCII|COLOR|HTML);
		useron.misc|=autoterm;
		if(!(useron.misc&ANSI) && text[AnsiTerminalQ][0] && yesno(text[AnsiTerminalQ]))
			useron.misc|=ANSI;
		if(useron.misc&(RIP|WIP|HTML)
			|| (useron.misc&ANSI && text[ColorTerminalQ][0] && yesno(text[ColorTerminalQ])))
			useron.misc|=COLOR;
		if(text[ExAsciiTerminalQ][0] && !yesno(text[ExAsciiTerminalQ]))
			useron.misc|=NO_EXASCII;
		for(i=0;i<cfg.total_xedits;i++)
			if(!stricmp(cfg.xedit[i]->code,cfg.new_xedit)
				&& chk_ar(cfg.xedit[i]->ar,&useron,&client))
				break;
		if(i<cfg.total_xedits)
			useron.xedit=i+1;
		else
			useron.xedit=0;
		useron.prot=cfg.new_prot;
		useron.shell=cfg.new_shell; 
	}

	if(!chk_ar(cfg.node_ar,&useron,&client)) {
		bputs(text[NoNodeAccess]);
		sprintf(str,"(%04u)  %-25s  Insufficient node access"
			,useron.number,useron.alias);
		logline(LOG_NOTICE,"+!",str);
		return(false); 
	}

	getnodedat(cfg.node_num,&thisnode,1);
	if(thisnode.misc&NODE_LOCK) {
		putnodedat(cfg.node_num,&thisnode);	/* must unlock! */
		if(!SYSOP && !(useron.exempt&FLAG('N'))) {
			bputs(text[NodeLocked]);
			sprintf(str,"(%04u)  %-25s  Locked node logon attempt"
				,useron.number,useron.alias);
			logline(LOG_NOTICE,"+!",str);
			return(false); 
		}
		if(yesno(text[RemoveNodeLockQ])) {
			getnodedat(cfg.node_num,&thisnode,1);
			logline("S-","Removed Node Lock");
			thisnode.misc&=~NODE_LOCK; 
		}
		else
			getnodedat(cfg.node_num,&thisnode,1); 
	}

	if(useron.exempt&FLAG('H'))
		console|=CON_NO_INACT;

	if((useron.exempt&FLAG('Q') && useron.misc&QUIET))
		thisnode.status=NODE_QUIET;
	else
		thisnode.status=NODE_INUSE;
	action=thisnode.action=NODE_LOGN;
	thisnode.connection=node_connection;
	thisnode.misc&=~(NODE_ANON|NODE_INTR|NODE_MSGW|NODE_POFF|NODE_AOFF);
	if(useron.chat&CHAT_NOACT)
		thisnode.misc|=NODE_AOFF;
	if(useron.chat&CHAT_NOPAGE)
		thisnode.misc|=NODE_POFF;
	thisnode.useron=useron.number;
	putnodedat(cfg.node_num,&thisnode);

	getusrsubs();
	getusrdirs();

	if(useron.misc&CURSUB && !(useron.rest&FLAG('G'))) {
		for(i=0;i<usrgrps;i++) {
			for(j=0;j<usrsubs[i];j++) {
				if(!strcmp(cfg.sub[usrsub[i][j]]->code,useron.cursub))
					break; 
			}
			if(j<usrsubs[i]) {
				curgrp=i;
				cursub[i]=j;
				break; 
			} 
		}
		for(i=0;i<usrlibs;i++) {
			for(j=0;j<usrdirs[i];j++)
				if(!strcmp(cfg.dir[usrdir[i][j]]->code,useron.curdir))
					break;
			if(j<usrdirs[i]) {
				curlib=i;
				curdir[i]=j;
				break; 
			} 
		} 
	}


	if(useron.misc&AUTOTERM) {
		useron.misc&=~(ANSI|RIP|WIP|HTML);
		useron.misc|=autoterm; 
	}

	if(!chk_ar(cfg.shell[useron.shell]->ar,&useron,&client)) {
		useron.shell=cfg.new_shell;
		if(!chk_ar(cfg.shell[useron.shell]->ar,&useron,&client)) {
			for(i=0;i<cfg.total_shells;i++)
				if(chk_ar(cfg.shell[i]->ar,&useron,&client))
					break;
			if(i==cfg.total_shells)
				useron.shell=0; 
		} 
	}

	logon_ml=useron.level;
	logontime=time(NULL);
	starttime=logontime;
	useron.logontime=(time32_t)logontime;
	last_ns_time=ns_time=useron.ns_time;
	// ns_time-=(useron.tlast*60); /* file newscan time == last logon time */
	delfiles(cfg.temp_dir,ALLFILES);
	sprintf(str,"%smsgs/n%3.3u.msg",cfg.data_dir,cfg.node_num);
	remove(str);            /* remove any pending node messages */
	sprintf(str,"%smsgs/n%3.3u.ixb",cfg.data_dir,cfg.node_num);
	remove(str);			/* remove any pending node message indices */

	if(!SYSOP && online==ON_REMOTE && !qwklogon) {
		rioctl(IOCM|ABORT);	/* users can't abort anything */
		rioctl(IOCS|ABORT); 
	}

	CLS;
	if(useron.rows)
		rows=useron.rows;
	unixtodstr(&cfg,(time32_t)logontime,str);
	if(!strncmp(str,useron.birth,5) && !(useron.rest&FLAG('Q'))) {
		bputs(text[HappyBirthday]);
		pause();
		CLS;
		user_event(EVENT_BIRTHDAY); 
	}
	useron.ltoday++;

	gettimeleft();
	sprintf(str,"%sfile/%04u.dwn",cfg.data_dir,useron.number);
	batch_add_list(str);
	if(!qwklogon) { 	 /* QWK Nodes don't go through this */

		if(cfg.sys_pwdays
			&& (ulong)logontime>(useron.pwmod+((ulong)cfg.sys_pwdays*24UL*60UL*60UL))) {
			bprintf(text[TimeToChangePw],cfg.sys_pwdays);

			c=0;
			while(c<LEN_PASS) { 				/* Create random password */
				str[c]=sbbs_random(43)+'0';
				if(isalnum(str[c]))
					c++; 
			}
			str[c]=0;
			bprintf(text[YourPasswordIs],str);

			if(cfg.sys_misc&SM_PWEDIT && yesno(text[NewPasswordQ]))
				while(online) {
					bputs(text[NewPassword]);
					getstr(str,LEN_PASS,K_UPPER|K_LINE);
					truncsp(str);
					if(chkpass(str,&useron,true))
						break;
					CRLF; 
				}

			while(online) {
				if(cfg.sys_misc&SM_PWEDIT) {
					CRLF;
					bputs(text[VerifyPassword]); 
				}
				else
					bputs(text[NewUserPasswordVerify]);
				console|=CON_R_ECHOX;
				getstr(tmp,LEN_PASS*2,K_UPPER);
				console&=~(CON_R_ECHOX|CON_L_ECHOX);
				if(strcmp(str,tmp)) {
					bputs(text[Wrong]);
					continue; 
				}
				break; 
			}
			strcpy(useron.pass,str);
			useron.pwmod=time32(NULL);
			putuserrec(&cfg,useron.number,U_PWMOD,8,ultoa((ulong)useron.pwmod,str,16));
			bputs(text[PasswordChanged]);
			pause(); 
		}
		if(useron.ltoday>cfg.level_callsperday[useron.level]
			&& !(useron.exempt&FLAG('L'))) {
			bputs(text[NoMoreLogons]);
			sprintf(str,"(%04u)  %-25s  Out of logons"
				,useron.number,useron.alias);
			logline(LOG_NOTICE,"+!",str);
			hangup();
			return(false); 
		}
		if(useron.rest&FLAG('L') && useron.ltoday>1) {
			bputs(text[R_Logons]);
			sprintf(str,"(%04u)  %-25s  Out of logons"
				,useron.number,useron.alias);
			logline(LOG_NOTICE,"+!",str);
			hangup();
			return(false); 
		}
		kmode=(cfg.uq&UQ_NOEXASC);
		if(!(cfg.uq&UQ_NOUPRLWR))
			kmode|=K_UPRLWR;

		if(!(useron.rest&FLAG('G'))) {
			if(!useron.name[0] && ((cfg.uq&UQ_ALIASES && cfg.uq&UQ_REALNAME)
				|| cfg.uq&UQ_COMPANY))
				while(online) {
					if(cfg.uq&UQ_ALIASES && cfg.uq&UQ_REALNAME)
						bputs(text[EnterYourRealName]);
					else
						bputs(text[EnterYourCompany]);
					getstr(useron.name,LEN_NAME,kmode);
					if(cfg.uq&UQ_ALIASES && cfg.uq&UQ_REALNAME) {
						if(trashcan(useron.name,"name") || !useron.name[0]
							|| !strchr(useron.name,' ')
							|| strchr(useron.name,0xff)
							|| (cfg.uq&UQ_DUPREAL
								&& userdatdupe(useron.number,U_NAME,LEN_NAME
								,useron.name,0,0)))
							bputs(text[YouCantUseThatName]);
						else
							break; 
					}
					else
						break; 
				}
			if(cfg.uq&UQ_HANDLE && !useron.handle[0]) {
				sprintf(useron.handle,"%.*s",LEN_HANDLE,useron.alias);
				while(online) {
					bputs(text[EnterYourHandle]);
					if(!getstr(useron.handle,LEN_HANDLE
						,K_LINE|K_EDIT|K_AUTODEL|(cfg.uq&UQ_NOEXASC))
						|| strchr(useron.handle,0xff)
						|| (cfg.uq&UQ_DUPHAND
							&& userdatdupe(useron.number,U_HANDLE,LEN_HANDLE
							,useron.handle,0,0))
						|| trashcan(useron.handle,"name"))
						bputs(text[YouCantUseThatName]);
					else
						break; 
				} 
			}
			if(cfg.uq&UQ_LOCATION && !useron.location[0])
				while(online) {
					bputs(text[EnterYourCityState]);
					if(getstr(useron.location,LEN_LOCATION,kmode))
						break; 
				}
			if(cfg.uq&UQ_ADDRESS && !useron.address[0])
				while(online) {
					bputs(text[EnterYourAddress]);
					if(getstr(useron.address,LEN_ADDRESS,kmode))
						break; 
				}
			if(cfg.uq&UQ_ADDRESS && !useron.zipcode[0])
				while(online) {
					bputs(text[EnterYourZipCode]);
					if(getstr(useron.zipcode,LEN_ZIPCODE,K_UPPER|(cfg.uq&UQ_NOEXASC)))
						break; 
				}
			if(cfg.uq&UQ_PHONE && !useron.phone[0]) {
				if(text[CallingFromNorthAmericaQ][0])
					i=yesno(text[CallingFromNorthAmericaQ]);
				else
					i=0;
				while(online) {
					bputs(text[EnterYourPhoneNumber]);
					if(i) {
						if(gettmplt(useron.phone,cfg.sys_phonefmt
							,K_LINE|(cfg.uq&UQ_NOEXASC))<strlen(cfg.sys_phonefmt))
							 continue; 
					} else {
						if(getstr(useron.phone,LEN_PHONE
							,K_UPPER|(cfg.uq&UQ_NOEXASC))<5)
							continue; 
					}
					if(!trashcan(useron.phone,"phone"))
						break; 
				} 
			}
			if(!(cfg.uq&UQ_NONETMAIL) && !useron.netmail[0]) {
				while(online) {
					bputs(text[EnterNetMailAddress]);
					if(getstr(useron.netmail,LEN_NETMAIL,K_EDIT|K_AUTODEL|K_LINE)
						&& !trashcan(useron.netmail,"email"))
						break;
				}
				if(useron.netmail[0] && cfg.sys_misc&SM_FWDTONET && !noyes(text[ForwardMailQ]))
					useron.misc|=NETMAIL;
				else 
					useron.misc&=~NETMAIL;
			}
			if(cfg.new_sif[0]) {
				sprintf(str,"%suser/%4.4u.dat",cfg.data_dir,useron.number);
				if(flength(str)<1L)
					create_sif_dat(cfg.new_sif,str); 
			} 
		}
	}	
	if(!online) {
		sprintf(str,"(%04u)  %-25s  Unsuccessful logon"
			,useron.number,useron.alias);
		logline(LOG_NOTICE,"+!",str);
		return(false); 
	}
	SAFECOPY(useron.modem,connection);
	useron.logons++;
	putuserdat(&cfg,&useron);
	getmsgptrs();
	sys_status|=SS_USERON;          /* moved from further down */

	if(useron.rest&FLAG('Q')) {
		sprintf(str,"(%04u)  %-25s  QWK Network Connection"
			,useron.number,useron.alias);
		logline("++",str);
		return(true); 
	}

	/********************/
	/* SUCCESSFUL LOGON */
	/********************/
	totallogons=logonstats();
	sprintf(str,"(%04u)  %-25s  Logon %lu - %u"
		,useron.number,useron.alias,totallogons,useron.ltoday);
	logline("++",str);

	if(!qwklogon && cfg.logon_mod[0])
		exec_bin(cfg.logon_mod,&main_csi);

	if(thisnode.status!=NODE_QUIET && (!REALSYSOP || cfg.sys_misc&SM_SYSSTAT)) {
		sprintf(str,"%slogon.lst",cfg.data_dir);
		if((file=nopen(str,O_WRONLY|O_CREAT|O_APPEND))==-1) {
			errormsg(WHERE,ERR_OPEN,str,O_RDWR|O_CREAT|O_APPEND);
			return(false); 
		}
		getuserrec(&cfg,useron.number,U_NOTE,LEN_NOTE,useron.note);
		getuserrec(&cfg,useron.number,U_LOCATION,LEN_LOCATION,useron.location);
		sprintf(str,text[LastFewCallersFmt],cfg.node_num
			,totallogons,useron.alias
			,cfg.sys_misc&SM_LISTLOC ? useron.location : useron.note
			,tm.tm_hour,tm.tm_min
			,connection,useron.ltoday > 999 ? 999 : useron.ltoday);
		write(file,str,strlen(str));
		close(file); 
	}

	if(cfg.sys_logon[0])				/* execute system logon event */
		external(cmdstr(cfg.sys_logon,nulstr,nulstr,NULL),EX_STDOUT); /* EX_SH */

	if(qwklogon)
		return(true);

	sys_status|=SS_PAUSEON;	/* always force pause on during this section */
	mailw=getmail(&cfg,useron.number,0);

	if(!(cfg.sys_misc&SM_NOSYSINFO)) {
		bprintf(text[SiSysName],cfg.sys_name);
		//bprintf(text[SiNodeNumberName],cfg.node_num,cfg.node_name);
		bprintf(text[LiUserNumberName],useron.number,useron.alias);
		bprintf(text[LiLogonsToday],useron.ltoday
			,cfg.level_callsperday[useron.level]);
		bprintf(text[LiTimeonToday],useron.ttoday
			,cfg.level_timeperday[useron.level]+useron.min);
		bprintf(text[LiMailWaiting],mailw);
		strcpy(str,text[LiSysopIs]);
		if(startup->options&BBS_OPT_SYSOP_AVAILABLE 
			|| (cfg.sys_chat_ar[0] && chk_ar(cfg.sys_chat_ar,&useron,&client)))
			strcat(str,text[LiSysopAvailable]);
		else
			strcat(str,text[LiSysopNotAvailable]);
		bprintf("%s\r\n\r\n",str);
	}

	if(sys_status&SS_EVENT)
		bprintf(text[ReducedTime],timestr(event_time));
	getnodedat(cfg.node_num,&thisnode,1);
	thisnode.misc&=~(NODE_AOFF|NODE_POFF);
	if(useron.chat&CHAT_NOACT)
		thisnode.misc|=NODE_AOFF;
	if(useron.chat&CHAT_NOPAGE)
		thisnode.misc|=NODE_POFF;
	putnodedat(cfg.node_num,&thisnode);

	getsmsg(useron.number); 		/* Moved from further down */
	SYNC;
	c=0;
	for(i=1;i<=cfg.sys_nodes;i++)
		if(i!=cfg.node_num) {
			getnodedat(i,&node,0);
			if(!(cfg.sys_misc&SM_NONODELIST)
				&& (node.status==NODE_INUSE
					|| ((node.status==NODE_QUIET || node.errors) && SYSOP))) {
				if(!c)
					bputs(text[NodeLstHdr]);
				printnodedat(i,&node);
				c=1; 
			}
			if(node.status==NODE_INUSE && i!=cfg.node_num && node.useron==useron.number
				&& !SYSOP && !(useron.exempt&FLAG('G'))) {
				SAFEPRINTF2(str,"(%04u)  %-25s  On two nodes at the same time"
					,useron.number,useron.alias);
				logline(LOG_NOTICE,"+!",str);
				bputs(text[UserOnTwoNodes]);
				hangup();
				return(false); 
			}
			if(thisnode.status!=NODE_QUIET
				&& (node.status==NODE_INUSE || node.status==NODE_QUIET)
				&& !(node.misc&NODE_AOFF) && node.useron!=useron.number) {
				sprintf(str,text[NodeLoggedOnAtNbps]
					,cfg.node_num
					,thisnode.misc&NODE_ANON ? text[UNKNOWN_USER] : useron.alias
					,connection);
				putnmsg(&cfg,i,str); 
			} 
		}

	if(cfg.sys_exp_warn && useron.expire && useron.expire>now /* Warn user of coming */
		&& (useron.expire-now)/(1440L*60L)<=cfg.sys_exp_warn) /* expiration */
		bprintf(text[AccountWillExpireInNDays],(useron.expire-now)/(1440L*60L));

	if(criterrs && SYSOP)
		bprintf(text[CriticalErrors],criterrs);
	if((i=getuserxfers(0,useron.number,0))!=0)
		bprintf(text[UserXferForYou],i,i>1 ? "s" : nulstr); 
	if((i=getuserxfers(useron.number,0,0))!=0)
		bprintf(text[UnreceivedUserXfer],i,i>1 ? "s" : nulstr);
	SYNC;
	sys_status&=~SS_PAUSEON;	/* Turn off the pause override flag */
	if(online==ON_REMOTE)
		rioctl(IOSM|ABORT);		/* Turn abort ability on */
	if(text[ReadYourMailNowQ][0] && mailw) {
		if(yesno(text[ReadYourMailNowQ]))
			readmail(useron.number,MAIL_YOUR); 
	}
	if(usrgrps && useron.misc&ASK_NSCAN && text[NScanAllGrpsQ][0] && yesno(text[NScanAllGrpsQ]))
		scanallsubs(SCAN_NEW);
	if(usrgrps && useron.misc&ASK_SSCAN && text[SScanAllGrpsQ][0] && yesno(text[SScanAllGrpsQ]))
		scanallsubs(SCAN_TOYOU);
	return(true);
}
Exemple #5
0
namespace wfc {

namespace {
static CursesWindow* CreateBoxedWindow(const std::string& title, int nlines, int ncols, int y, int x) {
  unique_ptr<CursesWindow> window(new CursesWindow(out->window(), out->color_scheme(), nlines, ncols, y, x));
  window->SetColor(SchemeId::WINDOW_BOX);
  window->Box(0, 0);
  window->SetTitle(title);
  window->SetColor(SchemeId::WINDOW_TEXT);
  return window.release();
}
}

auto noop = [](){};

static void wfc_command(int instance_location_id, std::function<void()> f, 
    std::function<void()> f2 = noop, std::function<void()> f3 = noop, std::function<void()> f4 = noop) {
  session()->reset_local_io(new CursesLocalIO(out->window()->GetMaxY()));

  wfc_cls();
  write_inst(instance_location_id, 0, INST_FLAGS_NONE);
  f();
  f2();
  f3();
  f4();
  write_inst(INST_LOC_WFC, 0, INST_FLAGS_NONE);
}

auto send_email_f = []() {
  session()->usernum = 1;
  bout << "|#1Send Email:";
  send_email();
  session()->WriteCurrentUser(1);
};

auto view_sysop_log_f = []() {
  unique_ptr<WStatus> pStatus(session()->status_manager()->GetStatus());
  const string sysop_log_file = GetSysopLogFileName(date());
  print_local_file(sysop_log_file);
};

auto view_yesterday_sysop_log_f = []() {
  unique_ptr<WStatus> pStatus(session()->status_manager()->GetStatus());
  print_local_file(pStatus->GetLogFileName(1));
};

auto read_mail_f = []() {
  session()->usernum = 1;
  readmail(0);
  session()->WriteCurrentUser(1);
};

auto getkey_f = []() { getkey(); };

ControlCenter::ControlCenter() {
  const string title = StringPrintf("WWIV %s%s Server.", wwiv_version, beta_version);
  CursesIO::Init(title);
  // take ownership of out.
  out_scope_.reset(out);
  session()->SetWfcStatus(0);
}

ControlCenter::~ControlCenter() {}

static void DrawCommands(CursesWindow* commands) {
  commands->SetColor(SchemeId::WINDOW_TEXT);
  commands->PutsXY(1, 1, "[B]oardEdit [C]hainEdit");
  commands->PutsXY(1, 2, "[D]irEdit [E]mail [G]-FileEdit");
  commands->PutsXY(1, 3, "[I]nit Voting Data  [J] ConfEdit");
  commands->PutsXY(1, 4, "Sysop[L]og  Read [M]ail  [N]etLog");
  commands->PutsXY(1, 5, "[P]ending Net Data [/] Net Callout");
  commands->PutsXY(1, 6, "[R]ead all email [S]ystem Status");
  commands->PutsXY(1, 7, "[U]serEdit [Y]-Log [Z]-Log");
}

static void DrawStatus(CursesWindow* statusWindow) {
  statusWindow->SetColor(SchemeId::WINDOW_TEXT);
  statusWindow->PutsXY(2, 1, "Today:");
  statusWindow->PutsXY(2, 2, "Calls: XXXXX Minutes: XXXXX");
  statusWindow->PutsXY(2, 3, "M: XXX L: XXX E: XXX F: XXX FW: XXX");
  statusWindow->PutsXY(2, 4, "Totals:");
  statusWindow->PutsXY(2, 5, "Users: XXXXX Calls: XXXXX");
  statusWindow->PutsXY(2, 6, "Last User:"******"XXXXXXXXXXXXXXXXXXXXXXXXXX");
}

static string GetLastUserName(int inst_num) {
  instancerec ir;
  get_inst_info(inst_num, &ir);

  if (ir.flags & INST_FLAGS_ONLINE) {
    return session()->names()->UserName(ir.user);
  } else {
    return "Nobody";
  }

}

static void UpdateStatus(CursesWindow* statusWindow) {
  statusWindow->SetColor(SchemeId::WINDOW_DATA);
  std::unique_ptr<WStatus> pStatus(session()->status_manager()->GetStatus());

  statusWindow->PrintfXY(9, 2, "%-5d", pStatus->GetNumCallsToday());
  statusWindow->PrintfXY(24, 2, "%-5d", pStatus->GetMinutesActiveToday());

  statusWindow->PrintfXY(5, 3, "%-3u", pStatus->GetNumMessagesPostedToday());
  statusWindow->PrintfXY(12, 3, "%-3u", pStatus->GetNumLocalPosts());
  statusWindow->PrintfXY(19, 3, "%-3u", pStatus->GetNumEmailSentToday());
  statusWindow->PrintfXY(26, 3, "%-3u", pStatus->GetNumFeedbackSentToday());

  fwaiting = session()->user()->GetNumMailWaiting();
  statusWindow->PrintfXY(34, 3, "%-3d", fwaiting);

  statusWindow->PrintfXY(9, 5, "%-5d", pStatus->GetNumUsers());
  statusWindow->PrintfXY(22, 5, "%-6lu", pStatus->GetCallerNumber());

  // TODO(rushfan): Need to know the last used node number
  // then call GetLastUserName.
  //  statusWindow->PutsXY(2, 7, "XXXXXXXXXXXXXXXXXXXXXXXXXX");
}

static void CleanNetIfNeeded() {
  static int mult_time = 0;
  if (session()->IsCleanNetNeeded() || std::abs(timer1() - mult_time) > 1000L) {
    cleanup_net();
    mult_time = timer1();
  }
}

static void RunEventsIfNeeded() {
  unique_ptr<WStatus> pStatus(session()->status_manager()->GetStatus());
  if (!IsEquals(date(), pStatus->GetLastDate())) {
    if ((session()->GetBeginDayNodeNumber() == 0) 
        || (session()->instance_number() == session()->GetBeginDayNodeNumber())) {
      cleanup_events();
      beginday(true);
    }
  }

  if (!do_event) {
    check_event();
  }

  while (do_event) {
    run_event(do_event - 1);
    check_event();
  }

  session()->SetCurrentSpeed("KB");
  static time_t last_time_c = 0;
  time_t lCurrentTime = time(nullptr);
  if ((((rand() % 8000) == 0) || (lCurrentTime - last_time_c > 1200)) && net_sysnum) {
    lCurrentTime = last_time_c;
    attempt_callout();
  }
}

void ControlCenter::Initialize() {
  // Initialization steps that have to happen before we
  // have a functional WFC system. This also supposes that
  // session()->InitializeBBS has been called.
  out->Cls(ACS_CKBOARD);
  const int logs_y_padding = 1;
  const int logs_start = 11;
  const int logs_length = out->window()->GetMaxY() - logs_start - logs_y_padding;
  log_.reset(new WfcLog(logs_length - 2));
  commands_.reset(CreateBoxedWindow("Commands", 9, 38, 1, 1));
  status_.reset(CreateBoxedWindow("Status", 9, 39, 1, 40));
  logs_.reset(CreateBoxedWindow("Logs", logs_length, 78, 11, 1));

  DrawCommands(commands_.get());
  DrawStatus(status_.get());
  vector<HelpItem> help_items0 = { { "?", "All Commands" },};
  vector<HelpItem> help_items1 = { {"Q", "Quit" } };
  out->footer()->ShowHelpItems(0, help_items0);
  out->footer()->ShowHelpItems(1, help_items1);

  session()->ReadCurrentUser(1);
  read_qscn(1, qsc, false);
  session()->ResetEffectiveSl();
  session()->usernum = 1;

  fwaiting = session()->user()->GetNumMailWaiting();
  session()->SetWfcStatus(1);
}

void ControlCenter::Run() {
  Initialize();
  bool need_refresh = false;
  for (bool done = false; !done;) {
    if (need_refresh) {
      // refresh the window since we call endwin before invoking bbs code.
      RefreshAll();
      need_refresh = false;
    }

    wtimeout(commands_->window(), 500);
    int key = commands_->GetChar();
    if (key == ERR) {
      // we have a timeout. process other events
      need_refresh = false;
      UpdateLog();
      UpdateStatus(status_.get());
      CleanNetIfNeeded();
      RunEventsIfNeeded();
      continue;
    }
    need_refresh = true;
    session()->SetWfcStatus(2);
    // Call endwin since we'll be out of curses IO
    endwin();
    switch (toupper(key)) {
    case 'B': wfc_command(INST_LOC_BOARDEDIT, boardedit, cleanup_net); log_->Put("Ran BoardEdit"); break;
    case 'C': wfc_command(INST_LOC_CHAINEDIT, chainedit); log_->Put("Ran ChainEdit"); break;
    case 'D': wfc_command(INST_LOC_DIREDIT, dlboardedit); log_->Put("Ran DirEdit"); break;
    case 'E': wfc_command(INST_LOC_EMAIL, send_email_f, cleanup_net); break;
    case 'G': wfc_command(INST_LOC_GFILEEDIT, gfileedit); break;
    case 'H': wfc_command(INST_LOC_EVENTEDIT, eventedit); break;
    case 'I': wfc_command(INST_LOC_VOTEEDIT, ivotes); break;
    case 'J': wfc_command(INST_LOC_CONFEDIT, edit_confs); break;
    case 'L': wfc_command(INST_LOC_WFC, view_sysop_log_f); break;
    case 'M': wfc_command(INST_LOC_EMAIL, read_mail_f, cleanup_net); break;
    case 'N': wfc_command(INST_LOC_WFC, []() { print_local_file("net.log"); }); break;
    case 'P': wfc_command(INST_LOC_WFC, print_pending_list); break;
    case 'R': wfc_command(INST_LOC_MAILR, mailr); break;
    case 'S': wfc_command(INST_LOC_WFC, prstatus, getkey_f); break;
    case 'U': wfc_command(INST_LOC_UEDIT, []() { uedit(1, UEDIT_NONE); } ); break;
    case 'Y': wfc_command(INST_LOC_WFC, view_yesterday_sysop_log_f); break;
    case 'Z': wfc_command(INST_LOC_WFC, zlog, getkey_f); break;
    case 'Q': done=true; break;
    // ansicallout doesn't work due to arrow keys and other drawing problems with it under curses.
    // case '/': wfc_command(INST_LOC_NET, []() { force_callout(0); }); log_->Put("Ran Network Callout"); break;
    case ' ': log_->Put("Not Implemented Yet"); break; 
    }
    TouchAll();
  }
}

void ControlCenter::TouchAll() {
  out->window()->TouchWin();
  commands_->TouchWin();
  status_->TouchWin();
  logs_->TouchWin();
}

void ControlCenter::RefreshAll() {
  out->window()->Refresh();
  commands_->Refresh();
  status_->Refresh();
  logs_->Refresh();
  UpdateStatus(status_.get());
}

void ControlCenter::UpdateLog() {
  if (!log_->dirty()) {
    return;
  }

  vector<string> lines;
  if (!log_->Get(lines)) {
    return;
  }

  int start = 1;
  const int width = logs_->GetMaxX() - 4;
  for (const auto& line : lines) {
    logs_->PutsXY(1, start, line);
    logs_->PutsXY(1 + line.size(), start, string(width - line.size(), ' '));
    start++;
  }
}

}