scfgchat.c 24.4 KB
Newer Older
1 2 3 4
/****************************************************************************
 * @format.tab-size 4		(Plain Text/Source Code File Header)			*
 * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
 *																			*
rswindell's avatar
rswindell committed
5
 * Copyright Rob Swindell - http://www.synchro.net/copyright.html			*
6 7 8 9 10 11 12 13 14 15 16 17 18
 *																			*
 * This program is free software; you can redistribute it and/or			*
 * modify it under the terms of the GNU General Public License				*
 * as published by the Free Software Foundation; either version 2			*
 * of the License, or (at your option) any later version.					*
 * See the GNU General Public License for more details: gpl.txt or			*
 * http://www.fsf.org/copyleft/gpl.html										*
 *																			*
 * For Synchronet coding style and modification guidelines, see				*
 * http://www.synchro.net/source.html										*
 *																			*
 * Note: If this box doesn't appear square, then you need to fix your tabs.	*
 ****************************************************************************/
rswindell's avatar
rswindell committed
19 20 21 22 23 24 25 26 27

#include "scfg.h"

void page_cfg()
{
	static int dflt,bar;
	char str[81],done=0;
	int j,k;
	uint i;
28
	uint u;
rswindell's avatar
rswindell committed
29 30
	static page_t savpage;

31 32 33 34 35 36 37 38 39 40 41
	while(1) {
		for(i=0;i<cfg.total_pages && i<MAX_OPTS;i++)
			sprintf(opt[i],"%-40.40s %-.20s",cfg.page[i]->cmd,cfg.page[i]->arstr);
		opt[i][0]=0;
		j=WIN_ACT|WIN_SAV|WIN_RHT|WIN_BOT;
		if(cfg.total_pages)
			j|=WIN_DEL|WIN_COPY|WIN_CUT;
		if(cfg.total_pages<MAX_OPTS)
			j|=WIN_INS|WIN_INSACT|WIN_XTR;
		if(savpage.cmd[0])
			j|=WIN_PASTE;
42
		uifc.helpbuf=
43 44 45 46 47
			"`External Sysop Chat Pagers:`\n"
			"\n"
			"This is a list of the configured external sysop chat pagers.\n"
			"\n"
			"To add a pager, select the desired location and hit ~ INS ~.\n"
48
			"\n"
49 50 51
			"To delete a pager, select it and hit ~ DEL ~.\n"
			"\n"
			"To configure a pager, select it and hit ~ ENTER ~.\n"
52
		;
53 54 55 56 57 58 59 60 61 62 63
		i=uifc.list(j,0,0,45,&dflt,&bar,"External Sysop Chat Pagers",opt);
		if((signed)i==-1)
			return;
		int msk = i & MSK_ON;
		i &= MSK_OFF;
		if (msk == MSK_INS) {
			sprintf(str,"%%!tone +chatpage.ton");
			uifc.helpbuf=
				"`External Chat Pager Command Line:`\n"
				"\n"
				"This is the command line to execute for this external chat pager.\n"
64
				SCFG_CMDLINE_PREFIX_HELP
65
				SCFG_CMDLINE_SPEC_HELP
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
			;
			if(uifc.input(WIN_MID|WIN_SAV,0,0,"Command Line",str,50
				,K_EDIT)<1)
				continue;
			if((cfg.page=(page_t **)realloc(cfg.page,sizeof(page_t *)*(cfg.total_pages+1)))
				==NULL) {
				errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_pages+1);
				cfg.total_pages=0;
				bail(1);
				continue; 
			}
			if(cfg.total_pages)
				for(u=cfg.total_pages;u>i;u--)
					cfg.page[u]=cfg.page[u-1];
			if((cfg.page[i]=(page_t *)malloc(sizeof(page_t)))==NULL) {
				errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(page_t));
				continue; 
			}
			memset((page_t *)cfg.page[i],0,sizeof(page_t));
85
			SAFECOPY(cfg.page[i]->cmd,str);
86 87 88
			cfg.total_pages++;
			uifc.changes=1;
			continue; 
89
		}
90 91 92 93 94 95 96 97
		if (msk == MSK_DEL || msk == MSK_CUT) {
			if(msk == MSK_CUT)
				savpage = *cfg.page[i];
			free(cfg.page[i]);
			cfg.total_pages--;
			for(j=i;j<cfg.total_pages;j++)
				cfg.page[j]=cfg.page[j+1];
			uifc.changes=1;
98 99
			continue; 
		}
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
		if (msk == MSK_COPY) {
			savpage=*cfg.page[i];
			continue; 
		}
		if (msk == MSK_PASTE) {
			*cfg.page[i]=savpage;
			uifc.changes=1;
			continue; 
		}
		if (msk != 0)
			continue;
		j=0;
		done=0;
		while(!done) {
			k=0;
115 116
			sprintf(opt[k++],"%-27.27s%s","Command Line",cfg.page[i]->cmd);
			sprintf(opt[k++],"%-27.27s%s","Access Requirements",cfg.page[i]->arstr);
117
			sprintf(opt[k++],"%-27.27s%s","I/O Method", io_method(cfg.page[i]->misc));
118 119 120 121
			sprintf(opt[k++],"%-27.27s%s","Native Executable"
				,cfg.page[i]->misc&XTRN_NATIVE ? "Yes" : "No");
			sprintf(opt[k++],"%-27.27s%s","Use Shell to Execute"
				,cfg.page[i]->misc&XTRN_SH ? "Yes" : "No");
122 123 124 125 126 127
			opt[k][0]=0;
			sprintf(str,"Sysop Chat Pager #%d",i+1);
			switch(uifc.list(WIN_ACT|WIN_MID|WIN_SAV,0,0,60,&j,0,str,opt)) {
				case -1:
					done=1;
					break;
128
				case 0:
129 130 131 132
					uifc.helpbuf=
						"`External Chat Pager Command Line:`\n"
						"\n"
						"This is the command line to execute for this external chat pager.\n"
133
						SCFG_CMDLINE_PREFIX_HELP
134
						SCFG_CMDLINE_SPEC_HELP
135
					;
136
					SAFECOPY(str,cfg.page[i]->cmd);
137 138
					if(!uifc.input(WIN_MID|WIN_SAV,0,10,"Command Line"
						,cfg.page[i]->cmd,sizeof(cfg.page[i]->cmd)-1,K_EDIT))
139
						SAFECOPY(cfg.page[i]->cmd,str);
140 141
					break;
				case 1:
142
					getar(str,cfg.page[i]->arstr);
143 144
					break;
				case 2:
145
					choose_io_method(&cfg.page[i]->misc);
146
					break;
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
				case 3:
					k=(cfg.page[i]->misc&XTRN_NATIVE) ? 0:1;
					uifc.helpbuf=
						"`Native Executable:`\n"
						"\n"
						"If this online program is a native (e.g. non-DOS) executable,\n"
						"set this option to `Yes`.\n"
					;
					k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
						,"Native",uifcYesNoOpts);
					if(!k && !(cfg.page[i]->misc&XTRN_NATIVE)) {
						cfg.page[i]->misc|=XTRN_NATIVE;
						uifc.changes=TRUE; 
					}
					else if(k==1 && (cfg.page[i]->misc&XTRN_NATIVE)) {
						cfg.page[i]->misc&=~XTRN_NATIVE;
						uifc.changes=TRUE; 
					}
					break;
				case 4:
					k=(cfg.page[i]->misc&XTRN_SH) ? 0:1;
					uifc.helpbuf=
						"`Use Shell to Execute Command:`\n"
						"\n"
						"If this command-line requires the system command shell to execute, (Unix\n"
						"shell script or DOS batch file), set this option to ~Yes~.\n"
					;
					k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
						,"Use Shell",uifcYesNoOpts);
					if(!k && !(cfg.page[i]->misc&XTRN_SH)) {
						cfg.page[i]->misc|=XTRN_SH;
						uifc.changes=TRUE; 
					}
					else if(k==1 && (cfg.page[i]->misc&XTRN_SH)) {
						cfg.page[i]->misc&=~XTRN_SH;
						uifc.changes=TRUE; 
					}
					break;

186 187 188
			} 
		} 
	}
rswindell's avatar
rswindell committed
189 190 191 192 193
}

void chan_cfg()
{
	static int chan_dflt,chan_bar,opt_dflt;
194
	char str[128],code[128],done=0;
rswindell's avatar
rswindell committed
195
	int j,k;
196
	uint i,u;
rswindell's avatar
rswindell committed
197 198
	static chan_t savchan;

199 200 201 202 203 204 205 206 207 208 209
	while(1) {
		for(i=0;i<cfg.total_chans && i<MAX_OPTS;i++)
			sprintf(opt[i],"%-25s",cfg.chan[i]->name);
		opt[i][0]=0;
		j=WIN_ACT|WIN_SAV|WIN_BOT|WIN_RHT;
		if(cfg.total_chans)
			j|=WIN_DEL|WIN_COPY|WIN_CUT;
		if(cfg.total_chans<MAX_OPTS)
			j|=WIN_INS|WIN_INSACT|WIN_XTR;
		if(savchan.name[0])
			j|=WIN_PASTE;
210
		uifc.helpbuf=
211
			"`Multinode Chat Channels:`\n"
212
			"\n"
213 214 215 216
			"This is a list of the configured multinode chat channels.\n"
			"\n"
			"To add a channel, select the desired location with the arrow keys and\n"
			"hit ~ INS ~.\n"
217
			"\n"
218 219 220
			"To delete a channel, select it with the arrow keys and hit ~ DEL ~.\n"
			"\n"
			"To configure a channel, select it with the arrow keys and hit ~ ENTER ~.\n"
221
		;
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
		i=uifc.list(j,0,0,45,&chan_dflt,&chan_bar,"Multinode Chat Channels",opt);
		if((signed)i==-1)
			return;
		int msk = i & MSK_ON;
		i &= MSK_OFF;
		if (msk == MSK_INS) {
			strcpy(str,"Open");
			uifc.helpbuf=
				"`Channel Name:`\n"
				"\n"
				"This is the name or description of the chat channel.\n"
			;
			if(uifc.input(WIN_MID|WIN_SAV,0,0,"Chat Channel Name",str,25
				,K_EDIT)<1)
				continue;
			SAFECOPY(code,str);
			prep_code(code,/* prefix: */NULL);
			uifc.helpbuf=
				"`Chat Channel Internal Code:`\n"
				"\n"
				"Every chat channel must have its own unique code for Synchronet to refer\n"
				"to it internally. This code is usually an abbreviation of the chat\n"
				"channel name.\n"
			;
			if(uifc.input(WIN_MID|WIN_SAV,0,0,"Internal Code"
				,code,LEN_CODE,K_EDIT|K_UPPER)<1)
				continue;
			if(!code_ok(code)) {
				uifc.helpbuf=invalid_code;
251
				uifc.msg(strInvalidCode);
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
				uifc.helpbuf=0;
				continue; 
			}
			if((cfg.chan=(chan_t **)realloc(cfg.chan,sizeof(chan_t *)*(cfg.total_chans+1)))
				==NULL) {
				errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_chans+1);
				cfg.total_chans=0;
				bail(1);
				continue; 
			}
			if(cfg.total_chans)
				for(u=cfg.total_chans;u>i;u--)
					cfg.chan[u]=cfg.chan[u-1];
			if((cfg.chan[i]=(chan_t *)malloc(sizeof(chan_t)))==NULL) {
				errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(chan_t));
				continue; 
			}
			memset((chan_t *)cfg.chan[i],0,sizeof(chan_t));
270 271
			SAFECOPY(cfg.chan[i]->name,str);
			SAFECOPY(cfg.chan[i]->code,code);
272 273 274
			cfg.total_chans++;
			uifc.changes=1;
			continue; 
275
		}
276 277 278 279 280 281 282 283 284
		if (msk == MSK_DEL || msk == MSK_CUT) {
			if(msk == MSK_CUT)
				savchan = *cfg.chan[i];
			free(cfg.chan[i]);
			cfg.total_chans--;
			for(j=i;j<cfg.total_chans;j++)
				cfg.chan[j]=cfg.chan[j+1];
			uifc.changes=1;
			continue; 
285
		}
286 287
		if (msk == MSK_COPY) {
			savchan=*cfg.chan[i];
288 289
			continue; 
		}
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
		if (msk == MSK_PASTE) {
			*cfg.chan[i]=savchan;
			uifc.changes=1;
			continue; 
		}
		if (msk != 0)
			continue;
		j=0;
		done=0;
		while(!done) {
			k=0;
			sprintf(opt[k++],"%-27.27s%s","Name",cfg.chan[i]->name);
			sprintf(opt[k++],"%-27.27s%s","Internal Code",cfg.chan[i]->code);
			sprintf(opt[k++],"%-27.27s%"PRIu32,"Cost in Credits",cfg.chan[i]->cost);
			sprintf(opt[k++],"%-27.27s%.40s","Access Requirements"
				,cfg.chan[i]->arstr);
			sprintf(opt[k++],"%-27.27s%s","Password Protection"
				,cfg.chan[i]->misc&CHAN_PW ? "Yes" : "No");
			sprintf(opt[k++],"%-27.27s%s","Guru Joins When Empty"
				,cfg.chan[i]->misc&CHAN_GURU ? "Yes" : "No");
			sprintf(opt[k++],"%-27.27s%s","Channel Guru"
				,cfg.chan[i]->guru<cfg.total_gurus ? cfg.guru[cfg.chan[i]->guru]->name : "");
			sprintf(opt[k++],"%-27.27s%s","Channel Action Set"
				,cfg.actset[cfg.chan[i]->actset]->name);
			opt[k][0]=0;
			uifc.helpbuf=
				"`Chat Channel Configuration:`\n"
				"\n"
				"This menu is for configuring the selected chat channel.\n"
			;
			sprintf(str,"%s Chat Channel",cfg.chan[i]->name);
			switch(uifc.list(WIN_ACT|WIN_MID|WIN_SAV,0,0,60,&opt_dflt,0,str,opt)) {
				case -1:
					done=1;
					break;
				case 0:
					uifc.helpbuf=
						"`Chat Channel Name:`\n"
						"\n"
						"This is the name or description of the chat channel.\n"
					;
331
					SAFECOPY(str,cfg.chan[i]->name);
332 333
					if(!uifc.input(WIN_MID|WIN_SAV,0,10,"Chat Channel Name"
						,cfg.chan[i]->name,sizeof(cfg.chan[i]->name)-1,K_EDIT))
334
						SAFECOPY(cfg.chan[i]->name,str);
335 336 337 338 339 340 341 342 343
					break;
				case 1:
					uifc.helpbuf=
						"`Chat Channel Internal Code:`\n"
						"\n"
						"Every chat channel must have its own unique code for Synchronet to refer\n"
						"to it internally. This code is usually an abbreviation of the chat\n"
						"channel name.\n"
					;
344
					SAFECOPY(str,cfg.chan[i]->code);
345 346 347 348
					if(!uifc.input(WIN_MID|WIN_SAV,0,10,"Internal Code"
						,str,LEN_CODE,K_UPPER|K_EDIT))
						break;
					if(code_ok(str))
349
						SAFECOPY(cfg.chan[i]->code,str);
350 351
					else {
						uifc.helpbuf=invalid_code;
352
						uifc.msg(strInvalidCode);
353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371
						uifc.helpbuf=0; 
					}
					break;
				case 2:
					ultoa(cfg.chan[i]->cost,str,10);
					uifc.helpbuf=
						"`Chat Channel Cost to Join:`\n"
						"\n"
						"If you want users to be charged credits to join this chat channel, set\n"
						"this value to the number of credits to charge. If you want this channel\n"
						"to be free, set this value to `0`.\n"
					;
					uifc.input(WIN_MID|WIN_SAV,0,0,"Cost to Join (in Credits)"
						,str,10,K_EDIT|K_NUMBER);
					cfg.chan[i]->cost=atol(str);
					break;
				case 3:
					sprintf(str,"%s Chat Channel",cfg.chan[i]->name);
					getar(str,cfg.chan[i]->arstr);
rswindell's avatar
rswindell committed
372
					break;
373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391
				case 4:
					k=1;
					uifc.helpbuf=
						"`Allow Channel to be Password Protected:`\n"
						"\n"
						"If you want to allow the first user to join this channel to password\n"
						"protect it, set this option to `Yes`.\n"
					;
					k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
						,"Allow Channel to be Password Protected"
						,uifcYesNoOpts);
					if(!k && !(cfg.chan[i]->misc&CHAN_PW)) {
						cfg.chan[i]->misc|=CHAN_PW;
						uifc.changes=1; 
					}
					else if(k==1 && cfg.chan[i]->misc&CHAN_PW) {
						cfg.chan[i]->misc&=~CHAN_PW;
						uifc.changes=1; 
					}
rswindell's avatar
rswindell committed
392
					break;
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428
				case 5:
					k=1;
					uifc.helpbuf=
						"`Guru Joins This Channel When Empty:`\n"
						"\n"
						"If you want the system guru to join this chat channel when there is\n"
						"only one user, set this option to `Yes`.\n"
					;
					k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
						,"Guru Joins This Channel When Empty"
						,uifcYesNoOpts);
					if(!k && !(cfg.chan[i]->misc&CHAN_GURU)) {
						cfg.chan[i]->misc|=CHAN_GURU;
						uifc.changes=1; 
					}
					else if(k==1 && cfg.chan[i]->misc&CHAN_GURU) {
						cfg.chan[i]->misc&=~CHAN_GURU;
						uifc.changes=1; 
					}
					break;
				case 6:
	uifc.helpbuf=
		"`Channel Guru:`\n"
		"\n"
		"This is a list of available chat Gurus.  Select the one that you wish\n"
		"to have available in this channel.\n"
	;
					k=0;
					for(j=0;j<cfg.total_gurus && j<MAX_OPTS;j++)
						sprintf(opt[j],"%-25s",cfg.guru[j]->name);
					opt[j][0]=0;
					k=uifc.list(WIN_SAV|WIN_RHT,0,0,25,&j,0
						,"Available Chat Gurus",opt);
					if(k==-1)
						break;
					cfg.chan[i]->guru=k;
rswindell's avatar
rswindell committed
429
					break;
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447
				case 7:
	uifc.helpbuf=
		"`Channel Action Set:`\n"
		"\n"
		"This is a list of available chat action sets.  Select the one that you\n"
		"wish to have available in this channel.\n"
	;
					k=0;
					for(j=0;j<cfg.total_actsets && j<MAX_OPTS;j++)
						sprintf(opt[j],"%-25s",cfg.actset[j]->name);
					opt[j][0]=0;
					k=uifc.list(WIN_SAV|WIN_RHT,0,0,25,&j,0
						,"Available Chat Action Sets",opt);
					if(k==-1)
						break;
					uifc.changes=1;
					cfg.chan[i]->actset=k;
					break; 
448 449 450
			} 
		} 
	}
rswindell's avatar
rswindell committed
451 452 453 454 455 456
}

void chatact_cfg(uint setnum)
{
	static int chatact_dflt,chatact_bar;
	char str[128],cmd[128],out[128];
rswindell's avatar
rswindell committed
457
	int j;
rswindell's avatar
rswindell committed
458 459 460
	uint i,n,chatnum[MAX_OPTS+1];
	static chatact_t savchatact;

461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532
	while(1) {
		for(i=0,j=0;i<cfg.total_chatacts && j<MAX_OPTS;i++)
			if(cfg.chatact[i]->actset==setnum) {
				sprintf(opt[j],"%-*.*s %s",LEN_CHATACTCMD,LEN_CHATACTCMD
					,cfg.chatact[i]->cmd,cfg.chatact[i]->out);
				chatnum[j++]=i; 
			}
		chatnum[j]=cfg.total_chatacts;
		opt[j][0]=0;
		i=WIN_ACT|WIN_SAV;
		if(j)
			i|=WIN_DEL|WIN_COPY|WIN_CUT;
		if(j<MAX_OPTS)
			i|=WIN_INS|WIN_INSACT|WIN_XTR;
		if(savchatact.cmd[0])
			i|=WIN_PASTE;
		uifc.helpbuf=
			"`Multinode Chat Actions:`\n"
			"\n"
			"This is a list of the configured multinode chat actions.  The users can\n"
			"use these actions in multinode chat by turning on action commands with\n"
			"the `/A` command in multinode chat.  Then if a line is typed which\n"
			"begins with a valid `action command` and has a user name, chat handle,\n"
			"or node number following, the output string will be displayed replacing\n"
			"the `%s` symbols with the sending user's name and the receiving user's\n"
			"name (in that order).\n"
			"\n"
			"To add an action, select the desired location with the arrow keys and\n"
			"hit ~ INS ~.\n"
			"\n"
			"To delete an action, select it with the arrow keys and hit ~ DEL ~.\n"
			"\n"
			"To configure an action, select it with the arrow keys and hit ~ ENTER ~.\n"
		;
		sprintf(str,"%s Chat Actions",cfg.actset[setnum]->name);
		i=uifc.list(i,0,0,70,&chatact_dflt,&chatact_bar,str,opt);
		if((signed)i==-1)
			return;
		int msk = i & MSK_ON;
		i &= MSK_OFF;
		if (msk == MSK_INS) {
			uifc.helpbuf=
				"`Chat Action Command:`\n"
				"\n"
				"This is the command word (normally a verb) to trigger the action output.\n"
			;
			if(uifc.input(WIN_MID|WIN_SAV,0,0,"Action Command",cmd,LEN_CHATACTCMD
				,K_UPPER)<1)
				continue;
			uifc.helpbuf=
				"`Chat Action Output String:`\n"
				"\n"
				"This is the output string displayed with this action output.\n"
			;
			if(uifc.input(WIN_MID|WIN_SAV,0,0,"",out,LEN_CHATACTOUT
				,K_MSG)<1)
				continue;
			if((cfg.chatact=(chatact_t **)realloc(cfg.chatact
				,sizeof(chatact_t *)*(cfg.total_chatacts+1)))==NULL) {
				errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_chatacts+1);
				cfg.total_chatacts=0;
				bail(1);
				continue; 
			}
			if(j)
				for(n=cfg.total_chatacts;n>chatnum[i];n--)
					cfg.chatact[n]=cfg.chatact[n-1];
			if((cfg.chatact[chatnum[i]]=(chatact_t *)malloc(sizeof(chatact_t)))==NULL) {
				errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(chatact_t));
				continue; 
			}
			memset((chatact_t *)cfg.chatact[chatnum[i]],0,sizeof(chatact_t));
533 534
			SAFECOPY(cfg.chatact[chatnum[i]]->cmd,cmd);
			SAFECOPY(cfg.chatact[chatnum[i]]->out,out);
535 536 537 538
			cfg.chatact[chatnum[i]]->actset=setnum;
			cfg.total_chatacts++;
			uifc.changes=1;
			continue; 
539
		}
540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561
		if (msk == MSK_DEL || msk == MSK_CUT) {
			if(msk == MSK_CUT)
				savchatact = *cfg.chatact[chatnum[i]];
			free(cfg.chatact[chatnum[i]]);
			cfg.total_chatacts--;
			for(j=chatnum[i];j<cfg.total_chatacts && j<MAX_OPTS;j++)
				cfg.chatact[j]=cfg.chatact[j+1];
			uifc.changes=1;
			continue; 
		}
		if (msk == MSK_COPY) {
			savchatact=*cfg.chatact[chatnum[i]];
			continue; 
		}
		if (msk == MSK_PASTE) {
			*cfg.chatact[chatnum[i]]=savchatact;
			cfg.chatact[chatnum[i]]->actset=setnum;
			uifc.changes=1;
			continue; 
		}
		if (msk != 0)
			continue;
562 563 564
		uifc.helpbuf=
			"`Chat Action Command:`\n"
			"\n"
565
			"This is the command that triggers this chat action.\n"
566
		;
567
		SAFECOPY(str,cfg.chatact[chatnum[i]]->cmd);
568 569
		if(!uifc.input(WIN_MID|WIN_SAV,0,10,"Chat Action Command"
			,cfg.chatact[chatnum[i]]->cmd,LEN_CHATACTCMD,K_EDIT|K_UPPER)) {
570
			SAFECOPY(cfg.chatact[chatnum[i]]->cmd,str);
571 572
			continue; 
		}
573 574 575
		uifc.helpbuf=
			"`Chat Action Output String:`\n"
			"\n"
576
			"This is the output string that results from this chat action.\n"
577
		;
578
		SAFECOPY(str,cfg.chatact[chatnum[i]]->out);
579 580
		if(!uifc.input(WIN_MID|WIN_SAV,0,10,""
			,cfg.chatact[chatnum[i]]->out,LEN_CHATACTOUT,K_EDIT|K_MSG))
581
			SAFECOPY(cfg.chatact[chatnum[i]]->out,str); 
582
	}
rswindell's avatar
rswindell committed
583 584 585 586 587
}

void guru_cfg()
{
	static int guru_dflt,guru_bar,opt_dflt;
588
	char str[128],code[128],done=0;
rswindell's avatar
rswindell committed
589
	int j,k;
590
	uint i,u;
rswindell's avatar
rswindell committed
591 592
	static guru_t savguru;

593 594 595 596 597 598 599 600 601 602 603
	while(1) {
		for(i=0;i<cfg.total_gurus && i<MAX_OPTS;i++)
			sprintf(opt[i],"%-25s",cfg.guru[i]->name);
		opt[i][0]=0;
		j=WIN_ACT|WIN_SAV|WIN_RHT|WIN_BOT;
		if(cfg.total_gurus)
			j|=WIN_DEL|WIN_COPY|WIN_CUT;
		if(cfg.total_gurus<MAX_OPTS)
			j|=WIN_INS|WIN_INSACT|WIN_XTR;
		if(savguru.name[0])
			j|=WIN_PASTE;
604
		uifc.helpbuf=
605
			"`Gurus:`\n"
606
			"\n"
607 608 609 610
			"This is a list of the configured Gurus.\n"
			"\n"
			"To add a Guru, select the desired location with the arrow keys and\n"
			"hit ~ INS ~.\n"
611
			"\n"
612 613 614
			"To delete a Guru, select it with the arrow keys and hit ~ DEL ~.\n"
			"\n"
			"To configure a Guru, select it with the arrow keys and hit ~ ENTER ~.\n"
615
		;
616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642
		i=uifc.list(j,0,0,45,&guru_dflt,&guru_bar,"Artificial Gurus",opt);
		if((signed)i==-1)
			return;
		int msk = i & MSK_ON;
		i &= MSK_OFF;
		if (msk == MSK_INS) {
			uifc.helpbuf=
				"`Guru Name:`\n"
				"\n"
				"This is the name of the selected Guru.\n"
			;
			if(uifc.input(WIN_MID|WIN_SAV,0,0,"Guru Name",str,25
				,0)<1)
				continue;
			SAFECOPY(code,str);
			prep_code(code,/* prefix: */NULL);
			uifc.helpbuf=
				"`Guru Internal Code:`\n"
				"\n"
				"Every Guru must have its own unique code for Synchronet to refer to\n"
				"it internally. This code is usually an abbreviation of the Guru name.\n"
			;
			if(uifc.input(WIN_MID|WIN_SAV,0,0,"Internal Code"
				,code,LEN_CODE,K_EDIT|K_UPPER)<1)
				continue;
			if(!code_ok(code)) {
				uifc.helpbuf=invalid_code;
643
				uifc.msg(strInvalidCode);
644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661
				uifc.helpbuf=0;
				continue; 
			}
			if((cfg.guru=(guru_t **)realloc(cfg.guru,sizeof(guru_t *)*(cfg.total_gurus+1)))
				==NULL) {
				errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_gurus+1);
				cfg.total_gurus=0;
				bail(1);
				continue; 
			}
			if(cfg.total_gurus)
				for(u=cfg.total_gurus;u>i;u--)
					cfg.guru[u]=cfg.guru[u-1];
			if((cfg.guru[i]=(guru_t *)malloc(sizeof(guru_t)))==NULL) {
				errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(guru_t));
				continue; 
			}
			memset((guru_t *)cfg.guru[i],0,sizeof(guru_t));
662 663
			SAFECOPY(cfg.guru[i]->name,str);
			SAFECOPY(cfg.guru[i]->code,code);
664 665 666
			cfg.total_gurus++;
			uifc.changes=1;
			continue; 
667
		}
668 669 670 671 672 673 674 675 676
		if (msk == MSK_DEL || msk == MSK_CUT) {
			if(msk == MSK_CUT)
				savguru = *cfg.guru[i];
			free(cfg.guru[i]);
			cfg.total_gurus--;
			for(j=i;j<cfg.total_gurus;j++)
				cfg.guru[j]=cfg.guru[j+1];
			uifc.changes=1;
			continue; 
677
		}
678 679
		if (msk == MSK_COPY) {
			savguru=*cfg.guru[i];
680 681
			continue; 
		}
682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712
		if (msk == MSK_PASTE) {
			*cfg.guru[i]=savguru;
			uifc.changes=1;
			continue; 
		}
		if (msk != 0)
			continue;
		j=0;
		done=0;
		while(!done) {
			k=0;
			sprintf(opt[k++],"%-27.27s%s","Guru Name",cfg.guru[i]->name);
			sprintf(opt[k++],"%-27.27s%s","Guru Internal Code",cfg.guru[i]->code);
			sprintf(opt[k++],"%-27.27s%.40s","Access Requirements",cfg.guru[i]->arstr);
			opt[k][0]=0;
			uifc.helpbuf=
				"`Guru Configuration:`\n"
				"\n"
				"This menu is for configuring the selected Guru.\n"
			;
			switch(uifc.list(WIN_ACT|WIN_MID|WIN_SAV,0,0,60,&opt_dflt,0,cfg.guru[i]->name
				,opt)) {
				case -1:
					done=1;
					break;
				case 0:
					uifc.helpbuf=
						"`Guru Name:`\n"
						"\n"
						"This is the name of the selected Guru.\n"
					;
713
					SAFECOPY(str,cfg.guru[i]->name);
714 715
					if(!uifc.input(WIN_MID|WIN_SAV,0,10,"Guru Name"
						,cfg.guru[i]->name,sizeof(cfg.guru[i]->name)-1,K_EDIT))
716
						SAFECOPY(cfg.guru[i]->name,str);
717 718 719 720 721 722 723 724
					break;
				case 1:
	uifc.helpbuf=
		"`Guru Internal Code:`\n"
		"\n"
		"Every Guru must have its own unique code for Synchronet to refer to\n"
		"it internally. This code is usually an abbreviation of the Guru name.\n"
	;
725
					SAFECOPY(str,cfg.guru[i]->code);
726 727 728 729
					if(!uifc.input(WIN_MID|WIN_SAV,0,0,"Guru Internal Code"
						,str,LEN_CODE,K_EDIT|K_UPPER))
						break;
					if(code_ok(str))
730
						SAFECOPY(cfg.guru[i]->code,str);
731 732
					else {
						uifc.helpbuf=invalid_code;
733
						uifc.msg(strInvalidCode);
734 735
						uifc.helpbuf=0; 
					}
rswindell's avatar
rswindell committed
736
					break;
737 738 739
				case 2:
					getar(cfg.guru[i]->name,cfg.guru[i]->arstr);
					break; 
740 741 742
			} 
		} 
	}
rswindell's avatar
rswindell committed
743 744 745 746 747 748 749
}

void actsets_cfg()
{
    static int actset_dflt,actset_bar,opt_dflt;
    char str[81];
    int j,k,done;
750
    uint i,u;
rswindell's avatar
rswindell committed
751 752
    static actset_t savactset;

753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768
	while(1) {
		for(i=0;i<cfg.total_actsets && i<MAX_OPTS;i++)
			sprintf(opt[i],"%-25s",cfg.actset[i]->name);
		opt[i][0]=0;
		j=WIN_ACT|WIN_RHT|WIN_BOT|WIN_SAV;
		if(cfg.total_actsets)
			j|=WIN_DEL|WIN_COPY|WIN_CUT;
		if(cfg.total_actsets<MAX_OPTS)
			j|=WIN_INS|WIN_INSACT|WIN_XTR;
		if(savactset.name[0])
			j|=WIN_PASTE;
		uifc.helpbuf=
			"`Chat Action Sets:`\n"
			"\n"
			"This is a list of the configured action sets.\n"
			"\n"
rswindell's avatar
rswindell committed
769 770
			"To add an action set, select the desired location with the arrow keys\n"
			"and hit ~ INS ~.\n"
771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805
			"\n"
			"To delete an action set, select it with the arrow keys and hit ~ DEL ~.\n"
			"\n"
			"To configure an action set, select it with the arrow keys and hit\n"
			"~ ENTER ~.\n"
		;
		i=uifc.list(j,0,0,45,&actset_dflt,&actset_bar,"Chat Action Sets",opt);
		if((signed)i==-1)
			return;
		int msk = i & MSK_ON;
		i &= MSK_OFF;
		if (msk == MSK_INS) {
			uifc.helpbuf=
				"`Chat Action Set Name:`\n"
				"\n"
				"This is the name of the selected chat action set.\n"
			;
			if(uifc.input(WIN_MID|WIN_SAV,0,0,"Chat Action Set Name",str,25
				,0)<1)
				continue;
			if((cfg.actset=(actset_t **)realloc(cfg.actset,sizeof(actset_t *)*(cfg.total_actsets+1)))
				==NULL) {
				errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_actsets+1);
				cfg.total_actsets=0;
				bail(1);
				continue; 
			}
			if(cfg.total_actsets)
				for(u=cfg.total_actsets;u>i;u--)
					cfg.actset[u]=cfg.actset[u-1];
			if((cfg.actset[i]=(actset_t *)malloc(sizeof(actset_t)))==NULL) {
				errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(actset_t));
				continue; 
			}
			memset((actset_t *)cfg.actset[i],0,sizeof(actset_t));
806
			SAFECOPY(cfg.actset[i]->name,str);
807 808 809
			cfg.total_actsets++;
			uifc.changes=1;
			continue; 
810
		}
811 812 813 814 815 816 817 818 819
		if (msk == MSK_DEL || msk == MSK_CUT) {
			if(msk == MSK_CUT)
				savactset = *cfg.actset[i];
			free(cfg.actset[i]);
			cfg.total_actsets--;
			for(j=i;j<cfg.total_actsets;j++)
				cfg.actset[j]=cfg.actset[j+1];
			uifc.changes=1;
			continue; 
820
		}
821 822 823 824 825 826 827 828 829 830 831
		if (msk == MSK_COPY) {
			savactset=*cfg.actset[i];
			continue; 
		}
		if (msk == MSK_PASTE) {
			*cfg.actset[i]=savactset;
			uifc.changes=1;
			continue; 
		}
		if (msk != 0)
			continue;
832

833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856
		j=0;
		done=0;
		while(!done) {
			k=0;
			sprintf(opt[k++],"%-27.27s%s","Action Set Name",cfg.actset[i]->name);
			sprintf(opt[k++],"%-27.27s","Configure Chat Actions...");
			opt[k][0]=0;
			uifc.helpbuf=
				"`Chat Action Set Configuration:`\n"
				"\n"
				"This menu is for configuring the selected chat action set.\n"
			;
			sprintf(str,"%s Chat Action Set",cfg.actset[i]->name);
			switch(uifc.list(WIN_ACT|WIN_MID|WIN_SAV,0,0,60,&opt_dflt,0,str
				,opt)) {
				case -1:
					done=1;
					break;
				case 0:
					uifc.helpbuf=
						"`Chat Action Set Name:`\n"
						"\n"
						"This is the name of the selected action set.\n"
					;
857
					SAFECOPY(str,cfg.actset[i]->name);
858 859
					if(!uifc.input(WIN_MID|WIN_SAV,0,10,"Action Set Name"
						,cfg.actset[i]->name,sizeof(cfg.actset[i]->name)-1,K_EDIT))
860
						SAFECOPY(cfg.actset[i]->name,str);
861 862 863 864
					break;
				case 1:
					chatact_cfg(i);
					break; 
865 866 867
			} 
		} 
	}
rswindell's avatar
rswindell committed
868 869
}