diff --git a/xtrn/sbj/sbj.c b/xtrn/sbj/sbj.c new file mode 100644 index 0000000000000000000000000000000000000000..bf895c6701e29502b45d5435a32d52010e8b1dd2 --- /dev/null +++ b/xtrn/sbj/sbj.c @@ -0,0 +1,1871 @@ +/* SBJ.C */ + +/* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */ + +/************************/ +/* Synchronet Blackjack */ +/************************/ + +/*******************************************************/ +/* Multiuser Blackjack game for Synchronet BBS systems */ +/*******************************************************/ + +/****************************************************************************/ +/* This source code is completely Public Domain and can be modified and */ +/* distributed freely (as long as changes are documented). */ +/* It is meant as an example to programmers of how to use the XSDK */ +/****************************************************************************/ + +/***********/ +/* History */ +/****************************************************************************\ + + Many bugs. Especially multiplayer. +v1.0 + Many bugs fixed. Timing problems still exist. +v1.01 + Fixed yet more bugs. No more timing problems. Appears bullet-proof. +v1.02 + Fixed dealer card up always showing card symbol (even when symbols off). + Added ctrl-e answer detection and user notification. + Fixed three 7's bug. + Raised maximum number of decks to 100 for large multinode systems. + Fixed /<CR> bug. + Fixed multiple split bug. + Fixed non-symbols being sent to other nodes bug. + Changed this node's hands to say "You" instead of the user name. +v1.03 + Changed the warning and timeout times +v1.04 + Fixed symbols being displayed on dealer's hand even when disabled. + Made different inactivity warning and timeout values for the main + menu and when in play. +v1.05 + Fixed invalid (usually negative) card bug. THELP random() doc error. + Card now actually contains all the cards minus one. + Fixed multinode play join and hang bug. +v1.06 + If player gets blackjack and dealer gets 21, player wins. Used to push. +v1.07 + Fixed split, then double bug. +v1.08 + Replaced bioskey(1) calls with inkey() and used XSDK v2.0 with node + intercommunication with users on BBS or in other external programs. +v2.00 + Fixed problem with loosing first character of chat lines + Added DESQview awareness +v2.01 + Replaced all calls to delay() with fdelay() +v2.02 + Listing users now displays what external program they're running. + Fixed problem with max bet being too small when users have over + 65mb of credit. +v2.02 + XSDK (and consequently SBJ) now supports shrinking Synchronet to run + (available in v1b r1). + SBBSNODE environment variable will be used for the current node's dir + if the node dir is not specified on the command line. +v2.03 + XSDK and SBJ now support the new message services of Synchronet + (added in v1b r2) for more full-proof internode messaging. +v2.10 + New XSDK that supports new file retrieval node status display. +v2.11 + Changed getnodemsg to eliminate tiny void where messages could fall. + + +\****************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> + +#include "xsdk.h" + +#define MAX_DECKS 100 +#define MAX_CARDS 10 /* maximum number of cards per hand */ +#define MAX_HANDS 4 /* maximum number of hands per player */ + +#define DEBUG 0 + +#define J 11 /* jack */ +#define Q 12 /* queen */ +#define K 13 /* king */ +#define A 14 /* ace */ + +#define H 0 /* heart */ +#define D 1 /* diamond */ +#define C 2 /* club */ +#define S 3 /* spade */ + /* bits used in misc variable */ +#define INPLAY (1<<0) /* hand in play */ + +enum { /* values for status bytes */ + BET /* betting */ + ,WAIT /* waiting for turn */ + ,PLAY /* playing his hand */ + ,SYNC_P /* In sync area - player */ + ,SYNC_D /* In sync area - dealer */ + }; + +typedef struct { char value, suit; } card_t; + +card_t newdeck[52]={ + 2,H, 2,D, 2,C, 2,S, + 3,H, 3,D, 3,C, 3,S, + 4,H, 4,D, 4,C, 4,S, + 5,H, 5,D, 5,C, 5,S, + 6,H, 6,D, 6,C, 6,S, + 7,H, 7,D, 7,C, 7,S, + 8,H, 8,D, 8,C, 8,S, + 9,H, 9,D, 9,C, 9,S, + 10,H,10,D,10,C,10,S, + J,H, J,D, J,C, J,S, + Q,H, Q,D, Q,C, Q,S, + K,H, K,D, K,C, K,S, + A,H, A,D, A,C, A,S }; + +uchar misc; +uchar curplayer; +uchar total_decks,sys_decks; +uchar total_nodes; +int cur_card; +uchar dc; +card_t dealer[MAX_CARDS]; +int gamedab; /* file handle for data file */ +card_t card[MAX_DECKS*52]; +card_t player[MAX_HANDS][MAX_CARDS]; +char hands,pc[MAX_HANDS]; +uchar total_players; +uchar symbols=1; +char autoplay=0; +int logit=0,tutor=0; +uint node[MAX_NODES]; /* the usernumber in each node */ +char status[MAX_NODES]; +ulong credits; +uint bet[MAX_HANDS],ibet,min_bet,max_bet; +char tmp[81]; +char *UserSays="\1n\1m\1h%s \1n\1msays \"\1c\1h%s\1n\1m\"\r\n"; +char *UserWhispers="\1n\1m\1h%s \1n\1mwhispers \"\1c\1h%s\1n\1m\"\r\n"; +char *ShoeStatus="\r\n\1_\1w\1hShoe: %u/%u\r\n"; + +#ifndef SBJCLEAN + +void play(void); +char *cardstr(card_t card); +char hand(card_t card[MAX_CARDS], char count); +char soft(card_t card[MAX_CARDS], char count); +char pair(card_t card[MAX_CARDS], char count); +void getgamedat(char lockit); +void putgamedat(void); +void getcarddat(void); +void putcarddat(void); +void shuffle(void); +void waitturn(void); +void nextplayer(void); +char lastplayer(void); +char firstplayer(void); +void getnodemsg(void); +void putnodemsg(char *msg,char nodenumber); +void putallnodemsg(char *msg); +void syncplayer(void); +void syncdealer(void); +void moduserdat(void); +char *hit(void); +char *stand(void); +char *doubit(void); +char *split(void); +void open_gamedab(void); +void create_gamedab(void); +char *activity(char status_type); +void chat(void); +void listplayers(void); +char *joined(void); +char *left(void); +void strip_symbols(char *str); +void debug(void); + +/****************************************************************************/ +/* Entry point */ +/****************************************************************************/ +int main(int argc, char **argv) +{ + char str[81],ch,*p; + int i,file; + FILE *stream; + +node_dir[0]=0; +for(i=1;i<argc;i++) + if(!stricmp(argv[i],"/L")) + logit=1; + else if(!stricmp(argv[i],"/T")) + tutor=2; + else if(!stricmp(argv[i],"/S")) + tutor=1; + else strcpy(node_dir,argv[i]); + +p=getenv("SBBSNODE"); +if(!node_dir[0] && p) + strcpy(node_dir,p); + +if(!node_dir[0]) { /* node directory not specified */ + bputs("usage: sbj <node directory> [/options]\r\n"); + bputs("\r\noptions: L = log wins/losses for each day\r\n"); + getch(); + return(1); } + +if(node_dir[strlen(node_dir)-1]!='\\') /* make sure node_dir ends in '\' */ + strcat(node_dir,"\\"); + +initdata(); /* read XTRN.DAT and more */ +credits=user_cdt; +total_nodes=sys_nodes; + +remove("DEBUG.LOG"); + +if((file=nopen("SBJ.CFG",O_RDONLY))==-1) { /* open config file */ + bputs("Error opening SBJ.CFG\r\n"); + pause(); + return(1); } +if((stream=fdopen(file,"rb"))==NULL) { /* convert to stream */ + bputs("Error converting SBJ.CFG handle to stream\r\n"); + pause(); + return(1); } +fgets(str,81,stream); /* number of decks in shoe */ +total_decks=sys_decks=atoi(str); +fgets(str,81,stream); /* min bet (in k) */ +min_bet=atoi(str); +fgets(str,81,stream); /* max bet (in k) */ +max_bet=atoi(str); +fgets(str,81,stream); /* default bet (in k) */ +ibet=atoi(str); +fclose(stream); +if(!total_decks || total_decks>MAX_DECKS) { + bputs("Invalid number of decks in SBJ.CFG\r\n"); + pause(); + return(1); } +if(!max_bet) { + bputs("Invalid max bet in SBJ.CFG\r\n"); + pause(); + return(1); } +if(min_bet>max_bet) { + bputs("Invalid min bet in SBJ.CFG\r\n"); + pause(); + return(1); } +if(ibet>max_bet || ibet<min_bet) { + bputs("Invalid default bet in SBJ.CFG\r\n"); + pause(); + return(1); } + +if(!fexist("CARD.DAB")) { + cur_card=0; + dc=0; + memset(dealer,0,sizeof(dealer)); + memset(card,0,sizeof(card)); + putcarddat(); } +else { + getcarddat(); + if(total_decks!=sys_decks) { + remove("CARD.DAB"); + total_decks=sys_decks; + putcarddat(); } } + +if(!fexist("GAME.DAB")) /* File's not there */ + create_gamedab(); + +open_gamedab(); + +getgamedat(0); +if(total_nodes!=sys_nodes) { /* total nodes changed */ + close(gamedab); + total_nodes=sys_nodes; + create_gamedab(); + open_gamedab(); } + +randomize(); + +while(_bios_keybrd(1)) /* clear input buffer */ + _bios_keybrd(0); +putchar(5); /* ctrl-e */ +mswait(500); +if(_bios_keybrd(1)) { + while(_bios_keybrd(1)) + _bios_keybrd(0); + bputs("\r\n\1r\1h\1i*** ATTENTION ***\1n\1h\r\n"); + bputs("\r\nSynchronet Blackjack uses Ctrl-E (ENQ) for the 'club' card " + "symbol."); + bputs("\r\nYour terminal responded to this control character with an " + "answerback string."); + bputs("\r\nYou will need to disable all Ctrl-E (ENQ) answerback " + "strings (Including \r\nCompuserve Quick B transfers) if you wish to " + "toggle card symbols on.\r\n\r\n"); + symbols=0; + pause(); } + +cls(); +bputs("\1n \1h\1cSynchronet\r\n"); +bputs("\1n\0011\1k Blackjack! \r\n"); +bputs("\1n\1r\1h v2.33\r\n"); +bprintf("\1n\1r(XSDK v%s)\r\n",xsdk_ver); + +getgamedat(1); +node[node_num-1]=0; +putgamedat(); + +sec_warn=120; /* Override default inactivity timeout values */ +sec_timeout=180; + +while(1) { + aborted=0; + mnemonics("\r\n~Instructions\r\n"); + mnemonics("~Join Game\r\n"); + mnemonics("~List Players\r\n"); + mnemonics("~Rules of the Game\r\n"); + mnemonics("~Toggle Card Symbols\r\n"); + sprintf(str,"~Quit to %s\r\n",sys_name); + mnemonics(str); + nodesync(); + bprintf("\1_\r\n\1y\1hWhich: \1n"); + switch(getkeys("IJLRTQ|!",0)) { + #if DEBUG + case '!': + if(!com_port) + autoplay=1; + break; + case '|': + debug(); + break; + #endif + case 'I': + printfile("SBJ.MSG"); + break; + case 'L': + listplayers(); + bprintf(ShoeStatus,cur_card,total_decks*52); + break; + case 'R': + bprintf("\1n\1c\r\nMinimum bet: \1h%uk",min_bet); + bprintf("\1n\1c\r\nMaximum bet: \1h%uk\r\n",max_bet); + bprintf("\1w\1h\r\nCard decks in shoe: \1h%u\r\n",sys_decks); + break; + case 'T': + symbols=!symbols; + bprintf("\1_\1w\r\nCard symbols now: %s\r\n",symbols ? "ON":"OFF"); + break; + case 'Q': + exit(0); + case 'J': + sec_warn=60; /* Override default inactivity timeout values */ + sec_timeout=90; + play(); + sec_warn=120; + sec_timeout=180; + break; } } +} + +#if DEBUG +void debug() +{ + int i; + +if(user_level<90) + return; +getgamedat(0); +getcarddat(); + +bprintf("\r\nDeck (%d) Current: %d\r\n\r\n",total_decks,cur_card); +for(i=0;i<total_decks*52;i++) { + if(!(i%11)) + bputs("\r\n"); + bprintf("%3d:%-11s",i,cardstr(card[i])); } + +pause(); +bprintf("\1n\r\nDealer (%d)\r\n\r\n",dc); +for(i=0;i<dc;i++) + bprintf("%s ",cardstr(dealer[i])); +bprintf("\1n\r\nNodes (%d) Current: %d\r\n\r\n" + ,total_nodes,curplayer); +for(i=0;i<total_nodes;i++) + bprintf("%d: node=%d status=%d %s\r\n",i+1,node[i] + ,status[i],activity(status[i])); +} + +void debugline(char *line) +{ + char str[256]; + int file; + time_t now; + struct dosdate_t date; + struct dostime_t curtime; + +#if 1 +now=time(NULL); +unixtodos(now,&date,&curtime); +if((file=nopen("DEBUG.LOG",O_WRONLY|O_APPEND|O_CREAT))==-1) + return; +sprintf(str,"%d %02u:%02u:%02u %s\r\n" + ,node_num,curtime.ti_hour,curtime.ti_min,curtime.ti_sec,line); +write(file,str,strlen(str)); +close(file); +#endif +} + +#endif + +void suggest(char action) +{ +bputs("Dealer suggests you "); +switch(action) { + case 'H': + bputs("hit"); + break; + case 'S': + bputs("stand"); + break; + case 'D': + bputs("double"); + break; + case 'P': + bputs("split"); + break; } +bputs("\r\n"); +} + +void wrong(char action) +{ +sound(100); +mswait(500); +nosound(); +bputs("Dealer says you should have "); +switch(action) { + case 'H': + bputs("hit"); + break; + case 'S': + bputs("stood"); + break; + case 'D': + bputs("doubled"); + break; + case 'P': + bputs("split"); + break; } +bputs("\r\n"); +} + +/****************************************************************************/ +/* This function is the actual game playing loop. */ +/****************************************************************************/ +void play() +{ + char str[256],str2[256],log[81],done,doub,dh,split_card,suggestion + ,*YouWereDealt="\1n\1k\0015 You \1n\1m were dealt: %s\r\n" + ,*UserWasDealt="\1n\1m\1h%s\1n\1m was dealt: %s\r\n" + ,*YourHand="\1n\1k\0015 You \1n\1m (%2d) %s" + ,*UserHand="\1n\1m\1h%-25s \1n\1m(%2d) %s" + ,*DealerHand="\1n\1hDealer \1n\1m(%2d) " + ,*Bust="\1n\1r\1hBust\1n\r\n" + ,*Natural="\1g\1h\1iNatural " + ,*Three7s="\1r\1h\1iThree 7's " + ,*Blackjack="\1n\0011\1k Blackjack! \1n\r\n" + ,*TwentyOne="\1n\0012\1k Twenty-one \1n\r\n"; + int h,i,j,file; + uint max; + long val; + time_t start,now; + struct dosdate_t date; + +sprintf(str,"MESSAGE.%d",node_num); /* remove message if waiting */ +if(fexist(str)) + remove(str); + +getgamedat(0); +if(node[node_num-1]) { + getgamedat(1); + node[node_num-1]=0; + putgamedat(); + getgamedat(0); } + +if(total_players && misc&INPLAY) { + bputs("\r\n\1hWaiting for end of hand (^A to abort)...\1n"); + start=now=time(NULL); + getgamedat(0); + while(total_players && misc&INPLAY) { + if((i=inkey(0))!=0) { /* if key was hit */ + if(i==1) { /* if ctrl-a */ + bputs("\r\n"); + return; } } /* return */ + mswait(100); + getgamedat(0); + now=time(NULL); + if(now-start>300) { /* only wait up to 5 minutes */ + bputs("\r\ntimeout\r\n"); + return; } } + bputs("\r\n"); } + +getgamedat(1); +node[node_num-1]=user_number; +putgamedat(); + +if(!total_players) + shuffle(); +else + listplayers(); + +sprintf(str,"\1n\1m\1h%s \1n\1m%s\r\n",user_name,joined()); +putallnodemsg(str); + +while(1) { + aborted=0; + #if DEBUG + debugline("top of loop"); + #endif + if(autoplay) + lncntr=0; + bprintf(ShoeStatus,cur_card,total_decks*52); + if(cur_card>(total_decks*52)-(total_players*10)-10 && lastplayer()) + shuffle(); + getgamedat(1); + misc&=~INPLAY; + status[node_num-1]=BET; + node[node_num-1]=user_number; + putgamedat(); + + bprintf("\r\n\1n\1cYou have \1h%s\1n\1ck credits\r\n" + ,ultoac(credits/1024L,str)); + if(credits<min_bet/1024) { + bprintf("\1n\1cMinimum bet: \1h%uk\r\n",min_bet); + bputs("\1n\1r\1hCome back when you have more credits.\r\n"); + break; } + if(credits/1024L>(ulong)max_bet) + max=max_bet; + else + max=credits/1024L; + sprintf(str,"\r\nBet amount (in kilobytes) or ~Quit [%u]: " + ,ibet<credits/1024L ? ibet : credits/1024L); + chat(); + mnemonics(str); + if(autoplay && _bios_keybrd(1)) + autoplay=0; + if(autoplay) + i=ibet; + else + i=getnum(max); + if(i==-1) /* if user hit ^C or 'Q' */ + break; + bputs("\r\n"); + if(i) /* if user entered a value */ + bet[0]=i; + else /* if user hit enter */ + bet[0]=ibet<credits/1024L ? ibet : credits/1024L; + if(bet[0]<min_bet) { + bprintf("\1n\1cMinimum bet: \1h%uk\r\n",min_bet); + bputs("\1n\1r\1hCome back when you're ready to bet more.\r\n"); + break; } + ibet=bet[0]; + getgamedat(0); /* to get all new arrivals */ + sprintf(str,"\1m\1h%s\1n\1m bet \1n\1h%u\1n\1mk\r\n",user_name,bet[0]); + putallnodemsg(str); + + pc[0]=2; /* init player's 1st hand to 2 cards */ + for(i=1;i<MAX_HANDS;i++) /* init player's other hands to 0 cards */ + pc[i]=0; + hands=1; /* init total player's hands to 1 */ + + getgamedat(1); /* first come first serve to be the */ + for(i=0;i<total_nodes;i++) /* dealer in control of sync */ + if(node[i] && status[i]==SYNC_D) + break; + if(i==total_nodes) { + #if DEBUG + debugline("syncdealer"); + #endif + syncdealer(); } /* all players meet here */ + else { /* first player is current after here */ + #if DEBUG + debugline("syncplayer"); + #endif + syncplayer(); } /* game is closed (INPLAY) at this point */ + + #if DEBUG + debugline("waitturn 1"); + #endif + waitturn(); + getnodemsg(); + /* Initial deal card #1 */ + getcarddat(); + player[0][0]=card[cur_card++]; + putcarddat(); + sprintf(str,YouWereDealt,cardstr(card[cur_card-1])); + if(!symbols) + strip_symbols(str); + bputs(str); + sprintf(str,UserWasDealt,user_name,cardstr(card[cur_card-1])); + putallnodemsg(str); + + if(lastplayer()) { + getcarddat(); + dealer[0]=card[cur_card++]; + dc=1; + putcarddat(); } + nextplayer(); + #if DEBUG + debugline("waitturn 2"); + #endif + waitturn(); + getnodemsg(); + + getcarddat(); /* Initial deal card #2 */ + player[0][1]=card[cur_card++]; + putcarddat(); + sprintf(str,YouWereDealt,cardstr(card[cur_card-1])); + if(!symbols) + strip_symbols(str); + bputs(str); + sprintf(str,UserWasDealt,user_name,cardstr(card[cur_card-1])); + putallnodemsg(str); + + if(lastplayer()) { + getcarddat(); + dealer[1]=card[cur_card++]; + dc=2; + putcarddat(); } + nextplayer(); + #if DEBUG + debugline("waitturn 3"); + #endif + waitturn(); + getnodemsg(); + getcarddat(); + + for(i=0;i<hands;i++) { + if(autoplay) + lncntr=0; + done=doub=0; + while(!done && pc[i]<MAX_CARDS && cur_card<total_decks*52) { + h=hand(player[i],pc[i]); + str[0]=0; + for(j=0;j<pc[i];j++) { + strcat(str,cardstr(player[i][j])); + strcat(str," "); } + j=bstrlen(str); + while(j++<19) + strcat(str," "); + if(h>21) { + strcat(str,Bust); + sprintf(str2,YourHand,h,str); + if(!symbols) + strip_symbols(str2); + bputs(str2); + sprintf(str2,UserHand,user_name,h,str); + putallnodemsg(str2); + break; } + if(h==21) { + if(pc[i]==2) { /* blackjack */ + if(player[i][0].suit==player[i][1].suit) + strcat(str,Natural); + strcat(str,Blackjack); } + else { + if(player[i][0].value==7 + && player[i][1].value==7 + && player[i][2].value==7) + strcat(str,Three7s); + strcat(str,TwentyOne); } + sprintf(str2,YourHand,h,str); + if(!symbols) + strip_symbols(str2); + bputs(str2); + sprintf(str2,UserHand,user_name,h,str); + putallnodemsg(str2); + // fdelay(500); + break; } + strcat(str,"\r\n"); + sprintf(str2,YourHand,h,str); + if(!symbols) + strip_symbols(str2); + bputs(str2); + sprintf(str2,UserHand,user_name,h,str); + putallnodemsg(str2); + if(doub) + break; + sprintf(str,"\1n\1hDealer\1n\1m card up: %s\r\n" + ,cardstr(dealer[1])); + if(!symbols) + strip_symbols(str); + bputs(str); + + if(tutor) { + if(pc[i]==2) + split_card=pair(player[i],pc[i]); + else + split_card=0; + if(split_card==A + || (split_card==9 && (dealer[1].value<7 + || (dealer[1].value>7 && dealer[1].value<10))) + || split_card==8 + || (split_card==7 && dealer[1].value<9) + || (split_card==6 && dealer[1].value<7) + || (split_card==4 && dealer[1].value==5) + || (split_card && split_card<4 && dealer[1].value<8)) + suggestion='P'; + else if(soft(player[i],pc[i])) { + if(h>18) + suggestion='S'; + else if(pc[i]==2 + && ((h==18 + && dealer[1].value>3 && dealer[1].value<7) + || (h==17 + && dealer[1].value>2 && dealer[1].value<7) + || (h>13 + && dealer[1].value>3 && dealer[1].value<7) + || (h==12 + && dealer[1].value>4 && dealer[1].value<7))) + suggestion='D'; + else + suggestion='H'; } + else { /* hard */ + if(h>16 || (h>13 && dealer[1].value<7) + || (h==12 && dealer[1].value>3 && dealer[1].value<7)) + suggestion='S'; + else if(pc[i]==2 + && (h==11 || (h==10 && dealer[1].value<10) + || (h==9 && dealer[1].value<7))) + suggestion='D'; + else + suggestion='H'; } } + + if(tutor==1) + suggest(suggestion); + strcpy(str,"\r\n~Hit"); + strcpy(tmp,"H\r"); + if(bet[i]+ibet<=credits/1024L && pc[i]==2) { + strcat(str,", ~Double"); + strcat(tmp,"D"); } + if(bet[i]+ibet<=credits/1024L && pc[i]==2 && hands<MAX_HANDS + && player[i][0].value==player[i][1].value) { + strcat(str,", ~Split"); + strcat(tmp,"S"); } + strcat(str,", or [Stand]: "); + chat(); + mnemonics(str); + if(autoplay && _bios_keybrd(1)) + autoplay=0; + + + if(autoplay) { + lncntr=0; + bputs("\r\n"); + strcpy(str,stand()); + bputs(str); + putallnodemsg(str); + done=1; } + else + switch(getkeys(tmp,0)) { + case 'H': /* hit */ + if(tutor==2 && suggestion!='H') + wrong(suggestion); + strcpy(str,hit()); + bputs(str); + putallnodemsg(str); + getcarddat(); + player[i][pc[i]++]=card[cur_card++]; + putcarddat(); + break; + case 'D': /* double down */ + if(tutor==2 && suggestion!='D') + wrong(suggestion); + strcpy(str,doubit()); + bputs(str); + putallnodemsg(str); + getcarddat(); + player[i][pc[i]++]=card[cur_card++]; + putcarddat(); + doub=1; + bet[i]+=ibet; + break; + case 'S': /* split */ + if(tutor==2 && suggestion!='P') + wrong(suggestion); + strcpy(str,split()); + bputs(str); + putallnodemsg(str); + player[hands][0]=player[i][1]; + getcarddat(); + player[i][1]=card[cur_card++]; + player[hands][1]=card[cur_card++]; + putcarddat(); + pc[hands]=2; + bet[hands]=ibet; + hands++; + break; + case CR: + if(tutor==2 && suggestion!='S') + wrong(suggestion); + strcpy(str,stand()); + bputs(str); + putallnodemsg(str); + done=1; + break; } } } + + if(lastplayer()) { /* last player plays the dealer's hand */ + getcarddat(); + while(hand(dealer,dc)<17 && dc<MAX_CARDS && cur_card<total_decks*52) + dealer[dc++]=card[cur_card++]; + putcarddat(); } + + nextplayer(); + #if DEBUG + debugline("waitturn 4"); + #endif + waitturn(); + getnodemsg(); + + if(firstplayer()==node_num) { + strcpy(str,"\1n\0014\1h Final \1n\r\n"); + bputs(str); + putallnodemsg(str); } + getcarddat(); + dh=hand(dealer,dc); /* display dealer's hand */ + sprintf(str,DealerHand,dh); + for(i=0;i<dc;i++) { + strcat(str,cardstr(dealer[i])); + strcat(str," "); } + i=bstrlen(str); + while(i++<50) /* was 50 */ + strcat(str," "); + if(dh>21) { + strcat(str,Bust); + if(!symbols) + strip_symbols(str); + bputs(str); } + else if(dh==21) { + if(dc==2) { /* blackjack */ + if(dealer[0].suit==dealer[1].suit) + strcat(str,Natural); + strcat(str,Blackjack); } + else { /* twenty-one */ + if(dc==3 && dealer[0].value==7 && dealer[1].value==7 + && dealer[2].value==7) + strcat(str,Three7s); + strcat(str,TwentyOne); } + if(!symbols) + strip_symbols(str); + bputs(str); } + else { + if(!symbols) + strip_symbols(str); + bprintf("%s\r\n",str); } + + for(i=0;i<hands;i++) { /* display player's hand(s) */ + h=hand(player[i],pc[i]); + str[0]=0; + for(j=0;j<pc[i];j++) { + strcat(str,cardstr(player[i][j])); + strcat(str," "); } + j=bstrlen(str); + while(j++<19) + strcat(str," "); + if(logit) { + _dos_getdate(&date); + sprintf(log,"%02d%02d%02d.LOG" /* log winnings */ + ,date.month,date.day,date.year-1900); + if((file=nopen(log,O_RDONLY))!=-1) { + read(file,tmp,filelength(file)); + tmp[filelength(file)]=0; + val=atol(tmp); + close(file); } + else + val=0L; + if((file=nopen(log,O_WRONLY|O_CREAT|O_TRUNC))==-1) { + bprintf("error opening %s\r\n",log); + return; } } + if(h<22 && (h>dh || dh>21 /* player won */ + || (h==21 && pc[i]==2 && dh==21 && dh>2))) { /* blackjack */ + j=bet[i]; /* and dealer got 21 */ + if(h==21 && /* natural blackjack or three 7's */ + ((player[i][0].value==7 && player[i][1].value==7 + && player[i][2].value==7) + || (pc[i]==2 && player[i][0].suit==player[i][1].suit))) + j*=2; + else if(h==21 && pc[i]==2) /* regular blackjack */ + j*=1.5; /* blackjack pays 1� to 1 */ + sprintf(tmp,"\1n\1h\1m\1iWon!\1n\1h %u\1n\1mk",j); + strcat(str,tmp); + credits+=j*1024L; + val-=j*1024L; + moduserdat(); } + else if(h<22 && h==dh) + strcat(str,"\1n\1hPush"); + else { + strcat(str,"\1nLost"); + credits-=bet[i]*1024L; + val+=bet[i]*1024L; + moduserdat(); } + if(logit) { + sprintf(tmp,"%ld",val); + write(file,tmp,strlen(tmp)); + close(file); } /* close winning log */ + strcat(str,"\1n\r\n"); + sprintf(str2,YourHand,h,str); + if(!symbols) + strip_symbols(str2); + bputs(str2); + sprintf(str2,UserHand,user_name,h,str); + putallnodemsg(str2); } + + nextplayer(); + if(!lastplayer()) { + #if DEBUG + debugline("lastplayer waitturn"); + #endif + waitturn(); + nextplayer(); } + #if DEBUG + debugline("end of loop"); + #endif + getnodemsg(); } + +getgamedat(1); +node[node_num-1]=0; +putgamedat(); +sprintf(str,"\1n\1m\1h%s \1n\1m%s\r\n",user_name,left()); +putallnodemsg(str); +} + +/****************************************************************************/ +/* This function returns a static string that describes the status byte */ +/****************************************************************************/ +char *activity(char status_type) +{ + static char str[50]; + +switch(status_type) { + case BET: + strcpy(str,"betting"); + break; + case WAIT: + strcpy(str,"waiting for turn"); + break; + case PLAY: + strcpy(str,"playing"); + break; + case SYNC_P: + strcpy(str,"synchronizing"); + break; + case SYNC_D: + strcpy(str,"synchronizing (dealer)"); + break; + default: + strcat(str,"UNKNOWN"); + break; } +return(str); +} + +/****************************************************************************/ +/* This function returns the string that represents a playing card. */ +/****************************************************************************/ +char *cardstr(card_t card) +{ + static char str[20]; + char tmp[20]; + +strcpy(str,"\1n\0017"); /* card color - background always white */ +if(card.suit==H || card.suit==D) + strcat(str,"\1r"); /* hearts and diamonds - foreground red */ +else + strcat(str,"\1k"); /* spades and clubs - foreground black */ +if(card.value>10) /* face card */ + switch(card.value) { + case J: + strcat(str,"J"); + break; + case Q: + strcat(str,"Q"); + break; + case K: + strcat(str,"K"); + break; + case A: + strcat(str,"A"); + break; } +else { + sprintf(tmp,"%d",card.value); + strcat(str,tmp); } +switch(card.suit) { /* suit */ + case H: + strcat(str,"\3"); + break; + case D: + strcat(str,"\4"); + break; + case C: + strcat(str,"\5"); + break; + case S: + strcat(str,"\6"); + break; } +strcat(str,"\1n"); +return(str); +} + + +/****************************************************************************/ +/* This function returns the best value of a given hand. */ +/****************************************************************************/ +char hand(card_t card[MAX_CARDS],char count) +{ + char c,total=0,ace=0; + +for(c=0;c<count;c++) { + if(card[c].value==A) { /* Ace */ + if(total+11>21) + total++; + else { + ace++; + total+=11; } } + else if(card[c].value>=J) /* Jack, Queen, King */ + total+=10; + else /* Number cards */ + total+=card[c].value; } +while(total>21 && ace) { /* ace is low if bust */ + total-=10; + ace--; } +return(total); +} + +/****************************************************************************/ +/* This function returns number of soft aces in a given hand */ +/****************************************************************************/ +char soft(card_t card[MAX_CARDS],char count) +{ + char c,total=0,ace=0; + +for(c=0;c<count;c++) { + if(card[c].value==A) { /* Ace */ + if(total+11>21) + total++; + else { + ace++; + total+=11; } } + else if(card[c].value>=J) /* Jack, Queen, King */ + total+=10; + else /* Number cards */ + total+=card[c].value; } +while(total>21 && ace) { /* ace is low if bust */ + total-=10; + ace--; } +return(ace); +} + +/****************************************************************************/ +/* This function returns card that is paired in the hand */ +/****************************************************************************/ +char pair(card_t card[MAX_CARDS],char count) +{ + char c,d; + +for(c=0;c<count;c++) + for(d=c+1;d<count;d++) + if(card[c].value==card[d].value) /* Ace */ + return(card[c].value); +return(0); +} + + +/****************************************************************************/ +/* This function shuffles the deck. */ +/****************************************************************************/ +void shuffle() +{ + char str[81]; + uint i,j; + card_t shufdeck[52*MAX_DECKS]; + + +getcarddat(); + +sprintf(str,"\1_\1w\1h\r\nShuffling %d Deck Shoe...",total_decks); +bputs(str); +strcat(str,"\r\n"); /* add crlf for other nodes */ +putallnodemsg(str); + +for(i=0;i<total_decks;i++) + memcpy(shufdeck+(i*52),newdeck,sizeof(newdeck)); /* fresh decks */ + +i=0; +while(i<(total_decks*52)-1) { + j=random((total_decks*52)-1); + if(!shufdeck[j].value) /* card already used */ + continue; + card[i]=shufdeck[j]; + shufdeck[j].value=0; /* mark card as used */ + i++; } + +cur_card=0; +for(i=0;i<MAX_HANDS;i++) + pc[i]=0; +hands=0; +dc=0; +putcarddat(); +bputs("\r\n"); +} + +/****************************************************************************/ +/* This function reads and displays a message waiting for this node, if */ +/* there is one. */ +/****************************************************************************/ +void getnodemsg() +{ + char str[81], *buf; + int file; + ulong length; + +nodesync(); +sprintf(str,"MESSAGE.%d",node_num); +if(flength(str)<1L) /* v1.02 fix */ + return; +if((file=nopen(str,O_RDWR))==-1) { + bprintf("Couldn't open %s\r\n",str); + return; } +length=filelength(file); +if((buf=malloc(length+1L))==NULL) { + close(file); + bprintf("\7\r\ngetnodemsg: Error allocating %lu bytes of memory for %\r\n" + ,length+1L,str); + return; } +buf[read(file,buf,length)]=0; +chsize(file,0); +close(file); +if(!symbols) + strip_symbols(buf); +bputs(buf); +free(buf); +} + +/****************************************************************************/ +/* This function creates a message for a certain node. */ +/****************************************************************************/ +void putnodemsg(char *msg, char nodenumber) +{ + char str[81]; + int file; + +sprintf(str,"MESSAGE.%d",nodenumber); +if((file=nopen(str,O_WRONLY|O_CREAT|O_APPEND))==-1) { + bprintf("\r\n\7putnodemsg: error opening/creating %s\r\n",str); + return; } +write(file,msg,strlen(msg)); +close(file); +} + +/****************************************************************************/ +/* This function creates a message for all nodes in the game. */ +/****************************************************************************/ +void putallnodemsg(char *msg) +{ + int i; + +for(i=0;i<total_nodes;i++) + if(node[i] && i+1!=node_num) + putnodemsg(msg,i+1); +} + +/****************************************************************************/ +/* This function waits until it is the current player. */ +/****************************************************************************/ +void waitturn() +{ + time_t start,now; + +start=now=time(NULL); +getgamedat(1); +status[node_num-1]=WAIT; +putgamedat(); +while(curplayer!=node_num) { + chat(); + mswait(100); + getgamedat(0); + if(curplayer && !node[curplayer-1] /* || status[curplayer-1]==BET */ ) + nextplayer(); /* current player is not playing? */ + + if(!node[node_num-1]) { /* current node not in game? */ + getgamedat(1); + node[node_num-1]=user_number; /* fix it */ + putgamedat(); } + + now=time(NULL); + if(now-start>300) { /* only wait upto 5 minutes */ + bputs("\r\nwaitturn: timeout\r\n"); + break; } } +getgamedat(1); +status[node_num-1]=PLAY; +putgamedat(); +} + +/****************************************************************************/ +/* This is the function that is called to see if the user has hit a key, */ +/* and if so, read in a line of chars and send them to the other nodes. */ +/****************************************************************************/ +void chat() +{ + char str1[150],str2[256],ch; + int i; + +aborted=0; +if((ch=inkey(0))!=0 || wordwrap[0]) { + if(ch=='/') { + bputs("\1n\1y\1hCommand: \1n"); + ch=getkeys("?LS|%\r",0); + switch(ch) { + case CR: + return; + #if DEBUG + case '|': + debug(); + return; + #endif + case '%': + if(!com_port) /* only if local */ + exit(0); + break; + case '?': + mnemonics("\r\n~List Players"); + mnemonics("\r\n~Send Private Message to Player"); + bputs("\r\n"); + return; + case 'L': + listplayers(); + bprintf(ShoeStatus,cur_card,total_decks*52); + return; + case 'S': + listplayers(); + bputs("\1n\r\n\1y\1hWhich node: \1n"); + i=getnum(sys_nodes); + getgamedat(0); + if(i>0 && i!=node_num && node[i-1]) { + bputs("\r\n\1n\1y\1hMessage: "); + if(getstr(str1,50,K_LINE)) { + sprintf(str2,UserWhispers,user_name + ,str1); + putnodemsg(str2,i); } } + else + bputs("\1n\r\n\1r\1hInvalid node.\1n\r\n"); + return; } } + ungetkey(ch); + if(!getstr(str1,50,K_CHAT|K_WRAP)) + return; + sprintf(str2,UserSays,user_name,str1); + putallnodemsg(str2); } +getnodemsg(); +} + +/****************************************************************************/ +/* This function returns 1 if the current node is the highest (or last) */ +/* node in the game, or 0 if there is another node with a higher number */ +/* in the game. Used to determine if this node is to perform the dealer */ +/* function */ +/****************************************************************************/ +char lastplayer() +{ + int i; + +getgamedat(0); +if(total_players==1 && node[node_num-1]) /* if only player, definetly */ + return(1); /* the last */ + +for(i=node_num;i<total_nodes;i++) /* look for a higher number */ + if(node[i]) + break; +if(i<total_nodes) /* if one found, return 0 */ + return(0); +return(1); /* else return 1 */ +} + +/****************************************************************************/ +/* Returns the node number of the lower player in the game */ +/****************************************************************************/ +char firstplayer() +{ + int i; + +for(i=0;i<total_nodes;i++) + if(node[i]) + break; +if(i==total_nodes) + return(0); +return(i+1); +} + +/****************************************************************************/ +/* This function is only run on the highest node number in the game. It */ +/* waits until all other nodes are waiting in their sync routines, and then */ +/* releases them by changing the status byte from SYNC_P to PLAY */ +/* it is assumed that getgamedat(1) is called immediately prior. */ +/****************************************************************************/ +void syncdealer() +{ + char *Dealing="\1n\1hDealing...\r\n\1n"; + int i; + time_t start,now; + +status[node_num-1]=SYNC_D; +putgamedat(); +start=now=time(NULL); +// fdelay(1000); /* wait for stragglers to join game v1.02 */ +getgamedat(0); +while(total_players) { + for(i=0;i<total_nodes;i++) + if(i!=node_num-1 && node[i] && status[i]!=SYNC_P) + break; + if(i==total_nodes) /* all player nodes are waiting */ + break; + chat(); + mswait(100); + getgamedat(0); + if(!node[node_num-1]) { /* current node not in game? */ + getgamedat(1); + node[node_num-1]=user_number; /* fix it */ + putgamedat(); } + now=time(NULL); + if(now-start>300) { /* only wait upto 5 minutes */ + bputs("\r\nsyncdealer: timeout\r\n"); + break; } } + +getgamedat(1); +misc|=INPLAY; +curplayer=firstplayer(); +putgamedat(); + +getnodemsg(); +bputs(Dealing); +putallnodemsg(Dealing); + +getgamedat(1); +for(i=0;i<total_nodes;i++) /* release player nodes */ + if(node[i]) + status[i]=PLAY; +putgamedat(); +} + + +/****************************************************************************/ +/* This function halts this node until the dealer releases it by changing */ +/* the status byte from SYNC_P to PLAY */ +/* it is assumed that getgamedat(1) is called immediately prior. */ +/****************************************************************************/ +void syncplayer() +{ + time_t start,now; + +status[node_num-1]=SYNC_P; +putgamedat(); +start=now=time(NULL); +while(node[node_num-1] && status[node_num-1]==SYNC_P) { + chat(); + mswait(100); + getgamedat(0); + if(!node[node_num-1]) { /* current node not in game? */ + getgamedat(1); + node[node_num-1]=user_number; /* fix it */ + putgamedat(); } + now=time(NULL); + if(now-start>300) { /* only wait upto 5 minutes */ + bputs("\r\nsyncplayer: timeout\r\n"); + break; } } +} + +/****************************************************************************/ +/* Updates the MODUSER.DAT file that SBBS reads to ajust the user's credits */ +/* This function is called whenever the user's credits are adjust so that */ +/* the file will be current in any event. */ +/****************************************************************************/ +void moduserdat() +{ + char str[128]; + FILE *stream; + +sprintf(str,"%sMODUSER.DAT",node_dir); +if((stream=fopen(str,"wt"))==NULL) { + bprintf("Error opening %s for write\r\n",str); + return; } +fprintf(stream,"%ld",credits-user_cdt); +fclose(stream); + +} + +/****************************************************************************/ +/* This function reads the entire shoe of cards and the dealer's hand from */ +/* the card database file (CARD.DAB) */ +/****************************************************************************/ +void getcarddat() +{ + int file; + +if((file=nopen("CARD.DAB",O_RDONLY))==-1) { + bputs("getcarddat: Error opening CARD.DAB\r\n"); + return; } +read(file,&dc,1); +read(file,dealer,sizeof(dealer)); +read(file,&total_decks,1); +read(file,&cur_card,2); +read(file,card,total_decks*52*sizeof(card_t)); +close(file); +} + +/****************************************************************************/ +/* This function writes the entire shoe of cards and the dealer's hand to */ +/* the card database file (CARD.DAB) */ +/****************************************************************************/ +void putcarddat() +{ + int file; + +if((file=nopen("CARD.DAB",O_WRONLY|O_CREAT))==-1) { + bputs("putcarddat: Error opening CARD.DAB\r\n"); + return; } +write(file,&dc,1); +write(file,dealer,sizeof(dealer)); +write(file,&total_decks,1); +write(file,&cur_card,2); +write(file,card,total_decks*52*sizeof(card_t)); +close(file); +} + +/****************************************************************************/ +/* This function creates random ways to say "hit" */ +/****************************************************************************/ +char *hit() +{ + static char str[81]; + +strcpy(str,"\1n\1r\1h"); +switch(rand()%10) { + case 1: + strcat(str,"Hit it."); + break; + case 2: + strcat(str,"Hit me, Baby!"); + break; + case 3: + strcat(str,"Give me an ace."); + break; + case 4: + strcat(str,"One more."); + break; + case 5: + strcat(str,"Just one more."); + break; + case 6: + strcat(str,"Give me a baby card."); + break; + case 7: + strcat(str,"Hit it, Dude."); + break; + case 8: + strcat(str,"Hit."); + break; + case 9: + strcat(str,"Um... Hit."); + break; + case 10: + strcat(str,"Thank you Sir, may I have another."); + break; + default: + strcat(str,"Face card, please."); + break; } +strcat(str,"\1n\r\n"); +return(str); +} + +/****************************************************************************/ +/* This function creates random ways to say "double" */ +/****************************************************************************/ +char *doubit() +{ + static char str[81]; + +strcpy(str,"\1n\1b\1h"); +switch(rand()%10) { + case 1: + strcat(str,"Double."); + break; + case 2: + strcat(str,"Double Down, Man."); + break; + case 3: + strcat(str,"Double it, Dude."); + break; + case 4: + strcat(str,"One more card for double the dough."); + break; + case 5: + strcat(str,"Double me."); + break; + case 6: + strcat(str,"Oh yeah... Double!"); + break; + case 7: + strcat(str,"I shouldn't do it, but... Double!"); + break; + case 8: + strcat(str,"Double my bet and give me one more card."); + break; + case 9: + strcat(str,"Um... Double."); + break; + case 10: + strcat(str,"Thank you Sir, may I Double?"); + break; + default: + strcat(str,"Double - face card, please."); + break; } +strcat(str,"\1n\r\n"); +return(str); +} + +/****************************************************************************/ +/* This function creates random ways to say "stand" */ +/****************************************************************************/ +char *stand() +{ + static char str[81]; + +strcpy(str,"\1n\1c\1h"); +switch(rand()%10) { + case 1: + strcat(str,"Stand."); + break; + case 2: + strcat(str,"Stay."); + break; + case 3: + strcat(str,"No more."); + break; + case 4: + strcat(str,"Just right."); + break; + case 5: + strcat(str,"I should hit, but I'm not gonna."); + break; + case 6: + strcat(str,"Whoa!"); + break; + case 7: + strcat(str,"Hold it."); + break; + case 8: + strcat(str,"No way, Jose!"); + break; + case 9: + strcat(str,"Um... Stand."); + break; + case 10: + strcat(str,"Thanks, but no thanks."); + break; + default: + strcat(str,"No card, no bust."); + break; } +strcat(str,"\1n\r\n"); +return(str); +} + +/****************************************************************************/ +/* This function creates random ways to say "split" */ +/****************************************************************************/ +char *split() +{ + static char str[81]; + +strcpy(str,"\1n\1y\1h"); +switch(rand()%10) { + case 1: + strcat(str,"Split."); + break; + case 2: + strcat(str,"Split 'em."); + break; + case 3: + strcat(str,"Split it."); + break; + case 4: + strcat(str,"Split, please."); + break; + case 5: + strcat(str,"I should hit, but I'm gonna split instead."); + break; + case 6: + strcat(str,"Whoa! Split them puppies..."); + break; + case 7: + strcat(str,"Split 'em, Dude."); + break; + case 8: + strcat(str,"Double the cards, for double the money."); + break; + case 9: + strcat(str,"Um... Split."); + break; + case 10: + strcat(str,"Thank you Sir, I think I'll split 'em."); + break; + default: + strcat(str,"Banana Split."); + break; } +strcat(str,"\1n\r\n"); +return(str); +} + +/****************************************************************************/ +/* This function creates random ways to say "joined" */ +/****************************************************************************/ +char *joined() +{ + static char str[81]; + +switch(rand()%10) { + case 1: + strcpy(str,"joined."); + break; + case 2: + strcpy(str,"sat down to play."); + break; + case 3: + strcpy(str,"plopped on the chair next to you."); + break; + case 4: + strcpy(str,"belched loudly to announce his entrance."); + break; + case 5: + strcpy(str,"dropped in."); + break; + case 6: + strcpy(str,"joined our game."); + break; + case 7: + strcpy(str,"fell on his face entering the casino!"); + break; + case 8: + strcpy(str,"slams a roll of credits on the table."); + break; + case 9: + strcpy(str,"rolled in to join the game."); + break; + case 10: + strcpy(str,"smiles widely as he takes your wife's seat."); + break; + default: + strcpy(str,"spills a drink on your pants while sitting down."); + break; } +return(str); +} + +/****************************************************************************/ +/* This function creates random ways to say "left" */ +/****************************************************************************/ +char *left() +{ + static char str[81]; + +switch(rand()%10) { + case 1: + strcpy(str,"left abruptly."); + break; + case 2: + strcpy(str,"sneaked away."); + break; + case 3: + strcpy(str,"took the credits and ran."); + break; + case 4: + strcpy(str,"fell out of the chair."); + break; + case 5: + strcpy(str,"left the game."); + break; + case 6: + strcpy(str,"slipped out the door."); + break; + case 7: + strcpy(str,"giggled as he left the table."); + break; + case 8: + strcpy(str,"left clenching empty pockets."); + break; + case 9: + strcpy(str,"went to the pawn shop to hawk a watch."); + break; + case 10: + strcpy(str,"bailed out the back door."); + break; + default: + strcpy(str,"made like a train and left."); + break; } +return(str); +} + +/****************************************************************************/ +/* This function creates the file "GAME.DAB" in the current directory. */ +/****************************************************************************/ +void create_gamedab() +{ + +if((gamedab=sopen("GAME.DAB" + ,O_WRONLY|O_CREAT|O_BINARY,SH_DENYNO,S_IWRITE|S_IREAD))==-1) { + bputs("Error creating GAME.DAB\r\n"); + pause(); + exit(1); } +misc=0; +curplayer=0; +memset(node,0,sizeof(node)); +memset(status,0,sizeof(status)); +write(gamedab,&misc,1); +write(gamedab,&curplayer,1); +write(gamedab,&total_nodes,1); +write(gamedab,node,total_nodes*2); +write(gamedab,status,total_nodes); +close(gamedab); +} + +/****************************************************************************/ +/* This function opens the file "GAME.DAB" in the current directory and */ +/* leaves it open with deny none access. This file uses record locking */ +/* for shared access. */ +/****************************************************************************/ +void open_gamedab() +{ +if((gamedab=sopen("GAME.DAB",O_RDWR|O_BINARY,SH_DENYNO))==-1) { + bputs("Error opening GAME.DAB\r\n"); /* open deny none */ + pause(); + exit(1); } +} + +/****************************************************************************/ +/* Lists the players currently in the game and the status of the shoe. */ +/****************************************************************************/ +void listplayers() +{ + int i; + +getgamedat(0); +bputs("\r\n"); +if(!total_players) { + bputs("\1_\1w\1hNo game in progress\r\n"); + return; } +for(i=0;i<total_nodes;i++) + if(node[i]) + bprintf("\1-\1mNode %2d: \1h%s \1n\1m%s\r\n" + ,i+1,username(node[i]),activity(status[i])); +getcarddat(); +/*** +bprintf("\r\nCurrent player=Node %d user #%d\r\n",curplayer,node[curplayer-1]); +***/ +} + +/****************************************************************************/ +/* This function replaces the card symbols in 'str' with letters to */ +/* represent the different suits. */ +/****************************************************************************/ +void strip_symbols(char *str) +{ + int i,j; + +j=strlen(str); +for(i=0;i<j;i++) + if(str[i]>=3 && str[i]<=6) + switch(str[i]) { + case 3: + str[i]='H'; + break; + case 4: + str[i]='D'; + break; + case 5: + str[i]='C'; + break; + case 6: + str[i]='S'; + break; } +} + +#endif /* end of function not needed for SBJCLEAN.C */ + +/****************************************************************************/ +/* Reads information from GAME.DAB file. If 'lockit' is 1, the file is */ +/* and putgamedat must be called to unlock it. If your updating the info */ +/* in GAME.DAB, you must first call getgamedat(1), then putgamedat(). */ +/****************************************************************************/ +void getgamedat(char lockit) +{ + int i=0; + +/* retry 100 times taking at least 3 seconds */ +while(lock(gamedab,0L,filelength(gamedab))==-1 && i++<100) + mswait(30); /* lock the whole thing */ +if(i>=100) { +// printf("gamedab=%d %04X:%p %04X\r\n",gamedab,_psp,&gamedab,_DS); + printf("\7getgamedat: error locking GAME.DAB\r\n"); } + +lseek(gamedab,0L,SEEK_SET); +read(gamedab,&misc,1); +read(gamedab,&curplayer,1); +read(gamedab,&total_nodes,1); +read(gamedab,node,total_nodes*2); /* user number playing for each node */ +read(gamedab,status,total_nodes); /* the status of the player */ +total_players=0; +for(i=0;i<total_nodes;i++) + if(node[i]) + total_players++; +if(!lockit) + unlock(gamedab,0L,filelength(gamedab)); +} + +/****************************************************************************/ +/* Writes information to GAME.DAB file. getgamedat(1) MUST be called before */ +/* this function is called. */ +/****************************************************************************/ +void putgamedat() +{ + +lseek(gamedab,0L,SEEK_SET); +write(gamedab,&misc,1); +write(gamedab,&curplayer,1); +write(gamedab,&total_nodes,1); +write(gamedab,node,total_nodes*2); +write(gamedab,status,total_nodes); +unlock(gamedab,0L,filelength(gamedab)); +} + +/***************************************************************/ +/* This function makes the next active node the current player */ +/***************************************************************/ +void nextplayer() +{ + int i; + +getgamedat(1); /* get current info and lock */ + +if((!curplayer /* if no current player */ + || total_players==1) /* or only one player in game */ + && node[node_num-1]) { /* and this node is in the game */ + curplayer=node_num; /* make this node current player */ + putgamedat(); /* write data and unlock */ + return; } /* and return */ + +for(i=curplayer;i<total_nodes;i++) /* search for the next highest node */ + if(node[i]) /* that is active */ + break; +if(i>=total_nodes) { /* if no higher active nodes, */ + for(i=0;i<curplayer-1;i++) /* start at bottom and go up */ + if(node[i]) + break; + if(i==curplayer-1) /* if no active nodes found */ + curplayer=0; /* make current player 0 */ + else + curplayer=i+1; } +else + curplayer=i+1; /* else active node current player */ + +putgamedat(); /* write info and unlock */ +} + +/* End of SBJ.C */ diff --git a/xtrn/sbj/sbj.cfg b/xtrn/sbj/sbj.cfg new file mode 100644 index 0000000000000000000000000000000000000000..9e5236e6ed78c03c3743f109abd513151bd2308a --- /dev/null +++ b/xtrn/sbj/sbj.cfg @@ -0,0 +1,4 @@ +6 Number of decks +10 Minimum bet (in kilobytes) +1000 Maximum bet (in kilobytes) +100 Default bet (in kilobytes) diff --git a/xtrn/sbj/sbj.doc b/xtrn/sbj/sbj.doc new file mode 100644 index 0000000000000000000000000000000000000000..8066b29359739102e2da37ed88d4cfdb2047633b Binary files /dev/null and b/xtrn/sbj/sbj.doc differ diff --git a/xtrn/sbj/sbj.msg b/xtrn/sbj/sbj.msg new file mode 100644 index 0000000000000000000000000000000000000000..647b4534fe6a8f6fe88d8587d1bc71a1d7df6362 --- /dev/null +++ b/xtrn/sbj/sbj.msg @@ -0,0 +1,22 @@ + chSynchronet + n1k Blackjack! n +c + As you might have guessed, this is a blackjack game. But not just any +blackjack game. With Synchronet Blackjack, you play against the house for +credits and your friends can play along side you simultaneously from the same +card shoe. You can even carry on a conversation while a hand is in play! + + Beware, you are gambling with your credits if you choose to play, but +the odds are pretty good. House pays double on a natural blackjack or three +sevens, 1� to 1 on regular blackjack, even money on other winning hands and +ties (pushes) break even. You can double down if you have enough dough and even +split pairs! + + If you choose to play, note that it is much more enjoyable with a +friend at the table with you. While the dealer is fast and curtious, he doesn't +make a very good conversation. + + If you notice that you're not seeing the card symbols for 'clubs' you +may have Compuserve Quick B transfers enabled or another answerback to Ctrl-E. +This should be disabled, or you should toggle card symbols OFF. + diff --git a/xtrn/sbj/sbjclean.c b/xtrn/sbj/sbjclean.c new file mode 100644 index 0000000000000000000000000000000000000000..814f3edba80f9e58918c9c01703bd4a719860729 --- /dev/null +++ b/xtrn/sbj/sbjclean.c @@ -0,0 +1,48 @@ +/* SBJCLEAN.C */ + +/* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */ + +/* Clean-up program for Synchronet Blackjack Online External Program */ + +#define SBJCLEAN + +#include "sbj.c" + + +int main(int argc, char **argv) +{ + char *p; + int i; + +node_dir[0]=0; +for(i=1;i<argc;i++) + if(!stricmp(argv[i],"/L")) + logit=1; + else strcpy(node_dir,argv[i]); + +p=getenv("SBBSNODE"); +if(!node_dir[0] && p) + strcpy(node_dir,p); + +if(!node_dir[0]) { /* node directory not specified */ + printf("usage: sbjclean <node directory>\r\n"); + getch(); + return(1); } + +if(node_dir[strlen(node_dir)-1]!='\\') /* make sure node_dir ends in '\' */ + strcat(node_dir,"\\"); + +initdata(); /* read XTRN.DAT and more */ + +if((gamedab=open("GAME.DAB",O_RDWR|O_DENYNONE|O_BINARY))==-1) { + printf("Error opening GAME.DAB\r\n"); /* open deny none */ + return(1); } +getgamedat(1); +node[node_num-1]=0; +status[node_num-1]=0; +putgamedat(); +if(curplayer==node_num) + nextplayer(); +close(gamedab); +return(0); +} diff --git a/xtrn/sbl/makefile.bor b/xtrn/sbl/makefile.bor new file mode 100644 index 0000000000000000000000000000000000000000..e9477a7212c17b477d7ef78a67e31628c6b06758 --- /dev/null +++ b/xtrn/sbl/makefile.bor @@ -0,0 +1,40 @@ +################################################################## +# Makefile for SBL (Synchronet BBS List Online External Program) # +# For use with Turbo C++ # +# Tabstop=8 # +################################################################## + +# Macros +CC = bcc +LD = tlink +SDK = ..\sdk +INCLUDE = \bc31\include;$(SDK) +LIB = \bc31\lib +MODEL = l +CFLAGS = -N -d -C -m$(MODEL) -I$(INCLUDE) +LFLAGS = /n /c +OBJS = xsdk.obj xsdkvars.obj ..\..\mswait\dos\mswait$(MODEL).obj +HEADERS = $(SDK)\xsdk.h $(SDK)\xsdkdefs.h $(SDK)\xsdkvars.c sbldefs.h + +# Implicit C Compile Rule +.c.obj: + @echo Compiling $*.c to $*.obj ... + $(CC) $(CFLAGS) -c $*.c + +# Main EXE Link Rule +sbl.exe: $(OBJS) sbl.obj + @echo Linking $< ... + $(LD) $(LFLAGS) @&&! +$(LIB)\c0$(MODEL) $(OBJS) sbl.obj +!, $*, $*, $(LIB)\c$(MODEL).lib $(LIB)\math$(MODEL).lib $(LIB)\emu.lib + +# All .obj modules +sbl.obj: $(HEADERS) + +xsdk.obj: $(SDK)\xsdk.c $(HEADERS) + @echo Compiling $(SDK)\$*.c to $*.obj ... + $(CC) $(CFLAGS) -c $(SDK)\$*.c + +xsdkvars.obj: $(SDK)\xsdkvars.c $(SDK)\xsdkdefs.h + @echo Compiling $(SDK)\$*.c to $*.obj ... + $(CC) $(CFLAGS) -c $(SDK)\$*.c diff --git a/xtrn/sbl/sbbslist.c b/xtrn/sbl/sbbslist.c new file mode 100644 index 0000000000000000000000000000000000000000..2bf0c444fac727778a202b254dfc7fb91986129b --- /dev/null +++ b/xtrn/sbl/sbbslist.c @@ -0,0 +1,250 @@ +/* SBBSLIST.C */ + +/* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */ + +/* Converts Synchronet BBS List (SBL.DAB) to text file */ + +#include "xsdk.h" +#include "sbldefs.h" + +char *wday[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; +char *mon[]={"Jan","Feb","Mar","Apr","May","Jun" + ,"Jul","Aug","Sep","Oct","Nov","Dec"}; +char *nulstr=""; +char tmp[256]; +struct date date; +struct time curtime; + +extern int daylight=0; +extern long timezone=0L; + +typedef struct { + + char str[13]; + short offset; + + } sortstr_t; + + +int sortstr_cmp(sortstr_t **str1, sortstr_t **str2) +{ +return(stricmp((*str1)->str,(*str2)->str)); +} + +/****************************************************************************/ +/* Generates a 24 character ASCII string that represents the time_t pointer */ +/* Used as a replacement for ctime() */ +/****************************************************************************/ +char *timestr(time_t *intime) +{ + static char str[256]; + char mer[3],hour; + struct tm *gm; + +gm=localtime(intime); +if(gm->tm_hour>=12) { + if(gm->tm_hour==12) + hour=12; + else + hour=gm->tm_hour-12; + strcpy(mer,"pm"); } +else { + if(gm->tm_hour==0) + hour=12; + else + hour=gm->tm_hour; + strcpy(mer,"am"); } +sprintf(str,"%s %s %02d %4d %02d:%02d %s" + ,wday[gm->tm_wday],mon[gm->tm_mon],gm->tm_mday,1900+gm->tm_year + ,hour,gm->tm_min,mer); +return(str); +} + +/****************************************************************************/ +/* Converts unix time format (long - time_t) into a char str MM/DD/YY */ +/****************************************************************************/ +char *unixtodstr(time_t unix, char *str) +{ + +if(!unix) + strcpy(str,"00/00/00"); +else { + unixtodos(unix,&date,&curtime); + if((unsigned)date.da_mon>12) { /* DOS leap year bug */ + date.da_mon=1; + date.da_year++; } + if((unsigned)date.da_day>31) + date.da_day=1; + sprintf(str,"%02u/%02u/%02u",date.da_mon,date.da_day + ,date.da_year>=2000 ? date.da_year-2000 : date.da_year-1900); } +return(str); +} + + +void long_bbs_info(FILE *out, bbs_t bbs) +{ + int i; + +fprintf(out,"BBS Name: %s since %s\r\n" + ,bbs.name,unixtodstr(bbs.birth,tmp)); +fprintf(out,"Operator: "); +for(i=0;i<bbs.total_sysops && i<MAX_SYSOPS;i++) { + if(i) { + if(bbs.total_sysops>2) + fprintf(out,", "); + else + fputc(SP,out); + if(!(i%4)) + fprintf(out,"\r\n "); + if(i+1==bbs.total_sysops) + fprintf(out,"and "); } + fprintf(out,"%s",bbs.sysop[i]); } +fprintf(out,"\r\n"); +fprintf(out,"Software: %-15.15s Nodes: %-5u " + "Users: %-5u Doors: %u\r\n" + ,bbs.software,bbs.nodes,bbs.users,bbs.xtrns); +fprintf(out,"Download: %lu files in %u directories of " + "%luMB total space\r\n" + ,bbs.files,bbs.dirs,bbs.megs); +fprintf(out,"Messages: %lu messages in %u sub-boards\r\n" + ,bbs.msgs,bbs.subs); +fprintf(out,"Networks: "); +for(i=0;i<bbs.total_networks && i<MAX_NETS;i++) { + if(i) { + if(bbs.total_networks>2) + fprintf(out,", "); + else + fputc(SP,out); + if(!(i%3)) + fprintf(out,"\r\n "); + if(i+1==bbs.total_networks) + fprintf(out,"and "); } + fprintf(out,"%s [%s]",bbs.network[i],bbs.address[i]); } +fprintf(out,"\r\n"); +fprintf(out,"Terminal: "); +for(i=0;i<bbs.total_terminals && i<MAX_TERMS;i++) { + if(i) { + if(bbs.total_terminals>2) + fprintf(out,", "); + else + fputc(SP,out); + if(i+1==bbs.total_terminals) + fprintf(out,"and "); } + fprintf(out,"%s",bbs.terminal[i]); } +fprintf(out,"\r\n\r\n"); +for(i=0;i<bbs.total_numbers && i<MAX_NUMBERS;i++) + fprintf(out,"%-30.30s %12.12s %5u %-15.15s " + "Minimum: %u\r\n" + ,i && !strcmp(bbs.number[i].location,bbs.number[i-1].location) + ? nulstr : bbs.number[i].location + ,bbs.number[i].number + ,bbs.number[i].max_rate,bbs.number[i].modem + ,bbs.number[i].min_rate); + +fprintf(out,"\r\n"); +for(i=0;i<5;i++) { + if(!bbs.desc[i][0]) + break; + fprintf(out,"%15s%s\r\n",nulstr,bbs.desc[i]); } + +fprintf(out,"\r\n"); +fprintf(out,"Entry created on %s by %s\r\n" + ,timestr(&bbs.created),bbs.user); +if(bbs.updated && bbs.userupdated[0]) + fprintf(out," Last updated on %s by %s\r\n" + ,timestr(&bbs.updated),bbs.userupdated); +if(bbs.verified && bbs.userverified[0]) + fprintf(out,"Last verified on %s by %s\r\n" + ,timestr(&bbs.verified),bbs.userverified); +} + +int main(int argc, char **argv) +{ + char str[128]; + int i,j,file,ff; + FILE *in,*shrt,*lng; + bbs_t bbs; + sortstr_t **sortstr=NULL; + +if((i=open("SBL.DAB",O_RDONLY|O_BINARY|O_DENYNONE))==-1) { + printf("error opening SBL.DAB\n"); + return(1); } + +if((in=fdopen(i,"rb"))==NULL) { + printf("error opening SBL.DAB\n"); + return(1); } + +if((shrt=fopen("SBBS.LST","wb"))==NULL) { + printf("error opening/creating SBBS.LST\n"); + return(1); } + +if((lng=fopen("SBBS_DET.LST","wb"))==NULL) { + printf("error opening/creating SBBS_DET.LST\n"); + return(1); } + +fprintf(shrt,"Synchronet BBS List exported from Vertrauen on %s\r\n" + "=======================================================" + "\r\n\r\n" + ,unixtodstr(time(NULL),str)); + +fprintf(lng,"Detailed Synchronet BBS List exported from Vertrauen on %s\r\n" + "================================================================" + "\r\n\r\n" + ,unixtodstr(time(NULL),str)); + +printf("Sorting..."); +fseek(in,0L,SEEK_SET); +i=j=0; +while(1) { + if(!fread(&bbs,sizeof(bbs_t),1,in)) + break; + j++; + printf("%4u\b\b\b\b",j); + if(!bbs.name[0] || strnicmp(bbs.software,"SYNCHRONET",10)) + continue; + i++; + strcpy(str,bbs.number[0].number); + if((sortstr=(sortstr_t **)farrealloc(sortstr + ,sizeof(sortstr_t *)*i))==NULL) { + printf("\r\n\7Memory allocation error\r\n"); + return(1); } + if((sortstr[i-1]=(sortstr_t *)farmalloc(sizeof(sortstr_t) + ))==NULL) { + printf("\r\n\7Memory allocation error\r\n"); + return(1); } + strcpy(sortstr[i-1]->str,str); + sortstr[i-1]->offset=j-1; } + +qsort((void *)sortstr,i,sizeof(sortstr[0]) + ,(int(*)(const void *, const void *))sortstr_cmp); + +printf("\nCreating index..."); +sprintf(str,"SBBSSORT.NDX"); +if((file=open(str,O_RDWR|O_CREAT|O_TRUNC|O_BINARY,S_IWRITE|S_IREAD))==-1) { + printf("\n\7Error creating %s\n",str); + return(1); } +for(j=0;j<i;j++) + write(file,&sortstr[j]->offset,2); +printf("\n"); + +lseek(file,0L,SEEK_SET); +ff=0; +while(1) { + if(read(file,&i,2)!=2) + break; + fseek(in,(long)i*sizeof(bbs_t),SEEK_SET); + if(!fread(&bbs,sizeof(bbs_t),1,in)) + break; + long_bbs_info(lng,bbs); + if(ff) + fprintf(lng,"\x0c\r\n"); + else + fprintf(lng,"\r\n---------------------------------------------" + "----------------------------------\r\n\r\n"); + ff=!ff; + for(i=0;i<bbs.total_numbers && i<MAX_NUMBERS;i++) + fprintf(shrt,"%-25.25s %-30.30s %12.12s %u\r\n" + ,i ? "" : bbs.name,bbs.number[i].location,bbs.number[i].number + ,bbs.number[i].max_rate); + } +} diff --git a/xtrn/sbl/sbl.c b/xtrn/sbl/sbl.c new file mode 100644 index 0000000000000000000000000000000000000000..9063f29fdd2b85120f2359152a39d3d5c9edb998 --- /dev/null +++ b/xtrn/sbl/sbl.c @@ -0,0 +1,1355 @@ +/* SBL.C */ + +/* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */ + +/****************************/ +/* Synchronet BBS List Door */ +/****************************/ + +/****************************************************************************/ +/* This source code is completely Public Domain and can be modified and */ +/* distributed freely (as long as changes are documented). */ +/* It is meant as an example to programmers of how to use the XSDK */ +/****************************************************************************/ + +/*********** + * History * + *********** + +****************** +* RELEASE: v1.00 * +****************** + +07/03/93 03:16am +Fixed bug with "Auto-deleting" already deleted entries. This would cause a +long list of "Auto-deletion" messages once a day. + +07/03/93 03:30am +The name of the user who last updated the entry is now stored and displayed. + +07/03/93 03:45am +Adding/Updating entries is now much easier and user friendly. + +07/03/93 04:00am +Added support for user "verification" of BBS entries. + +07/03/93 04:10am +Users may now update or remove entries using partial system names. + +07/03/93 04:30am +Sysops may now un-delete purged entries with the '*' key. + +****************** +* RELEASE: v1.10 * +****************** + +10/18/93 06:04pm +Fixed bug that would cause entries to be purged almost immediately. + +10/18/93 07:01pm +(F)ind text now searches user names who last updated and verified. + +10/19/93 01:34am +Added option for users to change the format of BBS listings. + +****************** +* RELEASE: v1.20 * +****************** + +10/20/93 04:44pm +Fixed cosmetic problem with opening menu (for users, not sysop). + +****************** +* RELEASE: v1.21 * +****************** + +11/29/93 09:40pm +More cosmetic changes. Added "Saving..." message. + +****************** +* RELEASE: v1.22 * +****************** + +02/02/94 +Added warning for pending auto-deletion of BBS entries. + +02/02/94 +Added option for turning screen pause off/on. + +02/03/94 +Added option in SBL.CFG for sysop/co-sysop notification of changes made to +BBS list by users. + +02/03/94 +Converted all file operations from handles to streams for buffered i/o (speed). + +02/09/94 +Added options for generating a sort index and displaying sorted list based on +various criteria. + +02/09/94 +Added nodesync() calls to display any messages waiting for this user/node. + +02/10/94 +Added search for duplicate names when adding new BBS entries. + +02/10/94 +Notification notice of actual auto-deletion sent to author of BBS entry upon +auto-deletion. + +****************** +* RELEASE: v1.30 * +****************** + +03/14/94 +Added /M switch to force daily maintenance. + +03/22/94 +Fixed occasional double pause after listings. + +03/22/94 +Added total entries found to find text listings. + +03/22/94 +If a user verifies an entry, the user who created the entry is notified. + +03/29/94 +Sysop can define/change the "owner" of an entry when adding or updating. + +04/18/94 +Fixed bug in the sort-by-string functions that caused lock-ups when sorting +more than 312 entries. + +04/18/94 +Lowered memory requirements for all sort functions. + +****************** +* RELEASE: v1.31 * +****************** + +08/23/94 +BBS entries now know whether they were created by a user or by SMB2SBL (via +message base). + +08/23/94 +Fixed problem with hitting Ctrl-C locally during regular (not extended) +listing. Returning to main menu would not clear screen or have correct colors. +'aborted' variable is now reset in main() loop. + +****************** +* RELEASE: v1.32 * +****************** + +08/30/94 +Fixed stack overflow that would cause periodic lock-ups on some systems. + +****************** +* RELEASE: v1.33 * +****************** + +09/08/94 +When deleting an entry, the name of the BBS deleted wasn't being printed. + +02/01/95 +Import utility made mistake of ignoring READ messages to SBL. This has been +fixed. + +*/ + +#include "xsdk.h" +#include "sbldefs.h" + +unsigned _stklen=16000; /* Set stack size in code, not header */ + +typedef struct { + + char str[32]; + short offset; + + } sortstr_t; + +typedef struct { + + long i; + short offset; + + } sortint_t; + +char *nulstr=""; +char *wday[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; +char *mon[]={"Jan","Feb","Mar","Apr","May","Jun" + ,"Jul","Aug","Sep","Oct","Nov","Dec"}; +char tmp[256]; +char list_fmt[128]; +uint del_days,add_ml,update_ml,remove_ml,verify_ml,sbl_pause=1,notify_user; +struct date date; +struct time curtime; +time_t now; + +/****************************************************************************/ +/* Generates a 24 character ASCII string that represents the time_t pointer */ +/* Used as a replacement for ctime() */ +/****************************************************************************/ +char *timestr(time_t *intime) +{ + static char str[256]; + char mer[3],hour; + struct tm *gm; + +gm=localtime(intime); +if(gm->tm_hour>=12) { + if(gm->tm_hour==12) + hour=12; + else + hour=gm->tm_hour-12; + strcpy(mer,"pm"); } +else { + if(gm->tm_hour==0) + hour=12; + else + hour=gm->tm_hour; + strcpy(mer,"am"); } +sprintf(str,"%s %s %02d %4d %02d:%02d %s" + ,wday[gm->tm_wday],mon[gm->tm_mon],gm->tm_mday,1900+gm->tm_year + ,hour,gm->tm_min,mer); +return(str); +} + + +/****************************************************************************/ +/* Converts unix time format (long - time_t) into a char str MM/DD/YY */ +/****************************************************************************/ +char *unixtodstr(time_t unix, char *str) +{ + +if(!unix) + strcpy(str,"00/00/00"); +else { + unixtodos(unix,&date,&curtime); + if((unsigned)date.da_mon>12) { /* DOS leap year bug */ + date.da_mon=1; + date.da_year++; } + if((unsigned)date.da_day>31) + date.da_day=1; + sprintf(str,"%02u/%02u/%02u",date.da_mon,date.da_day + ,date.da_year>=2000 ? date.da_year-2000 : date.da_year-1900); } +return(str); +} + + +/****************************************************************************/ +/* Converts a date string in format MM/DD/YY into unix time format */ +/****************************************************************************/ +time_t dstrtounix(char *str) +{ + +if(!strcmp(str,"00/00/00")) + return(NULL); +curtime.ti_hour=curtime.ti_min=curtime.ti_sec=0; +if(str[6]<7) + date.da_year=2000+((str[6]&0xf)*10)+(str[7]&0xf); +else + date.da_year=1900+((str[6]&0xf)*10)+(str[7]&0xf); +date.da_mon=((str[0]&0xf)*10)+(str[1]&0xf); +date.da_day=((str[3]&0xf)*10)+(str[4]&0xf); +return(dostounix(&date,&curtime)); +} + +void dots(int show) +{ + static int i; + +if(!show) { /* reset */ + i=0; + return; } +if(++i>5) { + bputs("\b\b\b\b\b \b\b\b\b\b"); + i=0; + return; } +outchar('.'); +} + + +/* Displays short information about BBS. Returns 0 if aborted. */ + +char short_bbs_info(bbs_t bbs) +{ + int i,j; + +for(i=0;i<bbs.total_numbers && i<MAX_NUMBERS;i++) { + for(j=0;list_fmt[j];j++) { + if(j) bputs(" "); + switch(toupper(list_fmt[j])) { + case 'N': + bprintf("\1h\1m%-25.25s",i ? nulstr : bbs.name); + break; + case 'S': + bprintf("\1h\1c%-15.15s",i ? nulstr : bbs.software); + break; + case 'P': + bprintf("\1n\1g%12.12s",bbs.number[i].number); + break; + case 'B': + bprintf("\1h\1g%5u",bbs.number[i].max_rate); + break; + case 'M': + bprintf("\1h\1b%-15.15s",bbs.number[i].modem); + break; + case 'Y': + bprintf("\1h\1y%-25.25s",i ? nulstr : bbs.sysop[0]); + break; + case 'T': + if(i) bputs(" "); + else bprintf("\1n\1h%3u",bbs.nodes); + break; + case 'U': + if(i) bputs(" "); + else bprintf("\1n\1r%5u",bbs.users); + break; + case 'H': + if(i) bprintf("%10.10s",nulstr); + else bprintf("\1h\1r%10u",bbs.megs); + break; + case 'L': + bprintf("\1n\1c%-25.25s",bbs.number[i].location); + break; + case 'F': + bprintf("\1n\1b%s",i ? nulstr : unixtodstr(bbs.birth,tmp)); + break; + case 'V': + bprintf("\1n\1m%s",i ? nulstr : unixtodstr(bbs.verified,tmp)); + break; + case 'D': + bprintf("\1n%s",i ? nulstr : unixtodstr(bbs.updated,tmp)); + break; + case 'C': + bprintf("\1n\1y%s",i ? nulstr : unixtodstr(bbs.created,tmp)); + break; + default: + bprintf("%c",list_fmt[j]); + break; + } } + bputs("\r\n"); } +if(kbhit()) + return(0); +return(1); +} + +char long_bbs_info(bbs_t bbs) +{ + int i; + +cls(); +bprintf("\1n\1gBBS Name: \1h%s \1n\1gsince \1h%s\r\n" + ,bbs.name,unixtodstr(bbs.birth,tmp)); +bprintf("\1n\1gOperator: "); +for(i=0;i<bbs.total_sysops && i<MAX_SYSOPS;i++) { + if(i) { + if(bbs.total_sysops>2) + bputs(", "); + else + outchar(SP); + if(!(i%4)) + bputs("\r\n "); + if(i+1==bbs.total_sysops) + bputs("and "); } + bprintf("\1h%s\1n\1g",bbs.sysop[i]); } +CRLF; +bprintf("\1n\1gSoftware: \1h%-15.15s \1n\1gNodes: \1h%-5u \1n\1g" + "Users: \1h%-5u \1n\1gDoors: \1h%u\r\n" + ,bbs.software,bbs.nodes,bbs.users,bbs.xtrns); +bprintf("\1n\1gDownload: \1h%lu \1n\1gfiles in \1h%u \1n\1gdirectories of \1h" + "%luMB \1n\1gtotal space\r\n" + ,bbs.files,bbs.dirs,bbs.megs); +bprintf("Messages: \1h%lu \1n\1gmessages in \1h%u \1n\1gsub-boards\r\n" + ,bbs.msgs,bbs.subs); +bprintf("Networks: "); +for(i=0;i<bbs.total_networks && i<MAX_NETS;i++) { + if(i) { + if(bbs.total_networks>2) + bputs(", "); + else + outchar(SP); + if(!(i%3)) + bputs("\r\n "); + if(i+1==bbs.total_networks) + bputs("and "); } + bprintf("\1h%s [%s]\1n\1g",bbs.network[i],bbs.address[i]); } +CRLF; +bprintf("Terminal: "); +for(i=0;i<bbs.total_terminals && i<MAX_TERMS;i++) { + if(i) { + if(bbs.total_terminals>2) + bputs(", "); + else + outchar(SP); + if(i+1==bbs.total_terminals) + bputs("and "); } + bprintf("\1h%s\1n\1g",bbs.terminal[i]); } +CRLF; +CRLF; +for(i=0;i<bbs.total_numbers && i<MAX_NUMBERS;i++) + bprintf("\1h\1b%-30.30s \1n\1g%12.12s \1h%5u \1b%-15.15s \1n\1c" + "Minimum: \1h%u\r\n" + ,i && !strcmp(bbs.number[i].location,bbs.number[i-1].location) + ? nulstr : bbs.number[i].location + ,bbs.number[i].number + ,bbs.number[i].max_rate,bbs.number[i].modem + ,bbs.number[i].min_rate); + +bputs("\r\n\1w\1h"); +for(i=0;i<5;i++) { + if(!bbs.desc[i][0]) + break; + bprintf("%15s%s\r\n",nulstr,bbs.desc[i]); } + +CRLF; +if(bbs.misc&FROM_SMB) + bputs("\1r\1hImported from message base.\r\n"); +bprintf("\1n\1cEntry created on \1h%s\1n\1c by \1h%s\r\n" + ,timestr(&bbs.created),bbs.user); +if(bbs.updated && bbs.userupdated[0]) + bprintf("\1n\1c Last updated on \1h%s\1n\1c by \1h%s\r\n" + ,timestr(&bbs.updated),bbs.userupdated); +if(bbs.verified && bbs.userverified[0]) + bprintf("\1n\1cLast verified on \1h%s\1n\1c by \1h%s\r\n" + ,timestr(&bbs.verified),bbs.userverified); +CRLF; +if(aborted) { + aborted=0; + return(0); } +if(!sbl_pause) { + if(kbhit()) + return(0); + return(1); } +nodesync(); +return(yesno("More")); +} + +/* Gets/updates BBS info from user. Returns 0 if aborted. */ + +char get_bbs_info(bbs_t *bbs) +{ + char str[128]; + int i; + +aborted=0; +if(!(bbs->user[0])) + strcpy(bbs->user,user_name); +if(SYSOP) { + bputs("\1y\1hUser Name (Creator/Owner of Entry): "); + if(!getstr(bbs->user,25,K_EDIT|K_LINE|K_AUTODEL)) + return(0); } +bputs("\1y\1hSystem Name: "); +if(getstr(bbs->name,25,K_EDIT|K_LINE|K_AUTODEL)<2) + return(0); +if(!bbs->software[0]) + strcpy(bbs->software,"Synchronet"); +bprintf("\1y\1hSoftware: \1w",bbs->software); +if(!getstr(bbs->software,15,K_AUTODEL|K_EDIT)) + return(0); + +for(i=0;i<MAX_SYSOPS && !aborted;i++) { + bprintf("\1y\1hName of System Operator #%d [\1wNone\1y]: ",i+1); + if(!getstr(bbs->sysop[i],25,K_EDIT|K_LINE|K_AUTODEL)) + break; } +bbs->total_sysops=i; +if(aborted) + return(0); + +unixtodstr(bbs->birth,str); +bprintf("\1y\1hFirst Day Online (MM/DD/YY): \1w"); +if(getstr(str,8,K_UPPER|K_EDIT|K_AUTODEL)) + bbs->birth=dstrtounix(str); +if(aborted) return(0); + +for(i=0;i<MAX_NETS && !aborted;i++) { + bprintf("\1y\1hName of Network #%d [\1wNone\1y]: ",i+1); + if(!getstr(bbs->network[i],15,K_EDIT|K_AUTODEL|K_LINE)) + break; + bprintf("\1y\1hNetwork \1wAddress\1y #%d [\1wNone\1y]: \1w",i+1); + getstr(bbs->address[i],25,K_EDIT|K_AUTODEL); } +bbs->total_networks=i; +if(aborted) return(0); + +for(i=0;i<MAX_TERMS && !aborted;i++) { + bprintf("\1y\1hSupported Terminal Type #%d (i.e. TTY, ANSI, RIP) " + "[\1wNone\1y]: ",i+1); + if(!getstr(bbs->terminal[i],15,K_EDIT|K_AUTODEL|K_LINE)) + break; } +bbs->total_terminals=i; +if(aborted) return(0); + +if(!bbs->nodes) + bbs->nodes=1; +bprintf("\1y\1hNodes (maximum number of simultaneous REMOTE users): \1w"); +sprintf(str,"%u",bbs->nodes); +if(getstr(str,5,K_NUMBER|K_EDIT|K_AUTODEL)) + bbs->nodes=atoi(str); +if(!bbs->nodes) + bbs->nodes=1; +if(aborted) return(0); + +for(i=0;i<MAX_NUMBERS;i++) { + if(!i && !bbs->number[i].number[0]) + sprintf(bbs->number[i].number,"%.8s",user_phone); + bprintf("\1y\1hPhone Number #%d (###-###-####) [\1wNone\1y]: ",i+1); + if(!getstr(bbs->number[i].number,12,K_EDIT|K_LINE)) + break; + if(!bbs->number[i].location[0]) { + if(!i) + strcpy(bbs->number[i].location,user_location); + else + strcpy(bbs->number[i].location,bbs->number[i-1].location); } + bprintf("\1y\1hLocation (City, State): \1w"); + if(!getstr(bbs->number[i].location,30,K_EDIT|K_AUTODEL)) + break; + if(aborted) return(0); + + if(!bbs->number[i].min_rate) { + if(i) + bbs->number[i].min_rate=bbs->number[i-1].min_rate; + else + bbs->number[i].min_rate=300; } + bprintf("\1y\1hMinimum Connect Rate: \1w"); + sprintf(str,"%u",bbs->number[i].min_rate); + if(getstr(str,5,K_NUMBER|K_EDIT|K_AUTODEL)) + bbs->number[i].min_rate=atoi(str); + if(aborted) return(0); + + if(!bbs->number[i].max_rate) { + if(i) + bbs->number[i].max_rate=bbs->number[i-1].max_rate; + else + bbs->number[i].max_rate=2400; } + if(bbs->number[i].max_rate<bbs->number[i].min_rate) + bbs->number[i].max_rate=bbs->number[i].min_rate; + bprintf("\1y\1hMaximum Connect Rate (i.e. 2400, 9600, 14400, etc): \1w"); + sprintf(str,"%u",bbs->number[i].max_rate); + if(getstr(str,5,K_NUMBER|K_EDIT|K_AUTODEL)) + bbs->number[i].max_rate=atoi(str); + if(aborted) return(0); + + bprintf("\1y\1hModem Description (i.e. Hayes, HST, V.32, etc): \1w"); + getstr(bbs->number[i].modem,15,K_EDIT|K_AUTODEL); } +if(!i) + return(0); +bbs->total_numbers=i; +if(aborted) + return(0); + +if(!bbs->users) + bbs->users=100; +bprintf("\1y\1hTotal Number of Users: \1w"); +sprintf(str,"%u",bbs->users); +if(getstr(str,5,K_NUMBER|K_EDIT|K_AUTODEL)) + bbs->users=atoi(str); +if(aborted) return(0); + +if(!bbs->subs) + bbs->subs=10; +bprintf("\1y\1hTotal Number of Sub-boards (Message Areas): \1w"); +sprintf(str,"%u",bbs->subs); +if(getstr(str,5,K_NUMBER|K_EDIT|K_AUTODEL)) + bbs->subs=atoi(str); +if(aborted) return(0); + +if(!bbs->msgs) + bbs->msgs=500; +bprintf("\1y\1hTotal Number of Public Messages: \1w"); +sprintf(str,"%lu",bbs->msgs); +if(getstr(str,10,K_NUMBER|K_EDIT|K_AUTODEL)) + bbs->msgs=atol(str); +if(aborted) return(0); + +if(!bbs->dirs) + bbs->dirs=5; +bprintf("\1y\1hTotal Number of Directories (File Areas): \1w"); +sprintf(str,"%u",bbs->dirs); +if(getstr(str,5,K_NUMBER|K_EDIT|K_AUTODEL)) + bbs->dirs=atoi(str); +if(aborted) return(0); + +if(!bbs->files) + bbs->files=250; +bprintf("\1y\1hTotal Number of Downloadable Files: \1w"); +sprintf(str,"%lu",bbs->files); +if(getstr(str,10,K_NUMBER|K_EDIT|K_AUTODEL)) + bbs->files=atol(str); +if(aborted) return(0); + +if(!bbs->xtrns) + bbs->xtrns=5; +bprintf("\1y\1hTotal Number of External Programs (Doors): \1w"); +sprintf(str,"%u",bbs->xtrns); +if(getstr(str,5,K_NUMBER|K_EDIT|K_AUTODEL)) + bbs->xtrns=atoi(str); +if(aborted) return(0); + +if(!bbs->megs) + bbs->megs=40; +bprintf("\1y\1hTotal Storage Space (in Megabytes): \1w"); +sprintf(str,"%lu",bbs->megs); +if(getstr(str,10,K_NUMBER|K_EDIT|K_AUTODEL)) + bbs->megs=atol(str); +if(aborted) return(0); + +for(i=0;i<5;i++) { + bprintf("\1y\1hBBS Description (%d of 5): ",i+1); + if(!getstr(bbs->desc[i],50,K_EDIT|K_AUTODEL|K_LINE)) + break; } + +return(1); +} + +char partname(char *inname, char *inpart) +{ + char name[128],part[128],str[256]; + +strcpy(name,inname); +strupr(name); +strcpy(part,inpart); +strupr(part); +if(inname[0] && (strstr(name,part) || strstr(part,name))) { + sprintf(str,"\r\nDo you mean %s",inname); + if(yesno(str)) + return(1); } +return(0); +} + +int sortint_cmp(sortint_t *int1, sortint_t *int2) +{ + +if(int1->i>int2->i) + return(-1); +if(int1->i<int2->i) + return(1); +return(0); +} + +int sortstr_cmp(sortstr_t *str1, sortstr_t *str2) +{ +return(stricmp(str1->str,str2->str)); +} + +void main(int argc, char **argv) +{ + char str[512],name[128],*p,ch; + short i,j,file,done,sort_by_str; + int maint=0; + long l,found; + bbs_t bbs,tmpbbs; + FILE *stream; + sortstr_t *sortstr; + sortint_t *sortint; + +for(i=1;i<argc;i++) + if(argv[i][0]=='/') + switch(toupper(argv[i][1])) { + case 'M': + maint=1; + break; } + +p=getenv("SBBSNODE"); +if(p) + strcpy(node_dir,p); +else { + printf("\nSBBSNODE environment variable must be set\n"); + exit(0); } + +if(node_dir[strlen(node_dir)-1]!='\\') + strcat(node_dir,"\\"); + +strcpy(str,"SBL.CFG"); +if((file=open(str,O_RDONLY|O_DENYNONE))==-1) { + printf("error opening %s\r\n",str); + exit(1); } +if((stream=fdopen(file,"rb"))==NULL) { + printf("fdopen error with %s\r\n",str); + exit(1); } +fgets(str,81,stream); +del_days=atoi(str); +fgets(str,81,stream); +add_ml=atoi(str); +fgets(str,81,stream); +update_ml=atoi(str); +fgets(str,81,stream); +remove_ml=atoi(str); +fgets(str,81,stream); +verify_ml=atoi(str); +fgets(str,81,stream); +notify_user=atoi(str); +fclose(stream); + +initdata(); +if(maint) + user_misc=(ANSI|COLOR); + +if((file=open("SBL.DAB",O_RDWR|O_BINARY|O_DENYNONE|O_CREAT + ,S_IWRITE|S_IREAD))==-1) { + bprintf("\r\n\7Error opening/creating SBL.DAB\r\n"); + exit(1); } +if((stream=fdopen(file,"w+b"))==NULL) { + bprintf("\r\n\7Error converting SBL.DAB file handle to stream\r\n"); + exit(1); } +setvbuf(stream,0L,_IOFBF,2048); + +if(del_days) { + now=time(NULL); + strcpy(str,"SBLPURGE.DAB"); + if((file=nopen(str,O_RDWR|O_CREAT))==-1) { + printf("Error creating %s\r\n",str); + exit(1); } + l=NULL; + read(file,&l,4); + if(now-l>(24L*60L*60L) || maint) { /* more than a day since update */ + bputs("\r\n\1n\1hRunning daily maintenance for Synchronet BBS List..."); + lseek(file,0L,SEEK_SET); + write(file,&now,4); + close(file); + fseek(stream,0L,SEEK_SET); + while(!feof(stream)) { + if(!fread(&bbs,sizeof(bbs_t),1,stream)) + break; + if(bbs.name[0] && !(bbs.misc&FROM_SMB)) { + if((now-bbs.updated)/(24L*60L*60L)>del_days + && (now-bbs.created)/(24L*60L*60L)>del_days + && (now-bbs.verified)/(24L*60L*60L)>del_days) { + lncntr=0; + bprintf("\r\n\1n\1hAuto-deleting \1m%s\r\n",bbs.name); + sprintf(str,"\1n\1hSBL: \1mYour BBS entry for \1y%s\1m\r\n" + " was auto-deleted from the \1cSynchronet BBS " + "List\r\n",bbs.name); + i=usernumber(bbs.user); + if(i) putsmsg(i,str); + bbs.name[0]=0; + fseek(stream,-(long)(sizeof(bbs_t)),SEEK_CUR); + fwrite(&bbs,sizeof(bbs_t),1,stream); } + else { /* Warn user */ + l=bbs.created; + if(l<bbs.updated) + l=bbs.updated; + if(l<bbs.verified) + l=bbs.verified; + if((now-l)/(24L*60L*60L)>=(del_days/2)) { + bprintf("\r\n\1n\1hWarning \1y%s\r\n",bbs.user); + lncntr=0; + sprintf(str,"\1n\1hSBL: \1mPlease verify your BBS " + "entry for \1y%s\1m\r\n " + "in the \1cSynchronet BBS List " + "\1mor it will be deleted in \1i\1r%u " + "\1n\1h\1mdays.\r\n" + ,bbs.name + ,del_days-((now-l)/(24L*60L*60L))); + i=usernumber(bbs.user); + if(i) putsmsg(i,str); } } } } } + else + close(file); } + +if(maint) + return; + +strcpy(list_fmt,DEF_LIST_FMT); +while(1) { + aborted=0; + attr(LIGHTGRAY); + cls(); + bprintf("\1n\1m\1hSynchronet \1wBBS List \1mv1.37 (XSDK v%s) " + "Developed 1994-1997 Rob Swindell\r\n\r\n",xsdk_ver); + sprintf(str,"~List all systems (condensed)\r\n" + "~Change list format\r\n" + "~Extended information on all systems\r\n" + "~Turn screen pause %s\r\n" + "~Find text in BBS entries\r\n" + "~Generate sorted list\r\n" + "~Display sorted list\r\n" + "~New entry scan\r\n" + "~Add a BBS entry\r\n" + "~Update a BBS entry\r\n" + "~Verify a BBS entry\r\n" + "~Remove a BBS entry\r\n" + "~Quit back to BBS\r\n" + ,sbl_pause ? "OFF" : "ON"); + mnemonics(str); + if(SYSOP) + mnemonics( "~* Undelete entries\r\n"); + + bputs("\r\n"); + + l=filelength(fileno(stream)); + if(l>0) + bprintf("\1n\1cThere are \1h%lu\1n\1c entries in the online BBS list " + "database.\r\n",l/(long)sizeof(bbs_t)); + + if(del_days) { + bprintf("\1n\1cEntries are auto-deleted \1h%u\1n\1c days after " + "last update or verification.\r\n",del_days); + bputs("Users are encouraged to \1hV\1n\1cerify (vouch for) any listed " + "BBSs they call.\r\n"); } + + nodesync(); /* Display any waiting messages */ + + bputs("\r\n\1y\1hWhich: \1w"); + switch(getkeys("CLGDEFSNAURTQV!*",0)) { + case '!': + bprintf("\r\nsizeof(bbs_t)=%u\r\n",sizeof(bbs_t)); + pause(); + break; + case '*': + cls(); + if(!SYSOP) + break; + fseek(stream,0L,SEEK_SET); + while(!feof(stream) && !aborted) { + if(!fread(&bbs,sizeof(bbs_t),1,stream)) + break; + if(!bbs.name[0]) { + bbs.name[0]='?'; + bbs.verified=time(NULL); + sprintf(bbs.userverified,"%.25s",user_name); + if(yesno(bbs.name)) { + bprintf("\1n\1gFirst char: \1h"); + bbs.name[0]=getkey(0); + bprintf("%s\r\n",bbs.name); + fseek(stream,-(long)sizeof(bbs_t),SEEK_CUR); + fwrite(&bbs,sizeof(bbs_t),1,stream); } } } + break; + case 'L': + cls(); + fseek(stream,0L,SEEK_SET); + i=0; + while(!feof(stream) && !aborted) { + if(!fread(&bbs,sizeof(bbs_t),1,stream)) + break; + if(!bbs.name[0]) + continue; + i++; + if(!short_bbs_info(bbs)) + break; + if(!sbl_pause) + lncntr=0; } + bprintf("\r\n\1n\1h%u systems listed.\r\n",i); + if(kbhit()) + getch(); + if(lncntr) + pause(); + break; + case 'C': + cls(); + bputs("\1n\1c\1hList Format Specifier Definitions:\1n\r\n\r\n"); + bputs("\1h\1w(\1mN\1w) \1n\1mName of System\r\n"); + bputs("\1h\1w(\1mS\1w) \1n\1mSoftware Used\r\n"); + bputs("\1h\1w(\1mP\1w) \1n\1mPhone Number\r\n"); + bputs("\1h\1w(\1mB\1w) \1n\1mMaximum Connect Rate (in bps)\r\n"); + bputs("\1h\1w(\1mM\1w) \1n\1mModem Type\r\n"); + bputs("\1h\1w(\1mY\1w) \1n\1mSysop's Name\r\n"); + bputs("\1h\1w(\1mT\1w) \1n\1mTotal Number of Nodes\r\n"); + bputs("\1h\1w(\1mU\1w) \1n\1mTotal Number of Users\r\n"); + bputs("\1h\1w(\1mH\1w) \1n\1mTotal Storage Capacity (in megabytes)\r\n"); + bputs("\1h\1w(\1mL\1w) \1n\1mLocation (City, State)\r\n"); + bputs("\1h\1w(\1mF\1w) \1n\1mDate System was First Online\r\n"); + bputs("\1h\1w(\1mC\1w) \1n\1mDate Entry was Created\r\n"); + bputs("\1h\1w(\1mV\1w) \1n\1mDate Entry was Last Verified\r\n"); + bputs("\1h\1w(\1mD\1w) \1n\1mDate Entry was Last Updated\r\n"); + bprintf("\r\n\1n\1gDefault Format: \1h%s",DEF_LIST_FMT); + bprintf("\r\n\1n\1gCurrent Format: \1h%s\r\n",list_fmt); + bprintf("\r\n\1y\1hNew Format: "); + if(getstr(tmp,10,K_UPPER|K_LINE)) { + if(!strchr(tmp,'P') || !strchr(tmp,'N')) { + bputs("\r\n\1h\1mP\1n\1mhone and \1hN\1n\1mame specifiers " + "must be present in format.\r\n\r\n"); + pause(); } + else + strcpy(list_fmt,tmp); } + break; + case 'E': + fseek(stream,0L,SEEK_SET); + while(!feof(stream) && !aborted) { + if(!fread(&bbs,sizeof(bbs_t),1,stream)) + break; + if(bbs.name[0] && !long_bbs_info(bbs)) + break; + if(!sbl_pause) + lncntr=0; } + break; + case 'F': /* Find text */ + cls(); + bputs("\1y\1hText to search for: "); + if(!getstr(name,25,K_UPPER|K_LINE)) + break; + ch=yesno("\r\nDisplay extended information"); + + found=0; + bputs("\1n\1h\r\nSearching...\r\n\r\n"); + fseek(stream,0L,SEEK_SET); + while(!feof(stream) && !aborted) { + if(!sbl_pause) + lncntr=0; + if(!fread(&bbs,sizeof(bbs_t),1,stream)) + break; + if(!bbs.name[0]) + continue; + tmpbbs=bbs; + strupr(tmpbbs.name); + strupr(tmpbbs.user); + strupr(tmpbbs.userverified); + strupr(tmpbbs.userupdated); + strupr(tmpbbs.software); + if(strstr(tmpbbs.name,name) + || strstr(tmpbbs.user,name) + || strstr(tmpbbs.software,name) + || strstr(tmpbbs.userverified,name) + || strstr(tmpbbs.userupdated,name) + ) { + found++; + if(ch && !long_bbs_info(bbs)) + break; + if(!ch && !short_bbs_info(bbs)) + break; + continue; } + + for(i=0;i<tmpbbs.total_sysops;i++) { + strupr(tmpbbs.sysop[i]); + if(strstr(tmpbbs.sysop[i],name)) + break; } + if(i<tmpbbs.total_sysops) { + found++; + if(ch && !long_bbs_info(bbs)) + break; + if(!ch && !short_bbs_info(bbs)) + break; + continue; } + + for(i=0;i<tmpbbs.total_networks;i++) { + strupr(tmpbbs.network[i]); + strupr(tmpbbs.address[i]); + if(strstr(tmpbbs.network[i],name) + || strstr(tmpbbs.address[i],name)) + break; } + if(i<tmpbbs.total_networks) { + found++; + if(ch && !long_bbs_info(bbs)) + break; + if(!ch && !short_bbs_info(bbs)) + break; + continue; } + + for(i=0;i<tmpbbs.total_terminals;i++) { + strupr(tmpbbs.terminal[i]); + if(strstr(tmpbbs.terminal[i],name)) + break; } + if(i<tmpbbs.total_terminals) { + found++; + if(ch && !long_bbs_info(bbs)) + break; + if(!ch && !short_bbs_info(bbs)) + break; + continue; } + + for(i=0;i<tmpbbs.total_numbers;i++) { + strupr(tmpbbs.number[i].number); + strupr(tmpbbs.number[i].modem); + strupr(tmpbbs.number[i].location); + if(strstr(tmpbbs.number[i].number,name) + || strstr(tmpbbs.number[i].modem,name) + || strstr(tmpbbs.number[i].location,name)) + break; } + if(i<tmpbbs.total_numbers) { + found++; + if(ch && !long_bbs_info(bbs)) + break; + if(!ch && !short_bbs_info(bbs)) + break; + continue; } } + if(!ch || !found) { + CRLF; + if(kbhit()) + getch(); + if(found) + bprintf("\1n\1h%u systems listed.\r\n",found); + pause(); } + break; + case 'G': /* Generated sorted list */ + cls(); + if(!filelength(fileno(stream))) { + bprintf("No BBS list exists.\r\n"); + pause(); + break; } + bputs("\1n\1c\1hSort Options:\1n\r\n\r\n"); + bputs("\1h\1w(\1mN\1w) \1n\1mName of System\r\n"); + bputs("\1h\1w(\1mS\1w) \1n\1mSoftware Used\r\n"); + bputs("\1h\1w(\1mP\1w) \1n\1mPhone Number\r\n"); + bputs("\1h\1w(\1mB\1w) \1n\1mMaximum Connect Rate (in bps)\r\n"); + bputs("\1h\1w(\1mM\1w) \1n\1mModem Type\r\n"); + bputs("\1h\1w(\1mY\1w) \1n\1mSysop's Name\r\n"); + bputs("\1h\1w(\1mT\1w) \1n\1mTotal Number of Nodes\r\n"); + bputs("\1h\1w(\1mU\1w) \1n\1mTotal Number of Users\r\n"); + bputs("\1h\1w(\1mH\1w) \1n\1mTotal Storage Capacity (in megabytes)\r\n"); + bputs("\1h\1w(\1mL\1w) \1n\1mLocation (City, State)\r\n"); + bputs("\1h\1w(\1mF\1w) \1n\1mDate System was First Online\r\n"); + bputs("\1h\1w(\1mC\1w) \1n\1mDate Entry was Created\r\n"); + bputs("\1h\1w(\1mV\1w) \1n\1mDate Entry was Last Verified\r\n"); + bputs("\1h\1w(\1mD\1w) \1n\1mDate Entry was Last Updated\r\n"); + bprintf("\r\n\1y\1hSort by (\1wQ\1y=Quit): \1w"); + ch=getkeys("NSPBMYTUHLFCVDQ",0); + if(!ch || ch=='Q') + break; + cls(); + bputs("\1n\1hSorting... \1m"); + fseek(stream,0L,SEEK_SET); + i=j=done=0; + sort_by_str=0; + sortstr=NULL; + sortint=NULL; + while(!feof(stream) && !done) { + if(!fread(&bbs,sizeof(bbs_t),1,stream)) + break; + j++; + bprintf("\b\b\b\b%4u",j); + if(!bbs.name[0]) /* don't sort deleted entries */ + continue; + i++; + switch(ch) { + case 'N': + sprintf(str,"%.30s",bbs.name); + sort_by_str=1; + break; + case 'S': + sprintf(str,"%.30s",bbs.software); + sort_by_str=1; + break; + case 'P': + sprintf(str,"%.30s",bbs.number[0].number); + sort_by_str=1; + break; + case 'M': + sprintf(str,"%.30s",bbs.number[0].modem); + sort_by_str=1; + break; + case 'Y': + sprintf(str,"%.30s",bbs.sysop[0]); + sort_by_str=1; + break; + case 'L': + sprintf(str,"%.30s",bbs.number[0].location); + sort_by_str=1; + break; + case 'B': + l=bbs.number[0].max_rate; + break; + case 'T': + l=bbs.nodes; + break; + case 'U': + l=bbs.users; + break; + case 'H': + l=bbs.megs; + break; + case 'F': + l=bbs.birth; + break; + case 'C': + l=bbs.created; + break; + case 'V': + l=bbs.verified; + break; + case 'D': + l=bbs.updated; + break; } + if(sort_by_str) { + if((sortstr=(sortstr_t *)farrealloc(sortstr + ,sizeof(sortstr_t)*i))==NULL) { + bprintf("\r\n\7Memory allocation error\r\n"); + farfree(sortstr); + done=1; + continue; } + strcpy(sortstr[i-1].str,str); + sortstr[i-1].offset=j-1; } + else { + if((sortint=(sortint_t *)farrealloc(sortint + ,sizeof(sortint_t)*i))==NULL) { + bprintf("\r\n\7Memory allocation error\r\n"); + farfree(sortint); + done=1; + continue; } + sortint[i-1].i=l; + sortint[i-1].offset=j-1; } } + + if(done) { + pause(); + break; } + + if(sort_by_str) + qsort((void *)sortstr,i,sizeof(sortstr[0]) + ,(int(*)(const void *, const void *))sortstr_cmp); + else + qsort((void *)sortint,i,sizeof(sortint[0]) + ,(int(*)(const void *, const void *))sortint_cmp); + + bprintf("\r\n\r\n\1h\1gCreating index..."); + sprintf(str,"SORT_%03d.NDX",node_num); + if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC))==-1) { + bprintf("\r\n\7Error creating %s\r\n",str); + if(sort_by_str) + farfree(sortstr); + else + farfree(sortint); + pause(); + break; } + for(j=0;j<i;j++) + if(sort_by_str) + write(file,&sortstr[j].offset,2); + else + write(file,&sortint[j].offset,2); + close(file); + if(sort_by_str) + farfree(sortstr); + else + farfree(sortint); + bputs("\r\n\r\n\1n\1hDone.\r\n"); + pause(); + break; + case 'D': + cls(); + sprintf(str,"SORT_%03d.NDX",node_num); + if((file=nopen(str,O_RDONLY))==-1) { + bputs("\1n\1r\1hSorted list not generated.\r\n"); + pause(); } + ch=yesno("Display extended information"); + cls(); + while(!eof(file) && !aborted) { + if(read(file,&i,2)!=2) + break; + fseek(stream,(long)i*sizeof(bbs_t),SEEK_SET); + if(!sbl_pause) + lncntr=0; + if(!fread(&bbs,sizeof(bbs_t),1,stream)) + break; + if(!bbs.name[0]) + continue; + if(ch && !long_bbs_info(bbs)) + break; + if(!ch && !short_bbs_info(bbs)) + break; } + close(file); + if(kbhit()) + getch(); + if(lncntr) + pause(); + break; + case 'N': /* New (updated) entry scan */ + cls(); + bputs("\1y\1hLast update (MM/DD/YY): "); + if(!getstr(str,8,K_UPPER|K_LINE)) + break; + l=dstrtounix(str); + ch=yesno("\r\nDisplay extended information"); + found=0; + bputs("\1n\1h\r\nSearching...\r\n\r\n"); + fseek(stream,0L,SEEK_SET); + while(!feof(stream) && !aborted) { + if(!sbl_pause) + lncntr=0; + if(!fread(&bbs,sizeof(bbs_t),1,stream)) + break; + if(!bbs.name[0]) + continue; + if(bbs.updated>=l || bbs.created>=l) { + if(ch && !long_bbs_info(bbs)) + break; + if(!ch && !short_bbs_info(bbs)) + break; + found++; + continue; } } + if(!ch || !found) { + CRLF; + pause(); } + break; + case 'A': + cls(); + if(user_level<add_ml) { + bprintf("\1h\1rYou have insufficient access.\r\n\r\n"); + pause(); + break; } + bputs("\1g\1hAdding a BBS entry:\1n\r\n\r\n"); + bputs("\1n\1gHit ENTER for unknown data items.\r\n\r\n"); + memset(&bbs,NULL,sizeof(bbs_t)); + if(!get_bbs_info(&bbs)) + break; + bputs("\1n\1h\r\nSearching for duplicates..."); + fseek(stream,0L,SEEK_SET); + i=0; + dots(0); + while(!feof(stream) && !i) { + dots(1); + if(!fread(&tmpbbs,sizeof(bbs_t),1,stream)) + break; + if(!stricmp(tmpbbs.name,bbs.name)) i=1; } + if(i) { + bprintf("\7\1n\1h\1r\1i\r\n\r\n%s \1n\1h\1ralready exists!" + "\r\n\r\n" + ,bbs.name); + pause(); + break; } + + bputs("\1n\1h\r\nSaving..."); + fseek(stream,0L,SEEK_SET); + dots(0); + while(!feof(stream)) { + dots(1); + if(!fread(&ch,1,1,stream)) + break; + if(!ch) { /* first byte is null */ + fseek(stream,-1L,SEEK_CUR); + break; } + fseek(stream,(long)sizeof(bbs_t)-1L,SEEK_CUR); } + bbs.created=time(NULL); + fwrite(&bbs,sizeof(bbs_t),1,stream); + if(notify_user && notify_user!=user_number) { + sprintf(str,"\1n\1hSBL: \1y%s \1madded \1c%s\1m " + "to the BBS List\r\n",user_name,bbs.name); + putsmsg(notify_user,str); } + break; + case 'R': /* Remove an entry */ + cls(); + if(user_level<remove_ml) { + bprintf("\1h\1rYou have insufficient access.\r\n\r\n"); + pause(); + break; } + bprintf("\1y\1hRemove which system: "); + if(!getstr(name,25,K_LINE|K_UPPER)) + break; + bputs("\1n\1h\r\nSearching..."); + fseek(stream,0L,SEEK_SET); + found=0; + dots(0); + while(!feof(stream) && !aborted) { + dots(1); + if(!fread(&bbs,sizeof(bbs_t),1,stream)) + break; + if(!stricmp(bbs.name,name) || partname(bbs.name,name)) { + found=1; + for(i=0;i<bbs.total_sysops && i<MAX_SYSOPS;i++) + if(!stricmp(bbs.sysop[i],user_name)) + break; + if(SYSOP || !stricmp(bbs.user,user_name) + || i<bbs.total_sysops) { + fseek(stream,-(long)(sizeof(bbs_t)),SEEK_CUR); + strcpy(tmp,bbs.name); + bbs.name[0]=0; + bbs.updated=time(NULL); + fwrite(&bbs,sizeof(bbs_t),1,stream); + bprintf("\r\n\r\n\1m%s\1c deleted." + ,tmp); + if(notify_user && notify_user!=user_number) { + sprintf(str,"\1n\1hSBL: \1y%s \1mremoved \1c%s\1m " + "from the BBS List\r\n",user_name,tmp); + putsmsg(notify_user,str); } } + else + bprintf("\r\n\r\n\1rYou did not create \1m%s\1n." + ,bbs.name); + break; } } + if(!found) + bprintf("\r\n\r\n\1m%s\1c not found.",name); + CRLF; + CRLF; + pause(); + break; + case 'T': + sbl_pause=!sbl_pause; + break; + case 'V': /* Verify an entry */ + cls(); + if(user_level<verify_ml) { + bprintf("\1h\1rYou have insufficient access.\r\n\r\n"); + pause(); + break; } + bprintf("\1y\1hVerify which system: "); + if(!getstr(name,25,K_LINE|K_UPPER)) + break; + bputs("\1n\1h\r\nSearching..."); + fseek(stream,0L,SEEK_SET); + found=0; + dots(0); + while(!feof(stream) && !aborted) { + dots(1); + if(!fread(&bbs,sizeof(bbs_t),1,stream)) + break; + if(!stricmp(bbs.name,name) || partname(bbs.name,name)) { + found=1; + bbs.verified=time(NULL); + sprintf(bbs.userverified,"%.25s",user_name); + fseek(stream,-(long)(sizeof(bbs_t)),SEEK_CUR); + fwrite(&bbs,sizeof(bbs_t),1,stream); + bprintf("\r\n\r\n\1m%s\1c verified. \1r\1h\1iThank you!" + ,bbs.name); + sprintf(str,"\1n\1hSBL: \1y%s \1mverified \1c%s\1m " + "in the BBS List\r\n",user_name,bbs.name); + if(notify_user && notify_user!=user_number) + putsmsg(notify_user,str); + if(stricmp(bbs.user,user_name)) { + i=usernumber(bbs.user); + if(i && i!=user_number) putsmsg(i,str); } + break; } } + if(!found) + bprintf("\r\n\r\n\1m%s\1c not found.",name); + CRLF; + CRLF; + pause(); + break; + case 'U': /* Update an entry */ + cls(); + if(user_level<update_ml) { + bprintf("\1h\1rYou have insufficient access.\r\n\r\n"); + pause(); + break; } + bprintf("\1y\1hUpdate which system: "); + if(!getstr(name,25,K_LINE|K_UPPER)) + break; + bputs("\1n\1h\r\nSearching..."); + fseek(stream,0L,SEEK_SET); + found=0; + dots(0); + while(!feof(stream) && !aborted) { + dots(1); + l=ftell(stream); + if(!fread(&bbs,sizeof(bbs_t),1,stream)) + break; + if(!stricmp(bbs.name,name) || partname(bbs.name,name)) { + found=1; + break; } } + if(found) { + for(i=0;i<bbs.total_sysops && i<MAX_SYSOPS;i++) + if(!bbs.sysop[i][0] || !stricmp(bbs.sysop[i],user_name)) + break; + if(SYSOP || !stricmp(bbs.user,user_name) + || i<bbs.total_sysops) { + CRLF; + CRLF; + if(get_bbs_info(&bbs)) { + bbs.misc&=~FROM_SMB; + bbs.updated=time(NULL); + sprintf(bbs.userupdated,"%.25s",user_name); + fseek(stream,l,SEEK_SET); + fwrite(&bbs,sizeof(bbs_t),1,stream); + bprintf("\r\n\1h\1m%s\1c updated.",bbs.name); + if(notify_user && notify_user!=user_number) { + sprintf(str,"\1n\1hSBL: \1y%s \1mupdated \1c%s\1m " + "in the BBS List\r\n",user_name,bbs.name); + putsmsg(notify_user,str); } } } + else + bprintf("\r\n\r\n\1h\1rYou did not create \1m%s\1n." + ,bbs.name); } + else + bprintf("\r\n\r\n\1h\1m%s\1c not found.",name); + CRLF; + CRLF; + pause(); + break; + case 'Q': + return; } } +} + +/* End of SBL.C */ diff --git a/xtrn/sbl/sbl.cfg b/xtrn/sbl/sbl.cfg new file mode 100644 index 0000000000000000000000000000000000000000..6b27510098b8ea9a8263a4eb90caa1e94b90af3d --- /dev/null +++ b/xtrn/sbl/sbl.cfg @@ -0,0 +1,6 @@ +90 Days to keep non-updated entries +10 Minimum security level to add +10 Minimum security level to update +10 Minimum security level to remove +10 Minimum security level to verify +1 User to notify of changes (0=none) diff --git a/xtrn/sbl/sbl.doc b/xtrn/sbl/sbl.doc new file mode 100644 index 0000000000000000000000000000000000000000..22852c29f82d78e76013a0658b444ee4527946f0 --- /dev/null +++ b/xtrn/sbl/sbl.doc @@ -0,0 +1,88 @@ +Synchronet BBS List v1.36 +========================= + +Create the directory: SBL off of your Synchronet XTRN directory. +(Example: C:\SBBS\XTRN\SBL) + +Make sure SBL.EXE and SBL.CFG are in this directory. + +Use an ASCII editor to edit the Synchronet BBS List config file (SBL.CFG) to +your liking. + +Under SCFG->External Programs->Online Programs->Main, hit INS and add +Synchronet BBS List with the following configuration: + +Name Synchronet BBS List +Internal Code SBL +Start-up Directory ..\XTRN\SBL +Command Line SBL +Clean-up Command Line +Multiuser Yes +Intercept I/O Interrupts Yes +Shrink BBS No +Modify User Data No +BBS Data File Type Synchronet XTRN.DAT +Place Drop File In Node Directory + +SBL Utilities +============= + +SBLPACK.EXE Remove deleted entries to save disk space and speed up listings +SBL2TXT.EXE Convert SBL listing to a text file + +Networking the Synchronet BBS List +================================== + +If you wish to link your SBL database with other Synchronet BBSs, you must +carry the Synchronet Data echo via DOVE-Net, FidoNet, or RIME and add +the following two events in SCFG->External Programs->Timed Events: + +Internal Code SMB2SBL +Start-up Directory ..\XTRN\SBL +Command Line SMB2SBL %jSUBS\SYNCDATA SBL.DAB +Execution Node 1 +Execution Days Sun Mon Tue Wed Thu Fri Sat +Execution Time 04:30 +Requires Exclusive Execution No +Force Users Off-line for Event No + +Internal Code SBL2SMB +Start-up Directory ..\XTRN\SBL +Command Line SBL2SMB SBL.DAB %jSUBS\SYNCDATA /S:SYN +Execution Node 1 +Execution Days Sun Mon Tue Wed Thu Fri Sat +Execution Time 04:31 +Requires Exclusive Execution No +Force Users Off-line for Event No + +Change "SYNCDATA" to the internal code of the Synchronet Data sub-board on +your BBS. We used SYNCDATA, since that is the example given in the Synchronet +manual for the DOVE-Net Synchronet Data sub-board internal code. It is okay +if you used a completely different internal code, as long as you specify that +code instead of "SYNCDATA" on the above command lines. + +Make note that all networked SBL entries will be deleted from Vertrauen +(Home of the Synchronet BBS List) after 90 days unless the entry is +retransmitted in the message base or updated manually on Vertrauen in that +time. To cause a retransmission from your BBS, you must (U)pdate the entry +using SBL and then SBL2SMB will re-export it automatically next time it is run +(via Timed Event). (V)erified entries are not re-exported by SBL2SMB, only new +and updated entries. You can also create a BBS entry message by hand (not +using SBL). Download SBBSLIST.ZIP from Vertrauen for more details. + +Source Code +=========== + +If you are a C programmer, you may find the included source code interesting +and/or useful as an example for writing your own XSDK and/or SMB utilities. + +MAKEFILE is for use with Borland C++ v3.x or v4.x and the Synchronet XSDK +to create SBL.EXE. SBL.C and SBLDEFS.H must also in the current directory when +MAKE is run. + +The SMB C library (SMB_120.ZIP) is required to compile SBL2SMB.C and SMB2SBL.C +(MAKE.BAT included to compile them). + +SBL2TXT.C is included as an SBL.DAB to SBL.TXT converter. + +/* End of SBL.DOC */ diff --git a/xtrn/sbl/sbl2smb.c b/xtrn/sbl/sbl2smb.c new file mode 100644 index 0000000000000000000000000000000000000000..a66ab1b105c3b5e31655f578c963f945e824ebc2 --- /dev/null +++ b/xtrn/sbl/sbl2smb.c @@ -0,0 +1,330 @@ +/* SBL2SMB.C */ + +/* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */ + +/* Scans SBL database and posts any additions/updates into the an SMB base */ + +#define uint unsigned int + +#include <dos.h> +#include "smblib.h" +#include "sbldefs.h" + +smb_t smb; +extern int daylight=0; +extern long timezone=0L; + +unsigned _stklen=16000; + +/****************************************************************************/ +/* Checks the disk drive for the existence of a file. Returns 1 if it */ +/* exists, 0 if it doesn't. */ +/****************************************************************************/ +char fexist(char *filespec) +{ + struct ffblk f; + +if(findfirst(filespec,&f,0)==0) + return(1); +return(0); +} + + +/****************************************************************************/ +/* Updates 16-bit "rcrc" with character 'ch' */ +/****************************************************************************/ +void ucrc16(uchar ch, ushort *rcrc) { + ushort i, cy; + uchar nch=ch; + +for (i=0; i<8; i++) { + cy=*rcrc & 0x8000; + *rcrc<<=1; + if (nch & 0x80) *rcrc |= 1; + nch<<=1; + if (cy) *rcrc ^= 0x1021; } +} + +/****************************************************************************/ +/* Returns 16-crc of string (not counting terminating NULL) */ +/****************************************************************************/ +ushort crc16(char *str) +{ + int i=0; + ushort crc=0; + +ucrc16(0,&crc); +while(str[i]) + ucrc16(str[i++],&crc); +ucrc16(0,&crc); +ucrc16(0,&crc); +return(crc); +} + + +/****************************************************************************/ +/* Converts unix time format (long - time_t) into a char str MM/DD/YY */ +/****************************************************************************/ +char *unixtodstr(time_t unix, char *str) +{ + struct time curtime; + struct date date; + +if(!unix) + strcpy(str,"00/00/00"); +else { + unixtodos(unix,&date,&curtime); + if((unsigned)date.da_mon>12) { /* DOS leap year bug */ + date.da_mon=1; + date.da_year++; } + if((unsigned)date.da_day>31) + date.da_day=1; + sprintf(str,"%02u/%02u/%02u",date.da_mon,date.da_day + ,date.da_year>=2000 ? date.da_year-2000 : date.da_year-1900); } +return(str); +} + +#define BUF_LEN 8192 + +int main(int argc, char **argv) +{ + uchar str[128],tmp[128],buf[BUF_LEN],*p,software[128]; + int i,file; + ushort xlat; + long length; + ulong offset; + time_t last,t; + bbs_t bbs; + smbmsg_t msg; + smbstatus_t status; + FILE *stream; + +fprintf(stderr,"\nSBL2SMB v2.00 - Write SBL to SMB - Developed 1994-1997 " + "Rob Swindell\n\n"); +if(argc<3) { + fprintf(stderr,"usage: sbl2smb <sbl.dab> <smb_file> [/s:software]\n\n"); + fprintf(stderr,"ex: sbl2smb c:\\sbbs\\xtrn\\sbl\\sbl.dab " + "c:\\sbbs\\data\\subs\\syncdata /s:syn\n"); + return(1); } + +software[0]=0; +if(argc>3 && !strnicmp(argv[3],"/S:",3)) + strcpy(software,argv[3]+3); + +strcpy(smb.file,argv[2]); +strupr(smb.file); + +strcpy(str,argv[1]); +strupr(str); +if((file=open(str,O_RDONLY|O_BINARY|O_DENYNONE))==-1) { + printf("error opening %s\n",str); + return(1); } +if((stream=fdopen(file,"rb"))==NULL) { + printf("error fdopening %s\n",str); + return(1); } +strcpy(tmp,str); +p=strrchr(tmp,'.'); +if(p) { + (*p)=0; + strcat(tmp,"2SMB.DAB"); + if((file=open(tmp,O_RDWR|O_BINARY|O_CREAT,S_IWRITE|S_IREAD))==-1) { + printf("error opening %s\n",str); + return(1); } + t=time(NULL); + if(read(file,&last,sizeof(time_t))!=sizeof(time_t)) + last=t; + lseek(file,0L,SEEK_SET); + write(file,&t,sizeof(time_t)); + close(file); } + +sprintf(str,"%s.SHD",smb.file); +if(!fexist(str)) { + printf("%s doesn't exist\n",smb.file); + return(0); } +fprintf(stderr,"Opening %s\n",smb.file); +smb.retry_time=30; +if((i=smb_open(&smb))!=0) { + printf("smb_open returned %d\n",i); + return(1); } +i=smb_locksmbhdr(&smb); +if(i) { + printf("smb_locksmbhdr returned %d\n",i); + return(1); } +i=smb_getstatus(&smb); +smb_unlocksmbhdr(&smb); +if(i) { + printf("smb_getstatus returned %d\n",i); + return(1); } + +while(!feof(stream)) { + if(!fread(&bbs,sizeof(bbs_t),1,stream)) + break; + if(!bbs.name[0] || bbs.misc&FROM_SMB + || (bbs.updated<last && bbs.created<last)) + continue; + if(software[0] && strnicmp(software,bbs.software,strlen(software))) + continue; + + printf("%s\r\n",bbs.name); + memset(buf,0,BUF_LEN); + + sprintf(str,"%-15.15s%s\r\n" + ,"Name:",bbs.name); + strcat(buf,str); + + sprintf(str,"%-15.15s%s\r\n" + ,"Birth:",unixtodstr(bbs.birth,tmp)); + strcat(buf,str); + + sprintf(str,"%-15.15s%s\r\n" + ,"Software:",bbs.software); + strcat(buf,str); + + for(i=0;i<bbs.total_sysops;i++) { + sprintf(str,"%-15.15s%s\r\n" + ,"Sysop:",bbs.sysop[i]); + strcat(buf,str); } + + strcat(buf,"\r\n"); + for(i=0;i<bbs.total_numbers;i++) { + sprintf(str,"%-15.15s%s\r\n" + ,"Number:",bbs.number[i].number); + strcat(buf,str); + sprintf(str,"%-15.15s%s\r\n" + ,"Modem:",bbs.number[i].modem); + strcat(buf,str); + sprintf(str,"%-15.15s%s\r\n" + ,"Location:",bbs.number[i].location); + strcat(buf,str); + sprintf(str,"%-15.15s%u\r\n" + ,"MinRate:",bbs.number[i].min_rate); + strcat(buf,str); + sprintf(str,"%-15.15s%u\r\n" + ,"MaxRate:",bbs.number[i].max_rate); + strcat(buf,str); + if(i+1<bbs.total_numbers) + strcat(buf,"\r\n"); } + + if(bbs.total_networks) + strcat(buf,"\r\n"); + for(i=0;i<bbs.total_networks;i++) { + sprintf(str,"%-15.15s%s\r\n" + ,"Network:",bbs.network[i]); + strcat(buf,str); + sprintf(str,"%-15.15s%s\r\n" + ,"Address:",bbs.address[i]); + strcat(buf,str); + if(i+1<bbs.total_networks) + strcat(buf,"\r\n"); } + + strcat(buf,"\r\n"); + for(i=0;i<bbs.total_terminals;i++) { + sprintf(str,"%-15.15s%s\r\n" + ,"Terminal:",bbs.terminal[i]); + strcat(buf,str); } + + strcat(buf,"\r\n"); + sprintf(str,"%-15.15s%lu\r\n" + ,"Megs:",bbs.megs); + strcat(buf,str); + sprintf(str,"%-15.15s%lu\r\n" + ,"Msgs:",bbs.msgs); + strcat(buf,str); + sprintf(str,"%-15.15s%lu\r\n" + ,"Files:",bbs.files); + strcat(buf,str); + sprintf(str,"%-15.15s%u\r\n" + ,"Nodes:",bbs.nodes); + strcat(buf,str); + sprintf(str,"%-15.15s%u\r\n" + ,"Users:",bbs.users); + strcat(buf,str); + sprintf(str,"%-15.15s%u\r\n" + ,"Subs:",bbs.subs); + strcat(buf,str); + sprintf(str,"%-15.15s%u\r\n" + ,"Dirs:",bbs.dirs); + strcat(buf,str); + sprintf(str,"%-15.15s%u\r\n" + ,"Xtrns:",bbs.xtrns); + strcat(buf,str); + + if(bbs.desc[0][0]) + strcat(buf,"\r\n"); + for(i=0;i<5;i++) { + if(!bbs.desc[i][0]) + break; + sprintf(str,"%-15.15s%s\r\n" + ,"Desc:",bbs.desc[i]); + strcat(buf,str); } + + strcat(buf,"\r\n--- SBL2SMB v1.10"); + + length=strlen(buf); /* +2 for translation string */ + + if(status.attr&SMB_HYPERALLOC) + offset=smb_hallocdat(&smb); + else { + i=smb_open_da(&smb); + if(i) { + printf("smb_open_da returned %d\n",i); + exit(1); } + offset=smb_allocdat(&smb,length+2,1); + fclose(smb.sda_fp); } + + fseek(smb.sdt_fp,offset,SEEK_SET); + xlat=XLAT_NONE; + fwrite(&xlat,2,1,smb.sdt_fp); + fwrite(buf,length,1,smb.sdt_fp); + length+=2; + + memset(&msg,0,sizeof(smbmsg_t)); + memcpy(msg.hdr.id,"SHD\x1a",4); + msg.hdr.version=SMB_VERSION; + msg.hdr.when_written.time=time(NULL); + + msg.hdr.offset=offset; + + strcpy(str,"SBL"); + i=smb_hfield(&msg,RECIPIENT,strlen(str),str); + if(i) { + printf("smb_hfield returned %d\n",i); + smb_freemsgdat(&smb,offset,length,1); + exit(1); } + strlwr(str); + msg.idx.to=crc16(str); + + strcpy(str,bbs.user); + i=smb_hfield(&msg,SENDER,strlen(str),str); + if(i) { + printf("smb_hfield returned %d\n",i); + smb_freemsgdat(&smb,offset,length,1); + exit(1); } + strlwr(str); + msg.idx.from=crc16(str); + + strcpy(str,bbs.name); + i=smb_hfield(&msg,SUBJECT,strlen(str),str); + if(i) { + printf("smb_hfield returned %d\n",i); + smb_freemsgdat(&smb,offset,length,1); + exit(1); } + strlwr(str); + msg.idx.subj=crc16(str); + + i=smb_dfield(&msg,TEXT_BODY,length); + if(i) { + printf("smb_dfield returned %d\n",i); + smb_freemsgdat(&smb,offset,length,1); + exit(1); } + + i=smb_addmsghdr(&smb,&msg,status.attr&SMB_HYPERALLOC); + if(i) { + printf("smb_addmsghdr returned %d\n",i); + smb_freemsgdat(&smb,offset,length,1); + exit(1); } + smb_freemsgmem(&msg); } +return(0); +} + +/* End of SBL2SMB.C */ diff --git a/xtrn/sbl/sbl2txt.c b/xtrn/sbl/sbl2txt.c new file mode 100644 index 0000000000000000000000000000000000000000..ee3b720ce866e8642361f9d525f9f98849c55914 --- /dev/null +++ b/xtrn/sbl/sbl2txt.c @@ -0,0 +1,178 @@ +/* SBL2TXT.C */ + +/* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */ + +/* Converts Synchronet BBS List (SBL.DAB) to text file */ + +#include "xsdk.h" +#include "sbldefs.h" + +char *wday[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; +char *mon[]={"Jan","Feb","Mar","Apr","May","Jun" + ,"Jul","Aug","Sep","Oct","Nov","Dec"}; +char *nulstr=""; +char tmp[256]; +struct date date; +struct time curtime; + +extern int daylight=0; +extern long timezone=0L; + +/****************************************************************************/ +/* Generates a 24 character ASCII string that represents the time_t pointer */ +/* Used as a replacement for ctime() */ +/****************************************************************************/ +char *timestr(time_t *intime) +{ + static char str[256]; + char mer[3],hour; + struct tm *gm; + +gm=localtime(intime); +if(gm->tm_hour>=12) { + if(gm->tm_hour==12) + hour=12; + else + hour=gm->tm_hour-12; + strcpy(mer,"pm"); } +else { + if(gm->tm_hour==0) + hour=12; + else + hour=gm->tm_hour; + strcpy(mer,"am"); } +sprintf(str,"%s %s %02d %4d %02d:%02d %s" + ,wday[gm->tm_wday],mon[gm->tm_mon],gm->tm_mday,1900+gm->tm_year + ,hour,gm->tm_min,mer); +return(str); +} + +/****************************************************************************/ +/* Converts unix time format (long - time_t) into a char str MM/DD/YY */ +/****************************************************************************/ +char *unixtodstr(time_t unix, char *str) +{ + +if(!unix) + strcpy(str,"00/00/00"); +else { + unixtodos(unix,&date,&curtime); + if((unsigned)date.da_mon>12) { /* DOS leap year bug */ + date.da_mon=1; + date.da_year++; } + if((unsigned)date.da_day>31) + date.da_day=1; + sprintf(str,"%02u/%02u/%02u",date.da_mon,date.da_day + ,date.da_year>=2000 ? date.da_year-2000 : date.da_year-1900); } +return(str); +} + + +void long_bbs_info(FILE *out, bbs_t bbs) +{ + int i; + +fprintf(out,"BBS Name: %s since %s\r\n" + ,bbs.name,unixtodstr(bbs.birth,tmp)); +fprintf(out,"Operator: "); +for(i=0;i<bbs.total_sysops;i++) { + if(i) { + if(bbs.total_sysops>2) + fprintf(out,", "); + else + fputc(SP,out); + if(!(i%4)) + fprintf(out,"\r\n "); + if(i+1==bbs.total_sysops) + fprintf(out,"and "); } + fprintf(out,"%s",bbs.sysop[i]); } +fprintf(out,"\r\n"); +fprintf(out,"Software: %-15.15s Nodes: %-5u " + "Users: %-5u Doors: %u\r\n" + ,bbs.software,bbs.nodes,bbs.users,bbs.xtrns); +fprintf(out,"Download: %lu files in %u directories of " + "%luMB total space\r\n" + ,bbs.files,bbs.dirs,bbs.megs); +fprintf(out,"Messages: %lu messages in %u sub-boards\r\n" + ,bbs.msgs,bbs.subs); +fprintf(out,"Networks: "); +for(i=0;i<bbs.total_networks;i++) { + if(i) { + if(bbs.total_networks>2) + fprintf(out,", "); + else + fputc(SP,out); + if(!(i%3)) + fprintf(out,"\r\n "); + if(i+1==bbs.total_networks) + fprintf(out,"and "); } + fprintf(out,"%s [%s]",bbs.network[i],bbs.address[i]); } +fprintf(out,"\r\n"); +fprintf(out,"Terminal: "); +for(i=0;i<bbs.total_terminals;i++) { + if(i) { + if(bbs.total_terminals>2) + fprintf(out,", "); + else + fputc(SP,out); + if(i+1==bbs.total_terminals) + fprintf(out,"and "); } + fprintf(out,"%s",bbs.terminal[i]); } +fprintf(out,"\r\n\r\n"); +for(i=0;i<bbs.total_numbers;i++) + fprintf(out,"%-30.30s %12.12s %5u %-15.15s " + "Minimum: %u\r\n" + ,i && !strcmp(bbs.number[i].location,bbs.number[i-1].location) + ? nulstr : bbs.number[i].location + ,bbs.number[i].number + ,bbs.number[i].max_rate,bbs.number[i].modem + ,bbs.number[i].min_rate); + +fprintf(out,"\r\n"); +for(i=0;i<5;i++) { + if(!bbs.desc[i][0]) + break; + fprintf(out,"%15s%s\r\n",nulstr,bbs.desc[i]); } + +fprintf(out,"\r\n"); +fprintf(out,"Entry created on %s by %s\r\n" + ,timestr(&bbs.created),bbs.user); +fprintf(out," Last updated on %s\r\n\r\n",timestr(&bbs.updated)); +} + + +void main(int argc, char **argv) +{ + char software[16]=""; + int i,in; + FILE *out; + bbs_t bbs; + +for(i=1;i<argc;i++) + if(argv[i][0]=='s' && argv[i][1]=='=') + sprintf(software,"%.15s",argv[i]+2); + +if((in=open("SBL.DAB",O_RDONLY|O_BINARY))==-1) { + printf("error opening SBL.DAB\n"); + return; } + +if((out=fopen("SBL.TXT","wb"))==NULL) { + printf("error opening/creating SBL.TXT\n"); + return; } + +while(!eof(in)) { + read(in,&bbs,sizeof(bbs_t)); + if(!bbs.name[0]) + continue; + if(software[0] && strnicmp(bbs.software,software,strlen(software))) + continue; + // long_bbs_info(out,bbs); + for(i=0;i<bbs.total_numbers;i++) + fprintf(out,"%-25.25s %12.12s %5u %s\r\n" + ,bbs.name,bbs.number[i].number + ,bbs.number[i].max_rate + ,bbs.number[i].modem); + } +close(in); +fclose(out); +} diff --git a/xtrn/sbl/sbldefs.h b/xtrn/sbl/sbldefs.h new file mode 100644 index 0000000000000000000000000000000000000000..7c4183cf81c59a46c73ecbba26b1335629f3870a --- /dev/null +++ b/xtrn/sbl/sbldefs.h @@ -0,0 +1,63 @@ +/* SBLDEFS.H */ + +/* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */ + +/* Macros, constants, and type definitions for Synchronet BBS List */ + +#define MAX_SYSOPS 5 +#define MAX_NUMBERS 20 +#define MAX_NETS 10 +#define MAX_TERMS 5 +#define DEF_LIST_FMT "NSPBM" + +/* Misc bits */ + +#define FROM_SMB (1L<<0) /* BBS info imported from message base */ + +typedef struct { + char number[13] /* Phone number */ + ,modem[16] /* Modem description */ + ,location[31]; /* Location of phone number */ + uint min_rate /* Minimum connect rate */ + ,max_rate; /* Maximum connect rate */ + } number_t; + +typedef struct { + char name[26] /* System name */ + ,user[26] /* User who created entry */ + ,software[16] /* BBS software */ + ,total_sysops + ,sysop[MAX_SYSOPS][26] /* Sysop names */ + ,total_numbers + ,total_networks + ,network[MAX_NETS][16] /* Network names */ + ,address[MAX_NETS][26] /* Network addresses */ + ,total_terminals + ,terminal[MAX_TERMS][16] /* Terminals supported */ + ,desc[5][51] /* 5 line description */ + ; + uint nodes /* Total nodes */ + ,users /* Total users */ + ,subs /* Total sub-boards */ + ,dirs /* Total file dirs */ + ,xtrns /* Total external programs */ + ; + time_t created /* Time/date entry was created */ + ,updated /* Time/date last updated */ + ,birth /* Birthdate of BBS */ + ; + ulong megs /* Storage space in megabytes */ + ,msgs /* Total messages */ + ,files /* Total files */ + ,misc /* Miscellaneous bits */ + ; + number_t number[MAX_NUMBERS]; /* Access numbers */ + + char userupdated[26]; /* User who last updated */ + time_t verified; /* Time/Date last vouched for */ + char userverified[26]; /* User who last vouched */ + char unused[444]; /* Unused space */ + } bbs_t; + +/* End of SBL.H */ + diff --git a/xtrn/sbl/sblpack.c b/xtrn/sbl/sblpack.c new file mode 100644 index 0000000000000000000000000000000000000000..9e590b2c0357cf9855a669b8439793a21be2173b --- /dev/null +++ b/xtrn/sbl/sblpack.c @@ -0,0 +1,55 @@ +/* SBLPACK.C */ + +/* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */ + +/***************************************/ +/* Synchronet BBS List Database Packer */ +/***************************************/ + +#include <stdio.h> +#include <share.h> +#include <time.h> +#include <io.h> +#include <fcntl.h> +#include <sys/stat.h> +#include "gen_defs.h" +#include "sbldefs.h" + +int main(void) +{ + int file; + FILE *in,*out; + bbs_t bbs; + +printf("\nSBLPACK v1.00 Developed 1995-1997 Rob Swindell\n\n"); + +if((file=open("SBL.DAB",O_RDWR|O_BINARY|O_DENYNONE|O_CREAT + ,S_IWRITE|S_IREAD))==-1) { + printf("\n\7Error opening/creating SBL.DAB\n"); + exit(1); } +if((in=fdopen(file,"w+b"))==NULL) { + printf("\n\7Error converting SBL.DAB file handle to stream\n"); + exit(1); } +setvbuf(in,0L,_IOFBF,2048); +if((out=fopen("SBL.TMP","wb"))==NULL) { + printf("\n\7Error opening SBL.TMP file\n"); + exit(1); } + +while(!feof(in)) { + if(!fread(&bbs,sizeof(bbs_t),1,in)) + break; + putchar('.'); + if(!bbs.name[0]) + continue; + fwrite(&bbs,sizeof(bbs_t),1,out); } +fcloseall(); +putchar('\n'); +if(remove("SBL.DAB")) { + printf("\n\7Data file in use, can't remove.\n"); + remove("SBL.TMP"); + exit(1); } +rename("SBL.TMP","SBL.DAB"); +printf("\nDone.\n"); +return(0); +} + diff --git a/xtrn/sbl/smb2sbl.c b/xtrn/sbl/smb2sbl.c new file mode 100644 index 0000000000000000000000000000000000000000..e82e560fa4ec7c224eb1e68fc725a28199129dbf --- /dev/null +++ b/xtrn/sbl/smb2sbl.c @@ -0,0 +1,457 @@ +/* SMB2SBL */ + +/* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */ + +/* Scans SMB message base for messages to "SBL" and adds them to the SBL */ +/* database. */ + +#define uint unsigned int + +#include <dos.h> +#include "smblib.h" +#include "sbldefs.h" + +extern int daylight=0; +extern long timezone=0L; +smb_t smb; + +char *loadmsgtxt(smbmsg_t msg, int tails) +{ + char *buf=NULL,*lzhbuf; + ushort xlat; + int i,lzh; + long l=0,lzhlen,length; + +for(i=0;i<msg.hdr.total_dfields;i++) { + if(!(msg.dfield[i].type==TEXT_BODY + || (tails && msg.dfield[i].type==TEXT_TAIL))) + continue; + fseek(smb.sdt_fp,msg.hdr.offset+msg.dfield[i].offset + ,SEEK_SET); + fread(&xlat,2,1,smb.sdt_fp); + lzh=0; + if(xlat==XLAT_LZH) { + lzh=1; + fread(&xlat,2,1,smb.sdt_fp); } + if(xlat!=XLAT_NONE) /* no other translations supported */ + continue; + + length=msg.dfield[i].length-2; + if(lzh) { + length-=2; + if((lzhbuf=MALLOC(length))==NULL) { + printf("ERR_ALLOC lzhbuf of %lu\n",length); + return(buf); } + fread(lzhbuf,1,length,smb.sdt_fp); + lzhlen=*(long *)lzhbuf; + if((buf=REALLOC(buf,l+lzhlen+3))==NULL) { + FREE(lzhbuf); + printf("ERR_ALLOC lzhoutbuf of %l\n",l+lzhlen+1); + return(buf); } + lzh_decode(lzhbuf,length,buf+l); + FREE(lzhbuf); + l+=lzhlen; } + else { + if((buf=REALLOC(buf,l+msg.dfield[i].length+3))==NULL) { + printf("ERR_ALLOC of %lu\n",l+msg.dfield[i].length+1); + return(buf); } + l+=fread(buf+l,1,length,smb.sdt_fp); } + buf[l]=CR; + l++; + buf[l]=LF; + l++; + buf[l]=0; } +return(buf); +} + + +/***************************************************************************/ +/* Truncates white-space chars off end of 'str' and terminates at first CR */ +/****************************************************************************/ +void truncsp(char *str) +{ + char c; + +str[strcspn(str,"\r")]=0; +c=strlen(str); +while(c && (uchar)str[c-1]<=SP) c--; +str[c]=0; +} + +/****************************************************************************/ +/* Checks the disk drive for the existence of a file. Returns 1 if it */ +/* exists, 0 if it doesn't. */ +/****************************************************************************/ +char fexist(char *filespec) +{ + struct ffblk f; + +if(findfirst(filespec,&f,0)==0) + return(1); +return(0); +} + +/****************************************************************************/ +/* Returns the length of the file in 'filespec' */ +/****************************************************************************/ +long flength(char *filespec) +{ + struct ffblk f; + +if(findfirst(filespec,&f,0)==0) + return(f.ff_fsize); +return(-1L); +} + + +/****************************************************************************/ +/* Converts a date string in format MM/DD/YY into unix time format */ +/****************************************************************************/ +time_t dstrtounix(char *str) +{ + struct date date; + struct time curtime; + +if(!strncmp(str,"00/00/00",8)) + return(0); +curtime.ti_hour=curtime.ti_min=curtime.ti_sec=0; +if(str[6]<7) + date.da_year=2000+((str[6]&0xf)*10)+(str[7]&0xf); +else + date.da_year=1900+((str[6]&0xf)*10)+(str[7]&0xf); +date.da_mon=((str[0]&0xf)*10)+(str[1]&0xf); +date.da_day=((str[3]&0xf)*10)+(str[4]&0xf); +return(dostounix(&date,&curtime)); +} + +/****************************************************************************/ +/* Updates 16-bit "rcrc" with character 'ch' */ +/****************************************************************************/ +void ucrc16(uchar ch, ushort *rcrc) { + ushort i, cy; + uchar nch=ch; + +for (i=0; i<8; i++) { + cy=*rcrc & 0x8000; + *rcrc<<=1; + if (nch & 0x80) *rcrc |= 1; + nch<<=1; + if (cy) *rcrc ^= 0x1021; } +} + +/****************************************************************************/ +/* Returns 16-crc of string (not counting terminating NULL) */ +/****************************************************************************/ +ushort crc16(char *str) +{ + int i=0; + ushort crc=0; + +ucrc16(0,&crc); +while(str[i]) + ucrc16(str[i++],&crc); +ucrc16(0,&crc); +ucrc16(0,&crc); +return(crc); +} + +time_t checktime() +{ + struct tm tm; + +memset(&tm,0,sizeof(tm)); +tm.tm_year=94; +tm.tm_mday=1; +return(mktime(&tm)^0x2D24BD00L); +} + +int main(int argc, char **argv) +{ + uchar str[128],*buf,*p; + int i,file,sysop,number,network,terminal,desc; + ulong l,last,high; + ushort sbl; + bbs_t bbs; + smbmsg_t msg; + FILE *stream; + +fprintf(stderr,"\nSMB2SBL v2.00 - Updates SBL via SMB - Developed 1994-1997 " + "Rob Swindell\n\n"); + +if(checktime()) { + printf("Time problem!\n"); + return(-1); } + +if(argc<3) { + fprintf(stderr,"usage: smb2sbl <smb_file> <sbl.dab>\n\n"); + fprintf(stderr,"ex: smb2sbl c:\\sbbs\\data\\subs\\syncdata " + "c:\\sbbs\\xtrn\\sbl\\sbl.dab \n"); + return(1); } + +strcpy(smb.file,argv[1]); +strupr(smb.file); + +strcpy(str,argv[2]); +strupr(str); +if((file=open(str,O_RDWR|O_BINARY|O_DENYNONE|O_CREAT,S_IWRITE|S_IREAD))==-1) { + printf("error opening %s\n",str); + return(1); } +if((stream=fdopen(file,"r+b"))==NULL) { + printf("error fdopening %s\n",str); + return(1); } +setvbuf(stream,NULL,_IOFBF,4096); + +sprintf(str,"%s.SBL",smb.file); +if((file=open(str,O_RDWR|O_BINARY|O_CREAT,S_IWRITE|S_IREAD))==-1) { + printf("error opening %s\n",str); + return(1); } +if(read(file,&last,4)!=4) + last=0; +high=last; + +sprintf(str,"%s.SHD",smb.file); +if(!fexist(str)) { + printf("%s doesn't exist\n",smb.file); + return(0); } +sprintf(str,"%s.SID",smb.file); +if(!flength(str)) { + printf("%s is empty\n",smb.file); + return(0); } +fprintf(stderr,"Opening %s\n",smb.file); +smb.retry_time=30; +if((i=smb_open(&smb))!=0) { + printf("smb_open returned %d\n",i); + return(1); } + +sbl=crc16("sbl"); + +if((i=smb_locksmbhdr(&smb))!=0) { /* Be sure noone deletes or */ + printf("Error locking %d\n",i); /* adds while we're reading */ + return(1); } + +while(!feof(smb.sid_fp)) { + if(!fread(&msg.idx,sizeof(idxrec_t),1,smb.sid_fp)) + break; + fprintf(stderr,"\r%lu ",msg.idx.number); + if(msg.idx.number<=last || msg.idx.to!=sbl) + continue; + high=msg.idx.number; + if((i=smb_lockmsghdr(&smb,&msg))!=0) { + printf("\7Error %d locking msg #%lu\n",i,msg.idx.number); + continue; } + if((i=smb_getmsghdr(&smb,&msg))!=0) { + smb_unlockmsghdr(&smb,&msg); + printf("\7Error %d reading msg #%lu\n",i,msg.idx.number); + continue; } + smb_unlockmsghdr(&smb,&msg); + if(!msg.from_net.type) { /* ignore local message */ + smb_freemsgmem(&msg); + continue; } + + printf("\nMessage #%lu by %s on %.24s\n" + ,msg.hdr.number,msg.from,ctime(&(time_t)msg.hdr.when_written.time)); + + truncsp(msg.subj); + if(!msg.subj[0]) { + smb_freemsgmem(&msg); + continue; } + fprintf(stderr,"Searching for %s...",msg.subj); + fseek(stream,0L,SEEK_SET); + memset(&bbs,0,sizeof(bbs_t)); + while(1) { + l=ftell(stream); + if(!fread(&bbs,sizeof(bbs_t),1,stream)) { + memset(&bbs,0,sizeof(bbs_t)); + break; } + if(msg.subj[0] && !stricmp(bbs.name,msg.subj)) { + fseek(stream,l,SEEK_SET); + break; } } + fprintf(stderr,"\n"); + if(bbs.name[0] && strnicmp(bbs.user,msg.from,25)) { + printf("%s didn't create the entry for %s\n",msg.from,msg.subj); + smb_freemsgmem(&msg); + continue; } + if(!bbs.name[0]) { + fprintf(stderr,"Searching for unused record..."); + fseek(stream,0L,SEEK_SET); + while(1) { /* Find deleted record */ + l=ftell(stream); + if(!fread(&bbs,sizeof(bbs_t),1,stream)) + break; + if(!bbs.name[0]) { + fseek(stream,l,SEEK_SET); + break; } } + fprintf(stderr,"\n"); + memset(&bbs,0,sizeof(bbs_t)); + bbs.created=time(NULL); + if(!bbs.birth) + bbs.birth=bbs.created; + sprintf(bbs.user,"%-.25s",msg.from); } + sprintf(bbs.name,"%-.25s",msg.subj); + bbs.updated=time(NULL); + bbs.misc|=FROM_SMB; + sprintf(bbs.userupdated,"%-.25s",msg.from); + buf=loadmsgtxt(msg,0); + sysop=number=network=terminal=desc=0; + l=0; + while(buf[l]) { + while(buf[l] && buf[l]<=SP) /* Find first text on line */ + l++; + if(!strnicmp(buf+l,"NAME:",5)) { + l+=5; + while(buf[l] && buf[l]<=SP && buf[l]!=CR) + l++; + sprintf(bbs.name,"%-.25s",buf+l); + truncsp(bbs.name); } + if(!strnicmp(buf+l,"BIRTH:",6)) { + l+=6; + while(buf[l] && buf[l]<=SP && buf[l]!=CR) + l++; + bbs.birth=dstrtounix(buf+l); } + if(!strnicmp(buf+l,"SOFTWARE:",9)) { + l+=9; + while(buf[l] && buf[l]<=SP && buf[l]!=CR) + l++; + sprintf(bbs.software,"%-.15s",buf+l); + truncsp(bbs.software); } + if(!strnicmp(buf+l,"SYSOP:",6)) { + l+=6; + while(buf[l] && buf[l]<=SP && buf[l]!=CR) + l++; + sprintf(bbs.sysop[sysop],"%-.25s",buf+l); + truncsp(bbs.sysop[sysop]); + if(sysop<MAX_SYSOPS-1) + sysop++; } + if(!strnicmp(buf+l,"NUMBER:",7)) { + l+=7; + while(buf[l] && buf[l]<=SP && buf[l]!=CR) + l++; + sprintf(bbs.number[number].number,"%-.12s",buf+l); + truncsp(bbs.number[number].number); + if(number<MAX_NUMBERS-1) + number++; } + if(!strnicmp(buf+l,"MODEM:",6)) { + l+=6; + while(buf[l] && buf[l]<=SP && buf[l]!=CR) + l++; + i=number; + if(i) i--; + sprintf(bbs.number[i].modem,"%-.15s",buf+l); + truncsp(bbs.number[i].modem); } + if(!strnicmp(buf+l,"LOCATION:",9)) { + l+=9; + while(buf[l] && buf[l]<=SP && buf[l]!=CR) + l++; + i=number; + if(i) i--; + sprintf(bbs.number[i].location,"%-.30s",buf+l); + truncsp(bbs.number[i].location); } + if(!strnicmp(buf+l,"MINRATE:",8)) { + l+=8; + while(buf[l] && buf[l]<=SP && buf[l]!=CR) + l++; + i=number; + if(i) i--; + bbs.number[i].min_rate=atoi(buf+l); } + if(!strnicmp(buf+l,"MAXRATE:",8)) { + l+=8; + while(buf[l] && buf[l]<=SP && buf[l]!=CR) + l++; + i=number; + if(i) i--; + bbs.number[i].max_rate=atoi(buf+l); } + if(!strnicmp(buf+l,"NETWORK:",8)) { + l+=8; + while(buf[l] && buf[l]<=SP && buf[l]!=CR) + l++; + sprintf(bbs.network[network],"%-.15s",buf+l); + truncsp(bbs.network[network]); + if(network<MAX_NETS-1) + network++; } + if(!strnicmp(buf+l,"ADDRESS:",8)) { + l+=8; + while(buf[l] && buf[l]<=SP && buf[l]!=CR) + l++; + i=network; + if(i) i--; + sprintf(bbs.address[i],"%-.25s",buf+l); + truncsp(bbs.address[i]); } + if(!strnicmp(buf+l,"TERMINAL:",9)) { + l+=9; + while(buf[l] && buf[l]<=SP && buf[l]!=CR) + l++; + sprintf(bbs.terminal[terminal],"%-.15s",buf+l); + truncsp(bbs.terminal[terminal]); + if(terminal<MAX_TERMS-1) + terminal++; } + if(!strnicmp(buf+l,"DESC:",5)) { + l+=5; + while(buf[l] && buf[l]<=SP && buf[l]!=CR) + l++; + sprintf(bbs.desc[desc],"%-.50s",buf+l); + truncsp(bbs.desc[desc]); + if(desc<4) + desc++; } + + if(!strnicmp(buf+l,"MEGS:",5)) { + l+=5; + while(buf[l] && buf[l]<=SP && buf[l]!=CR) + l++; + bbs.megs=atol(buf+l); } + if(!strnicmp(buf+l,"MSGS:",5)) { + l+=5; + while(buf[l] && buf[l]<=SP && buf[l]!=CR) + l++; + bbs.msgs=atol(buf+l); } + if(!strnicmp(buf+l,"FILES:",6)) { + l+=6; + while(buf[l] && buf[l]<=SP && buf[l]!=CR) + l++; + bbs.files=atol(buf+l); } + if(!strnicmp(buf+l,"NODES:",6)) { + l+=6; + while(buf[l] && buf[l]<=SP && buf[l]!=CR) + l++; + bbs.nodes=atoi(buf+l); } + if(!strnicmp(buf+l,"USERS:",6)) { + l+=6; + while(buf[l] && buf[l]<=SP && buf[l]!=CR) + l++; + bbs.users=atoi(buf+l); } + if(!strnicmp(buf+l,"SUBS:",5)) { + l+=5; + while(buf[l] && buf[l]<=SP && buf[l]!=CR) + l++; + bbs.subs=atoi(buf+l); } + if(!strnicmp(buf+l,"DIRS:",5)) { + l+=5; + while(buf[l] && buf[l]<=SP && buf[l]!=CR) + l++; + bbs.dirs=atoi(buf+l); } + if(!strnicmp(buf+l,"XTRNS:",6)) { + l+=6; + while(buf[l] && buf[l]<=SP && buf[l]!=CR) + l++; + bbs.xtrns=atoi(buf+l); } + while(buf[l] && buf[l]>=SP) { /* Go to end of line */ + putchar(buf[l]); + l++; } + printf("\n"); } + if(bbs.total_sysops<sysop) + bbs.total_sysops=sysop; + if(bbs.total_networks<network) + bbs.total_networks=network; + if(bbs.total_terminals<terminal) + bbs.total_terminals=terminal; + if(bbs.total_numbers<number) + bbs.total_numbers=number; + fwrite(&bbs,sizeof(bbs_t),1,stream); + FREE(buf); + smb_freemsgmem(&msg); + } +lseek(file,0L,SEEK_SET); +write(file,&high,4); +close(file); +return(0); +} + diff --git a/xtrn/scb/instruct.msg b/xtrn/scb/instruct.msg new file mode 100644 index 0000000000000000000000000000000000000000..26b95fdb3681763bf2c1e4ece288c9f7c083866b --- /dev/null +++ b/xtrn/scb/instruct.msg @@ -0,0 +1,22 @@ +l chSynchronet Callback + + ngWhen you continue the automatic validation process, chSynchronet Callback +(SCB) ngwill ask you for your phone number. This rhMUSTng be the phone number that +your modem is connected to and it must contain all of the digits necessary for +chSCBng to call you back (including a '1' and area code if necessary). + + If you choose not to continue with the validation process, answer hNOng +to the 'hContinue with verification?ng' question that chSCBng will ask you next. + + After you have entered an hACCEPTABLEng phone number, chSCBng will display a +short message, and call you back. When your phone rings you will need to +answer it with your modem. You should see a 'hRINGng' appear on your screen +(and you may also hear your phone ring if one is connected to the same line as +your modem), when this happens, you will need to type 'hATAng' and press hENTERng. +rhDO NOTng answer the phone by voice! + + The modems will then connect, and you will be given several chances to +enter your correct password. Once you have entered the hCORRECTng password, chSCBng +will display a short message notifying you of this, validate your account, +and then disconnect. If you enter your password hINCORRECTLYng, chSCBng will rhNOTng +validate your account. diff --git a/xtrn/scb/ld_time.msg b/xtrn/scb/ld_time.msg new file mode 100644 index 0000000000000000000000000000000000000000..cee29fdbf3194488a1f51c29ad521b8857faf822 --- /dev/null +++ b/xtrn/scb/ld_time.msg @@ -0,0 +1 @@ +Please try again later. diff --git a/xtrn/scb/no_one.msg b/xtrn/scb/no_one.msg new file mode 100644 index 0000000000000000000000000000000000000000..6d72f2a2f9abcdfbbf031510ba6d53b7e7681d67 --- /dev/null +++ b/xtrn/scb/no_one.msg @@ -0,0 +1 @@ +Phone numbers beginning with '1' are not allowed. diff --git a/xtrn/scb/no_zero.msg b/xtrn/scb/no_zero.msg new file mode 100644 index 0000000000000000000000000000000000000000..2905d1f464fbbed24d8457bc5833a9ab1099e70b --- /dev/null +++ b/xtrn/scb/no_zero.msg @@ -0,0 +1,2 @@ +Phone numbers beginning with '0' are not allowed. + \ No newline at end of file diff --git a/xtrn/scb/phonecan.msg b/xtrn/scb/phonecan.msg new file mode 100644 index 0000000000000000000000000000000000000000..66ddf7f9f7586a07598b27fad9ff40229ee0f6bd --- /dev/null +++ b/xtrn/scb/phonecan.msg @@ -0,0 +1,2 @@ +The number you entered was found in a list of invalid or previously verified +numbers. diff --git a/xtrn/scb/refused.msg b/xtrn/scb/refused.msg new file mode 100644 index 0000000000000000000000000000000000000000..9b984fd684d8e67bc4012b31cfefb7a3c84506ca --- /dev/null +++ b/xtrn/scb/refused.msg @@ -0,0 +1,7 @@ + + ngYou have chosen to refuse the callback verification process. As a +result, you may not be given access to the BBS. If you intend to gain access +to the system, you may wish to leave a note to the Sysop explaining that you +refused the callback verification, and your reasons for doing so, as well as +a number where you CAN be called at. + diff --git a/xtrn/scb/scb.cfg b/xtrn/scb/scb.cfg new file mode 100644 index 0000000000000000000000000000000000000000..e8672699badc050c97e9fc19d81dc5ce2fb9879f --- /dev/null +++ b/xtrn/scb/scb.cfg @@ -0,0 +1,32 @@ +5 +NYNNNNNN +\SBBS\TEXT\PHONE.CAN +\SBBS\TEXT\PHONE.CAN + + + + + + + + + + + +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +7 +11 + diff --git a/xtrn/scb/scb.doc b/xtrn/scb/scb.doc new file mode 100644 index 0000000000000000000000000000000000000000..878b3e69839ee1341d9079a3956b4d5912dd11a2 --- /dev/null +++ b/xtrn/scb/scb.doc @@ -0,0 +1,329 @@ + Synchronet Callback v1.32 Copyright 1995 Digital Dynamics + -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + + Callback Verification Program for Synchronet Multinode BBS Software + + +Installation: +============ + + 1. Create a directory called "SCB" off of your Synchronet XTRN directory. + + Example: + + MD C:\SBBS\XTRN\SCB + + 2. Copy all SCB files into this new directory. + + Example: + + COPY *.* C:\SBBS\XTRN\SCB + + Note, SCB files include: + + SCB.DOC This file + ORDER.TXT Purchase order form + SCB.EXE Callback verifier external program + SCBCFG.EXE Sysop configuration program for SCB + ALLOWED.DAT List of allowable number prefixes + LDPREFIX.DAT List of same-area prefixes that are long dist + SCB.MSG The opening screen for SCB + REFUSED.MSG Verification refused + INSTRUCT.MSG Instructions + NO_ONE.MSG Long distance starting with 1 not allowed + NO_ZERO.MSG Long distance starting with 0 not allowed + NO_LD.MSG Long distance in same area code not allowed + LD_TIME.MSG Not within long distance callback time range + TOOSHORT.MSG Phone number less than minimum number of digits + TOOLONG.MSG Phone number more than maximum number of digits + PHONECAN.MSG Phone number found in trash can file + VERIFIED.MSG Displayed to users after verification + + 3. Run SCFG from your NODE1 directory. + + 4. Go to the External Programs->Online Programs menu. + + 5. Hit the <INSERT> key and enter "Synchronet Callback". + + 6. Hit <ENTER> to edit the configuration for this new program. + + 7. Set the "Start-up Directory" to "..\XTRN\SCB". + + 8. Set "Multiuser" to "Yes". + + 9. Set "Modify Uesr Data" to "Yes". + +10. Set "BBS Drop File Type" to "Synchronet XTRN.DAT" + +11. If you wish to have SCB run automatically for new users or as a logon + event for unvalidated users, set the "Execute on Event" option to the + appropriate event type. Use "Access Requirements" if you wish SCB to be + only available to unvalidated users (i.e. "LEVEL NOT 20"). + +Example SCFG screen: + + �[�][?]���������������������������������������������������ͻ + � Synchronet Callback � + ���������������������������������������������������������� + � �Name Synchronet Callback � + � �Internal Code SCB � + � �Start-up Directory ..\XTRN\SCB � + � �Command Line scb � + � �Clean-up Command Line � + � �Cost in Credits 0 � + � �Access Requirements LEVEL NOT 20 � + � �Execution Requirements � + � �Multiple Concurrent Users Yes � + � �Intercept I/O Interrupts No � + � �Swap BBS out of Memory No � + � �Modify User Data Yes � + � �Execute on Event Logon � + � �BBS Drop File Type Synchronet XTRN.DAT � + � �Place Drop File In Node Directory � + ����������������������������������������������������������ͼ + + +Configuration: +============= + + 1. Go into your SCB directory and run SCBCFG. + + Example: + + CD \SBBS\XTRN\SCB + SCBCFG + + You will see a menu similar to the following: + + �[�][?]���������������������������������������������������ͻ + � Synchronet Callback Configuration � + ���������������������������������������������������������� + � �Toggle Options... � + � �Validation Values... � + � �Allowed Prefix List... � + � �Long Distance Prefix List... � + � �Long Distance Calling Times... � + � �Phone Number Trash Can \SBBS\TEXT\PHONE.CAN � + � �Validated Phone List \SBBS\TEXT\PHONE.CAN � + � �Callback Attempts 4 � + � �Minimum Phone Length 7 � + � �Maximum Phone Length 11 � + � �BBS Area Code 714 � + � �Send Message to Sysop User #1 � + � �Registration Number UNREGISTERED � + ����������������������������������������������������������ͼ + + 2. If your Synchronet text directory is in a directory or drive other + than "\SBBS\TEXT", change the Phone Can and Validated Phone List options + to reflect the correct location of your PHONE.CAN file. + + If you want to allow duplicate validated phone numbers, change the + Validated Phone List to another path and/or filename. If left blank, + the validated phone numbers will not be written to a file at all + (other than the SCB.LOG and possibly the user data). + + The phone number list(s) use the same syntax for trashcan files as + Synchronet BBS. Appending a '~' to a line specifies that the string + cannot be located anywhere within the phone number. Appending a '^' + indicates that the phone number cannot begin with the string. + + The stock PHONE.CAN for Synchronet BBS contains the following: + + 0-^ + 1-^ + 000-~ + 111-~ + 123-^ + 222-^ + 333-^ + 444-^ + 555-~ + 666-^ + 777-^ + 888-^ + 999-^ + 900-^ + 411-~ + 911-~ + 976-~ + 411^ + 911^ + + Since SCB does not allow non-numeric characters in phone numbers, all + entries with the dash (-) character above are ignored. + + 3. SCB uses the dial string specified in the modem configuration in SCFG + for each node for dialing the remote user's modem. The default dial + string is "ATDT". + + 4. Use the "Toggle Options" sub-menu to configure your preferences. + + �[�][?]����������������������������������������������ͻ + � Toggle Options � + ����������������������������������������������������� + � �Validate if Unable to Verify No � + � �Put Result in User Note Yes � + � �Long Distance if not an Allowed Prefix No � + � �Allow Long Distance (Starting with 0) No � + � �Allow Long Distance (Starting with 1) Yes � + � �Allow Long Distance (Same Area Code) Yes � + � �U.S. Style Phone Format (AAA-PPP-SSSS) Yes � + � �Stay Connected After Callback No � + �����������������������������������������������������ͼ + + If the "Validate if Unable to Verify" option is set to "Yes", users will + always be validated. Even if their number was not verified. + + If the "Put Result in User Note" option is set to "Yes", the result of + the verification attempt will be placed in the user's note field + (in the Synchronet BBS user database). + + If the "Long Distance if not an Allowed Prefix" option is set to "Yes", + then all numbers will be considered long distance unless the prefix + is specifically listed in the "Allowed Prefix List" off of the main + menu. If this option is set to "Yes", the "Long Distance Prefix List" + is not used. + + If the "Allow Long Distance (starting with 0)" option is set to "Yes", + then numbers starting with '0' will be allowed. This option does not + effect numbers included in the "Allowed Prefix List". + + If the "Allow Long Distance (starting with 1)" option is set to "Yes", + then numbers starting with '1' will be allowed. This option does not + effect numbers included in the "Allowed Prefix List". + + If the "Allow Long Distance (same area code)" option is set to "Yes", + then numbers that begin with a prefix located in the "Long Distance + Prefix List" will not be allowed. This option does not effect numbers + included in the "Allowed Prefix List". + + If the "U.S. Style Phone Format" option is set to "Yes", then SCB will + assume that phone numbers are in the AAA-PPP-SSSS format, and will + automatically strip the BBS area code from the prefix if the user + entered a number in the same area code as the BBS and included the + area code (both AAA and 1AAA will be stripped). + + The "Stay Connected After Callback" option can be set to "Yes", "No", + or "Local Only". SCB will not disconnect after calling the user back + if this option is set to "Yes". If set to "Local Only", SCB will only + remain connected if the number verfied does not begin with a '1' or '0'. + + 5. Use the "Validation Values" sub-menu to configure how you want validated + users' accounts to be modified. + + �[�][?]�������������������������������������������������������ͻ + � Validation Values � + �������������������������������������������������������������� + � �Security Level 23 � + � �Flag Set 1 CDLN � + � �Flag Set 2 � + � �Flag Set 3 � + � �Flag Set 4 -V � + � �Exemptions � + � �Restrictions -CX � + � �Days to Extend Expiration 0 � + � �Credits to Add � + � �Minutes to Add � + ��������������������������������������������������������������ͼ + + Note: The DEMO version will only set new security level and add credits. + The other validation options are only available in the registered + version. + + 6. Use the "Allowed Prefix List" sub-menu to set which prefixes will NOT be + affected by long distance restrictions (such as long distance + calling times, and numbers starting with 0 or 1). This option is useful + for specifying local numbers in other area codes. For example, in the + 714 area code, 529 prefix, the following non-714 prefixes are local (*): + + 1310690 1310691 1310694 1310697 1310902 1310905 1310943 1310947 + 1818330 1818333 1818336 1818369 1818810 1818854 1818855 1818912 + 1818913 1818937 1818961 1818964 1818965 1818968 1909396 1909468 + 1909594 1909595 1909598 1909860 1909861 1909869 + + * Multiple entries per line to conserve documentation space + + If the "Long Distance if not an Allowed Prefix" toggle option is set to + "Yes", then any number that is NOT included in this list will be + considered long distance. + + 7. Use the "Long Distance Prefix List" sub-menu to set which SAME-AREA + prefixes will be considered long distance. If the "Long Distance if not + an Allowed Prefix" toggle option is set to "Yes", then this list is not + used. For example, in the 714 area code, 529 prefix, the following + 714 prefixes are long distance (*): + + 241 258 259 265 285 418 432 433 434 435 436 437 438 479 480 + 505 513 531 540 541 542 543 544 545 546 547 549 550 554 556 + 557 558 560 564 565 566 567 568 569 571 573 641 647 648 662 + 664 665 667 668 669 691 708 730 731 751 754 755 775 832 834 + 835 836 838 839 850 953 954 957 966 967 972 973 977 979 + + * Multiple entries per line to conserve documentation space + + 8. Use the "Long Distance Calling Times" sub-menu to set the times on each day + when SCB is allowed to place long distance calls. All times are entered + in 24-hour format and ranges crossing midnight (e.g. 18:00 to 09:00) are + valid. Numbers included in the "Allowed Prefix List" will not be limited + to these calling times. + + 9. If you are a registered owner of SCB, be sure to enter your registration + number on the main menu. + +10. Hit ESC from the main SCB configuration menu and select "Yes" to save + the configuration file. + + +Notes: +===== + +All SCB activity is logged to the file SCB.LOG in the SCB directory in +the format: + + Node 7 : Mon Sep 27 16:44:31 1993 + User Name : Digital Man + Voice Number : 714-529-6328 + Modem Number : 5295313 + Result : Verified + +Results Description +------- ----------- +Hung up User hung up before or during validation process +Refused User refused validation +Long Dist User is a long distance call and long distance is disallowed +Invalid # User entered a number that is in the trashcan file, less than + minimum length, or begins with a disallowed number (0 or 1) +No Init Modem could not be initialized +No Connect Modem could not connect to user's modem (possibly wrong #) +Verified User was called, modem connected, and password verified +Bad Pass User was called, modem connected, and incorrect password + + +Customizations: +============== + +The following files can be modified (optionally using Ctrl-A codes for color): + +SCB.MSG The opening screen for SCB +REFUSED.MSG Verification refused +INSTRUCT.MSG Instructions +NO_ONE.MSG Long distance numbers starting with 1 not allowed +NO_ZERO.MSG Long distance numbers starting with 0 not allowed +LD_TIME.MSG Not within allowed long distance callback time range +TOOSHORT.MSG Phone number is less than configured minimum number of digits +PHONECAN.MSG Phone number found in trashcan file +VERIFIED.MSG Displayed to users after verification + + +Registration: +============ + +If you wish to order a registered copy of SCB at the same time as Synchronet, +use the Synchronet ORDER.TXT file (in the SBBS\DOCS directory). + +If registering SCB after already purchasing a copy of Synchronet, call +Digital Dynamics voice at 714-529-6328, Support BBS at 714-529-9525 (and use +Domain Shopper), or complete the ORDER.TXT file in the SCB directory and mail +or fax it to Digital Dynamics. + +/* End of SCB.DOC */ diff --git a/xtrn/scb/scb.msg b/xtrn/scb/scb.msg new file mode 100644 index 0000000000000000000000000000000000000000..617338c75d3cab422a30073429c9ce822744c7de --- /dev/null +++ b/xtrn/scb/scb.msg @@ -0,0 +1,8 @@ +ng Synchronet Callback can be used to verify your modem phone number. +If your modem phone number is verified, your access on the BBS may be +immediately upgraded or the sysop will be notified of the verification and your +access may be upgraded later. + + Some BBSs may not allow long distance verification calls. If you are +not a local call from this BBS and it doesn't allow long distance calls, +you will be notified of this when you start the verification procedure. diff --git a/xtrn/scb/toolong.msg b/xtrn/scb/toolong.msg new file mode 100644 index 0000000000000000000000000000000000000000..079411abdeee7b5559aa0c98c49ee77f864f5980 --- /dev/null +++ b/xtrn/scb/toolong.msg @@ -0,0 +1,2 @@ +Your phone number is too long to be valid. + diff --git a/xtrn/scb/tooshort.msg b/xtrn/scb/tooshort.msg new file mode 100644 index 0000000000000000000000000000000000000000..e31e216680ed482057ce281bce6cd55d9e3195ed --- /dev/null +++ b/xtrn/scb/tooshort.msg @@ -0,0 +1 @@ +Your phone number is too short to be valid. diff --git a/xtrn/scb/verified.msg b/xtrn/scb/verified.msg new file mode 100644 index 0000000000000000000000000000000000000000..ae5b1c8f293eec75d0eee41bee30520749295c83 --- /dev/null +++ b/xtrn/scb/verified.msg @@ -0,0 +1,5 @@ + +ghYour number has been verified and your access upgraded. Please call back +to use your upgraded security! + +p \ No newline at end of file diff --git a/xtrn/scb/whats.new b/xtrn/scb/whats.new new file mode 100644 index 0000000000000000000000000000000000000000..2945099c7fe7c0d220110fea7f2dc96da2239f09 --- /dev/null +++ b/xtrn/scb/whats.new @@ -0,0 +1,21 @@ +What's new in SCB v1.20 +======================= + + o Supports new communications routines, supporting UART, FOSSIL, + BIOS (PC BIOS), EBIOS (PS/2 BIOS), and DigiBoard support. + +If installing over existing SCB install, just update SCB*.EXE and SCB.DOC. + + +What's new in SCB v1.12 +======================= + + o Updated and more comprehensive documentation. + o New "Long Distance if not an Allowed Prefix" toggle option. + o If the user's expiration date is already set to the future, it will be + extended by the number of days in SCBCFG. Previously, expiration dates + would always be set to the current date plus the number of days set in + SCBCFG. + +If installing over existing SCB install, just update SCB*.EXE and SCB.DOC. + diff --git a/xtrn/sdk/xsdk.c b/xtrn/sdk/xsdk.c new file mode 100644 index 0000000000000000000000000000000000000000..34ebaa8abb1ad5d98269507dc292afff520a068f --- /dev/null +++ b/xtrn/sdk/xsdk.c @@ -0,0 +1,2476 @@ +/* XSDK.C */ + +/****************************************************************************/ +/* Synchronet External Program Software Development Kit */ +/* 1995 Digital Dynamics */ +/****************************************************************************/ + +/****************************************************************************/ +/* This source code file is public domain and may be modified, compiled */ +/* distributed, or used in any way, in part or whole for any purposes */ +/* without the consent or notification of Digital Dynamics. */ +/* */ +/* We only request that you display to the user, at some point, in your */ +/* program the character "XSDK" and the version number. */ +/* example: bprintf("XSDK v%s",xsdk_ver); */ +/****************************************************************************/ + +/****************************************************************************/ +/* The source code for two external programs developed by Digital Dynamics */ +/* using XSDK (Synchronet Blackjack [SBJ] and Synchronet BBS List [SBL]) */ +/* are available to the public domain as examples of how to implement the */ +/* functions and variables included in this software development kit. */ +/****************************************************************************/ + +/****************************************************/ +/* For use with Borland/Turbo C and C++ compilers. */ +/* Tabstop set to 4. */ +/****************************************************/ + +/***************************** Revision History *****************************\ + + Initial version for use with Synchronet v1a r6 + 1.0� + Added bgotoxy() macro + Added mnehigh and mnelow vars for control of the mnemonic colors + Added sys_nodes and node_num variables to xtrn_sdk.c + Added MAX_NODES to xtrn_sdk.h + Added printfile() function to xtrn_sdk.c + Added rputs() (Raw put string) + Added getstr() (Get string) + Added redrwstr() (Redraw string) + Added stripattr() (String attributes) + Added sys_op var and the reading from the xtrn.dat + Removed user_min and the reading from the xtrn.dat + Changed read_xtrn_dat() to initdata() + Added ctrl-break handler to xtrn_sdk + Changed xtrn.dat format (again), adding system operator, + guru name, user ml, tl, birthdate and sex. + Added username() function + Renamed xtrn_sdk.* to xsdk.* and xtrnvars.c to xsdkvars.c + and xtrndefs.h to xsdkdefs.h + Added fexist() function + 1.0 + Ctrl-p is now switched into ctrl-^ by SBBS + Fixed relative data_dir bug in username() + 1.01 + Added flength() function and lowered disk activity + Lowered MAX_CARDS from 20 to 10 and made the re-shuffling happen + less often. + 1.02 + Fixed bug in attr() for monochrome users + 1.03 + Made warning and timeout times variables (sec_warn and sec_timeout) + Added SYSOP macro + Made it so sysop won't get timeout + Added user's phone number to XTRN.DAT + Added modem and com port information to XTRN.DAT + Added ahtoul function + Changed getstr commands Ctrl-L to Ctrl-R and Ctrl-P to Ctrl-\ + 1.04 + Added intercommunication between the external programs and users + on the BBS or other external programs written with XSDK. + Added rprintf() function + Made many changes to getstr() function + 2.00 + Added DESQview awareness + Removed difftime() function calls completely + Added ungetkey() function + Added memory address of last modem status register for com routines + so we can track DCD incase user hangs up. + Added checkline function that does the checking of DCD. + Added new bug-free fdelay() routine to replace TC's delay() that + crashes multi-taskers such as DESQview and Windows + 2.01 + Added external program name access for user listings. + Added last node to send message to remembering and defaulting. + Added MALLOC and FREE macros for memory model non-specific memory + allocation. + 2.02 + Added INTRSBBS.DAT support for Synchronet shrinking to run programs + written with XSDK (new with v1b rev 01). + Added user's main flags, transfer flags, exemptions, and + restrictions to XTRN.DAT + Added support for the NODE_PAGE action (paging for private chat) + when listing nodes (printnodedat()). + Added user expiration date support to XTRN.DAT + 2.03 + Fixed bug with com_base variable being messed up. + New messaging system supported (for v1b r2 and higher) + (putnmsg and getnmsg functions). + 2.10 + Added support for file retrieving node status display. + NOPEN collision notice only appears after 25 retries. + 2.11 + Changed getnmsg function to not use IXB files. + Changed getsmsg function to not re-open for truncate. + Added user address, location, and zip/postal code suppport. + Added support for local arrow keys, home, end, ins, and del. + Remote keys ^] (back one space) and ^BkSpc (del) supported now. + Added support for high-bit Ctrl-A codes (for cursor positioning) + Removed file locking check - slowed down initialization sometimes. + Change user_ml to user_level, removed user_tl, changed user_mf to + user_flags1, changed user_tf to user_flags2, and added + user_flags3 and user_flags4. + cls() now updates lncntr like it should have. + Added ctrl-break handler so that users can abort printfile() + If a ctrl-c is received by inkey, the aborted flag is set. + Removed fdelay from XSDK and replaced with mswait for better + multitasker performance + 2.20 + New mswait that support OS2/Windows, DOS Idle, and non-DV modes. + XTRN.DAT passes mode of mswait configured in node setup. + 2.21 + Added user's real name/company name (user_realname) to XTRN.DAT + 2.22 + Added usernumber() function to get user number from a user name. + 2.23 + DTE rate (com_rate) now a ulong (instead of uint) to allow 115.2K + 2.24 + New K_AUTODEL mode for getstr() function, to be used in conjunction + with the K_EDIT mode. Makes overwriting existing strings very + easy for users. + Supports intelligent timeslice APIs while waiting for a key with + getkey() and with getstr() if K_LOWPRIO mode is used. + Hitting Ctrl-C sets the 'aborted' variable to 1. + Time zone and daylight savings automatically initialized to 0. + Modem strings up to 63 chars in XTRN.DAT now supported. + Fixed 10 character zip code bug in XSDKVARS.C. + Node directories (node_dir) up to 127 chars now supported. + nopen() can now open DENYNONE if passed access O_DENYNONE. + 2.30 + Added support for the following Ctrl-A codes: ;,.<>[]A + Changed definitions of TAB, SP, etc. to hex + 2.31 + C restriction disallows users to use Ctrl-P. + T exemption disables "Time's up" message. + Added center() function for outputting centered lines of text. + Added auto-pause to cls() and outchar() functions when clearing + the screen and lncntr is greater than 1 + Changed bstrlen() to not count control characters (CR,LF,TAB,etc) + XSDK is now Watcom C++ compatible (although SBJ.C and SBL.C aren't) + XSDK.H is now *.CPP compatible + Added support for Ctrl-AQ (reset pause) and Ctrl-AZ (premature EOF) + 2.32 + Change bstrlen(char *str) to bstrlen(uchar *str) + Fixed bug in getstr() when word-wrapping a line that contains + ctrl-a codes and the input string did not begin at column 1. + Added user_dce variable (initialized by initdata from XTRN.DAT) + Fixed printnodedat() to not show Waiting for call (M) + Fixed typo in C restriction Ctrl-P message. + Moved call of checkline() in getkey() to immediately abort when + user hangs-up, even when keys are in the input buffer. + Added setmode() call to initdata() to set stderr to binary mode + Changed putchar() to write() in outchar() to elminate LF to CRLF + expansion + 2.33 + Improved cls() routine for auto-pause feature. + Added get_term() automatic RIP and WIP terminal detection function. + 2.34 + Added exec_dir, text_dir, and temp_dir variables to XTRN.DAT + format and initdata() function. + Added _fullpath() calls to initdata() to fix dir paths. + Added sys_id (QWK ID) to XTRN.DAT format and initdat() func. + Added node_misc to XTRN.DAT format and initdata() function. + If NM_LOWPRIO (low priority string input) is toggled on in + node_misc, then time-slices are always given up during input. + XSDK is now Symantec C++ compatible + 2.40 + node_misc was being read as a decimal number (it's stored in + the XTRN.DAT as hex), thus causing time-slice APIs to not + function correctly. + 2.41 + Ctrl-T is now intercepted by inkey() and displays the time the + program was launched, the current time, time used, and time + left (similar to SBBS). + Users are now warned of their last 5 minutes available (like SBBS). + 2.42 + +\****************************************************************************/ + +#include "xsdk.h" + +char *xsdk_ver="2.42"; + +#ifdef __TURBOC__ +extern long timezone=0L; +extern daylight=0; +#endif + +#ifdef __SC__ +#include <disp.h> +short wherey(void); +void clrscr(void); +#endif + + +/****************************************************************************/ +/* This allows users to abort the listing of text by using Ctrl-C */ +/****************************************************************************/ +int cbreakh(void) /* ctrl-break handler */ +{ +aborted=1; +return(1); /* 1 to continue, 0 to abort */ +} + +/****************************************************************************/ +/* Performs printf() using bbs bputs function */ +/****************************************************************************/ +int bprintf(char *fmt, ...) +{ + va_list argptr; + char sbuf[1024]; + int chcount; + +va_start(argptr,fmt); +chcount=vsprintf(sbuf,fmt,argptr); +va_end(argptr); +bputs(sbuf); +return(chcount); +} + +/****************************************************************************/ +/* Performs printf() using bbs rputs function */ +/****************************************************************************/ +int rprintf(char *fmt, ...) +{ + va_list argptr; + char sbuf[1024]; + int chcount; + +va_start(argptr,fmt); +chcount=vsprintf(sbuf,fmt,argptr); +va_end(argptr); +rputs(sbuf); +return(chcount); +} + +/****************************************************************************/ +/* Outputs a NULL terminated string locally and remotely (if applicable) */ +/****************************************************************************/ +void bputs(char *str) +{ + ulong l=0; + +while(str[l] && !aborted) { + if(str[l]==1) { /* ctrl-a */ + ctrl_a(str[++l]); /* skip the ctrl-a */ + if(str[l]=='Z') /* Ctrl-AZ marks premature end of file */ + break; + l++; } /* skip the attribute code */ + else + outchar(str[l++]); } +} + +/****************************************************************************/ +/* Outputs a NULL terminated string locally and remotely (if applicable) */ +/* Does not process ctrl-a codes (raw output) */ +/* Max length of str is 64 kbytes */ +/****************************************************************************/ +void rputs(char *str) +{ + ulong l=0; + +while(str[l]) + outchar(str[l++]); +} + +/****************************************************************************/ +/* Returns the number of characters in 'str' not counting ctrl-ax codes */ +/* or the null terminator */ +/****************************************************************************/ +int bstrlen(uchar *str) +{ + int i=0; + +while(*str) { + if(*str<SP) { /* ctrl char */ + if(*str==1) /* ctrl-A */ + str++; + else if(*str!=CR && *str!=LF && *str!=FF) + i++; } + else + i++; + if(!(*str)) + break; + str++; } +return(i); +} + +/****************************************************************************/ +/* Outputs the string 'str' centered for an 80 column display */ +/* Automatically appends "\r\n" to output */ +/****************************************************************************/ +void center(char *str) +{ + int i,j; + +j=bstrlen(str); +for(i=0;i<(80-j)/2;i++) + outchar(SP); +bputs(str); +} + +/****************************************************************************/ +/* Outputs one character to the screen. Handles, pause, saving and */ +/* restoring lines, etc. */ +/****************************************************************************/ +void outchar(char ch) +{ + +write(fileno(con_fp),&ch,1); + +if(ch==LF) { + lncntr++; + lbuflen=0; + tos=0; } +else if(ch==FF) { + if(lncntr>1) { + lncntr=0; + CRLF; + pause(); } + lncntr=0; + lbuflen=0; + tos=1; } +else if(ch==BS) { + if(lbuflen) + lbuflen--; } +else { + if(!lbuflen) + latr=curatr; + if(lbuflen>=LINE_BUFSIZE) lbuflen=0; + lbuf[lbuflen++]=ch; } +if(lncntr==user_rows-1) { + lncntr=0; + pause(); } +} + +/****************************************************************************/ +/* Prints PAUSE message and waits for a key stoke */ +/****************************************************************************/ +void pause(void) +{ + uchar tempattrs=curatr,*msg="\1_\1r\1h[Hit a key] "; + int i,j; + +lncntr=0; +bputs(msg); +j=bstrlen(msg); +getkey(0); +for(i=0;i<j;i++) + bputs("\b \b"); +attr(tempattrs); +} + +/****************************************************************************/ +/* Prompts user for Y or N (yes or no) and CR is interpreted as a Y */ +/* Returns 1 for Y or 0 for N */ +/* Called from quite a few places */ +/****************************************************************************/ +char yesno(char *str) +{ + char ch; + +bprintf("\1_\1b\1h%s (Y/n) ? \1w",str); +while(1) { + ch=getkey(K_UPPER); + if(ch=='Y' || ch==CR) { + bputs("Yes\r\n"); + return(1); } + if(ch=='N' || aborted) { + bputs("No\r\n"); + return(0); } } +} + +/****************************************************************************/ +/* Prompts user for N or Y (no or yes) and CR is interpreted as a N */ +/* Returns 1 for N or 0 for Y */ +/* Called from quite a few places */ +/****************************************************************************/ +char noyes(char *str) +{ + char ch; + +bprintf("\1_\1b\1h%s (y/N) ? \1w",str); +while(1) { + ch=getkey(K_UPPER); + if(ch=='N' || ch==CR || aborted) { + bputs("No\r\n"); + return(1); } + if(ch=='Y') { + bputs("Yes\r\n"); + return(0); } } +} + +/****************************************************************************/ +/* Outputs a string highlighting characters preceeded by a tilde with the */ +/* color specified in mnehigh and the rest of the line is in color mnelow. */ +/* If the user doesn't have ANSI, it puts the character following the tilde */ +/* in parenthesis. */ +/****************************************************************************/ +void mnemonics(char *str) +{ + long l; + +attr(mnelow); +l=0L; +while(str[l]) { + if(str[l]=='~' && str[l+1]) { + if(!(user_misc&ANSI)) + outchar('('); + l++; + attr(mnehigh); + outchar(str[l]); + l++; + if(!(user_misc&ANSI)) + outchar(')'); + attr(mnelow); } + else + outchar(str[l++]); } +attr(LIGHTGRAY); +} + +/****************************************************************************/ +/* If a key has been pressed, the ASCII code is returned. If not, 0 is */ +/* returned. Ctrl-P and Ctrl-U are intercepted here. */ +/****************************************************************************/ +char inkey(int mode) +{ + static in_ctrl_p; + uchar ch=0,hour,min,sec; + ushort tleft; + uint i; + time_t now; + +if(keybufbot!=keybuftop) { + ch=keybuf[keybufbot++]; + if(keybufbot==KEY_BUFSIZE) + keybufbot=0; } +else if(_bios_keybrd(1)) { + i=_bios_keybrd(0); + if(i&0xff) + ch=i&0xff; + else { /* Local Alt or Function key hit */ + i>>=8; + switch(i) { + case 0x47: /* Home - Same as Ctrl-B */ + return(2); /* ctrl-b beginning of line */ + case 0x4b: /* Left Arrow - same as ctrl-] */ + return(0x1d); + case 0x4d: /* Right Arrow - same as ctrl-f */ + return(6); + case 0x48: /* Up arrow - same as ctrl-^ */ + return(0x1e); + case 0x50: /* Down arrow - same as CR */ + return(CR); + case 0x4f: /* End - same as Ctrl-E */ + return(5); /* ctrl-e - end of line */ + case 0x52: /* Insert */ + return(0x1f); /* ctrl-minus - insert mode */ + case 0x53: /* Delete */ + return(0x7f); /* ctrl-bkspc - del cur char */ + } + return(0); } } + +if(ch==0x10 || ch==0x1e) { /* Ctrl-P or Ctrl-^ */ + if(in_ctrl_p || !ctrl_dir[0]) /* keep from being recursive */ + return(0); + in_ctrl_p=1; + SAVELINE; + CRLF; + nodemsg(); + CRLF; + RESTORELINE; + lncntr=0; + in_ctrl_p=0; + return(0); } + +if(ch==20) { /* Ctrl-T Time left online */ + SAVELINE; + attr(LIGHTGRAY); + now=time(NULL); + checktimeleft(); + CRLF; + bprintf("\r\nStart : %.24s",ctime(&starttime)); + bprintf("\r\nNow : %.24s",ctime(&now)); + i=now-starttime; + hour=(i/60)/60; + min=(i/60)-(hour*60); + sec=i-((min+(hour*60))*60); + bprintf("\r\nTime Used : %02u:%02u:%02u",hour,min,sec); + tleft=timeleft-(now-starttime); + hour=(tleft/60)/60; + min=(tleft/60)-(hour*60); + sec=tleft-((min+(hour*60))*60); + bprintf("\r\nTime Left : %02u:%02u:%02u\r\n\r\n",hour,min,sec); + RESTORELINE; + lncntr=0; + return(0); } + +if(ch==21) { /* Ctrl-U Users online */ + if(!ctrl_dir[0]) + return(0); + SAVELINE; + CRLF; + whos_online(1); + CRLF; + RESTORELINE; + lncntr=0; + return(0); } + +if(ch==3) + aborted=1; +else if(aborted) + ch=3; + +if(!ch && (!(mode&K_GETSTR) || mode&K_LOWPRIO|| node_misc&NM_LOWPRIO)) + mswait(0); +return(ch); +} + +/****************************************************************************/ +/* Waits for remote or local user to hit a key. Inactivity timer is checked */ +/* and hangs up if inactive for 4 minutes. Returns key hit, or uppercase of */ +/* key hit if mode&K_UPPER or key out of KEY BUFFER. Does not print key. */ +/****************************************************************************/ +char getkey(int mode) +{ + char ch,warn=0; + ushort tleft; + time_t timeout,now; + +aborted=lncntr=0; +timeout=time(NULL); +do { + checkline(); + ch=inkey(mode); + now=time(NULL); + if(ch) { + if(mode&K_NUMBER && isprint(ch) && !isdigit(ch)) + continue; + if(mode&K_ALPHA && isprint(ch) && !isalpha(ch)) + continue; + if(ch==LF) continue; + if(mode&K_UPPER) + return(toupper(ch)); + return(ch); } + checktimeleft(); + + tleft=timeleft-(now-starttime); + if((tleft/60)<(5-timeleft_warn)) { /* Running out of time warning */ + timeleft_warn=5-(tleft/60); + SAVELINE; + bprintf("nh\r\n\7\r\nYou only have ri%unh minute%s " + "left.\r\n\r\n" + ,((ushort)tleft/60)+1,(tleft/60) ? "s" : ""); + RESTORELINE; } + + if(now-timeout>=sec_warn && !warn) /* Inactivity warning */ + for(warn=0;warn<5;warn++) + outchar(7); + } while(now-timeout<sec_timeout); +bputs("\r\nInactive too long.\r\n"); +exit(0); +return(0); /* never gets here, but makes compiler happy */ +} + +/****************************************************************************/ +/* If remote user, checks DCD to see if user has hung up or not. */ +/****************************************************************************/ +void checkline(void) +{ +if(com_port && !((*msr)&DCD)) exit(0); +} + +/****************************************************************************/ +/* Waits for remote or local user to hit a key that is contained inside str.*/ +/* 'str' should contain uppercase characters only. When a valid key is hit, */ +/* it is echoed (upper case) and is the return value. */ +/* If max is non-zero and a number is hit that is not in str, it will be */ +/* returned with the high bit set. If the return of this function has the */ +/* high bit set (&0x8000), just flip the bit (^0x8000) to get the number. */ +/****************************************************************************/ +int getkeys(char *str,int max) +{ + uchar ch,n=0; + int i=0; + +strupr(str); +while(!aborted) { + ch=getkey(K_UPPER); + if(max && ch>0x7f) /* extended ascii chars are digits to isdigit() */ + continue; + if(ch && !n && (strchr(str,ch))) { /* return character if in string */ + outchar(ch); + attr(LIGHTGRAY); + CRLF; + return(ch); } + if(ch==CR && max) { /* return 0 if no number */ + attr(LIGHTGRAY); + CRLF; + if(n) + return(i|0x8000); /* return number plus high bit */ + return(0); } + if(ch==BS && n) { + bputs("\b \b"); + i/=10; + n--; } + else if(max && isdigit(ch) && (i*10)+(ch&0xf)<=max && (ch!='0' || n)) { + i*=10; + n++; + i+=ch&0xf; + outchar(ch); + if(i*10>max) { + attr(LIGHTGRAY); + CRLF; + return(i|0x8000); } } } +return(0); +} + +/****************************************************************************/ +/* Hot keyed number input routine. */ +/****************************************************************************/ +int getnum(int max) +{ + uchar ch,n=0; + int i=0; + +while(1) { + ch=getkey(K_UPPER); + if(ch>0x7f) + continue; + if(ch=='Q') { + outchar('Q'); + CRLF; + return(-1); } + else if(ch==3) { /* ctrl-c */ + CRLF; + return(-1); } + else if(ch==CR) { + CRLF; + return(i); } + else if(ch==BS && n) { + bputs("\b \b"); + i/=10; + n--; } + else if(isdigit(ch) && (i*10)+(ch&0xf)<=max && (ch!='0' || n)) { + i*=10; + n++; + i+=ch&0xf; + outchar(ch); + if(i*10>max) { + CRLF; + return(i); } } } +return(-1); +} + +/****************************************************************************/ +/* Waits for remote or local user to input a CR terminated string. 'length' */ +/* is the maximum number of characters that getstr will allow the user to */ +/* input into the string. 'mode' specifies upper case characters are echoed */ +/* or wordwrap or if in message input (^A sequences allowed). ^W backspaces */ +/* a word, ^X backspaces a line, ^Gs, BSs, TABs are processed, LFs ignored. */ +/* ^N non-destructive BS, ^V center line. Valid keys are echoed. */ +/****************************************************************************/ +int getstr(char *strout, int maxlen, int mode) +{ + int i,l,x,z; /* i=current position, l=length, j=printed chars */ + /* x&z=misc */ + uchar ch,str1[256],str2[256],ins=0,atr; + +if(mode&K_LINE && user_misc&ANSI) { + attr(LIGHTGRAY|HIGH|(BLUE<<4)); /* white on blue */ + for(i=0;i<maxlen;i++) + outchar(SP); + bprintf("\x1b[%dD",maxlen); } +i=l=0; /* i=total number of chars, j=number of printable chars */ +if(wordwrap[0]) { + strcpy(str1,wordwrap); + wordwrap[0]=0; } +else str1[0]=0; +if(mode&K_EDIT) + strcat(str1,strout); +if(strlen(str1)>maxlen) + str1[maxlen]=0; +atr=curatr; +if(mode&K_AUTODEL && str1[0]) + attr(BLUE|(LIGHTGRAY<<4)); +rputs(str1); +if(mode&K_EDIT && !(mode&(K_LINE|K_AUTODEL)) && user_misc&ANSI) + bputs("\x1b[K"); /* destroy to eol */ +i=l=strlen(str1); + +if(mode&K_AUTODEL && str1[0]) { + ch=getkey(mode); + attr(atr); + if(isprint(ch) || ch==0x7f) { + for(i=0;i<l;i++) + bputs("\b \b"); + i=l=0; } + else { + for(i=0;i<l;i++) + outchar(BS); + rputs(str1); + i=l; } + if(ch!=SP && ch!=TAB) + ungetkey(ch); } + +while((ch=getkey(mode|K_GETSTR))!=CR && !aborted) { + switch(ch) { + case 1: /* Ctrl-A for ANSI */ + if(!(mode&K_MSG) || i>maxlen-3) + break; + if(ins) { + if(l<maxlen) + l++; + for(x=l;x>i;x--) + str1[x]=str1[x-1]; + rprintf("%.*s",l-i,str1+i); + rprintf("\x1b[%dD",l-i); + if(i==maxlen-1) + ins=0; } + outchar(str1[i++]=1); + break; + case 2: /* Ctrl-B Beginning of Line */ + if(user_misc&ANSI && i) { + bprintf("\x1b[%dD",i); + i=0; } + break; + case 4: /* Ctrl-D Delete word right */ + if(i<l) { + x=i; + while(x<l && str1[x]!=SP) { + outchar(SP); + x++; } + while(x<l && str1[x]==SP) { + outchar(SP); + x++; } + bprintf("\x1b[%dD",x-i); /* move cursor back */ + z=i; + while(z<l-(x-i)) { /* move chars in string */ + outchar(str1[z]=str1[z+(x-i)]); + z++; } + while(z<l) { /* write over extra chars */ + outchar(SP); + z++; } + bprintf("\x1b[%dD",z-i); + l-=x-i; } /* l=new length */ + break; + case 5: /* Ctrl-E End of line */ + if(user_misc&ANSI && i<l) { + bprintf("\x1b[%dC",l-i); /* move cursor right one */ + i=l; } + break; + case 6: /* Ctrl-F move cursor forewards */ + if(i<l && (user_misc&ANSI)) { + bputs("\x1b[C"); /* move cursor right one */ + i++; } + break; + case 7: + if(!(mode&K_MSG)) + break; + if(ins) { + if(l<maxlen) + l++; + for(x=l;x>i;x--) + str1[x]=str1[x-1]; + if(i==maxlen-1) + ins=0; } + if(i<maxlen) { + str1[i++]=7; + outchar(7); } + break; + case 14: /* Ctrl-N Next word */ + if(i<l && (user_misc&ANSI)) { + x=i; + while(str1[i]!=SP && i<l) + i++; + while(str1[i]==SP && i<l) + i++; + bprintf("\x1b[%dC",i-x); } + break; + case 0x1c: /* Ctrl-\ Previous word */ + if(i && (user_misc&ANSI)) { + x=i; + while(str1[i-1]==SP && i) + i--; + while(str1[i-1]!=SP && i) + i--; + bprintf("\x1b[%dD",x-i); } + break; + case 18: /* Ctrl-R Redraw Line */ + redrwstr(str1,i,l,0); + break; + case TAB: + if(!(i%TABSIZE)) { + if(ins) { + if(l<maxlen) + l++; + for(x=l;x>i;x--) + str1[x]=str1[x-1]; + if(i==maxlen-1) + ins=0; } + str1[i++]=SP; + outchar(SP); } + while(i<maxlen && i%TABSIZE) { + if(ins) { + if(l<maxlen) + l++; + for(x=l;x>i;x--) + str1[x]=str1[x-1]; + if(i==maxlen-1) + ins=0; } + str1[i++]=SP; + outchar(SP); } + if(ins) + redrwstr(str1,i,l,0); + break; + case BS: + if(!i) + break; + i--; + l--; + if(i!=l) { /* Deleting char in middle of line */ + outchar(BS); + z=i; + while(z<l) { /* move the characters in the line */ + outchar(str1[z]=str1[z+1]); + z++; } + outchar(SP); /* write over the last char */ + bprintf("\x1b[%dD",(l-i)+1); } + else + bputs("\b \b"); + break; + case 22: /* Ctrl-V Center line */ + str1[l]=0; + l=bstrlen(str1); + for(x=0;x<(maxlen-l)/2;x++) + str2[x]=SP; + str2[x]=0; + strcat(str2,str1); + strcpy(strout,str2); + l=strlen(strout); + if(mode&K_MSG) + redrwstr(strout,i,l,K_MSG); + else { + while(i--) + bputs("\b"); + bputs(strout); + if(mode&K_LINE) + attr(LIGHTGRAY); } + CRLF; + return(l); + case 23: /* Ctrl-W Delete word left */ + if(i<l) { + x=i; /* x=original offset */ + while(i && str1[i-1]==SP) { + outchar(BS); + i--; } + while(i && str1[i-1]!=SP) { + outchar(BS); + i--; } + z=i; /* i=z=new offset */ + while(z<l-(x-i)) { /* move chars in string */ + outchar(str1[z]=str1[z+(x-i)]); + z++; } + while(z<l) { /* write over extra chars */ + outchar(SP); + z++; } + bprintf("\x1b[%dD",z-i); /* back to new x corridnant */ + l-=x-i; } /* l=new length */ + else { + while(i && str1[i-1]==SP) { + i--; + l--; + bputs("\b \b"); } + while(i && str1[i-1]!=SP) { + i--; + l--; + bputs("\b \b"); } } + break; + case 24: /* Ctrl-X Delete entire line */ + while(i<l) { + outchar(SP); + i++; } + while(l) { + l--; + bputs("\b \b"); } + i=0; + break; + case 25: /* Ctrl-Y Delete to end of line */ + if(user_misc&ANSI) { + bputs("\x1b[s\x1b[K\x1b[u"); + l=i; } + break; + case 31: /* Ctrl-Minus Toggles Insert/Overwrite */ + if(!(user_misc&ANSI)) + break; + if(ins) { + ins=0; + redrwstr(str1,i,l,0); } + else if(i<l) { + ins=1; + bprintf("\x1b[s\x1b[%dC",80-i); /* save pos */ + z=curatr; /* and got to EOL */ + attr(z|BLINK|HIGH); + outchar('�'); + attr(z); + bputs("\x1b[u"); } /* restore pos */ + break; + case 0x1d: /* Ctrl-] Reverse Cursor Movement */ + if(i && (user_misc&ANSI)) { + bputs("\x1b[D"); /* move cursor left one */ + i--; } + break; + case 0x7f: /* Ctrl-BkSpc (DEL) Delete current char */ + if(i==l) + break; + l--; + z=i; + while(z<l) { /* move the characters in the line */ + outchar(str1[z]=str1[z+1]); + z++; } + outchar(SP); /* write over the last char */ + bprintf("\x1b[%dD",(l-i)+1); + break; + case ESC: + if(!(user_misc&ANSI)) + break; + if((ch=getkey(0x8000))!='[') { + ungetch(ch); + break; } + if((ch=getkey(0x8000))=='C') { + if(i<l) { + bputs("\x1b[C"); /* move cursor right one */ + i++; } } + else if(ch=='D') { + if(i) { + bputs("\x1b[D"); /* move cursor left one */ + i--; } } + else { + while(isdigit(ch) || ch==';' || isalpha(ch)) { + if(isalpha(ch)) { + ch=getkey(0); + break; } + ch=getkey(0); } + ungetch(ch); } + break; + default: + if(mode&K_WRAP && i==maxlen && ch>=SP && !ins) { + str1[i]=0; + if(ch==SP) { /* don't wrap a space as last char */ + strcpy(strout,str1); + if(stripattr(strout)) + redrwstr(strout,i,l,K_MSG); + CRLF; + return(i); } + x=i-1; + z=1; + wordwrap[0]=ch; + while(str1[x]!=SP && x) + wordwrap[z++]=str1[x--]; + if(x<(maxlen/2)) { + wordwrap[1]=0; /* only wrap one character */ + strcpy(strout,str1); + if(stripattr(strout)) + redrwstr(strout,i,l,K_MSG); + CRLF; + return(i); } + wordwrap[z]=0; + while(z--) { + i--; + bputs("\b \b"); } + strrev(wordwrap); + str1[x]=0; + strcpy(strout,str1); + if(stripattr(strout)) + redrwstr(strout,i,x,mode); + CRLF; + return(x); } + if(i<maxlen && ch>=SP) { + if(mode&K_UPRLWR) + if(!i || (i && (str1[i-1]==SP || str1[i-1]=='-' + || str1[i-1]=='.' || str1[i-1]=='_'))) + ch=toupper(ch); + else + ch=tolower(ch); + if(ins) { + if(l<maxlen) /* l<maxlen */ + l++; + for(x=l;x>i;x--) + str1[x]=str1[x-1]; + rprintf("%.*s",l-i,str1+i); + rprintf("\x1b[%dD",l-i); + if(i==maxlen-1) { + bputs(" \b\b"); + ins=0; } } + str1[i++]=ch; + outchar(ch); } } + if(i>l) + l=i; + if(mode&K_CHAT && !l) + return(0); } +if(i>l) + l=i; +str1[l]=0; +if(!aborted) { + strcpy(strout,str1); + if(stripattr(strout) || ins) + redrwstr(strout,i,l,K_MSG); } +else + l=0; +if(mode&K_LINE) attr(LIGHTGRAY); +if(!(mode&K_NOCRLF)) { + outchar(CR); + if(!(mode&K_MSG && aborted)) + outchar(LF); } +return(l); +} + +/****************************************************************************/ +/* Redraws str using i as current cursor position and l as length */ +/****************************************************************************/ +void redrwstr(char *strin, int i, int l, char mode) +{ + char str[256],c; + +sprintf(str,"%-*.*s",l,l,strin); +c=i; +while(c--) + outchar(BS); +if(mode&K_MSG) + bputs(str); +else + rputs(str); +if(user_misc&ANSI) { + bputs("\x1b[K"); + if(i<l) + bprintf("\x1b[%dD",l-i); } +else { + while(c<79) { /* clear to end of line */ + outchar(SP); + c++; } + while(c>l) { /* back space to end of string */ + outchar(BS); + c--; } } +} + +/****************************************************************************/ +/* Strips invalid Ctrl-Ax sequences from str */ +/* Returns number of ^A's in line */ +/****************************************************************************/ +char stripattr(char *strin) +{ + uchar str[81]; + uchar a,c,d,e; + +e=strlen(strin); +for(a=c=d=0;c<e;c++) { + if(strin[c]==1) { + a++; + switch(toupper(strin[c+1])) { + case '-': /* clear */ + case '_': /* clear */ + case 'B': /* blue fg */ + case 'C': /* cyan fg */ + case 'G': /* green fg */ + case 'H': /* high fg */ + case 'I': /* blink */ + case 'K': /* black fg */ + case 'L': /* cls */ + case 'M': /* magenta fg */ + case 'N': /* normal */ + case 'P': /* pause */ + case 'Q': /* pause reset */ + case 'R': /* red fg */ + case 'W': /* white fg */ + case 'Y': /* yellow fg */ + case '0': /* black bg */ + case '1': /* red bg */ + case '2': /* green bg */ + case '3': /* brown bg */ + case '4': /* blue bg */ + case '5': /* magenta bg */ + case '6': /* cyan bg */ + case '7': /* white bg */ + break; + default: + c++; + continue; } } + str[d++]=strin[c]; } +str[d]=0; +strcpy(strin,str); +return(a); +} + +/***************************************************************************/ +/* Changes local and remote text attributes accounting for monochrome */ +/***************************************************************************/ +void attr(char atr) +{ + +if(!(user_misc&ANSI) || aborted) + return; +if(!(user_misc&COLOR)) { /* eliminate colors if user doesn't have them */ + if(atr&LIGHTGRAY) /* if any bits set, set all */ + atr|=LIGHTGRAY; + if(atr&(LIGHTGRAY<<4)) + atr|=(LIGHTGRAY<<4); + if(atr&LIGHTGRAY && atr&(LIGHTGRAY<<4)) + atr&=~LIGHTGRAY; } /* if background is solid, forground is black */ +if(curatr==atr) /* attribute hasn't changed. don't send codes */ + return; + +if((!(atr&HIGH) && curatr&HIGH) || (!(atr&BLINK) && curatr&BLINK) + || atr==LIGHTGRAY) { + bprintf("\x1b[0m"); + curatr=LIGHTGRAY; } + +if(atr==LIGHTGRAY) { /* no attributes */ + curatr=atr; + return; } + +if(atr&BLINK) { /* special attributes */ + if(!(curatr&BLINK)) + bprintf("\x1b[5m"); } +if(atr&HIGH) { + if(!(curatr&HIGH)) + bprintf("\x1b[1m"); } + +if((atr&0x7)==BLACK) { /* foreground colors */ + if((curatr&0x7)!=BLACK) + bprintf("\x1b[30m"); } +else if((atr&0x7)==RED) { + if((curatr&0x7)!=RED) + bprintf("\x1b[31m"); } +else if((atr&0x7)==GREEN) { + if((curatr&0x7)!=GREEN) + bprintf("\x1b[32m"); } +else if((atr&0x7)==BROWN) { + if((curatr&0x7)!=BROWN) + bprintf("\x1b[33m"); } +else if((atr&0x7)==BLUE) { + if((curatr&0x7)!=BLUE) + bprintf("\x1b[34m"); } +else if((atr&0x7)==MAGENTA) { + if((curatr&0x7)!=MAGENTA) + bprintf("\x1b[35m"); } +else if((atr&0x7)==CYAN) { + if((curatr&0x7)!=CYAN) + bprintf("\x1b[36m"); } +else if((atr&0x7)==LIGHTGRAY) { + if((curatr&0x7)!=LIGHTGRAY) + bprintf("\x1b[37m"); } + +if((atr&0x70)==(BLACK<<4)) { /* background colors */ + if((curatr&0x70)!=(BLACK<<4)) + bprintf("\x1b[40m"); } +else if((atr&0x70)==(RED<<4)) { + if((curatr&0x70)!=(RED<<4)) + bprintf("\x1b[41m"); } +else if((atr&0x70)==(GREEN<<4)) { + if((curatr&0x70)!=(GREEN<<4)) + bprintf("\x1b[42m"); } +else if((atr&0x70)==(BROWN<<4)) { + if((curatr&0x70)!=(BROWN<<4)) + bprintf("\x1b[43m"); } +else if((atr&0x70)==(BLUE<<4)) { + if((curatr&0x70)!=(BLUE<<4)) + bprintf("\x1b[44m"); } +else if((atr&0x70)==(MAGENTA<<4)) { + if((curatr&0x70)!=(MAGENTA<<4)) + bprintf("\x1b[45m"); } +else if((atr&0x70)==(CYAN<<4)) { + if((curatr&0x70)!=(CYAN<<4)) + bprintf("\x1b[46m"); } +else if((atr&0x70)==(LIGHTGRAY<<4)) { + if((curatr&0x70)!=(LIGHTGRAY<<4)) + bprintf("\x1b[47m"); } + +curatr=atr; +} + +/****************************************************************************/ +/* Peform clear screen */ +/****************************************************************************/ +void cls(void) +{ + int i; + +if(lncntr>1 && !tos) { + lncntr=0; + CRLF; + pause(); + while(lncntr && !aborted) + pause(); } + +if(user_misc&ANSI) + bprintf("\x1b[2J"); +else { + outchar(FF); + clrscr(); } +tos=1; +lncntr=0; +} + +#ifdef __WATCOMC__ + +short wherey(void) +{ + struct rccoord rc; + +rc=_gettextposition(); +return(rc.col); +} + +void clrscr(void) +{ +_clearscreen(_GCLEARSCREEN); +} + +#endif + +/****************************************************************************/ +/* performs the correct attribute modifications for the Ctrl-A code */ +/****************************************************************************/ +void ctrl_a(char x) +{ + char atr=curatr; + int i,j; + +if((uchar)x>=0x7f) { + if(user_misc&ANSI) + bprintf("\x1b[%uC",(uchar)x-0x7f); + else + for(i=0;i<(uchar)x-0x7f;i++) + outchar(SP); + return; } + +switch(toupper(x)) { + case '-': /* turn off all attributes if */ + if(atr&(HIGH|BLINK|(LIGHTGRAY<<4))) /* high intensity, blink or */ + attr(LIGHTGRAY); /* background bits are set */ + break; + case '_': /* turn off all attributes if */ + if(atr&(BLINK|(LIGHTGRAY<<4))) /* blink or background is set */ + attr(LIGHTGRAY); + break; + case ',': /* Delay 1/10 sec */ + mswait(100); + break; + case ';': /* Delay 1/2 sec */ + mswait(500); + break; + case '.': /* Delay 2 secs */ + mswait(2000); + break; + case 'P': /* Pause */ + pause(); + break; + case 'Q': /* Pause reset */ + lncntr=0; + break; + case 'L': /* CLS (form feed) */ + cls(); + break; + case '>': /* CLREOL */ + if(user_misc&ANSI) + bputs("\x1b[K"); + else { + i=j=wherey(); + while(i++<80) + outchar(SP); + while(j++<80) + outchar(BS); } + break; + case '<': /* Non-destructive backspace */ + outchar(BS); + break; + case '[': /* Carriage return */ + outchar(CR); + break; + case ']': /* Line feed */ + outchar(LF); + break; + case 'A': /* Ctrl-A */ + outchar(1); + break; + case 'H': /* High intensity */ + atr|=HIGH; + attr(atr); + break; + case 'I': /* Blink */ + atr|=BLINK; + attr(atr); + break; + case 'N': /* Normal */ + attr(LIGHTGRAY); + break; + case 'R': + atr=(atr&0xf8)|RED; + attr(atr); + break; + case 'S': + nodesync(); + break; + case 'G': + atr=(atr&0xf8)|GREEN; + attr(atr); + break; + case 'B': + atr=(atr&0xf8)|BLUE; + attr(atr); + break; + case 'W': /* White */ + atr=(atr&0xf8)|LIGHTGRAY; + attr(atr); + break; + case 'C': + atr=(atr&0xf8)|CYAN; + attr(atr); + break; + case 'M': + atr=(atr&0xf8)|MAGENTA; + attr(atr); + break; + case 'Y': + atr=(atr&0xf8)|BROWN; + attr(atr); + break; + case 'K': /* Black */ + atr=(atr&0xf8)|BLACK; + attr(atr); + break; + case '0': /* Black Background */ + atr=(atr&0x8f)|(BLACK<<4); + attr(atr); + break; + case '1': /* Red Background */ + atr=(atr&0x8f)|(RED<<4); + attr(atr); + break; + case '2': /* Green Background */ + atr=(atr&0x8f)|(GREEN<<4); + attr(atr); + break; + case '3': /* Yellow Background */ + atr=(atr&0x8f)|(BROWN<<4); + attr(atr); + break; + case '4': /* Blue Background */ + atr=(atr&0x8f)|(BLUE<<4); + attr(atr); + break; + case '5': /* Magenta Background */ + atr=(atr&0x8f)|(MAGENTA<<4); + attr(atr); + break; + case '6': /* Cyan Background */ + atr=(atr&0x8f)|(CYAN<<4); + attr(atr); + break; + case '7': /* White Background */ + atr=(atr&0x8f)|(LIGHTGRAY<<4); + attr(atr); + break; } +} + +/****************************************************************************/ +/* Network open function. Opens all files DENYALL and retries LOOP_NOPEN */ +/* number of times if the attempted file is already open or denying access */ +/* for some other reason. All files are opened in BINARY mode. */ +/****************************************************************************/ +int nopen(char *str, int access) +{ + char count=0; + int file,share; + +if(access&SH_DENYNO) share=SH_DENYNO; +else if(access==O_RDONLY) share=SH_DENYWR; +else share=SH_DENYRW; +while(((file=sopen(str,O_BINARY|access,share,S_IWRITE))==-1) + && errno==EACCES && count++<LOOP_NOPEN) + if(count>10) + mswait(50); +if(count>(LOOP_NOPEN/2) && count<=LOOP_NOPEN) + bprintf("\r\nNOPEN COLLISION - File: %s Count: %d\r\n" + ,str,count); +if(file==-1 && errno==EACCES) + bputs("\7\r\nNOPEN: ACCESS DENIED\r\n\7"); +return(file); +} + +/****************************************************************************/ +/* Reads data from XTRN.DAT in the node directory and fills the appropriate */ +/* global variables. */ +/* Initializes starttime variable with current time. */ +/****************************************************************************/ +void initdata(void) +{ + char str[256],tmp[256]; + int i; + FILE *stream; + +#if defined(__TURBOC__) || defined(__SC__) /* Borland or Symantec */ + ctrlbrk(cbreakh); +#endif + +#ifdef __WATCOMC__ + putenv("TZ=UCT0"); + setvbuf(stdout,NULL,_IONBF,0); + setvbuf(stderr,NULL,_IONBF,0); +#endif + +#ifdef __SC__ + setvbuf(stdout,NULL,_IONBF,0); + con_fp=stdout; +#else + con_fp=stderr; +#endif + +if(setmode(fileno(con_fp),O_BINARY)==-1) { /* eliminate LF expansion */ + printf("Can't set console output to BINARY\n"); + exit(1); } + +sprintf(str,"%sXTRN.DAT",node_dir); +if((stream=fopen(str,"rt"))==NULL) { + printf("Can't open %s\r\n",str); + exit(1); } +fgets(str,81,stream); /* username */ +sprintf(user_name,"%.25s",str); +truncsp(user_name); +fgets(str,81,stream); /* system name */ +sprintf(sys_name,"%.40s",str); +truncsp(sys_name); +fgets(str,81,stream); /* system operator */ +sprintf(sys_op,"%.40s",str); +truncsp(sys_op); +fgets(str,81,stream); /* system guru */ +sprintf(sys_guru,"%.40s",str); +truncsp(sys_guru); + +fgets(str,81,stream); /* ctrl dir */ +str[50]=0; +if(str[0]=='.') + sprintf(ctrl_dir,"%s%s",node_dir,str); +else + strcpy(ctrl_dir,str); +truncsp(ctrl_dir); +if(_fullpath(str,ctrl_dir,50)) + strcpy(ctrl_dir,str); +backslash(ctrl_dir); + +fgets(str,81,stream); /* data dir */ +if(str[0]=='.') + sprintf(data_dir,"%s%s",node_dir,str); +else + sprintf(data_dir,"%.40s",str); +truncsp(data_dir); +if(_fullpath(str,data_dir,50)) + strcpy(data_dir,str); +backslash(data_dir); + +fgets(str,81,stream); /* total nodes */ +sys_nodes=atoi(str); +fgets(str,81,stream); /* current node */ +node_num=atoi(str); +fgets(str,81,stream); /* time left */ +timeleft=atoi(str); +fgets(str,81,stream); /* ANSI? (Yes, Mono, or No) */ +user_misc=0; +if(str[0]=='Y') + user_misc|=(ANSI|COLOR); +else if(str[0]=='M') + user_misc|=ANSI; +fgets(str,81,stream); /* screen lines */ +user_rows=atoi(str); +fgets(str,81,stream); /* credits */ +user_cdt=atol(str); +fgets(str,81,stream); /* level */ +user_level=atoi(str); +fgets(str,81,stream); /* was transfer level, left for compat. */ +fgets(str,81,stream); /* birthdate */ +truncsp(str); +sprintf(user_birth,"%.8s",str); +fgets(str,81,stream); /* sex */ +user_sex=str[0]; +fgets(str,81,stream); /* user number */ +user_number=atoi(str); +fgets(str,81,stream); /* user phone number */ +sprintf(user_phone,"%.12s",str); +truncsp(user_phone); +fgets(str,81,stream); /* com port (0 if local or no modem) */ +com_port=atoi(str); +fgets(str,81,stream); /* com (UART) irq */ +com_irq=atoi(str); +fgets(str,81,stream); /* com (UART) base address in hex */ +truncsp(str); +com_base=(uint)ahtoul(str); +fgets(str,81,stream); /* com rate */ +com_rate=(ulong)atol(str); +fgets(str,81,stream); /* hardware flow control (Y/N) */ +if(toupper(str[0])=='Y') + mdm_misc|=MDM_FLOWCTRL; +fgets(str,81,stream); /* locked DTE rate (Y/N) */ +if(toupper(str[0])=='Y') + mdm_misc|=MDM_STAYHIGH; +fgets(str,81,stream); /* modem initialization string */ +sprintf(mdm_init,"%.63s",str); +truncsp(mdm_init); +fgets(str,81,stream); /* modem special init string */ +sprintf(mdm_spec,"%.63s",str); +truncsp(mdm_spec); +fgets(str,81,stream); /* modem terminal mode string */ +sprintf(mdm_term,"%.63s",str); +truncsp(mdm_term); +fgets(str,81,stream); /* modem dial string */ +sprintf(mdm_dial,"%.63s",str); +truncsp(mdm_dial); +fgets(str,81,stream); /* modem off-hook string */ +sprintf(mdm_offh,"%.63s",str); +truncsp(mdm_offh); +fgets(str,81,stream); /* modem answer string */ +sprintf(mdm_answ,"%.63s",str); +truncsp(mdm_answ); +fgets(str,81,stream); /* memory address of modem status register */ +msr=(uint far *)atol(str); +if(!fgets(str,81,stream)) /* total number of external programs */ + total_xtrns=0; +else + total_xtrns=atoi(str); +if(total_xtrns && (xtrn=(char **)MALLOC(sizeof(char *)*total_xtrns))==NULL) { + printf("Allocation error 1: %u\r\n",sizeof(char *)*total_xtrns); + exit(1); } +for(i=0;i<total_xtrns;i++) { + fgets(str,81,stream); + truncsp(str); + if((xtrn[i]=(char *)MALLOC(strlen(str)+1))==NULL) { + printf("Allocation error 2 (%u): %u\r\n",i,strlen(str)+1); + exit(1); } + strcpy(xtrn[i],str); } +fgets(str,81,stream); /* user's main flags */ +sprintf(user_flags1,"%.26s",str); +fgets(str,81,stream); /* user's xfer flags */ +sprintf(user_flags2,"%.26s",str); +fgets(str,81,stream); /* user's exemptions */ +sprintf(user_exempt,"%.26s",str); +fgets(str,81,stream); /* user's restrictions */ +sprintf(user_rest,"%.26s",str); +fgets(str,81,stream); /* user's expiration date */ +truncsp(str); +user_expire=ahtoul(str); +str[0]=0; +fgets(str,81,stream); /* user's address */ +sprintf(user_address,"%.30s",str); +truncsp(user_address); +fgets(str,81,stream); /* user's location (city, state) */ +sprintf(user_location,"%.30s",str); +truncsp(user_location); +fgets(str,81,stream); /* user's zip/postal code */ +sprintf(user_zipcode,"%.10s",str); +truncsp(user_zipcode); +str[0]=0; +fgets(str,81,stream); +sprintf(user_flags3,"%.26s",str); +fgets(str,81,stream); +sprintf(user_flags4,"%.26s",str); +if(fgets(str,81,stream)) /* Time-slice API type */ + mswtyp=ahtoul(str); +str[0]=0; +fgets(str,81,stream); +truncsp(str); +sprintf(user_realname,"%.25s",str); +str[0]=0; +fgets(str,81,stream); +user_dce=atol(str); + +str[0]=0; +fgets(str,81,stream); /* exec dir */ +if(!str[0]) + sprintf(exec_dir,"%s..\\EXEC\\",ctrl_dir); +else { + if(str[0]=='.') + sprintf(exec_dir,"%s%s",node_dir,str); + else + sprintf(exec_dir,"%.50s",str); } +truncsp(exec_dir); +if(_fullpath(str,exec_dir,50)) + strcpy(exec_dir,str); +backslash(exec_dir); + +str[0]=0; +fgets(str,81,stream); /* text dir */ +if(!str[0]) + sprintf(text_dir,"%s..\\TEXT\\",ctrl_dir); +else { + if(str[0]=='.') + sprintf(text_dir,"%s%s",node_dir,str); + else + sprintf(text_dir,"%.50s",str); } +truncsp(text_dir); +if(_fullpath(str,text_dir,50)) + strcpy(text_dir,str); +backslash(text_dir); + +str[0]=0; +fgets(str,81,stream); /* temp dir */ +if(!str[0]) + sprintf(temp_dir,"%sTEMP\\",node_dir); +else { + if(str[0]!='\\' && str[1]!=':') + sprintf(temp_dir,"%s%s",node_dir,str); + else + sprintf(temp_dir,"%.50s",str); } +truncsp(temp_dir); +if(_fullpath(str,temp_dir,50)) + strcpy(temp_dir,str); +backslash(temp_dir); + +str[0]=0; +fgets(str,81,stream); +sprintf(sys_id,"%.8s",str); + +str[0]=0; +fgets(str,81,stream); +truncsp(str); +if(str[0]) + node_misc=(uint)ahtoul(str); +else + node_misc=NM_LOWPRIO; + +fclose(stream); + +sprintf(str,"%sINTRSBBS.DAT",node_dir); /* Shrank to run! */ +if(fexist(str)) { + if((stream=fopen(str,"rt"))==NULL) { + printf("Can't open %s\n",str); + exit(1); } + fgets(tmp,81,stream); /* so get MSR address from file */ + msr=(uint far *)atol(tmp); + fclose(stream); + remove(str); } + +starttime=time(NULL); /* initialize start time stamp */ +wordwrap[0]=0; /* set wordwrap to null */ +attr(LIGHTGRAY); /* initialize color and curatr to plain */ +mnehigh=LIGHTGRAY|HIGH; /* mnemonics highlight color */ +mnelow=GREEN; /* mnemonics normal text color */ +sec_warn=180; /* seconds till inactivity warning */ +sec_timeout=300; /* seconds till inactivity timeout */ +tos=lncntr=0; /* init topofscreen and linecounter to 0 */ +lastnodemsg=0; /* Last node to send message to */ +aborted=0; /* Ctrl-C hit flag */ +sysop_level=90; /* Minimum level to be considered sysop */ +timeleft_warn=0; /* Running out of time warning */ + +sprintf(str,"%s%s",ctrl_dir,"NODE.DAB"); +if((nodefile=sopen(str,O_BINARY|O_RDWR,SH_DENYNO))==-1) { + bprintf("\r\n\7Error opening %s\r\n",str); + exit(1); } + +sprintf(str,"%sUSER\\NAME.DAT",data_dir); +if((i=nopen(str,O_RDONLY))==-1) { + printf("\r\n\7Error opening %s\r\n",str); + exit(1); } +memset(str,0,30); +read(i,str,26); +close(i); +if(str[25]==CR) /* Version 1b */ + name_len=25; +else /* Version 1a */ + name_len=30; +} + +/****************************************************************************/ +/* Automatic RIP & WIP terminal detection function. Sets RIP and WIP bits */ +/* in user_misc variable. Must be called AFTER initdat(), not before. */ +/****************************************************************************/ +void get_term(void) +{ + char str[128],ch; + int i; + +bputs("\r\x1b[!_\x1b[0t_\r \r"); +mswait(500); +for(i=0;i<120;i++) { + ch=inkey(0); + if(!ch) + break; + mswait(1); + str[i]=ch; } +str[i]=0; +if(strstr(str,"RIPSCRIP")) + user_misc|=RIP; +if(strstr(str,"DC-TERM")) + user_misc|=WIP; +} + +/****************************************************************************/ +/* Truncates white-space chars off end of 'str' and terminates at first tab */ +/****************************************************************************/ +void truncsp(uchar *str) +{ + char c; + +str[strcspn(str,"\t")]=0; +c=strlen(str); +while(c && (uchar)str[c-1]<=SP) c--; +str[c]=0; +} + +/****************************************************************************/ +/* Puts a backslash on path strings */ +/****************************************************************************/ +void backslash(char *str) +{ + int i; + +i=strlen(str); +if(i && str[i-1]!='\\') { + str[i]='\\'; str[i+1]=0; } +} + + +/****************************************************************************/ +/* Checks the amount of time inside the external program against the amount */ +/* of time the user had left online before running the external program and */ +/* prints a message and exits the program if time has run out. */ +/****************************************************************************/ +void checktimeleft(void) +{ +if(!SYSOP && !strchr(user_exempt,'T') && time(NULL)-starttime>timeleft) { + bputs("\1_\n\1r\1hTime's up.\n"); + exit(0); } +} + +/****************************************************************************/ +/* Prints a file remotely and locally, interpreting ^A sequences. */ +/* 'str' is the path of the file to print */ +/****************************************************************************/ +void printfile(char *str) +{ + char *buf; + int file; + ulong length; + +strupr(str); +if(!tos) + CRLF; +if((file=nopen(str,O_RDONLY))==-1) { + bprintf("File not Found: %s\r\n",str); + return; } +length=filelength(file); +if((buf=MALLOC(length+1L))==NULL) { + close(file); + bprintf("\7\r\nPRINTFILE: Error allocating %lu bytes of memory for %s.\r\n" + ,length+1L,str); + return; } +buf[read(file,buf,length)]=0; +close(file); +bputs(buf); +aborted=0; +FREE(buf); +} + +/****************************************************************************/ +/* Returns a char pointer to the name of the user that corresponds to */ +/* usernumber. Takes value directly from database. */ +/****************************************************************************/ +char *username(uint usernumber) +{ + static char name[26]; + char str[128]; + int i,file; + +strcpy(name,"UNKNOWN USER"); +if(!data_dir[0]) + return(name); +if(!usernumber) { + bputs("\7username: called with zero usernumber\r\n"); + return(name); } +sprintf(str,"%sUSER\\NAME.DAT",data_dir); +if((file=nopen(str,O_RDONLY))==-1) { + bprintf("\7username: couldn't open %s\r\n",str); + return(name); } +if(filelength(file)<(long)(usernumber-1)*((long)name_len+2L)) { + close(file); + return(name); } +lseek(file,(long)(usernumber-1)*((long)name_len+2L),SEEK_SET); +read(file,name,25); +close(file); +for(i=0;i<25;i++) + if(name[i]==3) + break; +name[i]=0; +if(!name[0]) + strcpy(name,"DELETED USER"); +return(name); +} + +/****************************************************************************/ +/* Returns the number of the user 'username' from the NAME.DAT file. */ +/* If the username is not found, the function returns 0. */ +/****************************************************************************/ +uint usernumber(char *username) +{ + char str[128]; + int i,file; + FILE *stream; + +if(!data_dir[0]) + return(0); +sprintf(str,"%sUSER\\NAME.DAT",data_dir); +if((file=nopen(str,O_RDONLY))==-1 || (stream=fdopen(file,"rb"))==NULL) { + if(file!=-1) + close(file); + bprintf("\7usernumber: couldn't open %s\r\n",str); + return(0); } +for(i=1;!feof(stream);i++) { + if(!fread(str,27,1,stream)) + break; + str[25]=0; + truncsp(str); /* chop of trailing EOTs and spaces */ + if(!stricmp(str,username)) { + fclose(stream); + return(i); } } +fclose(stream); +return(0); +} + + +/****************************************************************************/ +/* Checks the disk drive for the existance of a file. Returns 1 if it */ +/* exists, 0 if it doesn't. */ +/* Called from upload */ +/****************************************************************************/ +char fexist(char *filespec) +{ +#ifdef __SC__ /* Symantec */ +if(findfirst(filespec,0)==NULL) + return(0); +return(1); +#else /* Not Symantec */ + struct ffblk f; + +if(findfirst(filespec,&f,0)==NULL) + return(1); +return(0); +#endif /* !__SC__ */ +} + +/****************************************************************************/ +/* Returns the length of the first file found that matches 'filespec' */ +/* -1 if the file doesn't exist. */ +/****************************************************************************/ +long flength(char *filespec) +{ +#ifdef __SC__ /* Symantec */ + struct FILE *f; + +if((f=findfirst(filespec,0))==NULL) + return(-1); +return(f->size); + +#else /* Not Symantec */ + + struct ffblk f; + +if(findfirst(filespec,&f,0)==NULL) +#ifdef __TURBOC__ /* Borland */ + return(f.ff_fsize); +#else /* Other (Watcom) */ + return(f.size); +#endif +return(-1L); +#endif /* !__SC__ */ +} + +/****************************************************************************/ +/* Returns in 'string' a character representation of the number in l with */ +/* commas. Maximum value of l is 4 gigabytes. */ +/****************************************************************************/ +char *ultoac(ulong l, char *string) +{ + char str[81]; + char i,j,k; + +ultoa(l,str,10); +i=strlen(str)-1; +j=i/3+1+i; +string[j--]=0; +for(k=1;i>-1;k++) { + string[j--]=str[i--]; + if(j>0 && !(k%3)) + string[j--]=','; } +return(string); +} + +/****************************************************************************/ +/* Converts an ASCII Hex string into a ulong */ +/****************************************************************************/ +ulong ahtoul(char *str) +{ + ulong l,val=0; + +while((l=(*str++)|0x20)!=0x20) + val=(l&0xf)+(l>>6&1)*9+val*16; +return(val); +} + +/****************************************************************************/ +/* Reads the data for node number 'number' into the structure 'node' */ +/* from NODE.DAB */ +/* if lockit is non-zero, locks this node's record. putnodedat() unlocks it */ +/****************************************************************************/ +void getnodedat(uchar number, node_t *node, char lockit) +{ + char str[256]; + int count=0; + +if(nodefile<0) + return; +number--; /* make zero based */ +while(count<LOOP_NODEDAB) { + lseek(nodefile,(long)number*sizeof(node_t),SEEK_SET); + if(lockit + && lock(nodefile,(long)number*sizeof(node_t),sizeof(node_t))==-1) { + count++; + continue; } + if(read(nodefile,node,sizeof(node_t))==sizeof(node_t)) + break; + count++; } +if(count==LOOP_NODEDAB) + bprintf("\7Error unlocking and reading NODE.DAB\r\n"); +} + +/****************************************************************************/ +/* Write the data from the structure 'node' into NODE.DAB */ +/* getnodedat(num,&node,1); must have been called before calling this func */ +/* NOTE: ------^ the indicates the node record has been locked */ +/****************************************************************************/ +void putnodedat(uchar number, node_t node) +{ + char str[256]; + int count; + +if(nodefile<0) + return; +number--; /* make zero based */ +lseek(nodefile,(long)number*sizeof(node_t),SEEK_SET); +if(write(nodefile,&node,sizeof(node_t))!=sizeof(node_t)) { + unlock(nodefile,(long)number*sizeof(node_t),sizeof(node_t)); + bprintf("\7Error writing NODE.DAB for node %u\r\n",number+1); + return; } +unlock(nodefile,(long)number*sizeof(node_t),sizeof(node_t)); +} + +/****************************************************************************/ +/* Checks for messages waiting for this node or interruption. */ +/****************************************************************************/ +void nodesync(void) +{ + node_t node; + +if(!ctrl_dir[0]) + return; +getnodedat(node_num,&node,0); + +if(node.misc&NODE_MSGW) + getsmsg(user_number); /* getsmsg clears MSGW flag */ + +if(node.misc&NODE_NMSG) /* getnmsg clears NMSG flag */ + getnmsg(); + +if(node.misc&NODE_INTR) + exit(0); + +} + +/****************************************************************************/ +/* Displays the information for node number 'number' contained in 'node' */ +/****************************************************************************/ +void printnodedat(uchar number, node_t node) +{ + char hour,mer[3],tmp[256]; + int i; + +attr(LIGHTGRAY|HIGH); +bprintf("Node %2d: ",number); +attr(GREEN); +switch(node.status) { + case NODE_WFC: + bputs("Waiting for call"); + break; + case NODE_OFFLINE: + bputs("Offline"); + break; + case NODE_NETTING: + bputs("Networking"); + break; + case NODE_LOGON: + bputs("At logon prompt"); + break; + case NODE_EVENT_WAITING: + bputs("Waiting for all nodes to become inactive"); + break; + case NODE_EVENT_LIMBO: + bprintf("Waiting for node %d to finish external event",node.aux); + break; + case NODE_EVENT_RUNNING: + bputs("Running external event"); + break; + case NODE_NEWUSER: + attr(GREEN|HIGH); + bputs("New user"); + attr(GREEN); + bputs(" applying for access "); + if(!node.connection) + bputs("Locally"); + else + bprintf("at %ubps",node.connection); + break; + case NODE_QUIET: + if(!SYSOP) { + bputs("Waiting for call"); + break; } + case NODE_INUSE: + attr(GREEN|HIGH); + if(node.misc&NODE_ANON && !SYSOP) + bputs("UNKNOWN USER"); + else + bputs(username(node.useron)); + attr(GREEN); + bputs(" "); + switch(node.action) { + case NODE_MAIN: + bputs("at main menu"); + break; + case NODE_RMSG: + bputs("reading messages"); + break; + case NODE_RMAL: + bputs("reading mail"); + break; + case NODE_RSML: + bputs("reading sent mail"); + break; + case NODE_RTXT: + bputs("reading text files"); + break; + case NODE_PMSG: + bputs("posting message"); + break; + case NODE_SMAL: + bputs("sending mail"); + break; + case NODE_AMSG: + bputs("posting auto-message"); + break; + case NODE_XTRN: + if(!node.aux) + bputs("at external program menu"); + else { + bputs("running "); + i=node.aux-1; + if(i>=total_xtrns || !xtrn[i][0]) + bputs("external program"); + else + bputs(xtrn[i]); } + break; + case NODE_DFLT: + bputs("changing defaults"); + break; + case NODE_XFER: + bputs("at transfer menu"); + break; + case NODE_RFSD: + bprintf("retrieving from device #%d",node.aux); + break; + case NODE_DLNG: + bprintf("downloading"); + break; + case NODE_ULNG: + bputs("uploading"); + break; + case NODE_BXFR: + bputs("transferring bidirectional"); + break; + case NODE_LFIL: + bputs("listing files"); + break; + case NODE_LOGN: + bputs("logging on"); + break; + case NODE_LCHT: + bprintf("in local chat with %s",sys_op); + break; + case NODE_MCHT: + if(node.aux) { + bprintf("in multinode chat channel %d",node.aux&0xff); + if(node.aux&0x1f00) /* password */ + outchar('*'); } + else + bputs("in multinode global chat channel"); + break; + case NODE_PAGE: + bprintf("paging node %u for private chat",node.aux); + break; + case NODE_PCHT: + bprintf("in private chat with node %u",node.aux); + break; + case NODE_GCHT: + bprintf("chatting with %s",sys_guru); + break; + case NODE_CHAT: + bputs("in chat section"); + break; + case NODE_TQWK: + bputs("transferring QWK packet"); + break; + case NODE_SYSP: + bputs("performing sysop activities"); + break; + default: + bputs(itoa(node.action,tmp,10)); + break; } + if(!node.connection) + bputs(" locally"); + else + bprintf(" at %ubps",node.connection); + if(node.action==NODE_DLNG) { + if((node.aux/60)>12) { + hour=(node.aux/60)-12; + strcpy(mer,"pm"); } + else { + if((node.aux/60)==0) /* 12 midnite */ + hour=12; + else hour=node.aux/60; + strcpy(mer,"am"); } + bprintf(" ETA %02d:%02d %s" + ,hour,node.aux%60,mer); } + break; } +i=NODE_LOCK; +if(node.status==NODE_INUSE || SYSOP) + i|=NODE_POFF|NODE_AOFF|NODE_MSGW|NODE_NMSG; +if(node.misc&i) { + bputs(" ("); + if(node.misc&(i&NODE_AOFF)) + outchar('A'); + if(node.misc&NODE_LOCK) + outchar('L'); + if(node.misc&(i&(NODE_MSGW|NODE_NMSG))) + outchar('M'); + if(node.misc&(i&NODE_POFF)) + outchar('P'); + outchar(')'); } +if(SYSOP && ((node.misc + &(NODE_ANON|NODE_UDAT|NODE_INTR|NODE_RRUN|NODE_EVENT|NODE_DOWN)) + || node.status==NODE_QUIET)) { + bputs(" ["); + if(node.misc&NODE_ANON) + outchar('A'); + if(node.misc&NODE_INTR) + outchar('I'); + if(node.misc&NODE_RRUN) + outchar('R'); + if(node.misc&NODE_UDAT) + outchar('U'); + if(node.status==NODE_QUIET) + outchar('Q'); + if(node.misc&NODE_EVENT) + outchar('E'); + if(node.misc&NODE_DOWN) + outchar('D'); + outchar(']'); } +if(node.errors && SYSOP) { + attr(RED|HIGH|BLINK); + bprintf(" %d error%c",node.errors, node.errors>1 ? 's' : '\0' ); } +CRLF; +} + +/****************************************************************************/ +/* Prints short messages waiting for 'usernumber', if any... */ +/* then deletes them. */ +/****************************************************************************/ +void getsmsg(int usernumber) +{ + char str[256], *buf; + int file; + long length; + node_t node; + +if(!data_dir[0]) + return; +sprintf(str,"%sMSGS\\%4.4u.MSG",data_dir,usernumber); +if(flength(str)<1L) { + return; } +if((file=nopen(str,O_RDWR))==-1) { + bprintf("\7Error opening %s for read/write access\r\n",str); + return; } +length=filelength(file); +if((buf=MALLOC(length+1))==NULL) { + close(file); + bprintf("\7Error allocating %u bytes of memory for %s\r\n",length+1,str); + return; } +if(read(file,buf,length)!=length) { + close(file); + FREE(buf); + bprintf("\7Error reading %u bytes from %s\r\n",length,str); + return; } +chsize(file,0L); +close(file); +buf[length]=0; +getnodedat(node_num,&node,0); +if(node.action==NODE_MAIN || node.action==NODE_XFER) { + CRLF; } +if(node.misc&NODE_MSGW) { + getnodedat(node_num,&node,1); + node.misc&=~NODE_MSGW; + putnodedat(node_num,node); } +bputs(buf); +FREE(buf); +} + +/****************************************************************************/ +/* Creates a short message for 'usernumber' than contains 'strin' */ +/****************************************************************************/ +void putsmsg(int usernumber, char *strin) +{ + char str[256]; + int file,i; + node_t node; + +if(!data_dir[0]) + return; +sprintf(str,"%sMSGS\\%4.4u.MSG",data_dir,usernumber); +if((file=nopen(str,O_WRONLY|O_CREAT|O_APPEND))==-1) { + bprintf("\7Error opening/creating %s for creat/append access\r\n",str); + return; } +i=strlen(strin); +if(write(file,strin,i)!=i) { + close(file); + bprintf("\7Error writing %u bytes to %s\r\n",i,str); + return; } +close(file); +for(i=1;i<=sys_nodes;i++) { /* flag node if user on that msg waiting */ + getnodedat(i,&node,0); + if(node.useron==usernumber + && (node.status==NODE_INUSE || node.status==NODE_QUIET) + && !(node.misc&NODE_MSGW)) { + getnodedat(i,&node,1); + node.misc|=NODE_MSGW; + putnodedat(i,node); } } +} + +/****************************************************************************/ +/* Prints short messages waiting for this node, if any... */ +/****************************************************************************/ +void getnmsg(void) +{ + char str[256], *buf; + int file; + long length; + node_t thisnode; + +if(!data_dir[0]) + return; +getnodedat(node_num,&thisnode,1); +thisnode.misc&=~NODE_NMSG; /* clear the NMSG flag */ +putnodedat(node_num,thisnode); + +sprintf(str,"%sMSGS\\N%3.3u.MSG",data_dir,node_num); +if(flength(str)<1L) { + return; } +if((file=nopen(str,O_RDWR))==-1) { + printf("Couldn't open %s for read/write\r\n",str); + return; } +length=filelength(file); +if((buf=MALLOC(length+1))==NULL) { + close(file); + printf("Couldn't allocate %lu bytes for %s\r\n",length+1,str); + return; } +if(read(file,buf,length)!=length) { + close(file); + FREE(buf); + printf("Couldn't read %lu bytes from %s\r\n",length,str); + return; } +chsize(file,0L); +close(file); +buf[length]=0; + +bputs(buf); +FREE(buf); +} + +/****************************************************************************/ +/* Creates a short message for node 'num' than contains 'strin' */ +/****************************************************************************/ +void putnmsg(int num, char *strin) +{ + char str[256]; + int file,i; + node_t node; + +if(!data_dir[0]) + return; +sprintf(str,"%sMSGS\\N%3.3u.MSG",data_dir,num); +if((file=nopen(str,O_WRONLY|O_CREAT|O_APPEND))==-1) { + printf("Couldn't open %s for append\r\n",str); + return; } +i=strlen(strin); +if(write(file,strin,i)!=i) { + close(file); + printf("Error writing %u bytes to %s\r\n",i,str); + return; } +close(file); +getnodedat(num,&node,0); +if((node.status==NODE_INUSE || node.status==NODE_QUIET) + && !(node.misc&NODE_NMSG)) { + getnodedat(num,&node,1); + node.misc|=NODE_NMSG; + putnodedat(num,node); } +} + +/****************************************************************************/ +/* This function lists users that are online. */ +/* If listself is true, it will list the current node. */ +/* Returns number of active nodes (not including current node). */ +/****************************************************************************/ +int whos_online(char listself) +{ + int i,j; + node_t node; + +if(!ctrl_dir[0]) + return(0); +CRLF; +for(j=0,i=1;i<=sys_nodes;i++) { + getnodedat(i,&node,0); + if(i==node_num) { + if(listself) + printnodedat(i,node); + continue; } + if(node.status==NODE_INUSE || (SYSOP && node.status==NODE_QUIET)) { + printnodedat(i,node); + if(!lastnodemsg) + lastnodemsg=i; + j++; } } +if(!j) + bputs("\1nNo other active nodes.\r\n"); +return(j); +} + +/****************************************************************************/ +/* Sending single line messages between nodes */ +/****************************************************************************/ +void nodemsg(void) +{ + char str[256],line[256],buf[512]; + int i,j; + node_t thisnode; + node_t node; + +if(!ctrl_dir[0]) + return; +if(strchr(user_rest,'C')) { + bputs("You cannot send messages.\r\n"); + return; } +getnodedat(node_num,&thisnode,0); +wordwrap[0]=0; +if(lastnodemsg) { + getnodedat(lastnodemsg,&node,0); + if(node.status!=NODE_INUSE) + lastnodemsg=0; } +if(!whos_online(0)) + return; +bprintf("\r\nngNumber of node to send message to, whAngll, " + "or whQnguit [%u]: wh",lastnodemsg); +i=getkeys("QA",sys_nodes); +if(i==-1) + return; +if(i&0x8000 || !i) { + if(!i) + i=lastnodemsg; + else { + i^=0x8000; + lastnodemsg=i; } + if(!i || i>sys_nodes) + return; + getnodedat(i,&node,0); + if(node.status!=NODE_INUSE && !SYSOP) + bprintf("\r\n_whNode %d is not in use.\r\n",i); + else if(i==node_num) + bputs("\r\nThere's no need to send a message to yourself.\r\n"); + else if(node.misc&NODE_POFF && !SYSOP) + bprintf("\r\nrhiDon't bug %s.n\r\n" + ,node.misc&NODE_ANON ? "UNKNOWN USER" + : username(node.useron)); + else { + bputs("_yhMessage: "); + if(!getstr(line,70,K_LINE)) + return; + sprintf(buf + ,"\7_whNode %2d: g%sng sent you a message:\r\nwh4%sn\r\n" + ,node_num + ,thisnode.misc&NODE_ANON ? "UNKNOWN USER" : user_name,line); + putnmsg(i,buf); } } +else if(i=='A') { + bputs("_yhMessage: "); + if(!getstr(line,70,K_LINE)) + return; + sprintf(buf + ,"\7_whNode %2d: g%sng sent all nodes a message:\r\n" + "wh4%sn\r\n" + ,node_num + ,thisnode.misc&NODE_ANON ? "UNKNOWN USER" : user_name,line); + for(i=1;i<=sys_nodes;i++) { + if(i==node_num) + continue; + getnodedat(i,&node,0); + if((node.status==NODE_INUSE || (SYSOP && node.status==NODE_QUIET)) + && (SYSOP || !(node.misc&NODE_POFF))) + putnmsg(i,buf); } } + +} + +/****************************************************************************/ +/* Puts a character into the input buffer */ +/****************************************************************************/ +void ungetkey(char ch) +{ + +keybuf[keybuftop++]=ch; +if(keybuftop==KEY_BUFSIZE) + keybuftop=0; +} + +#ifdef __SC__ /* Missing from Symantec RTL */ +void clrscr(void) +{ + asm + { mov ah,8 /*function # for "Get char with attr*/ + xor bh,bh /*page 0*/ + int 10h /*Call interrupt 10h (video)*/ + + mov bh,ah /*set "set attr" to "current attr"*/ + mov ah,6 /*function # for "Scroll Window Up"*/ + xor cx,cx /*set upper row & column (0,0)*/ + xor al,al /*set "# lines to scroll" to 0*/ + mov dh,119 /*set lowqer colum*/ + int 10h /*Call interrupt 10h*/ + + mov ah,2 /*function # for "Set Cursor Position"*/ + xor bh,bh /*set page to 0*/ + xor dx,dx /*set row & colum to 0 (upper left)*/ + int 10h /*Call interrupt 10h*/ + } + return; +} + +short wherey(void) +{ + struct disp_t rc; + return(rc.cursorcol); +} +#endif /* __SC__ */ + diff --git a/xtrn/sdk/xsdk.h b/xtrn/sdk/xsdk.h new file mode 100644 index 0000000000000000000000000000000000000000..592d24c1cad9e13f2224b3c89ef1348282febbf2 --- /dev/null +++ b/xtrn/sdk/xsdk.h @@ -0,0 +1,273 @@ +/* XSDK.H */ + +#ifndef _XSDK_H +#define _XSDK_H + +/****************************************************************************/ +/* Synchronet External Program Software Development Kit */ +/* 1993 Digital Dynamics */ +/****************************************************************************/ + +/****************************************************************************/ +/* This source code file is public domain and may be modified, compiled */ +/* distributed, or used in any way, in part or whole for any purposes */ +/* without the consent or notification of Digital Dynamics. */ +/* */ +/* We only request that you display to the user, at some point, in your */ +/* program the character "XSDK" and the version number. */ +/* example: bprintf("XSDK v%s",xsdk_ver); */ +/****************************************************************************/ + +/****************************************************************************/ +/* The source code for two external programs developed by Digital Dynamics */ +/* using XSDK (Synchronet Blackjack [SBJ] and Synchronet BBS List [SBL]) */ +/* are available to the public domain as examples of how to implement the */ +/* functions and variables included in this software development kit. */ +/****************************************************************************/ + + +/****************************************************/ +/* For use with Borland/Turbo C and C++ compilers. */ +/* Tabstop set to 4. */ +/****************************************************/ + +/*********************************************/ +/* Standard Borland/Turbo C/C++ Header Files */ +/*********************************************/ +#include <io.h> +#include <dos.h> +#include <bios.h> +#include <time.h> +#include <ctype.h> +#include <stdio.h> +#include <share.h> +#include <conio.h> +#include <errno.h> +#include <fcntl.h> +#include <string.h> +#include <stdlib.h> +#include <stdarg.h> +#include <malloc.h> +#include <sys/stat.h> +#include <sys/types.h> + +#ifdef __TURBOC__ + #include <dir.h> +#endif + +#ifdef __WATCOMC__ + #include <graph.h> +#endif + +#define GLOBAL extern /* turns XSDKVAR.C into a header file */ +#include "xsdkvars.c" + +#ifdef __cplusplus + extern "C" { +#endif + +extern char *xsdk_ver; /* XSDK version number */ +extern int mswtyp; /* MSwait type */ + +/***********************/ +/* Function Prototypes */ +/***********************/ + +/* Initialize Data + - Reads XTRN.DAT and initializes variables */ +void initdata(void); + +/* Get Terminal Type + - Detects RIP and WIP terminal compatibility */ +void get_term(void); + +/* BBS Print String + - Displays a string locally and remotely (with Ctrl-A codes) */ +void bputs(char *str); + +/* Raw Print String + - Oututs a string locally and remotely (verbatim) */ +void rputs(char *str); + +/* BBS Print Formatted + - Displays a formatted string locally and remotely (with Ctrl-A codes) + - printf() equivalent */ +int bprintf(char *fmt, ...); + +/* Raw Print Formated + - Displays a formatted string locally and remotely (verbatim) + - printf() equivalent */ +int rprintf(char *fmt, ...); + +/* BBS String Length + - Returns length of string, excluding Ctrl-A codes */ +int bstrlen(uchar *str); + +/* Output character + - Displays a single character */ +void outchar(char ch); + +/* Mnemonics + - Display a string expanding ~letter combinations to command keys + - Automatically colorizes mnemonic letters or places them in parenthesis + for non-ANSI users */ +void mnemonics(char *str); + +/* Pause prompt + - Displays [Hit a key] and waits for the user to hit a key */ +void pause(void); + +/* Yes/no Question + - Displays a string with (Y/n) ? appended and waits for the user to hit + 'Y', 'N' or enter + - Returns 1 if the user hit 'Y' or enter + - Automatic colorization */ +char yesno(char *str); + +/* No/yes Question + - Displays a string with (y/N) ? appended and waits for the user to hit + 'Y', 'N' or enter + - Returns 1 if the user hit 'N' or enter */ +char noyes(char *str); + +/* Inbound Keystroke + - If the local or remote user has struck a key, this function returns the + key, otherwise it returns 0 + - Does not wait for a keystroke */ +char inkey(int mode); + +/* Get a Key + - Waits for the local or remote user to hit a valid key + - See K_* constants in XSDKDEFS.H for possible values of mode */ +char getkey(int mode); + +/* Get One of these Keys or a Number + - Waits for the user to hit a valid key or if max is non-zero, then enter + a number not greater than max + - Hot-keyed input, automatically displays the struck key (in upper case) + followed by CRLF + - If the user entered a number, the number is ORed with 0x8000 and returned + you must XOR (or not) this bit to get the correct number */ +int getkeys(char *str, int max); + +/* Get a Number + - Waits for the user to enter a number from 0 to max, 'Q' or ENTER + - Returns -1 if the user hit 'Q' or Ctrl-C + - Returns 0 if the user just hit ENTER */ +int getnum(int max); + +/* Change Attribute + - Sends ANSI escape sequences (if user supports ANSI) to change color + - Valid color bits are defined in INCLUDE\CONIO.H */ +void attr(char atr); + +/* Clear Screen + - Clears local and remote screen (using ANSI if appropriate) + - Automatically pauses before clearing if lncntr is >1 */ +void cls(void); + +/* Process Ctrl-A Code + - Changes color or performs special Ctrl-A function */ +void ctrl_a(char x); + +/* Network Open + - Opens a file in DENYNONE or DENYWRITE mode, automatically retrying */ +int nopen(char *str, int access); + +/* Truncate Space + - Removes white space characters from the end of a string */ +void truncsp(uchar *str); + +/* Adds Backslash + - Adds backslash to end of string if it doesn't exist */ +void backslash(char *str); + +/* Check Time Left + - Checks the amount of time the user has left and sets the timeleft + variable + - Automatically exits if user runs out of time */ +void checktimeleft(void); + +/* Print File + - Displays contents of file (expanding Ctrl-A characters if appropriate) */ +void printfile(char *str); + +/* Get String + - Waits for the user to enter a string + - maxlen is the maximum length of the string + - See K_* constants in XSDKDEFS.H for possible values of mode */ +int getstr(char *str, int maxlen, int mode); + +/* Redraw String + - Redisplays a string, mainly called by getstr() */ +void redrwstr(char *strin, int i, int l, char mode); + +/* Strip Invalid Ctrl-A codes */ +char stripattr(char *strin); + +/* Returns the name of the user number passed */ +char *username(uint usernumber); + +/* Returns the number of the user name passed */ +uint usernumber(char *username); + +/* Returns 1 if the file exists, 0 otherwise */ +char fexist(char *filespec); + +/* Returns the length of the file */ +long flength(char *filespec); + +/* Convert unsigned long to an ASCII string with commas */ +char *ultoac(ulong l, char *string); + +/* Convert an ASCII string of hex digits into an unsigned long */ +ulong ahtoul(char *str); + +/* Display status of node */ +void printnodedat(uchar number, node_t node); + +/* Checks to see if this node has been interrupted or any messages waiting */ +void nodesync(void); + +/* Writes the node information to disk */ +void putnodedat(uchar number, node_t node); + +/* Reads the node information from disk */ +void getnodedat(uchar number, node_t *node, char lockit); + +/* Writes a short message (telegram) for specified user number */ +void putsmsg(int usernumber, char *strin); + +/* Reads and displays short message for specified user number */ +void getsmsg(int usernumber); + +/* Writes a node message for specified node */ +void putnmsg(int num, char *strin); + +/* Reads and displays node message for current node */ +void getnmsg(void); + +/* Displays users online */ +int whos_online(char listself); + +/* Send a node-message (ctrl-P) */ +void nodemsg(void); + +/* Put a key into the keyboard buffer */ +void ungetkey(char ch); + +/* Check to see if the user has hung-up */ +void checkline(void); + +/* Wait a specific number of milliseconds */ +void mswait(int ms); + +/* Display a line (with ctrl-A codes) centered on the screen */ +void center(char *str); + +#ifdef __cplusplus + } +#endif + + +#endif /* Don't add anything after this #endif */ diff --git a/xtrn/sdk/xsdkdefs.h b/xtrn/sdk/xsdkdefs.h new file mode 100644 index 0000000000000000000000000000000000000000..9f0cb632d2920e9e8f009472d26d4f610fc47d62 --- /dev/null +++ b/xtrn/sdk/xsdkdefs.h @@ -0,0 +1,249 @@ +/* XSDKDEFS.H */ + +#ifndef _XSDKDEFS_H +#define _XSDKDEFS_H + +/**********/ +/* Macros */ +/**********/ + /* Control characters */ +#define STX 0x02 /* Start of text ^B */ +#define ETX 0x03 /* End of text ^C */ +#define BS 0x08 /* Back space ^H */ +#define TAB 0x09 /* Horizontal tabulation ^I */ +#define LF 0x0a /* Line feed ^J */ +#define FF 0x0c /* Form feed ^L */ +#define CR 0x0d /* Carriage return ^M */ +#define ESC 0x1b /* Escape ^[ */ +#define SP 0x20 /* Space */ + + +#define DCD 0x8000 /* Data carrier detect bit in msr */ + +#define TABSIZE 4 /* Tabs will expand to 4 chars upon input */ + +#define SAVE_LINES 4 /* Maximum number of lines to save */ +#define LINE_BUFSIZE 512 /* Size of line output buffer */ + +#define HIGH 8 /* High intensity attribute bit */ + + /* user_misc bits */ +#define ANSI (1<<0) /* user has ANSI capability */ +#define COLOR (1<<1) /* user has monochrome ANSI display */ +#define RIP (1<<2) /* RIP compatible terminal detected */ +#define WIP (1<<3) /* WIP compatible terminal detected */ + +#ifndef uchar /* Short-hand for unsigned data types */ +#define uchar unsigned char +#endif +#ifndef uint +#define uint unsigned int +#endif +#ifndef ushort +#define ushort unsigned short +#endif +#ifndef ulong +#define ulong unsigned long +#endif + + /* Bits in 'mode' for getkey and getstr */ +#define K_UPPER (1<<0) /* Converts all letters to upper case */ +#define K_UPRLWR (1<<1) /* Upper/Lower case automatically */ +#define K_NUMBER (1<<2) /* Allow numbers only */ +#define K_WRAP (1<<3) /* Allows word wrap */ +#define K_MSG (1<<4) /* Allows ANSI, ^N ^A ^G */ +#define K_SPIN (1<<5) /* Spinning cursor (same as SPIN) */ +#define K_LINE (1<<6) /* Input line (inverse color) */ +#define K_EDIT (1<<7) /* Edit string passed */ +#define K_CHAT (1<<8) /* In chat multi-chat */ +#define K_NOCRLF (1<<9) /* Don't print CRLF after string input */ +#define K_ALPHA (1<<10) /* Only allow alphabetic characters */ +#define K_AUTODEL (1<<11) /* Auto-delete text (used with K_EDIT) */ +#define K_LOWPRIO (1<<12) /* Low priority getstr() operation */ +#define K_GETSTR (1<<13) /* getkey() called from getstr() */ + + /* Miscellaneous Modem Settings (mdm_misc) */ +#define MDM_FLOWCTRL (1<<0) /* Use flow control with modem */ +#define MDM_STAYHIGH (1<<1) /* Stay at highest DTE rate */ + +#define LOOP_NOPEN 50 /* Retries before file access denied */ +#define LOOP_NODEDAB 100 /* Retries on NODE.DAB locking/unlocking */ + +#define MAX_NODES 250 /* Maximum number of nodes */ + +enum { /* Node Status */ + NODE_WFC /* Waiting for Call */ + ,NODE_LOGON /* at logon prompt */ + ,NODE_NEWUSER /* New user applying */ + ,NODE_INUSE /* In Use */ + ,NODE_QUIET /* In Use - quiet mode */ + ,NODE_OFFLINE /* Offline */ + ,NODE_NETTING /* Networking */ + ,NODE_EVENT_WAITING /* Waiting for all nodes to be inactive */ + ,NODE_EVENT_RUNNING /* Running an external event */ + ,NODE_EVENT_LIMBO /* Allowing another node to run an event */ + }; + + /* Bit values for node.misc */ +#define NODE_ANON (1<<0) /* Anonymous User */ +#define NODE_LOCK (1<<1) /* Locked for sysops only */ +#define NODE_INTR (1<<2) /* Interrupted - hang up */ +#define NODE_MSGW (1<<3) /* Message is waiting */ +#define NODE_POFF (1<<4) /* Page disabled */ +#define NODE_AOFF (1<<5) /* Activity Alert disabled */ +#define NODE_UDAT (1<<6) /* User data has been updated */ +#define NODE_RRUN (1<<7) /* Re-run this node when log off */ +#define NODE_EVENT (1<<8) /* Must run node event after log off */ +#define NODE_DOWN (1<<9) /* Down this node after logoff */ +#define NODE_RPCHT (1<<10) /* Reset private chat */ +#define NODE_NMSG (1<<11) /* Node message waiting (new way) */ + + +enum { /* Node Action */ + NODE_MAIN /* Main Prompt */ + ,NODE_RMSG /* Reading Messages */ + ,NODE_RMAL /* Reading Mail */ + ,NODE_SMAL /* Sending Mail */ + ,NODE_RTXT /* Reading G-Files */ + ,NODE_RSML /* Reading Sent Mail */ + ,NODE_PMSG /* Posting Message */ + ,NODE_AMSG /* Auto-message */ + ,NODE_XTRN /* Running External Program */ + ,NODE_DFLT /* Main Defaults Section */ + ,NODE_XFER /* Transfer Prompt */ + ,NODE_DLNG /* Downloading File */ + ,NODE_ULNG /* Uploading File */ + ,NODE_BXFR /* Bidirectional Transfer */ + ,NODE_LFIL /* Listing Files */ + ,NODE_LOGN /* Logging on */ + ,NODE_LCHT /* In Local Chat with Sysop */ + ,NODE_MCHT /* In Multi-Chat with Other Nodes */ + ,NODE_GCHT /* In Local Chat with Guru */ + ,NODE_CHAT /* In Chat Section */ + ,NODE_SYSP /* Sysop Activity */ + ,NODE_TQWK /* Transferring QWK packet */ + ,NODE_PCHT /* Private node-to-node chat */ + ,NODE_PAGE /* Paging node for Private Chat */ + ,NODE_RFSD /* Retrieving file from sequential dev */ + }; + + /* Different bits in node_misc */ +#define NM_ANSALARM (1<<0) /* Alarm locally on answer */ +#define NM_WFCSCRN (1<<1) /* Wait for call screen */ +#define NM_WFCMSGS (1<<2) /* Include total messages/files on WFC */ +#define NM_LCL_EDIT (1<<3) /* Use local editor to create messages */ +#define NM_EMSOVL (1<<4) /* Use expanded memory of overlays */ +#define NM_WINOS2 (1<<5) /* Use Windows/OS2 time slice API call */ +#define NM_INT28 (1<<6) /* Make int 28 DOS idle calls */ +#define NM_NODV (1<<7) /* Don't detect and use DESQview API */ +#define NM_NO_NUM (1<<8) /* Don't allow logons by user number */ +#define NM_LOGON_R (1<<9) /* Allow logons by user real name */ +#define NM_LOGON_P (1<<10) /* Secure logons (always ask for password) */ +#define NM_NO_LKBRD (1<<11) /* No local keyboard (at all) */ +#define NM_SYSPW (1<<12) /* Protect WFC keys and Alt keys with SY: */ +#define NM_NO_INACT (1<<13) /* No local inactivity alert/logoff */ +#define NM_NOBEEP (1<<14) /* Don't beep locally */ +#define NM_LOWPRIO (1<<15) /* Always use low priority input */ +#define NM_7BITONLY (1L<<16) /* Except 7-bit input only (E71 terminals) */ + +#ifdef __WATCOMC__ + + #if !defined(__COLORS) + #define __COLORS + + enum COLORS { + BLACK, /* dark colors */ + BLUE, + GREEN, + CYAN, + RED, + MAGENTA, + BROWN, + LIGHTGRAY, + DARKGRAY, /* light colors */ + LIGHTBLUE, + LIGHTGREEN, + LIGHTCYAN, + LIGHTRED, + LIGHTMAGENTA, + YELLOW, + WHITE + }; + #endif + + #define BLINK 128 /* blink bit */ + + #define ffblk find_t + #define findfirst(x,y,z) _dos_findfirst(x,z,y) + #define findnext(x) _dos_findnext(x) + #pragma aux mswait "_*" +#endif + +/****************************************************************************/ +/* MALLOC/FREE Macros for various compilers and environments */ +/* MALLOC is used for allocations of 64k or less */ +/* FREE is used to free buffers allocated with MALLOC */ +/* LMALLOC is used for allocations of possibly larger than 64k */ +/* LFREE is used to free buffers allocated with LMALLOC */ +/* REALLOC is used to re-size a previously MALLOCed or LMALLOCed buffer */ +/****************************************************************************/ +#if defined(__COMPACT__) || defined(__LARGE__) || defined(__HUGE__) + #if defined(__TURBOC__) + #define REALLOC(x,y) farrealloc(x,y) + #define LMALLOC(x) farmalloc(x) + #define MALLOC(x) farmalloc(x) + #define LFREE(x) farfree(x) + #define FREE(x) farfree(x) + #elif defined(__WATCOMC__) + #define REALLOC realloc + #define LMALLOC(x) halloc(x,1) /* far heap, but slow */ + #define MALLOC malloc /* far heap, but 64k max */ + #define LFREE hfree + #define FREE free + #else /* Other 16-bit Compiler */ + #define REALLOC realloc + #define LMALLOC malloc + #define MALLOC malloc + #define LFREE free + #define FREE free + #endif +#else /* 32-bit Compiler or Small Memory Model */ + #define REALLOC realloc + #define LMALLOC malloc + #define MALLOC malloc + #define LFREE free + #define FREE free +#endif + +#define KEY_BUFSIZE 256 + +#define CRLF { outchar(CR); outchar(LF); } + +#define SYSOP (user_level>=sysop_level) /* Is current user sysop t/f macro */ + +#define bgotoxy(x,y) printf("\x1b[%d;%dH",y,x) /* place the cursor at */ + /* location x,y via ANSI */ + +#define SAVELINE { slatr[slcnt]=latr; \ + sprintf(slbuf[slcnt<SAVE_LINES ? slcnt++ : slcnt] \ + ,"%.*s",lbuflen,lbuf); \ + lbuflen=0; } +#define RESTORELINE { lbuflen=0; attr(slatr[--slcnt]); \ + bputs(slbuf[slcnt]); } + +/************/ +/* Typedefs */ +/************/ + +typedef struct { /* Node information kept in NODE.DAB */ + uchar status, /* Current Status of Node */ + errors, /* Number of Critical Errors */ + action; /* Action User is doing on Node */ + uint useron, /* User on Node */ + connection, /* Connection rate of Node */ + misc, /* Miscellaneous bits for node */ + aux; /* Auxillary word for node */ + ulong extaux; /* Extended aux dword for node */ + } node_t; + +#endif /* Don't add anything after this endif */ diff --git a/xtrn/sdk/xsdkvars.c b/xtrn/sdk/xsdkvars.c new file mode 100644 index 0000000000000000000000000000000000000000..68182bdf756b1f92775fb781b830ca0b6f940d0d --- /dev/null +++ b/xtrn/sdk/xsdkvars.c @@ -0,0 +1,94 @@ +/* XSDKVARS.C */ + +#include <time.h> +#include <stdio.h> +#include "xsdkdefs.h" + +#ifndef GLOBAL +#define GLOBAL +#endif + +/*******************************/ +/* Global Variable Definitions */ +/*******************************/ +GLOBAL char lncntr; /* Line counter */ +GLOBAL char tos; /* Top of screen */ +GLOBAL uchar curatr; /* Current attribute */ +GLOBAL char mnehigh, /* Colors for mnemonics */ + mnelow; +GLOBAL uchar sys_nodes, /* Number of nodes on system */ + node_num; /* Current node number */ +GLOBAL ulong node_misc; /* Misc. node toggles */ +GLOBAL char sys_name[41], /* System name */ + sys_id[9], /* System QWK ID */ + sys_op[41], /* System operator name */ + sys_guru[41]; /* System guru name */ +GLOBAL ushort timeleft; /* Time left in seconds */ +GLOBAL char ctrl_dir[128], /* SBBS dirs */ + data_dir[128], + node_dir[128], + exec_dir[128], + text_dir[128], + temp_dir[128]; +GLOBAL uint user_number; /* User's number */ +GLOBAL char user_name[45], /* User's name/alias */ + user_misc, /* User's misc settings */ + user_rows, /* User's rows per screen */ + user_level, /* User's main level */ + user_flags1[27], /* User's flag set #1 */ + user_flags2[27], /* User's flag set #2 */ + user_flags3[27], /* User's flag set #3 */ + user_flags4[27], /* User's flag set #4 */ + user_exempt[27], /* User's exemptions */ + user_rest[27], /* User's restrictions */ + user_sex, /* User's sex */ + user_birth[9], /* User's birthday */ + user_phone[13], /* User's phone number */ + user_address[31], /* User's address */ + user_location[31], /* User's location */ + user_zipcode[11], /* User's zip/postal code */ + user_realname[26]; /* User's real name or company name */ +GLOBAL ulong user_cdt, /* User's credits */ + user_dce; /* User's DCE rate */ +GLOBAL time_t user_expire; /* User's expiration date */ + + /* COM port registers: */ +GLOBAL uint com_base, /* COM base address */ + com_irq; /* irq line number */ +GLOBAL ulong com_rate; /* DTE rate in bps */ +GLOBAL char com_port; /* Number of COM port */ + + /* Modem command strings */ +GLOBAL char mdm_init[64], /* Initialization */ + mdm_spec[64], /* Special Initialization */ + mdm_term[64], /* Terminal Initialization String */ + mdm_dial[64], /* Dial */ + mdm_offh[64], /* Off hook */ + mdm_answ[64], /* Answer */ + mdm_misc; /* Misc bits used for flags */ + +GLOBAL time_t starttime; /* Start time-stamp */ +GLOBAL char wordwrap[81]; /* Wordwrap buffer */ +GLOBAL uint sec_warn, /* Seconds till inactivity warning */ + sec_timeout; /* Seconds till disconnect */ +GLOBAL char timeleft_warn; /* Minutes left warning */ + +GLOBAL int nodefile; /* File descriptor for NODE.DAB */ + +GLOBAL char slbuf[SAVE_LINES][LINE_BUFSIZE+1]; /* Saved for redisplay */ +GLOBAL char slatr[SAVE_LINES]; /* Starting attribute of each line */ +GLOBAL char slcnt; /* Number of lines currently saved */ +GLOBAL char lbuf[LINE_BUFSIZE];/* Temp storage for each line output */ +GLOBAL int lbuflen; /* Number of characters in line buffer */ +GLOBAL char latr; /* Starting attribute of line buffer */ +GLOBAL uint inDV; /* DESQview version if running under DV */ +GLOBAL int keybuftop,keybufbot; /* Keyboard input buffer pointers */ +GLOBAL char keybuf[KEY_BUFSIZE]; /* Keyboard input buffer */ +GLOBAL uint far *msr; /* Last modem status register contents */ +GLOBAL char **xtrn; /* List of external program names */ +GLOBAL uint total_xtrns; /* Total number of external programs */ +GLOBAL uchar lastnodemsg; /* Last node to send a message to */ +GLOBAL uchar name_len; /* Length of name field in NAME.DAT */ +GLOBAL char aborted; /* Aborted flag - if ctrl-c hit */ +GLOBAL uint sysop_level; /* Sysop Level */ +GLOBAL FILE *con_fp; /* Console file pointer (stdout/stderr) */ diff --git a/xtrn/smm/adult.que b/xtrn/smm/adult.que new file mode 100644 index 0000000000000000000000000000000000000000..dd10f2f4c89cbb22d1a74be1d85364ef45a134eb --- /dev/null +++ b/xtrn/smm/adult.que @@ -0,0 +1,93 @@ +20 +How old were you when you lost your virginity? +9 +1 +I still have it +Younger than 12 +Between 12 and 14 +Between 15 and 16 +Between 17 and 18 +Between 19 and 20 +Between 21 and 25 +Between 25 and 30 +Older than 30 +How many sexual partners have you had? +8 +1 +None +Between 1 and 5 +Between 6 and 10 +Between 11 and 20 +Between 21 and 30 +Between 31 and 50 +Between 51 and 100 +More than 100 +When engaged in a relationship, how often do you prefer to have sex? +8 +1 +Never +At least once a day +Between 4 and 6 times a week +Between 1 and 3 times a week +Between 1 and 3 times a month +Between 6 and 11 times a year +Between 1 and 5 times a year +Less than once a year +What form of sexually transmitted disease protection do you prefer? +5 +1 +I don't know +Abstinence +No protection +Male condoms +Female condoms +Do you enjoy oral sex? +5 +1 +I don't know +No +Yes, giving +Yes, receiving +Yes, both giving and receiving +Do you enjoy anal sex? +5 +1 +I don't know +No +Yes, giving +Yes, receiving +Yes, both giving and receiving +How often do you masturbate? +8 +1 +At least once a day +Between 4 and 6 times a week +Between 1 and 3 times a week +Between 1 and 3 times a month +Between 6 and 11 times a year +Between 1 and 5 times a year +Less than once a year +Never +Do you reach orgasm (alone or with a partner)? +5 +1 +I don't know +Yes, always +Yes, occasionally +Yes, rarely +No +Have you had sexual partners of your same gender? +6 +1 +I don't know +Yes, always +Yes, occasionally +Yes, rarely +No, but I'm curious +No, never +Do you shave your pubic area? +3 +1 +Yes, all of it +Yes, some of it +No diff --git a/xtrn/smm/appear.que b/xtrn/smm/appear.que new file mode 100644 index 0000000000000000000000000000000000000000..b7b1b7ea02a51d80816883dc50d08d9f84bed505 --- /dev/null +++ b/xtrn/smm/appear.que @@ -0,0 +1,119 @@ +8 +Do you wear any of the following? +16 +16 +Eye glasses +Partial beard (goatee, five o'clock shadow, etc.) +Full beard +Mustache +Side burns +Earring(s) +Make-up +Body piercing (nose, tongue, naval, eyebrow, etc.) +Visible tatoos +Covered tatoos +Unnaturally colored/bleached hair (blue, purple, pink, etc.) +Brades or dreds +Pony tail +Long fingernails +Painted fingernails +None of the above +Larger than average or smaller than average attributes? +16 +8 +Small eyes +Large eyes +Small ears +Large ears +Small nose +Large nose +Small breasts +Large breasts +Large arms +Large legs +Large hips/buttocks +Thin-lips +Thick-lips +Thin eyebrows +Thick eyebrows +None of the above +Do you have a sun-tan? +5 +1 +No, I'm naturally dark +No, but I will this summer +No, I don't try to tan +No, I always burn +Yes +Your (natural) complexion? +9 +3 +Very dark +Medium dark (olive) +Light dark +White +Whiter than white (alabaster) +Sparse freckles +Dense freckles +Mild acne +Cystic acne +Your hair (on your head)? +16 +5 +Gone (bald) +Thin (balding) +Thinner than average +Average thickness +Thicker than average +Feathered +All one length +Curly +Wavy +Straight +Partially shaved +Completely shaved +Short length +Medium length +Long length +Very long length +Your teeth? +11 +4 +Very white +Average whiteness +Slightly stained (smoke, coffee, etc.) +Very stained (smoke, coffee, etc.) +Very straight +Average straightness +Slightly crooked +Very crooked +Visible missing teeth +Visible caps (gold or silver) +Visible braces +Your build? +6 +1 +Thin, wirey +Thin, but toned +Average +Chunky +Stocky +Muscle-bound +Physical disabilities/deformities? +14 +5 +Missing fingers +Gimpy or missing limbs +Scarred face +Scarred arms or hands +Mongloidian eyes +Lazy/cross/cock-eyed +Cleft pallette +Paraplegic +Quadriplegic +Blind +Deaf +Mute +Other +None + diff --git a/xtrn/smm/basic.que b/xtrn/smm/basic.que new file mode 100644 index 0000000000000000000000000000000000000000..aaf3634eb02a3553e5e2569e92c06b52b12cd9f6 --- /dev/null +++ b/xtrn/smm/basic.que @@ -0,0 +1,179 @@ +17 +What is your religious belief? +9 +1 +Christian +Jewish +Catholic +Buddihst +Muslim +Mormon +Jehovah's Witness +Other +None +Do you participate in organized religion? +3 +1 +Yes +No +Sometimes +Do you smoke tobacco? +5 +1 +Yes, daily +Yes, occasionally +Yes, I'm trying to quit +No, I quit +No, I never smoked tobacco regularly +Do you use forms of nicotine other than tobacco (dip, snuff, etc)? +5 +1 +Yes, daily +Yes, occasionally +Yes, I'm trying to quit +No, I quit +No, never +Do you drink alcohol? +6 +1 +Yes, daily +Yes, occasionally +Yes, but never enough to get drunk +Yes, I'm trying to quit +No, I quit +No, I never drank +Do you dance? +7 +1 +Yes, professionally (exotic) +Yes, professionally (tame) +Yes, regularly +Yes, occasionally +Yes, rarely +No, not recently +No, not ever +Favorite types of music? +16 +16 +Easy Listening +New Age +Classical +Classic Rock +Heavy Metal +Punk Rock +Alternative +Industrial +Techno +Pop +Rap +Disco +Rhthym and Blues +Jazz +Folk +Country and Western +Completed education? +7 +6 +Grade school +High school +Trade school +College (Associate's) +College (Bachelor's) +College (Master's) +None +Are you currently enrolled in school? +8 +1 +Yes, grade school +Yes, high school +Yes, trade school +Yes, city college +Yes, state college +No, but I plan to return +No, but I plan to start +No, and I have no plans to +Are you currently employed? +4 +1 +Yes, full-time +Yes, part-time +No, but I'm seeking employment +No, I don't need/want to work right now +Are you financially independant? +5 +1 +Yes +No, I depend on my parent(s) +No, I depend on other relative(s) +No, I depend on my spouse +No, I depend on a significant other +Do you play sports? +5 +1 +Yes, professionally +Yes, frequently +Yes, occasionally +Yes, rarely +No +Do you do any recreational reading? +4 +1 +Yes, frequently +Yes, occasionally +Yes, rarely +No +Favorite out-door activities? +16 +16 +Water (swimming, skiing, surfing, etc.) +Snow (skiing, boarding, ice skating, etc.) +Hiking/camping/climbing +Roller skating/blading +Bicycling +Running/jogging/walking +Team sports (baseball, basketball, football, soccer, etc.) +Racket sports (tennis, racquetball, badminton, etc.) +Golf +Shooting (firearms, archery, etc.) +Off-road (motorcycles, ATVs, etc.) +Sky diving/bungee jumping +Gardening +Fishing/hunting +Horseback riding +None of the above +Favorite in-home activities? +16 +16 +Painting/drawing/sculpting/etc. +Sewing/weaving/etc. +Cooking +Writing +Reading +Playing a musical instrument/singing +Playing video/computer games +Playing card/board games +Cleaning +Computer programming/exploring +BBS/E-mail/Internet communications +CB/HAM/shortwave radio communications +Electronics/chemistry/physics experiments +Talking on the telephone +Watching television +Listening to music (CDs, records, tapes, radio, etc.) +Do you have any children? +6 +1 +Yes, three or more +Yes, two +Yes, one +No, but definitely someday +No, but possibly someday +No, I don't ever want children +What kind of relationship are you seeking? +5 +5 +Platonic friendship (no intimacy) +Dating (no commitment) +Long term relationship (boyfriend/girlfriend/lover) +Marriage +None of the above diff --git a/xtrn/smm/file_id.diz b/xtrn/smm/file_id.diz new file mode 100644 index 0000000000000000000000000000000000000000..5b423d7a3f4db10074039113ceb646dd2842a419 --- /dev/null +++ b/xtrn/smm/file_id.diz @@ -0,0 +1,7 @@ +Synchronet Match Maker (BBS door) v2.10 +supports any DOOR.SYS or Synchronet BBS. +Internationally networked profiles, +telegrams, wall, photographs, and more! +Developed by Digital Dynamics, makers of +Synchronet BBS Software. Perhaps the most +comprehensive match maker available. diff --git a/xtrn/smm/list_hdr.asc b/xtrn/smm/list_hdr.asc new file mode 100644 index 0000000000000000000000000000000000000000..182a1298dd2ff79ae8d05de74f2ee8b7a2c8784e --- /dev/null +++ b/xtrn/smm/list_hdr.asc @@ -0,0 +1,5 @@ +nh���Marital Status or Orientation (Single, Married, Divorced, Widowed, etc) +�ng��Race (White, Black, Hispanic, Indian, Middle Eastern, Asian, or Other) +hw�ng�hc�Sex m �Eyes y�Weight +w�ng�hc�bAge gHairm� rHeighty� ng�Location cPhoto�hw�Name/Alias mMatch� +w�ng�hc� b� g� m� r� y�ng � c�hw�m � diff --git a/xtrn/smm/material.que b/xtrn/smm/material.que new file mode 100644 index 0000000000000000000000000000000000000000..2de521f0150f61b7dd4025f43ca153597b8150ef --- /dev/null +++ b/xtrn/smm/material.que @@ -0,0 +1,91 @@ +16 +Do you own a passenger vehicle? +5 +1 +Yes, more than one +Yes +No, but I will soon +No, and I don't know when/if I will +No, I don't have a driver's license +Do you own a recreational vehicle? +2 +1 +Yes +No +Do you own a home (mortage counts)? +4 +1 +Yes, more than one +Yes +No, I'm renting +No +Do you own furniture? +3 +1 +Yes +No, I'm renting +No +Do you own a computer? +4 +1 +Yes, more than one +Yes +No, I'm renting +No +Do you have a savings account? +2 +1 +Yes +No +Do you have a checking account? +2 +1 +Yes +No +Do you have a credit card? +3 +1 +Yes, more than one +Yes +No +Do you have health insurance? +2 +1 +Yes +No +Do you have life insurance? +2 +1 +Yes +No +Do you have car insurance? +2 +1 +Yes +No +Do you have an accountant? +2 +1 +Yes +No +Do you have a maid? +2 +1 +Yes +No +Do you own a swimming pool (i.e. in your backyard)? +2 +1 +Yes +No +Do you own an acre or more of land? +2 +1 +Yes +No +Do you own any stocks or bonds? +2 +1 +Yes +No + diff --git a/xtrn/smm/mb-e.asc b/xtrn/smm/mb-e.asc new file mode 100644 index 0000000000000000000000000000000000000000..2b612f78b2f06864bce8dbc5667aa911a9904393 --- /dev/null +++ b/xtrn/smm/mb-e.asc @@ -0,0 +1,7 @@ +An Extrovert is energized by people. A strong extrovert feels very much alone +without lots of people around. E's tend to talk first & think later, know a +lot of people, don't mind having a conversation while the TV is on, are +approachable, don't consider the telephone to be an interruption, tend to +think out loud and use people as a sounding board for their ideas, need +affirmation from friends about who I am & how do I look. +About 75% of the population are type E. diff --git a/xtrn/smm/mb-enfj.asc b/xtrn/smm/mb-enfj.asc new file mode 100644 index 0000000000000000000000000000000000000000..7dadc77fe75706a029dc3ce7ff44c9c4e806a044 --- /dev/null +++ b/xtrn/smm/mb-enfj.asc @@ -0,0 +1,134 @@ +ENFJs in short: + +Responsive and responsible. Generally feel real concern for what +others think or want, and try to handle things with due regard for +other person's feelings. Can present a proposal or lead a group +discussion with ease and tact. Sociable, popular, sympathetic. +Responsive to praise and criticism. + +About 5% of the population. + +Details about ENFJs: + +ENFJs are outstanding leaders of groups, both task groups and +growth groups. They have the charming characteristic of seeming to +take for granted that they will be followed, never doubting that +people will want to do what they suggest. And, more often than +not, people do, because this type of has unusual charisma. ENFJs +place a high value on cooperation from others and are most willing +to cooperate themselves. + +Found in only about 5 percent of the general population, ENFJs +place people as being of highest importance and priority. As a +result, ENFJs may find themselves feeling responsible for the +feelings of others to an extent which places a burden on the +relationship. + +An ENFJ communicates caring, concern, and a willingness to be +involved. Thus people turn to ENFJs for nurture and support, which +an ENFJ is usually able to deliver. At times, however, these kinds +of demands can overwhelm ENFJs, who find at this point that they +lack the skills to dissociate. ENFJs do not seem able to turn away +from these demands even when they become unreasonable. Or, if +forced to let go of the burden through sheer unavailability of time +or energy, ENFJs experience a guilt all out of proportion to the +realities of the commitment to the relationship. + +ENFJs are vulnerable to idealize interpersonal relationships, +raising these relationships to a plane which seldom can sustain the +realities of human nature. Because of this tendency to raise +interpersonal relations to the ideal, ENFJs may unwittingly +overpower their friends, who believe that they cannot possibly live +up to an ENFJ's perception of them. The fact is, ENFJs are +extraordinarily tolerant of others, seldom critical, and always +trustworthy. + +ENFJs take communication for granted and believe that they are +understood and that their communications are accepted. Just as +they themselves are accepting, so do they assume that others are +the same. When ENFJs find that their position or beliefs were not +comprehended or accepted, they are surprised, puzzled, and +sometimes hurt. Fortunately, this does not happen with high +frequency, as ENFJs have a remarkable fluency with language, +especially in speech; they are particularly adept when +communicating face-to-face as opposed to communicating in writing. + +They are influential, therefore, in groups, having no hesitation +about speaking out, no matter how large or small the group may be. + +ENFJs have an unusual ability to relate to others with empathy, +taking into themselves the characteristics, emotions, and beliefs +of others. This can pose a danger for ENFJs, they can +unconsciously over-identify with others and pick up their burdens +as if they were their own. In the process, ENFJs may risk their +own sense of identity. + +They have a natural ability to mimic because of this highly +developed ability to empathize by interjection. They are likely to +be very concerned about the problems of those close to them, but +they also may get as deeply involved in the problems of those not +so close and may find themselves overextended emotionally. + +ENFJs would do well to follow their hunches, for their intuition +tends to be well developed. Decisions made purely on the basis of +logic may not be so sound, and checking with a person who has a +strong T preference might be at times advisable for the ENFJ. In +the framework of values, however, the ENFJ is on certain ground. +Generally, they know what they prefer and can read other people +with outstanding accuracy. Seldom is an ENFJ wrong about the +motivations or intents of another, hidden or not. + +ENFJs are socially adept and make excellent companions and mates. +They also are deeply devoted to their children, yet tend not to be +domineering to either the children or a mate. In fact, the ENFJ is +so even-tempered that he or she can be victimized by a mate who +might have become more than demanding. + +ENFJ mates always try to please and feel personally responsible +when home life does not go smoothly. They are tireless in their +efforts to see that it does, providing generously from available +income, time and energy. This dedication often exists, however, +side by side with an ENFJ's dream of the perfect relationship - a +characteristic of all NFs, but one which is particularly strong in +an ENFJ. Thus an ENFJ has that longing for the ideal which results +in a vague dissatisfaction with whatever is in the way of +relationships, mating as well as friendship. + +This longing for the perfect carries over into the careers of +ENFJs, who experience some degree of restlessness whatever their +jobs. And, as with ENFPs, ENFJs have a wide range of occupations +which offer success. + +Being verbally adept, ENFJs contribute to an unusual level when +dealing with people, particularly face-to-face: the media, the +ministry, and the stage and screen are populated with successful +ENFJs. They make superior therapists, charismatic teachers, +excellent executives, and personalized executives. Areas that +would not permit utilization of the interaction talents of the +ENFJs, for example, accounting, should be avoided; otherwise, +almost any people-to-people occupation where personal, sustained +contact is involved capitalizes on the personality of an ENFJ. + +ENFJs like to have things organized and settled. They prefer to +plan both work and social engagements ahead and tend to be +absolutely reliable in honoring these commitments. ENFJs are very +much at home in complex situations which require the juggling of +much data. At the same time they can handle people with charm and +concern. + +ENFJs are usually popular wherever they are. Their ability to be +comfortable either leading or following makes them easy to have +around, whatever the situation. A well-developed ENFJ group leader +can provide, almost endlessly, activities for groups to play. In +some, this can amount to genius which other types find hard to +emulate. In this ability to organize without planning there is a +certain, similarity to the ESFJ, but the latter acts more as a +master of ceremonies than as a leader of groups. The ESFJ is more +of a recreational leader, who insures that each member has fun at a +party and that the right things are expressed at social occasions, +especially institutional social occasions such as weddings, +funerals, parties, and the like. + +ENFJs, just like ESFJs, value harmonious human relations above all +else; but ENFJs are not so easily crushed by indifference as are +ESFJs and are more independent of others' valuations. diff --git a/xtrn/smm/mb-enfp.asc b/xtrn/smm/mb-enfp.asc new file mode 100644 index 0000000000000000000000000000000000000000..b8bcfdb153f8419529a418c96e59c5959015c9c7 --- /dev/null +++ b/xtrn/smm/mb-enfp.asc @@ -0,0 +1,157 @@ +ENFPs in short: + +Warmly enthusiastic, high-spirited, ingenious, imaginative. Able +to do almost anything that interests them. Quick with a solution +for any difficulty and ready to help anyone with a problem. Often +rely on their ability to improvise instead of preparing in advance. +Can usually find compelling reasons for whatever they want. + +About 5% of the population. + +Details on ENFPs: + +For ENFPs nothing occurs which does not have some significance, and +they have an uncanny sense of the motivations of others. This +gives them a talent for seeing life as an exciting drama, pregnant +with possibilities for both good and evil. This type is found in +only about 5 percent of the general population, but they have great +influence because of their extraordinary impact on others. + +ENFPs strive toward the authentic, even when acting spontaneously, +and this intent is usually communicated nonverbally to others, who +find this characteristic attractive. ENFPs, however, find their +own efforts of authenticity and spontaneity always lacking, and +tend to heap coals of fire on themselves, always berating +themselves for being so conscious of self. + +ENFPs consider intense emotional experiences vital; when they have +these, however, they are made uneasy by a sense of being there but +with a part of themselves cut off. They strive for congruency, but +always see themselves in some danger of losing touch with their +real feelings, which ENFPs possess in a wide range and variety. + +ENFPs exercise a continuous scanning of the external environment +and nothing out of the ordinary is likely to escape their +attention. They are keen and penetrating observers and are capable +of intense concentration on another individual while aware of what +is going on about them. Their attention is never passive or +casual, never wandering, but always directed. + +At times, ENFPs find themselves interpreting events in terms of +another's "hidden motive," giving special meaning to words or +actions. This interpretation tends to be negative and, more often +than not, inaccurately negative. In the process, an ENFP may find +that he or she has introduced an unnecessary, toxic element into +the relationship. + +While ENFPs are brilliantly perceptive, they can make serious +mistakes in judgement, which works to their discomfort. These +mistakes derive from their tendency to focus on data which confirm +their own biases. They may be absolutely correct in their +perceptions but wrong in their conclusions. + +Because they tend to be hypersensitive and hyperalert, they may +suffer from muscle tension. They live in readiness for +emergencies; because they have this facility, they assume this is +true for others. They can become bored rather quickly with both +situations and people, and resist repeating experiences. + +They enjoy the process of creating something - an idea or a project +- but are not as interested in the follow-through. They are +typically enthusiastic, and this is contagious. People get caught +up and entranced by an ENFP. Yet this type is marked with a fierce +independence, repudiating any kind of subordination, either in +themselves or in others in relation to them. + +They do tend to attribute more power to authority figures than is +there and give over to these figures an ability to "see through" +them - which also is not apt to be there. + +While ENFPs resist the notion of others becoming dependent or +having power over them, their charisma draws followers who wish to +be shown the way. ENFPs constantly find themselves surrounded by +others who look toward the ENFP for wisdom, inspiration, courage, +leadership, and so on - an expectancy which, at times, weighs +rather heavily on an ENFP. + +ENFPs are characteristically optimistic and are surprised when +people and events do not turn out as anticipated. Often their +confidence in the innate goodness of fate and human nature is a +self-fulfilling prophecy. + +ENFPs have a remarkable latitude in career choices and succeed in +many fields. As workers, they are warmly enthusiastic, high +spirited, ingenious, imaginative, and can do almost anything that +interests them. They can solve most problems, particularly those +dealing with people. They are charming and at ease with +colleagues; others enjoy their presence. + +ENFPs are outstanding in getting people together, and are good at +initiating meetings and conferences, although not as talented at +providing for the operational details of these events. They enjoy +inventing new ways of doing things, and their projects tend to +become a cause, quickly becoming personalized. + +They are imaginative themselves, but can have difficulty picking up +on ideas and projects initiated by others. They must make these +ideas and projects their own if ENFPs are to lend energy and +interest. Once people or projects become routine, ENFPs are likely +to lose interest; what 'might be' is always more fascinating than +'what is.' + +ENFPs make extensive use of their intuitive powers. They usually +have a wide range of personal and telephone contacts, expending +energy in maintaining both career and personal relationships. + +ENFPs make excellent salespeople, advertising people, politicians, +screen or play writers, and in general are attracted to the +interpretive arts, particularly, character acting. +People-to-people work is essential for ENFPs, who need the feedback +of interaction with others. + +ENFPs may find it difficult to work within the constraints of an +institution, especially in following rules, regulations, and +standard operating procedures. More frequently, institutional +procedures and policies are targets to be challenged and bent by +the will of an ENFP. Colleagues and superiors sometimes find +themselves in the position of having to accommodate and salvage. + +At times, ENFPs demonstrate impatience with others; they may get +into difficulty in an organization by siding with its detractors, +who find in an ENFP a sympathetic ear and a natural rescuer. In +occupational choice, ENFPs quickly become restless if the choice +involves painstaking detail and follow-through over a period of +time. Variety in day-to-day operations and interactions best suits +the talents of ENFPs, who need quite a bit of latitude in which to +exercise their adaptive ingenuity. + +As mates, ENFPs tend to be charming, gentle, sympathetic, and +nonconformist. They are not likely to be interested in the +less-inspired routines of daily maintenance and ever will be +seeking new outlets for their inspirations. + +As parents, ENFPs are devoted to their children, shifting from a +role of "friend in need rescuer" to stern authority figure. They +may not always be willing to enforce their impulsive +pronouncements, but leave it to their mates to follow through. + +A mate of an ENFP can expect charming surprises: extravagant +generosity punctuated by periods of frugality. Independent actions +regarding money on the part of an ENFP's mate are not ordinarily +welcomed, and the mate may find him or herself in an embarrassing +situation of having to return purchases. + +ENFPs generally are the ones in charge of the home, and a +conflict-free home is desired, almost demanded. When he or she is +in charge of economic resources, the ENFPs may contain extravagant +luxuries, while necessities may be missing. They are not always +interested in saving for the future and may be casual in giving +consideration to such things as life insurance, savings accounts, +and even a ready cash supply for mate and children. + +ENFPs are characteristic in their pursuit of the novel, their +strong sense of the possible, and outstanding intuitive powers. At +the same time, they have warmth and fun with people and generally +are unusually skilled in handling people. Their extroverted role +tends to be well developed, as is their capacity for the novel and +the dramatic. diff --git a/xtrn/smm/mb-entj.asc b/xtrn/smm/mb-entj.asc new file mode 100644 index 0000000000000000000000000000000000000000..a37af1d7e69f038528b89029a41d5f8606f06317 --- /dev/null +++ b/xtrn/smm/mb-entj.asc @@ -0,0 +1,105 @@ +ENTJs in short: + +Hearty, frank, decisive, leaders in activities. Usually good in +anything that requires reasoning and intelligent talk, such as +public speaking. Are usually well-informed and enjoy adding to +their fund of knowledge. May sometimes be more positive and +confident than their experience in an area warrants. + +About 5% of the population. + +Details about ENTJs: + +If one word were used to capture ENTJ's style, it would be +commandant. The basic driving force and need of ENTJs is to lead, +and from an early age they can be observed taking over groups. This +type is found in approximately 5 percent of the total population. + +ENTJs have a strong urge to give structure wherever they are - to +harness people to distant goals. Their empirical, objective, and +extroverted thinking may be highly developed; if this is the case, +they use classification, generalization, summarization, adduction +of evidence, and demonstration with ease. + +They resemble ESTJs in their tendency to establish plans for a +task, enterprise, or organization, but ENTJs search more for policy +and goals than for regulations and procedures. + +An ENTJ's introverted thinking (analysis and conservation) may be +less well developed than the extroverted thinking processes, and +the ENTJ leader may turn to an ENTP or INTP to provide this kind of +input. ENTJs are similar to INTJs except that the former places +greater trust in empirical thought than in intuition; it is the +ENTJs own intuitive sense of coherence, however, that augments and +supports their empirical thinking. + +Although ENTJs are tolerant of established procedures, they can +abandon any procedure when it can be shown to be indifferent to the +goal it seemingly serves. Inefficiency is especially rejected by +ENTJs, and repetition of error causes them to become impatient. For +the ENTJ, there must always be a reason for doing anything, and +people's feelings usually are not sufficient reason. + +When in charge of an organization, ENTJs more than any other type +desire (and generally have the ability) to visualize where the +organization is going and seem able to communicate that vision to +others. They are the natural organization builders, and they +cannot not lead. They find themselves in command and sometimes are +mystified as to how this happened. + +As administrators, ENTJs organize their units into a smooth +functioning system, planning in advance, keeping both short-term +and long-range objectives well in mind. They seek and can see +efficiency and effectiveness in personnel. They prefer decisions +to be based on impersonal data, want to work from well-thought-out +plans, and like to use engineered operations - and they prefer that +others follow suit. ENTJs will support the policy of the +organization and will expect others to do so. + +ENTJs will usually rise to positions of responsibility and enjoy +being executives. They are tireless in their devotion to their +jobs and can easily block out other areas of life for the sake of +work. They will be able to reduce inefficiency, ineffectiveness, +and aimless confusion, being willing to dismiss employees who +perpetuate such behaviors. + +ENTJs tend to work in organizational structures of some sort, tend +to be in charge administratively, and rise to top levels of +responsibility, whether in the military, business, education, or +government. + +ENTJs take charge of the home. When the ENTJ is present, there +will be little doubt as to who is in command. Because their work +is so important to them, however, they can become increasingly +absent, especially if male. + +Male or female, ENTJs expect a great deal of their mates, who need +to possess a strong personality of their own, a well-developed +autonomy, many and varied interests, and a healthy self-esteem. A +career wife, however, may not be appealing to an ENTJ male, who is +apt to view his home and family as a part of his professional +background, a resource, and adjunct to his own career development. + +As a parent, an ENTJ will be thoroughly in charge, and the children +will know what is expected of them - and will be expected to obey. +When this does not occur, an ENTJ parent is not apt to make a +scene; rather, there is likely to be a low-key, firm issuance of +reprimand and a taking-for-granted of immediate obedience. + +While both mating and parenting are roles of importance to the +ENTJ, they are to some degree preempted by the ENTJ's strong career +interest. The romantic dream and the quest for the ideal mate is +usually not a characteristic of this type. + +ENTJs generally do, however, expect a home to be attractive, +well-ordered, with meals served punctually and maintenance +accomplished on schedule - all these in the service of the larger +goal of creating a family system where children can be reared to be +productive and healthy and establishing a devoted, harmonious +relationship between man and woman. + +An ENTJ male might expect his mate to be active in civic and +community affairs, to be socially sophisticated, and to be as +well-educated as he. The ENTJ female may find it difficult to +select a mate who is not overwhelmed by her strong personality and +will. diff --git a/xtrn/smm/mb-entp.asc b/xtrn/smm/mb-entp.asc new file mode 100644 index 0000000000000000000000000000000000000000..4817854f1d243baddc38eb1a8359470a2327143d --- /dev/null +++ b/xtrn/smm/mb-entp.asc @@ -0,0 +1,145 @@ +ENTPs in short: + +Quick, ingenious, good at many things. Stimulating company, alert +and outspoken. May argue for fun on either side of a question. +Resourceful in solving new and challenging problems, but may +neglect routine assignments. Apt to turn to one new interest after +another. Skillful in finding logical reasons for what they want. + +About 5% of the population. + +Details about ENTPs: + +ENTPs wish to exercise their ingenuity in the world of people and +things. Found in about five out of every hundred people, ENTPs +extrovert intuition; thus they deal imaginatively with social +relationships as well as physical and mechanical relations. They +are very alert to what is apt to occur next, and always sensitive +to possibilities. + +ENTPs are good at analysis, especially functional analysis, and +have both a tolerance for and enjoyment of the complex. Usually +enthusiastic, ENTPs are apt to express interest in everything, and +thus are a source of inspiration to others, who find themselves +caught up by the ENTP's enthusiasm. This type is delighted over +many things and so is easy to please, often showing the +effervescence of their NF counterpart, the ENFP. + +The ENTP is the most reluctant of all the types to do things in a +particular manner just because that is the way things have always +been done. They characteristically have an eye for a better way, +always on the lookout for new projects, new activities, new +procedures. + +ENTPs are confident in the value of their pursuits and display a +charming capacity to ignore the standard, the traditional, and the +authoritative. As a result of this open attitude, they often bring +a fresh, new approach to their work and their lives. The ENTP is a +keen judge of the pragmatics of both the social and the mechanical, +and may become expert at directing relationships between means and +ends. + +Where the introverted NTP sees design as an end in itself, the +extroverted NTP sees design as a 'means'; the end is the invention +that works, the prototype that is replicatable. Ideas are valuable +when and only when they make possible actions and objects. "It +can't be done" is a challenge to an ENFP and elicits a reaction of +"I can do it." + +They are not, however, the movers of mountains as are the INTJs. +Rather, the faith of the ENTPs is in their ability to improvise +something, and they display an unusual talent for rising to the +expectancy of a situation. + +Superficially, ENTPs resemble ESTPs in their derring-do. But the +focus of the ENTP is on competency and the sense of power this +gives, rather than on the feeling of freedom of action experienced +by the ESTP. + +ENTPs can be fascinating conversationalists, able as they are to +follow the complex verbalizations of others. They may deliberately +employ debate tactics to the disadvantage of their opponents, even +when the "opponents" are close associates and valued friends. + +ENTPs are the most able of all types to maintain a one-up position +with others. They value adaptability and innovation and thus +respond quickly and adeptly to another's shifting position. They +may even be several jumps ahead. + +The ENTP, talkative and motivating, is often the life of an +enterprise. The ENTP can be an entrepreneur and cleverly makes do +with whatever or whoever is at hand, counting on ingenuity to solve +problems as they arise, rather than carefully generating a detailed +blueprint in advance. A rough draft is all an ENTP needs to feel +confident and ready to proceed into action, counting on the ability +to improvise as a situation develops. + +Because of this tendency to depend on ingenuity and improvisation, +they may neglect very necessary preparation at times. After +repeated failures in situations where improvising has met with +defeat, the ENTP may develop ways of avoiding such situations as a +substitute to thorough preparation. + +ENTPs can succeed in a variety of occupations, as long as the job +does not involve too much humdrum routine. At this point, they +become restless. If a project in which they are engaged is no +longer challenging, they tend to lose interest in that project and +fail to follow through - often to the discomfort of colleagues. + +Seldom are ENTPs conformists. ENTPs enjoy outwitting the system +and use rules and regulations within the system to win the game - +whatever it may be. They understand well the politics of +institutions and deal with these realities very well, always aiming +to understand the people within the system rather than to judge +them. + +ENTPs are good at innovative projects and can administer them well +if dull routine is not involved. They usually are outstanding +teachers, continuously devising new participative ways to make +learning exciting for the students. + +As an employee, an ENTP may work against the system just for the +joy of being one-up. For ENTPs, to be taken-in, to be manipulated +by another, is humiliating; this offends their joy in being masters +of the art of one-upmanship. + +ENTPs are the natural engineers of human relationships and human +systems. Their good humor and optimistic outlook tend to be +contagious, and people seek out their company. + +As mates, ENTPs tend to create a lively living environment. They +are gregarious, laugh easily and often, and are typically in good +humor. + +Orderliness in the routines of daily living is not apt to inspire +them; they usually solve this problem by mobilizing those around +them. Tom Sawyer illustrated this talent when he solved the +problem of getting his Aunt Polly's fence whitewashed. Life with +ENTPs is likely to be a daring adventure; they can lead families +into physical and economic dangers. ENTPs improvise to remain +unaware that they do not have the necessary knowledge of the +situation to ward off such dangers. + +If the mate of an ENTP is not competitive, he or she is likely to +find the one-up/one-down transactions somewhat wearing. If the +mate is competitive, the result might be conflict. + +Although usually good providers of economic necessities, ENTPs at +times engage in brinkmanship with their careers, placing them in +jeopardy and behaving as if unaware of the consequences; they may +thus offer unnecessary challenges to those who have power over +their professional success. When challenges elicit negative +responses from superiors, ENTPs are apt to react with delight at +having an opportunity to improvise a solution to the crisis - and, +more often than not, they succeed in doing so. + +ENTPs are likely to have all sorts of hobbies and to be experts in +unexpected areas, but they are not apt to share these hobbies with +their mates or children in the sense of teaching them. In fact, +ENTPs may be very inconsistent in the attention given to offspring. + +Usually, it is feast or famine. ENTPs have a lively circle of +friends and are interested in their ideas and activities. They are +usually easygoing, seldom critical or nagging. At their worst, +they can show undependable, fickle characteristics and may be +easily discouraged. diff --git a/xtrn/smm/mb-esfj.asc b/xtrn/smm/mb-esfj.asc new file mode 100644 index 0000000000000000000000000000000000000000..c3801a37f6f07bf4b3b308a40146e9ee33cf69b9 --- /dev/null +++ b/xtrn/smm/mb-esfj.asc @@ -0,0 +1,118 @@ +ESFJs in short: + +Warmhearted, talkative, popular, conscientious, born cooperators, +active committee members. Need harmony and may be good at creating +it. Always doing something nice for someone. Work best with +encouragement and praise. Little interest in abstract thinking or +technical subjects. Main interest is in things that directly and +visibly affect people's lives. + +About 13% of the population. + +Details about ESFJs: + +ESFJs, the most sociable of all the types, are energized by +interactions with people, tending to idealize whatever or whoever +they admire. 'Harmony' is a key to this type, which is represented +in about 13 percent of the general population. + +ESFJs are the great nurturers of established institutions such as +the home, the school, the church, and civic groups. Wherever they +go, they promote harmony and harmonious relationships. They are +outstanding hosts or hostesses, able to call people by name, +usually after one introduction. At a social gathering they can be +observed attending to the needs of others, trying to insure that +all are comfortable and involved. + +Social ties matter to the ESFJs, and their conversations often +drift to the nostalgic recounting of past memories. Traditions are +developed, supported, and carefully observed by the ESFJ. + +ESFJs are hurt by indifference and need to be appreciated both for +themselves and for the abundance, typically in the form of +services, they give to others. They are conscious of appearances +and take the opinions of others regarding social standards very +seriously. Values in an ESFJ may take the form of 'shoulds' and +'should nots' and may be freely expressed. Conscientious and +orderly, ESFJs may become restless when isolated from people. + +Career selection by ESFJs may lean toward service occupations. +They have such outgoing personalities that they are outstanding at +selling, being an invariable winner in sales contests. They are +apt to have seniority in any sales group within an organization. +Observation of ESFJs at work in a sales transaction will +demonstrate how this type personalizes the sale: The customer is +not buying the product; he or she is buying personally from the +ESFJ. + +This same characteristic causes ESFJs to be good in teaching, +preaching, supervision, administration, coaching, and, in general, +people-to-people jobs. They seldom become a source of irritation +to their superiors, for they respect and obey the rules and +regulations, are duty and service oriented. They are loyal to +their bosses. + +ESFJs are likely to be aware of and enjoy discussing events and +problems in the lives of their colleagues; but when conversations +turn to abstractions of philosophy or science, the ESFJ may become +restive. Analysis of the complex - for example, an attempt to find +an explanation of events through an analysis of principles - does +not excite their interest, as it does the NTs. + +ESFJ mates have a set of values which contain clear 'shoulds' and +'should-nots', and they expect their family to abide by these. +They are conscientious about home responsibilities, are orderly +about the home, and prefer that other occupants be the same. They +enjoy socializing and entertaining. + +ESFJs want family decisions settled efficiently and quickly and +want family living routinized, scheduled, and correctly executed. +They do not rebel against routine operations, and are devoted to +the traditional values of home and hearth, respect their marriage +vows, and are the most sympathetic of all types. + +They tend to be dependent on their mates and may marry to insure +that they have a proper place in the social strata. They enjoy the +rituals in connected with serving of good food and beverages, +thrive on festive occasions, respect and accumulate a goodly store +of material possessions. They take their role in the community +seriously and are sensitive to the acknowledged, official +decision-makers and identify with them. They are aware of status, +and often depend on higher authority as the source of opinions and +attitudes. + +ESFJs wear their hearts on their sleeves and are outgoing in their +emotional reactions. They need to be needed, loved, and +appreciated and may spend much energy reassuring themselves that +this is the case. They can become melancholy and depressed and +even suicidal if they take the blame for whatever might be wrong in +their institution or their personal relationships - as they are +prone to do. + +ESFJs usually respect and revere their parents, and as children +were responsive and obedient pupils. They seem able to express the +right feeling for a given situation. + +They are softhearted, sentimental, and usually observe with gusto +and a flourish birthdays, anniversaries, and the like, making of +the event a delightful, important occasion. At the same time, +however, ESFJs can cause others undue tension by expressing +anticipations of gloom and doom, exhibiting a bent toward the +pessimistic that can be contagious. They need to control their +fears that the worst is sure to happen and suppress their tendency +toward crepe-hanging and anticipating disasters. + +The children of an ESFJ are seen as an extension of the family, and +all they do reflects on the ESFJ. If things do not go well, the +SFJ may be critical, even carping toward his or her mate and +children. + +This type may marry alcoholics or others who are particularly +needy. If a female ESFJ is married to a mate who is not a good +provider, she can become nagging and brood over a comparison of her +possessions and status with that of others. + +ESFJs, male or female, live in terms of people and things rather +than in terms of ideas and principles. They enjoy the process of +decision-making, particularly when focus is on the 'usefulness' of +things and people. diff --git a/xtrn/smm/mb-esfp.asc b/xtrn/smm/mb-esfp.asc new file mode 100644 index 0000000000000000000000000000000000000000..633ade2c9b416ce9e7b14a820623ffb6516b9c96 --- /dev/null +++ b/xtrn/smm/mb-esfp.asc @@ -0,0 +1,89 @@ +ESFPs in short: + +Outgoing, easygoing, accepting, friendly, enjoy everything and make +things more fun others by their enjoyment. Like sports and making +things. Know what's going and join in eagerly. Find remembering +facts easier than mastering theories. Are best in situations that +need sound common sense and practical ability with people as well +as with things. + +About 13% of the population. + +Details about ESFPs: + +ESFPs radiate attractive warmth and optimism. Smooth, witty, +charming, clever, voluble, and open to the environment - this +describes ESFPs who, like ESTPs, represent about 13 percent of the +general population. They are great fun to be with and are the most +generous of all the types. 'Performer' would be the word which +best describes an ESFP. + +ESFPs will avoid being alone and seek the company of others +whenever possible. ESFPs easily find company, for others are +usually highly entertained by the presence of an ESFP. ESFPs love +excitement and create it wherever they are. Their joy of living is +contagious and generally they wear happy faces. Often outstanding +conversationalists, their flowing banter is amusing in its wit. + +ESFPs have an air of sophistication and are likely to be dressed in +the latest fashion, displaying an enjoyment of all the good things +of life: dress, food, physical comfort, and happy times. ESFPs +create a mood of "eat, drink, and be merry" wherever they go, and +around them life can have a continual party-like atmosphere of +gaiety. + +ESFPs make exciting, if somewhat unpredictable mates, which may +give quieter type mates some anxiety and tension from living on the +edge of adventure. The home of an ESFP is likely to be filled with +people all having a good time. Problems will not be allowed to +make their appearance. The ESFP accomplishes this by taking an +attitude of "walking by the graveyard whistling," refusing to +recognize doom and gloom. + +ESFPs can be generous to a fault. What is theirs is yours, and +what is yours is yours still. They give assistance to one and all +without expectation of a return, just as they love freely without +expecting something in return. ESFPs seem to view life as an +eternal cornucopia from which flows an endless supply of pleasures +that require no effort on their part to insure. + +ESFPs' talent for enjoying life can make them more subject to +temptations than are other types. They are inclined to be +impulsive, and thus both male and female ESFPs are vulnerable to +psychological seduction, if not physical seduction, with an ESFP +giving in easily and agreeably to the demands of others. As a +parent, the ESFP will be entertaining, a friend, and a source of +fun and excitement. When there is sickness, or trouble, however, +ESFPs may become impatient and may want to absent themselves. + +ESFPs' tolerance for anxiety is the lowest of all types. Anxiety +is avoided by ignoring the dark side of a situation as long as +possible. They are inclined to be somewhat self-indulgent, but, +rather than make an outward show of resistance or make waves, ESFPs +will give apparent compliance - and then go their own way to what +they enjoy. + +ESFPs prefer active jobs and should not be given lonely, solitary +assignments. Outstanding in public relations, they love working +with people. Decisions are made with personal warmth, based on +personal reference or reference to significant others. This type +relies on their personal experiences and generally show good common +sense. + +The gregarious sociability and adaptability of ESFPs make them a +source of warmth to others. They do not mind telephone or personal +interruptions and are verbally facile in both situations. They can +be counted on to have accurate data about the people around them, +gaining these data through effortless and continuous observations. + +ESFPs are not deeply interested in scholastic pursuits, wanting +knowledge only for immediate utility. They avoid science and +engineering, gravitate toward business, and are adept at selling, +particularly selling tangibles. + +They can be effective in education, especially elementary school +teaching, and can enjoy nursing for its drama. They are good at +working with people in crisis, a facility, which often leads ESFPs +into social work. They also enjoy entertaining people and are thus +drawn to the performing arts, thriving on the excitement of being +in the limelight. diff --git a/xtrn/smm/mb-estj.asc b/xtrn/smm/mb-estj.asc new file mode 100644 index 0000000000000000000000000000000000000000..a58f235e23972f61f097e6ed7999204b4af43eae --- /dev/null +++ b/xtrn/smm/mb-estj.asc @@ -0,0 +1,70 @@ +ESTJs in short: + +Practical, realistic, matter-of-fact, with a natural head for +business or mechanics. Not interested in subjects they see no use +for, but can apply themselves when necessary. Like to organize and +run activities. May make good administrators, especially if they +remember to consider others' feelings and points of view. + +About 13% of the population. + +Details about ESTJs: + +ESTJs are very much in touch with the external environment. They +know their community and usually are pillars of strength. The best +adjective to describe ESTJs would be 'responsible.' They represent +about 13 percent of the general population. + +ESTJs are outstanding at organizing procedures and in detailing +rules and regulations. They like to see things done correctly. +They tend to be impatient with those who do not carry out +procedures with sufficient attention to those details, prescribed +by those with the most experience, that will get the job done +right. + +ESTJs are comfortable in evaluating others and tend to judge how a +person is doing in terms of standard operating procedures. They +may, at times, be abrupt with those who do not follow the rules +correctly. ESTJs are realistic, matter-of-fact, and more curious +about new devices and processes than about new principles and +theories. + +ESTJs generally are loyal to their institutions, work, and +community and make excellent, faithful mates and parents. They see +where their duty lies and are not likely to shirk the doing of that +duty, even when this requires considerable sacrifice on their part. + +They frequently rise to positions of responsibility in their jobs, +in the community, and in their religious affiliations. They very +often belong to several civic clubs and support them both through +steady attendance and through their spoken attitudes. ESTJs +themselves are punctual and expect others to be also. + +ESTJs may not always be responsive to points of view and emotions +of others and may have a tendency to jump to conclusions too +quickly at times. They may not always be willing to listen +patiently to opposing views; they are especially vulnerable to this +tendency when in positions of authority. They may need to make +special effort to remain open to input from others who are +dependent on them - their children, spouses, and employees. + +ESTJs are so in tune with the established, time-honored +institutions and ways of behaving within those institutions that +they cannot understand those who might wish to abandon or radically +change those institutions. They follow routines well at home and +at work, tending to have a place for everything and wanting +everything in its place. They are usually neat and orderly at work +and at play. + +They approach human relations through traditions and rituals, +promoting harmony and contentment in their relationships through +creating well-worked-out routines and procedures. Family +traditions have meaning for ESTJs, and they willingly participate +in observing these. They enjoy opportunities to see friends, +former colleagues, and relatives at functions such as retirement +dinners, annual picnics, Thanksgiving gatherings, and weddings. + +ESTJs are relatively easy to get to know; they do not tend to +confuse people by sending double messages. They are dependable and +consistent, and what they seem to be is what they are. + diff --git a/xtrn/smm/mb-estp.asc b/xtrn/smm/mb-estp.asc new file mode 100644 index 0000000000000000000000000000000000000000..e8c8c956fe9f53f729444e80eff0fbb5a5567459 --- /dev/null +++ b/xtrn/smm/mb-estp.asc @@ -0,0 +1,119 @@ +ESTPs in short: + +Matter-of-fact, do not worry or hurry, enjoy whatever comes along. +Tend to like mechanical things and sports, with friends on the +side. May be a bit blunt or insensitive. Adaptable, tolerant, +generally conservative in values. Dislike long explanations. Are +best with real things that can be worked, handled, taken apart or +put together. + +About 13% of the population. + +Details about ESTPs: + +ESTPs are men and women of action. When someone of this +personality is present, things begin to happen. The lights come +on, the music plays, the game begins. And a game it is for the +ESTP, The outstanding entrepreneur, the international diplomat, the +conciliator, and the negotiator 'par excellence.' + +Approximately 13 percent of the general population are of this +extroverted, sensing, thinking, perceiving type, and if only one +adjective could be used to describe ESTPs 'resourceful' would be an +apt choice. + +Life is never dull around ESTPs. Their attractive, friendly style +has a theatrical flourish which makes even the most routine, +mundane event seem exciting. ESTPs usually know the location of +the best restaurants, and headwaiters are likely to call them by +name. ESTPs are socially sophisticated, suave, and urbane and are +master manipulators of the external environment. + +ESTPs are uncanny at observing people's motivations, somehow +hypersensitive to minimal nonverbal cues which other types might +miss. And they are masters at using these observations to "sell" +the "client." The eye of the ESTP is ever on the eye of the +beholder, and all actions are directed toward this audience. + +Witty, clever, and fun, ESTPs seem to possess an unusual amount of +empathy, when in fact this is not the case; rather, they are so +acutely aware of minimal signals from others that they are usually +several jumps ahead in anticipation of another's position. And +ESTPs can use information gained to the ends they have in mind - +apparently with nerves of steel, engaging in what seems to others +to be suicidal brinkmanship. Other types may find this exhausting, +but ESTPs are exhilarated by working close to the edge of disaster. + +ESTPs are ruthless pragmatists and often offer the ends as +justification for whatever means they see as necessary - +regrettable, perhaps, but necessary. Usually, however, ESTPs do +not care to justify actions, but prefer instead to get on to the +next action. + +ESTPs are outstanding as initiators of enterprises that bring +people together to negotiate. They make invaluable itinerant +administrators who can pull troubled companies or institutions out +of the red very quickly, and with style! + +They can sell an idea or project in a way no other type can, but +won't follow through on the tedious administrative details of a +project. This characteristic often causes ESTPs to be +unappreciated for the extraordinary talents they have, for people +lose sight of the idea contributed and focus on the details left +undone, becoming critical of ESTPs' weaknesses rather than +appreciating their strength. + +Few enterprises which are institutionally based use ESTPs as they +should be used. When they strike out on their own, however, they +do not always succeed, for their unwillingness to bother with +follow-up details may cause an otherwise excellent project to fail. +ESTPs need to be sure they have someone who will take care of +follow-up if at all possible. + +If the promotional, entrepreneurial capabilities of ESTPs are used +to constructive ends, an institution is fortunate for their +presence. + +If their desire for excitement is not met constructively, however, +these energies may be channeled into destructive, antisocial +activities such as those of the confidence rackets - +counterfeiting, bad-check artistry, safe-cracking, and swindling. A +movie of the early 1970's which caught this use of the ESTP's +talent was The Sting. + +ESTPs live in the immediate moment and as mates lend excitement - +and unpredictability - to the relationship. The ESTP mate is +usually extremely attentive in public and smooth in social rituals. +They carry on amusing repartee, and laughter surrounds them as they +recount from their endless supply of clever jokes and stories. + +Charm radiates from ESTPs. Nothing is too good for their friends, +although family responsibilities may, at times, be given second +priority. The ESTP's mate may in time come to feel like an object +- the female a chattel and the male a negotiable commodity. Deep +commitments do not always occur in the lives of ESTPs, although +they are always popular and know many, many people by name. + +Relationships usually are conditional, and the condition is the +consideration of what the ESTP has to gain from the relationship. +Anything gained, however, is shared freely and generously with the +mate. The unexpected gift, the impulsive trip to Paris, the +extravagant surprise at Christmas - all these an ESTP brings to a +mate. Fun, excitement, laughter, and that element of +unpredictability are characteristic of their relationship. + +The ESTPs have a low tolerance for anxiety and are apt to avoid or +leave situations that are consistently filled with interpersonal +tensions. ESTPs are usually somewhat of a mystery to their mates +and to others. Few people comprehend this unique personality. + +ESTPs themselves understand well the maxim, "He who travels +fastest, travels alone." Still, ESTPs are not likely to be lonely +for long. + +ESTPs meet life with a hearty appetite for the good things of the +world, searching out excitement, perhaps as a warrior, an athlete, +an adventurer, or as a professional gambler, but always seeking the +thrill of courting Lady Luck in one fashion or another. A theme of +seeking excitement through taking of risks runs through the lives +of ESTPs. diff --git a/xtrn/smm/mb-f.asc b/xtrn/smm/mb-f.asc new file mode 100644 index 0000000000000000000000000000000000000000..49cec2c04674a129e55f92a69445efb9fd231c59 --- /dev/null +++ b/xtrn/smm/mb-f.asc @@ -0,0 +1,7 @@ +The Feeler tends toward subjective & social values, personal feelings, +harmony, intimacy, sympathy and devotion. The F overextends himself to meet +others needs, enjoys serving people, tends to retract statements that offend +others, asks himself 'how will this affect the people involved'. +The feeler feels the thinker has ice in his veins. +The population is equally divided between Ts and Fs, although more men tend +to be Thinkers & more women tend to be Feelers. diff --git a/xtrn/smm/mb-fp.asc b/xtrn/smm/mb-fp.asc new file mode 100644 index 0000000000000000000000000000000000000000..cdc07cb81e34bdf64acbbb1968a2db2161de9bce --- /dev/null +++ b/xtrn/smm/mb-fp.asc @@ -0,0 +1 @@ +You should never have a party without an FP. diff --git a/xtrn/smm/mb-i.asc b/xtrn/smm/mb-i.asc new file mode 100644 index 0000000000000000000000000000000000000000..8ff52b2d3e61ef668e0123b8e7e6f0e0bf8c6e62 --- /dev/null +++ b/xtrn/smm/mb-i.asc @@ -0,0 +1,9 @@ +An Introvert gets his energy from inside himself and needs his own space for +recharging his batteries. An Introvert is drained by being around people. +I is perceived as a good listener, tends to be shy, likes to share occasions +with a few close friends, doesn't like interruptions, is suspicious if people +are too complimentary, gets irritated if people repeat what has already been +said. 'I' tends to consider - then speak, An 'I' is reluctant to reveal himself +and may resist taking this test for fear of being exposed, but can complete +the test in a short time without carefully considering & weighing each +question. About 25% of the population are type I. diff --git a/xtrn/smm/mb-infj.asc b/xtrn/smm/mb-infj.asc new file mode 100644 index 0000000000000000000000000000000000000000..73e1893f97ed90c324ce71ca53b6cea9830a5e98 --- /dev/null +++ b/xtrn/smm/mb-infj.asc @@ -0,0 +1,144 @@ +INFJs in short: + +Succeed by perseverance, originality and desire to do whatever is +needed or wanted. Put their best efforts into their work. Quietly +forceful, conscientious, concerned for others. Respected for their +firm principles. Likely to be honored and followed for their clear +convictions as to how best to serve the common good. + +About 1% of the population. + +Details about INFJs: + +INFJs focus on possibilities, think in terms of values, and come +easily to decisions. The small number of this type (1 percent) is +regrettable, since INFJs have an unusually strong drive to +contribute to the welfare of others and genuinely enjoy helping +their fellow men. This type has great depth of personality; they +are themselves complicated, and can understand and deal with +complex issues and people. + +It is an INFJ who is likely to have visions of human events past, +present, or future. If a person demonstrates an ability to +understand psychic phenomenon better than most others, this person +is likely to be an INFJ. + +Characteristically, INFJs have strong empathetic abilities and can +be aware of another's emotions or intents even before that person +is conscious of these. This can take the form of feeling the +distress or illnesses of others to an extent which is difficult for +other types. INFJs can intuit good and evil in others, although +they seldom can tell how they came to know. Subsequent events tend +to bear them out, however. + +INFJs are usually good students, achievers who exhibit an +unostentatious creativity. They take their work seriously and +enjoy academic activity. They can exhibit qualities of +over-perfectionism and put more into a task than perhaps is +justified by the nature of the task. They generally will not be +visible leaders, but will quietly exert influence behind the +scenes. + +INFJs are hard to get to know. They have an unusually rich inner +life, but they are reserved and tend not to share their reactions +with those they trust. Because of their vulnerability through a +strong facility to interject, INFJs can be hurt rather easily by +others, which, perhaps, is at least one reason they tend to be +private people. People who have known an INFJ for years may find +sides emerging which come as a surprise. Not that INFJs are +inconsistent; they are very consistent and value integrity. But +they have convoluted, complex personalities which sometimes puzzle +even them. + +INFJs like to please others and tend to contribute their best +efforts in all situations. They prefer and enjoy agreeing with +others, and find conflict disagreeable and destructive. What is +known as ESP is likely found in an INFJ. + +INFJs have vivid imaginations exercised both as memory and +intuition, and this can amount to genius, resulting at times in an +INFJs being seen as mystical. This unfettered imagination often +will enable this person to compose complex and often aesthetic +works of arts such as music, mathematical systems, poems, plays, +and novels. In a sense the INFJ is the most poetic of all the +types. INFJs can have uncanny communications with certain +individuals at a distance. + +INFJs often select liberal arts as a college major and opt for +occupations which involve interacting with people, but on a +one-to-one basis. For example, the general practitioner in +medicine might be an INFJ, or the psychiatrist or psychologist. As +with all NFs, the ministry holds attraction, although the INFJ must +develop an extroverted role here which requires a great deal of +energy. + +INFJs may be attracted to writing as a profession, and often they +use language which contains an unusual degree of imagery. They are +masters of the metaphor, and both their verbal and written +communications tend to be elegant and complex. Their great talent +for language usually is directed toward people, describing people +and writing to communicate with people in a personalized way. INFJs +who write comment often that they write with a particular person in +mind; writing to a faceless abstract audience leaves them +uninspired. + +INFJs make outstanding individual therapists who have the ability +to get in touch with the archetypes of their patients in a way some +other types do not. The INFJs are also the most vulnerable of all +types to the eruptions of their own archetypal material. As +therapists, INFJs may choose counseling, clinical psychology, or +psychiatry, or may choose to teach in these fields. Writing about +these professions often intrigues an INFJ. + +Whatever their choice, they generally are successful in these +fields because of their great personal warmth, their enthusiasm, +their insight, their depth of concentration, their originality, and +their organizational skills can all be brought into play. + +At work as well as socially, INFJs are highly sensitive in their +handling of others and tend to work well in an organizational +structure. They have a capacity for working at jobs which require +solitude and concentration, but also do well when in contact with +people, providing the human interaction is not superficial. + +INFJs enjoy problem-solving and can understand and use human +systems creatively and humanistically. As employees and employers, +INFJs are concerned with people's feelings and are able to provide +in themselves a barometer of the feelings of individuals and groups +within the organization. INFJs listen well and are willing and +able to consult and cooperate with others. Once a decision is +made, they work to implement it. + +INFJs are usually good at public relations and themselves have good +interpersonal relations. They value staff harmony and want an +organization to run smoothly and pleasantly, themselves making +every effort to contribute to that end. + +They are crushed by too much criticism and can have their feelings +hurt rather easily. They respond to praise and use approval as a +means of motivating others, just as they, the INFJs, are motivated +by approval. If they are subject to a hostile, unfriendly working +condition or to constant criticism, they tend to lose confidence, +become unhappy and immobilized, and finally become physically ill. + +As mates INFJs are devoted to their spouses, but may not always be +open to physical approaches. They tend to be physically +demonstrative at times, but wish to choose when, which is when they +are in the mood. This may be quite confusing to an extroverted +mate. + +Often an INFJs expressions of affection will be subtle, taking a +humorous, unexpected turn. INFJs need and want harmony in their +home and find constant conflict, overt or covert, extremely +destructive to their psyches. Their friendship circle is likely to +be small, deep, and longstanding. + +As parents, INFJs usually are fiercely devoted. A female INFJ, +particularly, is linked to her children in a way different from the +other types: with almost a psychic symbiosis. This deep bond can +create an overdependency that can be unhealthy for both mother and +child. At the same time, INFJs tend to be good friends with their +children, while firm in discipline. They usually are concerned +about the comfort of a home and most especially the comfort, +physical health, and emotional well-being of both mates and +children. diff --git a/xtrn/smm/mb-infp.asc b/xtrn/smm/mb-infp.asc new file mode 100644 index 0000000000000000000000000000000000000000..f99ff2b82f182c82526befe1da89b7e53bbebdba --- /dev/null +++ b/xtrn/smm/mb-infp.asc @@ -0,0 +1,118 @@ +INFPs in short: + +Full of enthusiasms and loyalties, but seldom talk of these until +they know you well. Care about learning, ideas, language, and +independent projects of their own. Tend to undertake too much, +then somehow get it done. Friendly, but often too absorbed in what +they are doing to be sociable. Little concerned with possessions +or physical surroundings. + +About 1% of the population. + +Details about INFPs: + +INFPs present a calm, pleasant face to the world and are seen as +reticent and even shy. Although they demonstrate a cool reserve +toward others, inside they are anything but distant. They have a +capacity for caring which is not always found in other types. They +care deeply - indeed passionately - about a few special persons or +cause. One word that captures this type is 'idealistic'. At +times, this characteristic leaves them feeling isolated, especially +since INFPs are found in only 1 percent of the general population. + +INFPs have a profound sense of honor derived from internal values. +The INFP is the Prince or Princess of mythology, the King's +champion, Defender of the Faith, and guardian of the castle. Sir +Galahad and Joan of Arc are male and female prototypes of an INFP. +To understand INFPs their cause must be understood, for they are +willing to make unusual sacrifices for someone or something +believed in. + +INFPs seek unity in their lives, unity of body and mind, emotions +and intellect. They often have a subtle tragic motif running +through their lives, but others seldom detect this inner minor key. +The deep commitment of INFPs to the positive and the good causes +them to be alert to the negative and the evil, which can take the +form of a fascination with the profane. Thus INFPs may live a +paradox, drawn toward purity and unity but looking over the +shoulder toward the sullied and desecrated. When INFPs believe +that they have yielded to an impure temptation, they may be given +to acts of self-sacrifice in atonement. The atonement, however, is +within the INFP, who does not feel compelled to make public the +issue. + +INFPs prefer the valuing process over the purely logical. They +respond to the beautiful versus the ugly, the good versus the bad, +and the moral versus the immoral. Impressions are gained in a +fluid, global, diffused way. Metaphors and similes come naturally +but may be strained. + +INFPs have a gift of interpreting symbols, as well as creating +them, and thus often write in lyric fashion. They may demonstrate +a tendency to take deliberate liberties with logic. Unlike the NT, +they see logic as something optional. + +INFPs also may, at times, assume an unwarranted familiarity with a +domain, because their global, impressionistic way of dealing with +reality may have failed to register a sufficient number of details +for mastery. INFPs may have difficulty thinking in terms of a +conditional framework; they see things as either real or fancied, +and are impatient with the hypothetical. + +At work, INFPs are adaptable, welcome new ideas and new +information, are well aware of people and their feelings, and +relate well to most, albeit with some psychological distance. +INFPs dislike telephone interruptions and work well alone, as well +as with others. They are patient with complicated situations, but +impatient with routine details. They can make errors of fact, but +seldom of values. Their career choices may be toward the ministry, +missionary work, college teaching, psychiatry, architecture, +psychology - and away from business. + +They seem willing and usually are able to apply themselves +scholastically to gain the necessary training for professional +work, often doing better in college than in high school. They have +a natural interest in scholarly activities and demonstrate, as do +other NFs, a remarkable facility for languages. Often they hear a +calling to go forth into the world to help others; they seem +willing to make the necessary personal sacrifices involved in +responding to that call, even if it means asking others to do +likewise. + +INFPs can make outstanding novelists and character actors, for they +able to efface their own personalities in their portrayal of a +character in a way other types cannot. + +As mates, INFPs have a deep commitment to their pledges. They like +to live in harmony and may go to great lengths to avoid constant +conflict. They are sensitive to the feelings of others and enjoy +pleasing those they care for. They may find it difficult to +reconcile a romantic, idealized concept of conjugal life with the +realities of everyday living with another person. + +At times, INFPs may seem fearful of exuberant attainment, afraid +that current advances may have to be paid for with later +sacrifices. The devil is sure to get his due if the INFP +experiences too freely of success, or beauty, or health, or wealth, +or knowledge. And thus, INFPs guard against giving way to relaxing +in the happiness of mating. They may have difficulty in expressing +affection directly, but communicate interest and affection +indirectly. + +For INFPs, their home is their castle. As parents, they are fierce +in protection of their home and family and are devoted to the +welfare of family members. They have a strong capacity for +devotion, sympathy, and adaptability in their relationships, and +thus are easy to live with. They are loyal to their family and, +although they may dream of greener pastures, they soon locate the +nettles. The almost preconscious conviction that pleasure must be +paid for with pain can cause a sense of uneasiness in the family +system of an INFP, who may transmit an air of being ever-vigilant +against invasion. + +In the routine rituals of daily living, INFPs tend to be compliant +and may even prefer having decisions made on their behalf - until +their value system is violated! Then INFPs dig in their heels and +will not budge from ideals. Life with an INFP will go gently along +for long periods, until an ideal is struck and violated. Then an +INFP will resist and insist. diff --git a/xtrn/smm/mb-intj.asc b/xtrn/smm/mb-intj.asc new file mode 100644 index 0000000000000000000000000000000000000000..18d1d03349d4806f6721f8a2e97282ff4ea8eb89 --- /dev/null +++ b/xtrn/smm/mb-intj.asc @@ -0,0 +1,169 @@ +INTJs in short: + +Usually have original minds and great drive for their own ideas and +purposes. In fields that appeal to them, they have a fine power to +organize a job and carry it through with or without help. +Skeptical, critical, independent, determined, often stubborn. Must +learn to yield less important points in order to win the most +important. + +About 1% of the population. + +Details about INTJs: + +INTJs are the most self-confident of all the types, having +"self-power" awareness. Found in about 1 percent of the general +population, the INTJs live in an introspective reality, focusing +on possibilities, using thinking in the form of empirical logic, +and preferring that events and people serve some positive use. +Decisions come naturally to the INTJs; once a decision is made, +INTJs are at rest. INTJs look to the future rather than the past, +and a word which captures the essence of INTJs is 'builder' - a +builder of systems and the applier of theoretical models. + +To INTJs, authority based on position, rank, title, or publication +has absolutely no force. This type is not likely to succumb to the +magic of slogans, watchwords, or shibboleths. If an idea or +position makes sense to an INTJ, it will be adopted; if it doesn't, +it won't, regardless of who took the position or generated the +idea. As with the INTP, authority per se does not impress the +INTJ. + +INTJs do, however, tend to conform to rules if they are useful, not +because they believe in them, or because they make sense, but +because of their unique view of reality. They are the supreme +pragmatists, who see reality as something which is quite arbitrary +and made up. Thus it can be used as a tool - or ignored. + +Reality is quite malleable and can be changed, conquered, or +brought to a heel. Reality is a crucible for the refining of +ideas, and in this sense, INTJs are the most theoretical of all the +types. An INTJ sees reality as the pawn of ideas: No idea is too +farfetched to be entertained. INTJs are natural brainstormers, +always open to new concepts, and, in fact, aggressively seeking +them. + +INTJs manipulate the world of theory as if on a gigantic chess +board, always seeking strategies and tactics that have high payoff. +In their penchant for logic, the INTJs resemble the INTPs. The +logic of an INTJ, however, is not confined to the expressibly +logical. Unlike INTPs, INTJs need only to have a vague, intuitive +impression of the unexpressed logic of a system to continue surely +on their way. Things need only 'seem' logical; this is entirely +sufficient. + +Moreover, they always have a keen eye for the consequences of the +application of new ideas or positions. They can be quite ruthless +in the implementation of systems, seldom counting personal cost in +terms of time and energy. Theories which cannot be made to work +are quickly discarded by the INTJs. + +To understand INTJs, their way of dealing with reality rather than +their way of dealing with ideas should be observed closely. Their +conscious thought is extroverted and empirical. Hence, they are +better at generalizing, classifying, summarizing, adducing +evidence, proving and demonstrating than are the INTPs. + +The INTJs are somewhat less at home with pure reason, that is, +systemic logic, where principles are explicit. In this respect +they resemble the ENTJs. The INTJs, rather than using deductive +logic, use their intuition to grasp coherence. + +INTJs have a drive to completion, always with an eye to long-term +consequences. Ideas seem to carry their own force for INTJs, +although they subject every idea to the test of usefulness. + +Difficulties are highly stimulating to INTJs, who love responding +to a challenge that requires creativity. Those personality traits +lead INTJs to occupations where theoretical models can be +translated into actuality. They build data and human systems +wherever they work if given even a slight opportunity. They can be +outstanding in scientific research and also outstanding as +executives who generate a plethora of implementations of ideas. + +Teamed with an INTP who is the architect of systems, the INTJ +provides a dimension to an organization which insures that the work +of the INTP does not gather dust on library shelves. + +INTJs can be very single-minded at times; this can be either a +weakness or a strength in their careers, for they can ignore the +points of view and wishes of others. INTJs usually rise to +positions of responsibility, for they work long and hard and steady +in their pursuit of goals, sparing neither time nor effort on their +part or that of their colleagues and employees. + +INTJs live to see systems translated into substance; an INTP, by +way of contrast, is content to design the system. In both, these +types, however, coherence is the master. Both internal and +external consistency are important, and if an INTJ finds that he or +she is in a working situation where overlapping functions, +duplication of effort, inefficient paper flow, and waste of human +and material resources abound, the INTJ cannot rest until an effort +is made to correct the situation. Cost-effectiveness is a concept +which has a strong imperative for INTJs, who frequently select +occupations in engineering, particularly human engineering. + +They also can be found in the physical sciences, in roles which +require development, such as curriculum building, and, in general, +any job which requires the creation and application of technology +to complex areas. + +Fellow workers of INTJs often feel as if the INTJ can see right +through them, and often believe that the INTJ finds them wanting. +This tendency of people to feel transparent in the presence of the +INTJ often results in relationships which have psychological +distance. Thus colleagues find the INTJ apparently unemotional +and, at times, cold and dispassionate. Because of their tendency +to drive others as hard as themselves, INTJs often seem demanding +and difficult to satisfy. + +INTJs are high achievers in school and on the job. On the job, +they take the goals of the institution seriously and continually +strive to respond to these goals. They make dedicated, loyal +employees whose loyalties are directed toward the system, rather +than toward individuals within the system. So as the people of an +institution come and go, the INTJs have little difficulty - unlike +the NFs, who have their loyalties involved more with persons than +offices. + +INTJs ordinarily tend to verbalize the positive and eschew comments +of a negative nature; they are more interested in moving an +institution forward than commiserating about mistakes of the past. + +As mates, INTJs want harmony and order in the home and in +relationships. They are the most independent of all the types. +They will trust their intuitions about others when making choices +of friends and mates, even in the face of contradictory evidence +and pressures applied by others. + +The emotions of an INTJ are hard to read, and neither male nor +female INTJ is apt to express emotional reactions. At times, both +will seem cold, reserved, and unresponsive, while in fact INTJs are +almost hypersensitive to signals of rejection from those for whom +they care. + +In social situations, INTJs may also be unresponsive and may +neglect to observe small rituals designed to put others at their +ease. For example, INTJs may communicate that time is wasted if +used for idle dialogue, and thus people receive a sense of hurry +from an INTJ which is not always intended. In their interpersonal +relationships, INTJs are usually better in a working situation than +in recreational situations. They do not enjoy physical contact +except with a chosen few. + +As parents, INTJs are dedicated and single-minded in their +devotion: Their children are a major focus in life. They are +supportive of their children and tend to allow them to develop in +directions of their own choosing. INTJs usually are firm and +consistent in their discipline and rarely care to repeat directions +given to children - or others. + +Being the most independent of all the types, they have a strong +need for autonomy; indifference or criticism from people in general +does not particularly bother INTJs, if they believe that they are +right. They also have a strong need for privacy. + +The most important preference of an INTJ is 'intuition', but this +is seldom seen. Rather, the function of 'thinking' is used to deal +with the world and with people. INTJs are vulnerable in the +emotional area and may make serious mistakes here. diff --git a/xtrn/smm/mb-intp.asc b/xtrn/smm/mb-intp.asc new file mode 100644 index 0000000000000000000000000000000000000000..97594584b51cc919a9a4f7e051f459220aa97e14 --- /dev/null +++ b/xtrn/smm/mb-intp.asc @@ -0,0 +1,118 @@ +INTPs in short: + +Quiet, reserved, impersonal. Enjoy especially theoretical or +scientific subjects. Logical to the point of hairsplitting. +Usually interested mainly in ideas, with little liking for parties +or small talk. Tend to have sharply defined interests. Need +careers where some strong interest can be used and useful. + +About 1% of the population. + +Details on INTPs: + +INTPs exhibit the greatest precision in thought and language of all +the types; they tend to see the distinctions and inconsistencies in +thought and language instantaneously. The one word which captures +the unique style of INTPs is 'architect' - the architect of ideas +and systems as well as the architect of edifices. This type is +found in only 1 percent of the population and therefore is not +encountered as frequently as some of the other types. + +INTPs detect contradictions in statements no matter how distant in +space or time the contradictory statements were produced. The +intellectual scanning of INTPs has a principled quality; that is, +INTPs search for whatever is relevant and pertinent to the issue at +hand. Consequently, INTPs can concentrate better than any other +type. + +Authority derived from office, position, or wide acceptance does +not impress INTPs. External authority per se is irrelevant. INTPs +abhor redundancy and incoherence. + +Possessing a desire to understand the universe, an INTP is +constantly looking for natural law. Curiosity concerning these +keys to the universe is a driving force in this type. + +INTPs prize intelligence in themselves and in others, but can +become intellectual dilettantes as a result of their need to amass +ideas, principles, or understanding of behavior. And once they +know something, it is remembered. + +INTPs can become obsessed with analysis. Once caught up in a +thought process that thought process seems to have a will of its +own for INTPs, and they persevere until the issue is comprehended +in all its complexity. They can be intellectual snobs and may show +impatience at times with others less endowed intellectually. This +quality, INTPs find, generates hostility and defensive behaviors on +the part of others, who may describe an INTP as arrogant. + +For INTPs, the world exists primarily to be understood. Reality is +trivial, a mere arena for proving ideas. It is essential that the +universe is understood and that whatever is stated about the +universe is stated correctly, with coherence and without +redundancy. This is the INTP's final purpose. It matters not +whether others understand or accept his or her truths. + +The INTP is the logician, the mathematician, the philosopher, the +scientist; any pursuit requiring architecture of ideas intrigues +this type. + +INTPs should not, however, be asked to work out the implementation +of application of their models to the real world. The INTP is the +architect of a system and leaves it to others to be the builder and +the applicator. Very often, therefore, the INTP's work is not +credited to him or her. The builder and the applier gains fame and +fortune, while the INTP's name remains obscure. Appreciation of an +INTP's theoretical work frequently comes posthumously - or the work +may never be removed from library shelves at all and thus lost. + +INTPs tend not to be writers or to go into sales work. They are, +however, often excellent teachers, particularly for advanced +students, although INTPs do not always enjoy much popularity, for +they can be hard taskmasters. + +They are not good at clerical tasks and are impatient with routine +details. They prefer to work quietly, without interruption, and +often alone. If an organization is to use the talents of an INTP +appropriately, the INTP must be given an efficient support staff +who can capture ideas as they emerge and before the INTP loses +interest and turns to another idea. + +INTPs take their mating relationship seriously and usually are +faithful and devoted - albeit preoccupied at times. They are not +likely to welcome constant social activity or disorganization in +the home. + +In all probability, the mate of an INTP will initiate and manage +the social life. If left to his or her own devices, the INTP mate +will retreat into the world of books and emerge only when physical +needs become imperative. + +INTPs are, however, willing, compliant, and easy to live with, +although somewhat forgetful of appointments, anniversaries, and the +rituals of daily living - unless reminded. They may have +difficulty expressing their emotions verbally, and the mate of an +INTP may believe that he/she is somewhat taken for granted. + +As a parent, the INTP is devoted; they enjoy children and are +serious about their upbringing. The home of an INTP parent is +usually calm, low-key in discipline, but well run and ordered. + +INTPs deal with the environment primarily through intuition, and +their strongest quality, the thinking function, remains relatively +hidden except in close associations. Therefore, INTPs are often +misunderstood, seen as difficult to know, and seldom perceived at +their true level of competency. + +They are inclined to be shy except with close friends, and their +reserve is difficult to penetrate. They are very adaptable until +one of their principles is violated. Then INTPs are not adaptable +at all! + +They may have difficulty in being understood by others because they +tend to think in a complicated fashion and want to be precise, +never redundant in their communications. + +Because their feeling qualities may be underdeveloped, they may be +insensitive to the wants and wishes of others, often quiet unaware +of the existence of these wants and wishes. diff --git a/xtrn/smm/mb-intro.asc b/xtrn/smm/mb-intro.asc new file mode 100644 index 0000000000000000000000000000000000000000..bdd60da67d3464895750139400e8d345bc9425f1 --- /dev/null +++ b/xtrn/smm/mb-intro.asc @@ -0,0 +1,18 @@ +nyhThe Myers-Briggs Personality Test nc + +The test you are about to take is titled, "hThe Keirsey Temperament Sorternc". + +There are no "right" or "wrong" answers to the questions in this inventory. +Your answers will help show how you like to look at things and how you like to +go about deciding things. Knowing your own preferences and learning about +other people's can help you understand where your special strengths are, what +kind of work you might enjoy and be successful doing, and how people with +different preferences can relate to each other and be valuable to society. + +Read each question carefully and indicate your answer by typing 'A', 'B' or +'C' for cannot decide. + +Do not think too long about any question. + +The test consists of 70 questions. + diff --git a/xtrn/smm/mb-isfj.asc b/xtrn/smm/mb-isfj.asc new file mode 100644 index 0000000000000000000000000000000000000000..c59d1d4a1930ac18c7ee6a63731e95fd0fe8c72c --- /dev/null +++ b/xtrn/smm/mb-isfj.asc @@ -0,0 +1,116 @@ +ISFJs in short: + +Quiet, friendly, responsible and conscientious. Work devotedly to +meet their obligations. Lend stability to any project or group. +Thorough, painstaking, accurate. May need time to master technical +subjects, as their interests are usually not technical. Patient +with detail and routine. Loyal, considerate, concerned with how +other people feel. + +About 6% of the population. + +Details about ISFJs: + +Six out of every hundred people are ISFJs. Here the primary is to +be of service and to minister to individual needs. ISFJs carry a +sense of history, a sense of continuity with past events and +relationships. Traditions and the conservation of resources are +highly valued. + +The least hedonistic of all types, ISFJs believe work is good, play +must be earned. ISFJs are willing to work long, long hours. When +they undertake a task, it will be completed if at all humanly +possible. + +Adhering to an established way of doing things and doing them well +is valued and respected. The efficiency and effectiveness of an +established procedure is not often questioned. Procedures dictated +by handbooks are law. If others violate or ignore these standard +operating procedures, ISFJs are annoyed and irritated, although +they may not always display this reaction. Usually, such +irritation is turned inward and may be experienced as fatigue and +muscle tension. + +ISFJs are super-dependable and seldom are happy working in +situations where rules are constantly changing. Their major need +to be of service to others leads them into occupations such as +nursing, teaching, secretarial work, medical practice (especially +general practice), librarian work, and middle-management +administrative jobs. + +They relate well to people who need them, for example, the sick, +the ignorant, students, and the "boss." Much satisfaction comes to +them when they are taking care of the needs of another and they +render the service gently and helpfully. When the recipient is no +longer in need, the relationship may change its character, the ISFJ +becoming disinterested. + +They enjoy assisting the downtrodden and can handle better than +other types servility of others. If a situation calls for such +behavior on their part, they will show "due respect." + +ISFJs have an extraordinary sense of responsibility and an +outstanding talent for executing routines which call for repeated, +sequential procedures; for example, ISFJs make extraordinary +secretaries, highly efficient nurses, and dedicated teachers. +Speculation and theory do not intrigue ISFJs, who would rather +leave the less practical matters to others while remaining +themselves practical and down-to-earth. + +ISFJs tend to be devoted and loyal to a boss and tend to identify +personally rather than institutionally. They expect others, +including the boss, to follow procedures and are distressed and +embarrassed when people do not behave as they are supposed to +behave. + +ISFJs often seem to feel personally responsible for seeing to it +that people in an institution or business carry out established +rules and routines. They often are aware of status given by +titles, environment, offices, and the like and can use this to +advantage. + +They are aware of the value of material resources and abhor the +squandering or misuse of these resources. To save, to put +something aside against an unpredictable future, to prepare for +emergencies - these are important actions. + +ISFJs may experience some discomfort when placed in positions of +authority over others and may tend to try to do everything +themselves rather than insist that others do their jobs. As a +result, ISFJs are frequently overworked. + +ISFJs are devoted to mate and family and usually are excellent +homemakers. The home of an ISFJ is likely to be well kept inside +and out. Interior and exterior are meticulously maintained and +appointed in the traditional manner. + +As a parent, the ISFJ expects children to conform to the rules of +society and has a feeling of personal responsibility to see to it +that these rules are honored. + +An ISFJ is apt to find the putting on of airs as offensive and +tends to prefer modest, quiet friends rather than more boisterous +ones. For the ISFJ, people should behave according to their +position in life, and the ISFJ may be annoyed by others who act +either above or below their social or economic station. + +The ISFJ female often displays a flair for making the interior of +the home attractive in a time-honored style, provides attractive, +nourishing meals, and maintains the environment in a neat and +orderly state. To the ISFJ male and female, the home territory is +important to own and to preserve. + +While ISFJs are super-dependable, they may be fascinated by and +attracted to the irresponsible, the lush, the glutton. Many ISFJs +marry alcoholics and then proceed to conduct a rescue-rejection +game without end, with the rescuing phase taking the guise of an +attempt to reform. Occasionally an ISFJ mother may reveal a +tendency to find humor in the "waywardness" of a son, while raising +her daughters to respect traditions and to do the Right Thing at +the Right Time - always. + +ISFJs are frequently misunderstood and undervalued. Their +contributions often are taken for granted, and the ISFJ as well is +often taken for granted. This can cause an ISFJ to harbor feelings +of resentment, and this bottled up emotion can gnaw inwardly, +causing the ISFJ much undeserved suffering. diff --git a/xtrn/smm/mb-isfp.asc b/xtrn/smm/mb-isfp.asc new file mode 100644 index 0000000000000000000000000000000000000000..4b9b4d322b01c9f64fde08c362edddc48c7c3784 --- /dev/null +++ b/xtrn/smm/mb-isfp.asc @@ -0,0 +1,166 @@ +ISFPs in short: + +Retiring, quietly friendly, sensitive, kind, modest about their +abilities. Shun disagreements, do not force their opinions or +values on others. Usually do not care to lead but are often loyal +followers. Often relaxed about getting things done, because they +enjoy the present moment and do not want to spoil it by undue haste +or exertion. + +About 5% of the population. + +Details about ISFPs: + +Although all SPs (Sensuous Performers) are artisans in their +nature, they usually do not pursue their artistry with the same +devotion and adornment as the ISFP. For whatever reason, the ISFP +seems more inclined to the "fine arts" than the other SPs; so when +an especially gifted composer, painter, or dancer shows up, he or +she, more frequently than not, possesses the character of an ISFP. +Beethoven, Toscanini, Rembrandt, and Nijinski, as shown by +typohistorical research, were clear-cut ISFPs. + +But the ISFP temperament is very difficult to observe, even in the +great artists, and so ISFP is probably the most misunderstood of +all the types. + +A major source of misunderstanding is the tendency of ISFPs not to +express themselves directly, but through action. If they find a +medium of expression, some art form, then the character is +expressed in some degree in the medium. If not, it simply doesn't +come out, and no one knows them, this social reticence making the +character all but invisible. + +Of course, in those rare cases where remarkable skill is achieved, +such as in the virtuoso, ISFPs become celebrities, but their nature +is still far from visible. Harpo Marx, a brilliant comedic actor, +may well be seen as a prototype, in his simultaneous celebrity and +mute invisibility. + +On close observation, these relatively infrequent SPs (5 percent of +the population is ISFP, as compared to 15 percent ESFP) are just as +hedonistic and impulsive as the other SPs. Here is no NF search +for significance, nor for that matter any fascination with science +(NT) or commerce (SJ). + +ISFPs live Epicurean lives in the here and now, and as gracefully +as possible. They do not plan and prepare. Submergence in their +artistry is not preparation for something later; rather they +experience intensely, now. ISFPs do not wait, for to wait is to +see their impulse wither and die; they want and value their +impulses and see them as the center of their lives. + +Nor are ISFPs devoted or committed to artful play; rather they are +caught, as by a magnet or a whirlwind. So then the long hours of +"practice" the virtuoso "gives" to artistry is not practice at all +and it is not given; it is doing and it is taken from the (willing) +ISFP by the performance itself. The act is ISFP's master, not the +reverse, so we must abandon any notion of ISFPs as careful and +devoted planners and of dutiful preparation and rehearsal. They +paint, or sing, or toot, or dance, or run, or skate, or pot, or +whatever, simply because must: the mountain is climbed 'because it +is there'. + +Because the ISFP is always caught up, so to speak, in whatever +actions are underway, rather than practicing toward some distant +goal, there is no question of the ISFP noticing fatigue, pain, or +danger. They are usually quite oblivious to the accompaniments of +many of their favorite activities. It is not that ISFPs are inured +to them as much as it is that, wholly engaged by an action, they +simply do not notice them. In this ISFP is similar to other SPs +and different from all other types. + +ISFP, like other SPs, has a special kind of intelligence. Please +recall that intelligence is defined in this book as doing things +well under varying circumstances. This particular category of +intelligence might be called "artisan concretized." Such talent +differs from that possessed by NFs, NTs, and SJs (granting of +course, that they too have their own unique and inherent +abilities). This artisan concretization somehow keeps the ISFP +more closely in touch with the very real. + +While the ISTP is attuned to the tool, so to speak, the ISFP is +attuned to color, line, texture, shading - touch, motion, seeing, +and hearing in harmony. The senses of the ISFP seem more keenly +tuned than those of others. Rembrandt could almost taste colors so +great was his discrimination. Toscanini could hear a single false +note in the most complex operatic-orchestral score, and Hemingway's +words tasted and smelled and felt the waves. This extreme +concreteness and specificity seems to come naturally to the ISFP +and is embedded "in the warp and woof of the man's make." + +The social side of the ISFP character must not be eclipsed by the +more spectacular performances some of this group are capable of. +The ISFP has to be the kindest of all the types with no near +competitors. This kindness is unconditional. Here is sympathy, of +which we are all capable, carried to its most extreme form. The +ISFP is especially sensitive to the pain and suffering of others +and, like St. Francis of Assisi, with sympathetic impulsivity +gives freely to the sufferer. + +ISFP is usually not interested in developing facility in speaking, +writing, or conversation. Speech, after all, is abstract, not +concrete, ISFPs preferring to have their fingers on the pulse of +life. That pulse must be felt - by touch, in the muscles, in the +eyes, in the ears. + +This insistence on the senses being so closely attuned to reality +can, in some ISFPs, occasion a breach with language, and language +becomes a barrier to smooth interpersonal relations. So ISFPs are +sometimes seen by others as reserved and private, tending to give +up rather easily in their attempts to express themselves verbally. + +But this reluctant speech is not so much a lack of ability as it is +disinterest. Hemingway broke that barrier, a splendid instance of +an ISFP entering the world of words and making apparent +inarticulateness into art, changing the face of 20th Century +literature. + +The number of great artisans who, upon investigation, were found +clearly to have been ISFPs, is truly awesome. The other SPs seem +to have contributed far fewer masters to the fine arts. Gaugin and +Puccini, both ESTPs, were in this sense exceptional. Music and the +dance seems almost the province of ISFP, and surely investigation +will show many of the great athletes come from this group. + +Of course, all ISFPs have not been and need not be artisans in the +narrow sense of the word. Art, broadly conceived, is any action +the next move of which is a free variable, and it is art thus +conceived that is the forte of SPs in general and the ISFP in +particular. + +Thus ISFPs have a lot of leeway in choice of occupation, especially +if they do not drop out of school early (most SPs do, since the +school offers little that is of interest to them or that challenges +their special brand of intelligence). It is a sad day indeed when +the ISFP chooses work wherein the operations are fixed by rule or +necessity and not free. To be happy and productive the ISFP must +choose variable actions and be rewarded for doing them. + +Finally, in many ISFPs may be found an instinctive longing for the +natural, the pastoral, the bucolic. They are quite at home in the +wilds, and nature seems to welcome them. Some have a remarkable +way with animals, even wild animals, almost as if there were a bond +of mutual sympathy and trust. In some instances a similar bond may +be seen between the ISFP and young children, instant and unstudied. + +Perhaps the most important thing to understand about ISFPs is that +they are SPs, with much in common with ESFPs especially, often +resembling ISTPs, and even sharing some traits with the seemingly +very different ESTP. + +To summarize this commonality with other SPs, ISFPs may be seen as +optimistic and cheerful; egalitarian, fraternal, and insubordinate; +tending to ward off obligation, duty, confinement, and fetters; a +lover of freedom, easily bored, wanting excitement, risk, chance, +and tests of luck; uncomplicated in motivation, trusting, +receptive, generous, and in every sense of the word a spender +rather than a saver. + +ISFPs are misunderstood not only because they are retiring, +reserved, and even self-effacing, but because the Jungians have +cast them as "introverted feeling types," and therefore very much +like the INFPs. Watch a few thoroughgoing ISFPs and you'll find +they have very little in common with INFPs. Other types are +reminded to guard against the natural tendency to project their own +traits of character onto the silent ISFP. diff --git a/xtrn/smm/mb-istj.asc b/xtrn/smm/mb-istj.asc new file mode 100644 index 0000000000000000000000000000000000000000..399af67a1bde56e24327c2d24847a2ff999eba25 --- /dev/null +++ b/xtrn/smm/mb-istj.asc @@ -0,0 +1,121 @@ +ISTJs in short: + +Serious, quiet, earn success by concentration and thoroughness. +Practical, orderly, matter-of-fact, logical, realistic, and +dependable. See to it that everything is well organized. Take +responsibility. Make up their own minds as to what should be +accomplished and work toward it steadily, regardless of protests or +distractions. + +About 6% of the population. + +Details about ISTJs: + +ISTJs are characterized by decisiveness in practical affairs, are +the guardians of time-honored institutions, and, if only one +adjective could be selected, 'dependable' would best describe this +type which represents about 6 percent of the general population. +The word of ISTJs is their bond, and they experience great +uneasiness by thoughts of a bankrupt nation, state, institution, or +family. + +Whether at home or at work, this type is rather quiet and serious. +ISTJs are extraordinary persevering and dependable. The thought of +dishonoring a contract would appall a person of this type. When +they give their word, they give their honor. + +ISTJs can be counted on to conserve the resources of the +institution they serve and bring to their work a practical point of +view. They perform their duties without flourish or fanfare; +therefore, the dedication they bring to their work can go unnoticed +and unappreciated. + +ISTJ's interest in thoroughness, details, justice, practical +procedures, and smooth flow of personnel and material leads this +type to occupations where these preferences are useful. + +For example, ISTJs make excellent bank examiners, auditors, +accountants, or tax examiners. Investments in securities are +likely to interest this type, particularly investments in blue chip +securities, ISTJs are not likely to take chances with their own or +others' money. + +ISTJs can handle difficult, detailed figures and make sense of +them. They communicate a message of reliability and stability, +which often makes them excellent supervisors of, for example, a +ward of a hospital, a library, or a business operation. + +They would be capable of handling the duties of a mortician, a +legal secretary, or a law researcher. High school teachers of +business, home economics, physical education, and the physical +sciences, are ISTJs, as are top-ranking officers of the Women's +Army Corps. Often this type seem to have ice in their veins, for +people fail to see an ISTJ's vulnerability to criticism. + +ISTJs are patient with their work and with procedures within an +institution, although not always patient with the individual goals +of people in that institution. ISTJs will see to it that resources +are delivered when and where they are supposed to be; materiel will +be in the right place at the right time. And ISTJs would prefer +that this be the case with people, too. + +As a husband or wife, the ISTJ is a pillar of strength. Just as +this type honors business contracts, so do they honor the marriage +contract. Loyal and faithful mates, they take responsibilities to +children and mate seriously, giving lifelong commitment to these. +'Duty' is a word the ISTJ understands. + +The male ISTJ sees himself as the breadwinner of a family, although +he can accept a working wife - as long as responsibilities to +children are not shirked. The male ISTJ's concept of masculinity +is patriarchal, and both female and male ISTJs make steady, +dependable partners. The female ISTJ may abandon the frivolous for +the sensible and may not always deepen her sensuality. + +As parents, ISTJs are consistent in handling children, and the +rules of family are made clear. A rebellious, nonconformist child +may have a difficult time, however, with an ISTJ parent - and vice +versa. As a child, the ISTJ is apt to be obedient and a source of +pleasure to parents and teachers. + +Although ISTJs are outstandingly practical and sensible, they can +marry people who are thoroughly irresponsible, with the marriage +developing into a relationship more parent-to-child than +adult-to-adult. + +The ISTJ fluctuates from being rescuer to reformer of the wayward +mate. The marriage then becomes a lifelong game: On one side, +there is Irresponsibility, Promise of Reform, Brief Period of +Reform, and Irresponsibility again; on the ISTJ's part, the cycle +is Disapproval, Rescue, Scolding, Forgiveness, Acceptance of +Promise To Do Better, and on and on. + +This pattern often is seen when an ISTJ marries an alcoholic and +enters a life of care taking punctuated by periods of anger and +rejection. Somehow, although ISTJs can accept periodic fickleness +and selfishness in significant others, they do not see this kind of +behavior as acceptable in themselves. + +ISTJs have a distaste for and distrust of fanciness in speech, +dress, or home. The ostentatious is abhorred, and a neat, orderly, +and functional home and work environment is preferred. Durability +of furnishings are of primary concern, esthetics given slim +consideration. The clothes of an ISTJ tend to be practical and +durable rather than in the latest style or luxurious. "No +nonsense" in both food and clothes seem characteristic of this type +who tend not to be attracted by exotic foods, beverages, or places. + +The male ISTJ may enjoy stag, men-only parties and use a different +sort of language when only men are present. The yearly hunting or +fishing trip as a male ritual is often a part of recreation for an +ISTJ. More than the female, the ISTJ male is apt to be involved in +community service organizations that transmit traditional values to +the young, such as Boy Scouting. They understand and appreciate +the contributions these groups make in preserving the national +heritage. + +Along with the SJs, the ISTJ takes particular delight in festive +occasions held in the context of rituals, for example, weddings, +holiday feasts, and birthdays. At work, the ISTJ is apt to see the +holiday office party as a necessary nuisance and would be likely to +participate and enjoy these events. diff --git a/xtrn/smm/mb-istp.asc b/xtrn/smm/mb-istp.asc new file mode 100644 index 0000000000000000000000000000000000000000..6341a59e448c4715865140cc49099481e64b4b54 --- /dev/null +++ b/xtrn/smm/mb-istp.asc @@ -0,0 +1,191 @@ +ISTPs in short: + +Cool-onlookers - quiet, reserved, observing and analyzing life with +detached curiosity and unexpected flashes of original humor. +Usually interested in impersonal principles, cause and effect, how +and why mechanical things work. Exert themselves no more than they +think necessary, because any waste of energy would be inefficient. + +About 13% of the population. + +Details about ISTPs: + +Just as impulsive as other SPs, the ISTP's life is artful action - +and action is end in itself. Action for the ISTP is more +gratifying if it is born of impulse rather than purpose. If the +action is in the service of an end or aim, let the aim look out for +itself; it cannot be allowed to influence execution. The act is +self-directed, self-leading, containing its own imperatives which +cannot be suborned to mere rules, regulations, or laws. + +ISTPs are egalitarian and can be fiercely loyal to "brothers." They +can also be fiercely insubordinate seeing hierarchy and authority +as unnecessary and even superfluous. It is not so much a matter of +going against regulations as it is simply ignoring them. + +The ISTP must do his or her own thing, free to vary each next move. +And ISTPs are, or want to be, proud of their ability to make the +next move skillfully. + +ISTPs are often fearless, risking themselves more than other types, +despite (even frequent) injury. Of all the types, ISTPs are most +likely to pit themselves, or their technique, against chance, odds, +or fate. They thrive on excitement; they crave some excitement +each day, in the form of fast motion - racing, sky diving, or +surfing, for instance. This hunger for action makes them much more +subject to boredom than any other type, their urge driving them to +a faster pace. Strangely, however, they are not bored while doing +their thing, even though there may be long stretches when nothing +happens, as during travel, surfing, hunting, or fishing. + +The ISTP nature is most easily seen in their mastery of tools, +tools of any kind, from microscopic drill to supersonic jet. From +an early age, they are drawn to tools as to a magnet; they must +manipulate them, and tools fall into their hands demanding use. +Many pilots knew by the age of five that they were going to be +pilots. + +ISTPs tend to take up activities that allow them to use tools; +driving, steering, operating. And if given a tool, whether scalpel +or earth mover, is operated with a precision that defies belief, +that operator is likely an ISTP. Others use tools, of course, but +not with the virtuosity of the ISTP. + +Indeed, we must call ISTP's the tool artisans, for they above all +others command the tool and bend it to their impulse. But again, +ISTPs - personified in Michaelangelo and Leonardo - work (or +better, play) with their tools on personal impulse and not on +schedule. If an externally imposed schedule coincides with +impulse, fine; if not, so much the worse for the schedule. + +One tool especially attractive to the ISTP is the weapon. Should +ISTPs turn against society (for whatever reason), they wield their +weapons with lethal genius to support their rejection. The hit man +of today, the gunslinger of the American West, and the duelist of +18th Century Europe, may be seen as virtuosos of precision +homicide. + +Hit man, gunslinger, and duelist alike took pride in their prowess. +Fortunately, they face their own kind in battle, the good warriors +of the land: soldier, marshal, police, intelligence agent. This is +not to say that all warriors, good or bad, are ISTPs, or that ISTPs +are all weapons experts; rather that the weapon virtuoso is more +frequently ISTP than not. + +ISTPs also play on impulse, taking off at any time just because +they "feel like it." (We are advised not to try to stop the ISTP +who "feels like" doing something.) The neurosurgeon does crop +dusting on the side and rides a motorcycle to the airport, and the +financier goes on a hunting trip in the middle of an audit (i.e., +SJ scrutiny). There can be no end to the ways ISTPs seek thrills +in play. + +Although they may have the appearance of loners in their work, they +nonetheless hang around their own kind in play. The climbers, +racers, flyers, hunters, and in general, movers flock together. The +companionship is mediated through the tool, and conversation is +sparse and terse. + +Like the ISFPs, ISTPs communicate through action, and show little +interest in developing verbal skills. Indeed, this lack of +interest in communication may be mistaken for what well meaning but +misguided medics and educators call "learning disability" or +"dyslexia," both preposterous notions when meant as explanations. +Let ISFPs get near a tool of any complexity and power and see how +fast they pass up everybody in 'learning' to use it and how precise +their 'lexicon' in talking of its features. + +Despite their egalitarianism, insubordination, and love of freedom, +they can be leaders, even great ones. But they must be "up front," +sword in hand, leading the charge. That is to say, ISTPs can be +very successful as battle leaders, for instance, no matter how +large or small the force under their command. Their supreme +realism, timing, and sense of expediency allows them to seize the +moment and fully exploit whatever resources can be gotten (theirs +or others) and capitalize on deficits and mistakes of their +opponent. + +Theirs is an expediency or exploitative leadership, based on a +special kind of intelligence which may be called artistic +concreteness. Yes, for the ISTP battle leader, combat is an art, +an intellectual game, not in the sense of strategy (that is for +NTs), but rather using whatever is at hand to defeat the other with +the least injury. + +Battle leaders are duellists. Patton was such a leader, and we +must credit Marshall (an NTJ strategist) for seeing beneath that +flamboyant, impulsive, insubordinate, and reckless exterior a +peerless warrior. The same credit goes to Grant (another NTJ) for +selecting Sheridan (STP), and to Hitler (ENFJ) for selecting Rommel +(ISTP). Patton, Sheridan, and Rommel were cut from the same cloth +and showed the same artistic espionage and rapier-like tactics. + +Glory is a pre-20th Century concept better understood by the ISTP +than by others. Or at least the ISTP is more interested in it than +most others. In battle there is glory, for it is in battle that +one can exercise one's lethal skills with positive sanction. + +The Seven Samurai were glorified and so have been duellists down +through the ages. Foss, Boyington, Fonck, and von Richtoffen, all +virtuosos of the winged machine gun, are still glorified heroes. +But there are hundreds of warriors just like them in nature. One +can test one's mettle in lethal duel, there's glory in it, as the +film The Great Waldo Pepper showed most poetically. + +The education and intelligence of the ISTP is worth special +comment. Possessed of artisan intelligence, ISTP is not in the +least interested in the clerical, interpretive, and "science" +curricula that abound in the 20th Century school. The other SPs, +equally bored by the school, will at least act as if they're trying +to learn, but not ISTP. ISTP will stare coldly into the eyes of +the teacher and not even say no. No amount of cajoling, bribing, +rewarding, punishing, or threat will get them to do their school +work. + +School work, quite apart from being irrelevant to the talents of +SPs, is, after all, mere preparation for something the ISTPs figure +they're never going to do anyway. SPs do not wish to prepare - for +anything - and ISTPs are careful to make this clear to their +would-be instructors. + +What is there to 'do', 'now', that is 'worthwhile'? ISTP will not +sit still (literally) for the trivial fare dished out +(sanctimoniously, in the eyes of the ISTP). Most seem to agree +that ISTPs "should" do their school work. But why? The arguments +are piddling and incoherent, warranting the scorn they get from the +unshakable ISTP. + +ISTPs are not "minimally brain damaged," or "hyperactive," or +"dyslexic"; they are active, and they are stubbornly insistent upon +getting to do, in school, some things that allow them to test their +intelligence and their mettle. Name-calling and pill-pushing won't +change them, other than destroying their self confidence and +perhaps creating a stimulant addict now and then. Give them a +tool-centered curriculum and watch their speed. + +Behaviorally the ISTP is more like the ESTP than any other type, +and the older they get, the greater the resemblance. When young, +ISTPs may look very much like ISFPs, but as their confidence and +pride increase this resemblance recedes. Jungians think ISTPs are +just like INTPs with only minor differences, but this is based on +the definition of ISTPs as "introverted thinking types." + +INTPs are logicians, philologists, and architects in the way they +think, but ISTPs are completely disinterested in these pursuits. +Even a cursory observation of a few clear-cut ISTPs will show how +striking the contrast, and how trivial the resemblance. + +Still, the most important thing about the ISTPs is their +commonality with other SPs. We might think that there would be +some resemblance to the ISTJ, having as they do, "IST" in common. +but no, their behavior is antithetical in almost every dimension of +comparison. One is pessimistic while the other optimistic; one is +parental, the other, fraternal; one saves, the other spends; one +believes in rules, the other is instinctual insubordinate and +recalcitrant to rules; and so on. + +ISTPs have infinitely more in common with the very different ESFP +than they do with any NT or SJ; besides the above, their mood is +one of good cheer, they are loyal to their equals, they want no +obligations, duties, or confining promises, are uncomplicated in +their desires, and are trusting, receptive, and generous. diff --git a/xtrn/smm/mb-j.asc b/xtrn/smm/mb-j.asc new file mode 100644 index 0000000000000000000000000000000000000000..92c1cb6cbfb6de7c2ba943db5b7873a9b221b40f --- /dev/null +++ b/xtrn/smm/mb-j.asc @@ -0,0 +1,11 @@ +The Judgement type tends toward planning, goal setting, deciding, and +getting-things-done. Once the J makes a decision he tends to be fixed and +inflexible. The J finds himself always waiting for others - who are always +late; thinks that if everyone would do what they are supposed to, the world +would be a better place, has a personal schedule for the day, and gets +frustrated when the schedule is interrupted, doesn't like surprises, keeps +lists, thrives on order, likes to finish-the-job. +J creates an environment that is structured, scheduled, ordered, planned, +and controlled; is decisive, deliberate. +J's plan their work and work their plan. +The population is equally divided between Js and Ps. diff --git a/xtrn/smm/mb-n.asc b/xtrn/smm/mb-n.asc new file mode 100644 index 0000000000000000000000000000000000000000..3347e8fb90085b5856e368ae99d31c076274ae2d --- /dev/null +++ b/xtrn/smm/mb-n.asc @@ -0,0 +1,7 @@ +The iNtuitive type gets his information from within himself, tends to favor +hunches, bases his decisions on possibilities, is innovative, imaginative. +An N tends to think about several things at once, finds future possibilities +more intriguing than frightening, thinks 'boring details' is a redundancy, +believes time is relative, likes to figure out how things work, is prone to +puns & word games, thinks in terms of general directions rather than specific +steps. About 25% of the population are type N. diff --git a/xtrn/smm/mb-nf.asc b/xtrn/smm/mb-nf.asc new file mode 100644 index 0000000000000000000000000000000000000000..988b822688f39d23feb96c153e37df7762741872 --- /dev/null +++ b/xtrn/smm/mb-nf.asc @@ -0,0 +1,22 @@ +The purpose of life for an NF is to find his purpose in life. NF is self in +search of self & has difficulty understanding what seem to be the false goals +of others. Search for identity, meaning, & actualization. Believes his real +self is somewhat less than what it should be. Desires to be genuine, +transparent; without masks or game-playing. Life is a drama; each encounter +is pregnant with becoming. Very sensitive to non-verbal communication. +Relationships can fall into a pattern of generous investment of energy followed +by disappointment in what-could-have-been. Tend to be writers, poets, musicians +teachers, counselors, actors; excellent communicators; gift of helping people +grow; strong empathy. Good at appearing to be what the beholder wants to see. +Seeks greater intensity in relationships, seeks elusive intimacy. At once both +the audience and the actor. Often has difficulty putting limits on time & +energy spent at work. Seeks perfection; and is often disappointed. Tends to +romanticize experience. Hunger for relationships. +NF strengths are a capacity for working with people & drawing out their best, +being articulate & persuasive, a strong desire to help others, and the ability +to affirm others freely & easily. +As a manager, NF has difficulty being firm, tends to give workers too much +leeway. As mate, NF has a deep need to give & receive affection and avoid +conflict. As a teacher, NF makes each student feel important & cared about. +Desire to please & comfortable with theory makes NF an excellent student. +About 12% of the population. diff --git a/xtrn/smm/mb-nt.asc b/xtrn/smm/mb-nt.asc new file mode 100644 index 0000000000000000000000000000000000000000..0b6ebfbf443cf8cabaf91305b0be804a4e9a5ac7 --- /dev/null +++ b/xtrn/smm/mb-nt.asc @@ -0,0 +1,32 @@ +NT often feel like aliens in a world of SPs and SJs. The NT has a hunger for +understanding, control & power; not over people as much as over things. +Basic drives are for competence, abilities, skills, ingenuity. Loves doing +things well. Addicted to storing up wisdom & acquiring intelligence. Has +more interest in figuring things out than actually doing them. Self critical +and self doubt to the point of paralysis. Perfectionist, tense, compulsive, +fear-of-failure. Doesn't accept the conventional wisdom. Tries to lift others +to his own exaggerated levels of competence and can be arrogant with those +who choose not to see the complexity of his chosen area. His arrogance causes +others to withhold their reactions for fear of being labeled 'stupid' and +isolates him from the people around him. His speech tends to be terse, +compact, logical, precise. Wastes few words. Doesn't like to state the obvious. +Passion for knowing. Tends to seek complicated & exacting profession; engineer, +mathematics, philosophy. Enjoys building systems, developing models, exploring +ideas. Tends to be straightforward in dealing with others; others find him +cold, remote, detached & enigmatic. Vulnerable to all-work-and-no-play. +Enjoys playing with words, paradox, bad puns. Tends to focus on the future; +the past is dead & gone. Is humiliated when others witness his errors. +Not sensitive to emotions of others, capable of biting sarcasm. +NT strengths are the ability to see the big picture, a talent for systems +planning, insight into the internal logic & principles of systems, and the +ability to speak & write clearly. +As managers, NT is the strategic planner; as mate NT is more interested in +intellectualizing feeling & emotions than in experiencing them; As parent +NT provides a role model that is impossible to live up to; as teacher, NT +clarity & precision can be both exciting & intimidating to students, but +they can bore their students by working a point to death; in finances, NT +probably has a plan, but at the same time is comfortable with high risk +ventures. +NT chooses clothes for comfort & utility, doesn't pay much attention to +fashion. +About 12% of the population. diff --git a/xtrn/smm/mb-p.asc b/xtrn/smm/mb-p.asc new file mode 100644 index 0000000000000000000000000000000000000000..2cccc090a00033d51af214107930556be35cbcf3 --- /dev/null +++ b/xtrn/smm/mb-p.asc @@ -0,0 +1,9 @@ +The Perceptive type tends toward plan-as-you-go, flexibility, open-ended +tentative agreements, and letting-life-unfold. P is easily distracted, loves +to explore the unknown, doesn't plan tasks, depends on last-minute-spurts to +meet deadlines, doesn't believe neatness counts, enjoys creativity, trys to turn +work into play, doesn't like to be pinned down, tends toward non-judgemental +statements. 'P' must generate alternatives for everything. +Likes to keep his options open, but not always - it all depends. + +The population is equally divided between Js and Ps. diff --git a/xtrn/smm/mb-s.asc b/xtrn/smm/mb-s.asc new file mode 100644 index 0000000000000000000000000000000000000000..ef399f5634c69606dcc546f40685a54234a7538c --- /dev/null +++ b/xtrn/smm/mb-s.asc @@ -0,0 +1,11 @@ +The Sensor gets his information from external events; tends to be practical, +base his decisions on experience, is down to earth, and notices details. +An S prefers specific answers to specific questions, would rather DO something +rather than think about it, likes to concentrate on the task at hand, likes +tasks with tangible results, prefers facts to theories, thinks 'fantasy' is +a dirty word, prefers clear/complete plans to vague guidelines, are very +literal in use of words, very much a 'show me' person. An S may resist +taking this test & quickly get bored with it because it is not practical +and doesn't have an immediate application. S will take a long time to take +this test, reading every question carefully. +About 75% of the population are type S. diff --git a/xtrn/smm/mb-sj.asc b/xtrn/smm/mb-sj.asc new file mode 100644 index 0000000000000000000000000000000000000000..78fc2553399dba0e0faa9a13f6739138c38a5405 --- /dev/null +++ b/xtrn/smm/mb-sj.asc @@ -0,0 +1,16 @@ +The SJ exists to belong and be useful to his social group. A giver, provider, +caretaker, parent; feels uncomfortable in a dependent role. Duty oriented, +desires to serve, very aware of what-should-be-done. Is comfortable with +obligations. Has a strong work ethic & desire for hierarchy & rule & order. +Pessimistic, spends much energy in preparing for the future. Tradition & +heritage are important. Has a keen sense for detecting ingratitude & lack of +appreciation. Drawn to institutions; banking, teaching, government, service. +Strong desire to conserve & store-up-for-the-future. Obligation to serve +often overrides the fact that he is already overburdened. Backbone of society. +SJ strengths are administration, dependability, ability to take charge. +Home & hearth are cornerstones of SJ marriages, ritual & tradition is +important. SJ makes very clear who is the parent & what is expected of +children. As teacher SJ places high importance on neatness & punctuality. +SJ's are the money - and moneyed - people of the world. Prefers classic, +durable clothes. 60% of public school teachers are SJ. +About 38% of the population. diff --git a/xtrn/smm/mb-sp.asc b/xtrn/smm/mb-sp.asc new file mode 100644 index 0000000000000000000000000000000000000000..76882d4822516e5c46a7b13af950fcb6b25aca05 --- /dev/null +++ b/xtrn/smm/mb-sp.asc @@ -0,0 +1,20 @@ +The SP must be free & will not be tied down with responsibility. Eat, drink & +be merry, for tomorrow we die. In Aesop's fable of the ant & the grasshopper, +the SP is the grasshopper. SP has the urge for impulsive action-for-right-now +rather than practicing for some future event. Waiting is the same as death. +Likes diversity & trying new things. Easy come easy go. Not goal oriented. +Yet the SP shows long endurance; He wouldn't climb a mountain to get to the +top, but for the thrill of every moment. Gravitates toward jobs where action +is involved. Tends to be fraternal & loyal to his equals. Master of the grand +gesture, but not of the small important acts or words. Capable of abruptly +abandoning his path & striking out in a completely different direction. +Optimistic, libertarian, social equality. Compulsion to perform. +SP strengths are practicality, adept problem solving skills, resourcefulness. +As manager, SP is excellent in a crisis - and is not above creating a crisis +to give him a sense of purpose. As mate, enjoys intensity & a thrill a minute. +As teachers, are best at practical-vocational, tend to shy away from +theoretical or abstract. Not good at lesson plans. Dealing with money, SP is +the original high roller. Not good at academics, poor spellers, least likely +of all the types to receive a college degree. +Chooses clothes for IMPACT. +About 38% of the population. diff --git a/xtrn/smm/mb-t.asc b/xtrn/smm/mb-t.asc new file mode 100644 index 0000000000000000000000000000000000000000..b6d430d8b14021b716077a1097b23fc8210ec6cd --- /dev/null +++ b/xtrn/smm/mb-t.asc @@ -0,0 +1,7 @@ +The Thinker tends toward logic, reason, laws, policy, principals, justice, +and impersonal decisions. The T tends to favor critical analysis, stay calm +& objective when others panic, enjoy proving their point, would rather be +right than liked, remember facts better than faces. +The thinker thinks the feeler is fuzzybrained. +The population is equally divided between Ts and Fs, although more men tend +to be Thinkers & more women tend to be Feelers. diff --git a/xtrn/smm/mb-tj.asc b/xtrn/smm/mb-tj.asc new file mode 100644 index 0000000000000000000000000000000000000000..a5c3dbeca2f99c0b95b65a0702a632ad7cb587b5 --- /dev/null +++ b/xtrn/smm/mb-tj.asc @@ -0,0 +1 @@ +60 % of the world's managers are TJ. diff --git a/xtrn/smm/mb-type.asc b/xtrn/smm/mb-type.asc new file mode 100644 index 0000000000000000000000000000000000000000..efd263b45fe7c01c4eea68ee4a6e40cfa1efe6d4 --- /dev/null +++ b/xtrn/smm/mb-type.asc @@ -0,0 +1,20 @@ +yhMyers-Briggs Personality Types:nc + +The first letter of the personality type indicates how you are energized +(hEncxtroversion or hIncntroversion). + +The second letter of the personality type indicates how you obtain information +for your decisions (hSncensation or ihNnctuition). + +The third letter of the personality type measures your preference to operate +from your head to your heart (hTnchinking or hFnceeling). + +The fourth letter of the personality type indicates how you like to order your +life (hJncudging or hPncerception). + +An asterisk (h*nc) in any of your letter positions indicates you are equally +divided between the two personality tendancies. + +From here you can read definitions of letter combinations (types): +hEnc, hInc, hSnc, hNnc, hTnc, hFnc, hJnc, hPnc, hTJnc, hSPnc, hSJnc, hNTnc, hNFnc, hENFPnc, hENFJnc, hENTPnc, hENTJnc, hESFPnc, hESFJnc, +hESTPnc, hESTJnc, hINFPnc, hINFJnc, hINTPnc, hINTJnc, hISFPnc, hISFJnc, hISTPnc, and hISTJnc. diff --git a/xtrn/smm/mb-type.que b/xtrn/smm/mb-type.que new file mode 100644 index 0000000000000000000000000000000000000000..987d79d569596870372afd7bab47c819ab32259e Binary files /dev/null and b/xtrn/smm/mb-type.que differ diff --git a/xtrn/smm/purity-1.asc b/xtrn/smm/purity-1.asc new file mode 100644 index 0000000000000000000000000000000000000000..773f53d0a268533ae5d004bc9ae8940b4dc8aad3 --- /dev/null +++ b/xtrn/smm/purity-1.asc @@ -0,0 +1,16 @@ +Section 1: Platonic Relations. 19 Questions. + +For this section, if you are mostly a: + + - heterosexual, then your partner in deed, often referred to + by the word "someone" or "partner", is to be someone + of the OPPOSITE gender. + + - homosexual, then your partner in deed, often referred to by the + word "someone" or "partner", is to be someone of + YOUR OWN gender. + + - 50-50 confirmed bisexual, then your partner in deed, often + referred to by the word "someone" or "partner", is to + be someone of the OPPOSITE gender. + diff --git a/xtrn/smm/purity-2.asc b/xtrn/smm/purity-2.asc new file mode 100644 index 0000000000000000000000000000000000000000..b69f67e1b615f499890f2a8a87ef1beca4e19c8d --- /dev/null +++ b/xtrn/smm/purity-2.asc @@ -0,0 +1,7 @@ +Section 2: Auto-erotica and Mono-sexualism. 51 Questions. + + Although this section is termed Auto-erotica and mono-sexualism, the + events herein still count even if you are with someone else at the time. + It was so named because these activities, like the harp, (and the + porcelain goddess) are predominantly solo events. + diff --git a/xtrn/smm/purity-3.asc b/xtrn/smm/purity-3.asc new file mode 100644 index 0000000000000000000000000000000000000000..5c33111569d7280eac84a367aba80fe63c414e57 --- /dev/null +++ b/xtrn/smm/purity-3.asc @@ -0,0 +1,2 @@ +Section 3: Legislative Misfits and Other Ethical Matters. 61 Questions. + diff --git a/xtrn/smm/purity-4.asc b/xtrn/smm/purity-4.asc new file mode 100644 index 0000000000000000000000000000000000000000..37289ae749fe509a0af279ca5d89a1ba95f27f36 --- /dev/null +++ b/xtrn/smm/purity-4.asc @@ -0,0 +1,2 @@ +Section 4: Drugs. 43 Questions. + diff --git a/xtrn/smm/purity-5.asc b/xtrn/smm/purity-5.asc new file mode 100644 index 0000000000000000000000000000000000000000..14d44dda2ceaa5d8f6d2c288d9d7d740a1ff3818 --- /dev/null +++ b/xtrn/smm/purity-5.asc @@ -0,0 +1,16 @@ +Section 5: Non Platonic Relations. 63 Questions. + +For this section, it you are mostly a: + + - heterosexual, then your partner in deed, often referred to by + the word "someone" or "partner", is someone of the + OPPOSITE gender. + + - homosexual, then your partner in deed, often referred to by the + word "someone" or "partner", is to be someone of + your OWN gender. + + - 50-50 confirmed bisexual, then your partner in deed, often referred + to by the word "someone" or "partner", is to be + someone of the OPPOSITE gender. + diff --git a/xtrn/smm/purity-6.asc b/xtrn/smm/purity-6.asc new file mode 100644 index 0000000000000000000000000000000000000000..3531a8ef778a37285eadbc69629b43a49bd368d3 --- /dev/null +++ b/xtrn/smm/purity-6.asc @@ -0,0 +1,18 @@ +Section 6: Non Primary Choice Relations. 39 questions. + + This section of the test deals with whether you have done things with + people whom you may not be altogether comfortable, therefore in this + section of the test, if you are mostly a: + + - heterosexual, then your partner in deed, often referred to by the + word "someone" or "partner", is to be someone of your + OWN gender. + + - homosexual, then your partner in deed, often referred to by the + word "someone" or "partner", is someone of the + OPPOSITE gender. + + - 50-50 confirmed bisexual, then your partner in deed, often + referred to by the word "someone" or "partner", is to + be someone of your OWN gender. + diff --git a/xtrn/smm/purity-7.asc b/xtrn/smm/purity-7.asc new file mode 100644 index 0000000000000000000000000000000000000000..4cf23745bc29143dfd1c9ccc8977cc76b99a5e02 --- /dev/null +++ b/xtrn/smm/purity-7.asc @@ -0,0 +1,8 @@ +Section 7: Alternate Choices. 26 questions. + + For any of the questions in this section, a yes answer is in order if it + is something that you do as an alternative to other sexual gratifications + or as an aid and/or in conjunction with other means of sexual + gratification. In other words, have you done it in a serious basis? + Trying it a few times to see what it's like does not count. + diff --git a/xtrn/smm/purity-8.asc b/xtrn/smm/purity-8.asc new file mode 100644 index 0000000000000000000000000000000000000000..bad4ef2b31a91350ab10dcbbefd9966e1c76dc6e --- /dev/null +++ b/xtrn/smm/purity-8.asc @@ -0,0 +1,7 @@ +Section 8: Group Sexual Relations. 27 questions. + + This section relates to what you have or have not done. Accordingly, the + group of people of which we are speaking are of both genders. In + questions where groups of people are concerned, there must be at least + one person in the group who is of the opposite gender. + diff --git a/xtrn/smm/purity-9.asc b/xtrn/smm/purity-9.asc new file mode 100644 index 0000000000000000000000000000000000000000..85a257e743f874233e8ec6a35211d1d1e8ed1041 --- /dev/null +++ b/xtrn/smm/purity-9.asc @@ -0,0 +1,6 @@ +Section 9: Non sentient objects. 62 questions. + + This section measures your kinkiness. Therefore, the questions apply to + actions and events which occurred while you were alone, as well as those + which occurred while you were with someone else. + diff --git a/xtrn/smm/purity-a.asc b/xtrn/smm/purity-a.asc new file mode 100644 index 0000000000000000000000000000000000000000..3218f28900d925e24603aaf83b5ac584c7cc0c5d --- /dev/null +++ b/xtrn/smm/purity-a.asc @@ -0,0 +1,5 @@ +Section 10: Locality. 33 questions. + +This section tries to figure out how many places you have done it. It +applies only to those situations in which you were with someone else. + diff --git a/xtrn/smm/purity-b.asc b/xtrn/smm/purity-b.asc new file mode 100644 index 0000000000000000000000000000000000000000..ad61bbf6c6ad4f79cbc523232493cc16824e89e5 --- /dev/null +++ b/xtrn/smm/purity-b.asc @@ -0,0 +1,2 @@ +Section 11: Style. 76 questions. + diff --git a/xtrn/smm/purity.100 b/xtrn/smm/purity.100 new file mode 100644 index 0000000000000000000000000000000000000000..c97b56bea11a7bd40fdf3adfd7c99c4de4744912 --- /dev/null +++ b/xtrn/smm/purity.100 @@ -0,0 +1,100 @@ +Had a date +Been out on a date past 4 am +Had a blind date +Kissed a MOS +Been french kissed +Kissed a MOS in the horizontal position +French kissed three or more MOS's in 24 hours +Kissed a MOS in the last three months +Necked for more than 2 hours consecutively +Slow danced cheek-to-cheek +Had an alcoholic drink +Been drunk +Driven while under the influence of alcohol or drugs +Had a lapse of memory due to drinking or drugs +Used alcohol or drugs to lower a MOS's resistance +Smoked tobacco +Smoked pot or hashish +Used a stronger drug +Taken 4 or more "recreational" drugs within 24 hours +Read a pornographic book or magazine +Seen a pornographic movie +Seen a stripper +Been arrested +Been convicted of a crime +Had an erection/clitoral erection +Had an orgasm +Had an orgasm in a dream +Fondled a MOS's ass +Caressed a MOS's thigh +Fondled a breast or had your breast fondled +Wrestled with a MOS +Showered, bathed, jacuzzied, or saunaed with a MOS +Gone coed skinny-dipping +Gone through the motions of intercourse while fully clothed +Spent the night in a MOS's room +Slept in the same bed with a MOS +Seen a naked post-pubescent MOS +Been seen naked by a MOS after puberty +Undressed or been undressed by a MOS +Kissed a MOS on the breast or been kissed on the breast +Fondled a MOS's genitals or had your genitals fondled by a MOS +Had an orgasm due to manipulation by a MOS +Kissed a MOS on the thigh +Engaged in cunnilingus +Engaged in fellatio +Had sexual intercourse at a parents house while they were home +Engaged in definitely sexual activity on the first date +Masturbated +Masturbated to a picture +Masturbated with another person in the room +Watched another person masturbate +Been caught masturbating +Simulated intercourse with an inanimate object +Committed an act of voyeurism +Committed an act of exhibitionism +Massaged or been massaged by a MOS +Unintentionally interrupted a couple in a significant state of undress +Participated in a tickle orgy, gross out, truth or dare, etc. +Experimented sexually before puberty +Purchased contraceptives in a drug store +Had sexual intercourse +Had sexual intercourse more than 10 times +Had sexual intercourse continuously for 1/2 hour +Had sexual intercourse within the last 3 months +Had sexual intercourse 3 or more times in 1 night +Had sexual intercourse in 3 or more positions +Had sexual intercourse in a car +Had sexual intercourse using a condom +Done sixty-nine +Had sexual intercourse outdoors +Had sexual intercourse with 3 different people +Had sexual intercourse with a virgin +Had sexual intercourse during menstruation +Had sexual intercourse without using birth control +Had sexual intercourse with 2 MOSs in 24 hours +Had sexual intercourse in a public place +Described a sexual experience to a separate party +Committed statutory rape +Been the object of travel or traveled 100 miles or more for sexual activity +Impregnated a woman or been pregnant +Arranged or had an abortion +Displaced a roommate by staying with a MOS for 1 or more nights +Shacked up with a MOS for a month or more +Tasted semen +Been propositioned by a prostitute or pimp +Accepted +Had anal intercourse +Been tested for V.D. due to reasonable suspicion +Had V.D. +Picked up a strange MOS for sexual purposes +Engaged in group sex +Engaged in sadism or masochism for sexual enjoyment +Been propositioned by a member of the same sex +Accepted a proposition by a member of the same sex +Been masturbated by a member of the same sex +Been orally stimulated by a member of the same sex +Committed incest +Fondled a pre-pubescent MOS +Engaged in transvestitism for sexual enjoyment +Committed bestiality diff --git a/xtrn/smm/purity.500 b/xtrn/smm/purity.500 new file mode 100644 index 0000000000000000000000000000000000000000..5f389c7ea827353afce460ace6278b9e0af58297 --- /dev/null +++ b/xtrn/smm/purity.500 @@ -0,0 +1,511 @@ +*PURITY-1.ASC +Kissed a friend or stranger as a friendly gesture +Held hands with someone +Had a date +Had a date past 1 a.m. +Dated someone on a regular basis +Picked someone up +Been picked up +Gone steady +Slow danced +Had the symptoms of Russian fingers (rushin' fingers) +Had the symptoms of Roman hands (roamin' hands) +Shared a bed with someone without anything steamy happening +Given a back or neck rub or massage with no ulterior motive +Used tickling as a pick-up get-to-know-you-better routine +Directly asked someone if they were a virgin +Used physical strength as a get-to-know-you-better routine +Secretly lusted after someone without that person knowing +Dropped subtle hints to someone hoping they would pick up on it +Written anonymous 'love letters' to someone +*PURITY-2.ASC +Had an arousing dream (Wet dreams and the like.) +Been sexually aroused +Uttered/muttered/yelled/screamed obscenities +Fantasized about your instructor or teacher +Fantasized about your lawyer, doctor, nurse, psychiatrist +Fantasized about someone you know personally but not closely +Fantasized about anyone and masturbated at the same time +Read or bought pornographic periodicals +Ever had a subscription to pornographic periodicals +Read sexually explicit literature +Gone skinny dipping alone +Made obscene phone calls +Phoned up any recorded phone sex numbers +Phoned up any live phone sex numbers +Stuffed your bra or stuffed your pants +Shaved your genital pubic hair +Shaved your genital pubic hair on a fairly regular basis +Colored or bleached your genital pubic hair +Shaved or shaped your genital pubic hair in a particular design +Masturbated +Masturbated at least five times in one twenty-four hour period +Masturbated on a fairly regular basis of no less than once a week +Masturbated where you could have been discovered +Masturbated out in the wilds or in nature +Masturbated to orgasm +Masturbated while reading sexually explicit materials +Masturbated while driving a *moving* land vehicle +Masturbated while on the phone +Masturbated while in a bathroom of the opposite sex +Masturbated while watching an R or X-rated show +Seen any burlesque show (Rocky Horror counts) +Been to a peep show +Been to a private showing of a pornographic movie +Seen a pornographic movie in a theater +Walked around in your room/apartment/house/habitation in nude +Walked around in a public or semi-public area bottomless +Bought blatant sexual objects +Owned any erotic art pieces +Written your own fantasies for masturbatory purposes +Sculpted erotic/obscene artworks in food +Eaten any erotic food items (Chocolate tits, banana dicks) +Sculpted erotic/obscene artworks in soap, wood, etc +Made an X- or R-rated snowman or snowwoman +Tasted your own orgasmic liquids +Inserted your finger into your rectum +Used ben-wa balls or anal beads +Performed oral sex on yourself +Willingly urinated on your garments while wearing them +Willingly urinated on any part of your body +Willingly defecated on your garments while wearing them +Willingly defecated on yourself +*PURITY-3.ASC +Administered a whole Purity Test or in the process +Taken Purity Tests of any versions more than 5 times +Lied on any previous Purity Tests +Exaggerated about any sexual experiences +Gone to (or escorted someone to) a Planned Parenthood Clinic +Broken your word, promise, or vow +Lied to someone at someone else's request +Lied about your sexual preference in order to avoid a date +Written graffitti +Plagiarized +Shoplifted +Stolen +Made out a check that bounced +Used someone else's credit card without their knowledge +Committed breaking and entering +Seen a snuff film +Read someone else's diary without their knowledge or consent +Searched someone's room without their knowledge or consent +Told someone that you loved them when you did not +Told someone that you loved them just for sex +Fantasized about someone else while having sex +Intentionally listened in on other people having sex +Used alcohol to lower someone else's inhibitions for sex +Used drugs to lower someone else's inhibitions for sex +Drugged someone without their knowledge and/or consent +Forced someone into having intimate physical relations with you +Had dates with more than one person in the same night +Gone steady with two or more people at the same time(secret) +Gone steady with two or more people at the same time(known) +Urinated on someone else intentionally (Piss fights!) +Urinated in object that was not designed for such purpose +Urinated anywhere other than commonly accepted piss hole +Urinated from higher than the fifth floor or off a bridge +Defecated anywhere other accepted shit hole +Stored any excretia in a refrigerator/oven +Stored evacuated excretia in your room/apartment +Entered a bathroom of the opposite sex- unaccompanied +Mooned or flashed someone from the front +Farted (audibly) in mixed company +Streaked/flashed or exposed yourself in public +Streaked/flashed or exposed yourself at a formal gathering +Been arrested (Picture taken and all) +Received money to have sex or mutual masturbation with someone +Given money to have sex mutual masturbation with someone +Thought you might be or might have caused someoneto be pregnant +Bought a home pregnancy test +Bought condoms +Borrowed/stolen/taken birth control devices from someone else +Had or given someone an unwanted pregnancy +Lied about being pregnant or about having made someone pregnant +Had sex while either you or your partner were under age +Thought you had VD +Had VD of any sort (VD/STD's/the clap/crabs/herpes/etc.) +Had an AIDS test due to reasonable suspicion or imagination +Given a sympathy fuck +Initiated sex with someone for the sake of sex only +Willingly committed incest +Committed adultery +Bought lingerie/undergarments of the opposite sex +Stolen the underwear of someone you knew not for joke +Intentionally taken a stranger's underwear +*PURITY-4.ASC +Had an alcoholic drink +Been intoxicated +Thrown up from having drunk too much alcohol +Passed out due to having drunk too much alcohol +Forgotten events that occurred while you were drunk +Smoked tobacco (cigarette/pipe/cigar/hookah) +Chewed tobacco (snuff) +Bought controlled/illicit drugs in violation of the law +Sold or re-sold controlled/illicit substances +Taken stimulants +Taken depressants excluding alcohol +Inhaled nitrous oxide while not visiting a dentist +Inhaled anything containing butyl nitrate +Used a commercial aphrodisiac +Taken valium +Smoked marijuana/sensemilia +Smoked marijuana/sensemilia more than four times +Eaten marijuana/sensemilia +Eaten marijuana or sensemilia more than four times +Taken opiate in any form +Taken opiate in any form more than twice +Used cocaine +Used cocaine more than four times +Injected any drugs into your body other than medical +Injected any illegal drug into your body more than twice +Taken Ecstasy/X +Taken PCP +Taken PCP more than twice +Taken LSD-25, peyote or psilocybin +Taken LSD/peyote or psilocybin more than twice +Taken LSD more than six times +Deliberately injured yourself so as to obtain medication +Played any games in which drugs were the prize +Gone to class or work while under the influence of drugs +Mixed drugs (alcohol counts) +Sold possessions in order to obtain drugs +Had sex while under the influence of nitrous +Had an orgasm while under the influence of nitrous +Had sex while under the influence of cocaine +Had sex while under the influence of marijuana/sensemilia +Had sex while under the influence of Ecstasy/X +Had sex while under the influence of LSD/peyote or psilocybin +Had sex while under the influence with a unknowing partner +*PURITY-5.ASC +Propositioned someone for necking or petting +Propositioned someone for sex/oral sex or mutual masturbation +Pinched or patted someone else's buttocks +French kissed +Been kissed below the neck but not including arms or hands +Kissed someone else below the neck not including arms or hands +Necked +Petted above the waist +Petted below the waist +Kissed on the first date +Necked on the first date +Petted above the waist on the first date +Petted below the waist on the first date +Given a hickey +Received a hickey +Worn specific clothes for the purpose of hiding hickeys +Fondled or stroked someone else's clothed legs +Fondled or stroked someone else's bare legs +Fondled or stroked someone else's frontal chest/torso region +Had your frontal chest/torso region fondled or stroked +Been involved with pelvic thrusting while fully clothed +Had your fingers licked or sucked +Had your ear or ear region licked/sucked, or nibbled +Licked, breathed onto, sucked, or nibbled an ear or ear region +Licked or sucked someone else's finger(s) +Fondled someone who was asleep +Given a back massage with ulterior motives +Given a back massage that led to something steamier +Seen someone completely nude when under good light conditions +Been seen nude by someone else under good lighting conditions +Been in someone's company while both were completely nude +Bathed or showered with someone +Let someone else wash you when you were capable of doing it +Gone skinny dipping in mixed company +Been involved with the fondling of a woman's clothed breast +Been involved with the fondling of a woman's bare breast +Licked, sucked, or nibbled on someone else's nipple +Had your nipple licked, sucked, or nibbled upon +Petted/fondled or otherwise handled someone's covered genitals +Had your covered genitals petted/fondled or handled +Petted/fondled or otherwise handled someone's bare genitals +Had your bare genitals petted/fondled or otherwise handled +Had an orgasm while petting +Given your partner an orgasm while petting +Given finger scratch marks +Received finger scratch marks +Drawn blood by scratching during sex +Drawn blood by biting during sex +Given or received *scars* from scratches or bites during sex +Performed oral sex +Received oral sex +Swallowed semen, or licked female liquids off of fingers +Done sixty-nine +Performed mutual masturbation +Had sex (No need for orgasm; penetration counts.) +Had sex on the first date +Had sex without the use of birth control devices +Had sex with a virgin (Not yourself.) +Had sex with someone whose name you did not know +Had sex with someone whose face you never saw +Had sex with someone with a 20 year age difference +Had sex with someone not of your own race +Had sex with a religious officiary +*PURITY-6.ASC +Held hands or otherwise displayed public affection +Kissed someone on the lips +French kissed someone +Necked +Petted +Received manual sex +Given manual sex +Received oral sex +Given oral sex +Had sex +Had sex with a virgin (not yourself.) +Had sex with someone with age difference of more than 20 years +Had anal sex +Been involved in fist-fucking +Done 69 (simultaneous oral sex.) +Propositioned someone for sex, oral sex, or mutual masturbation +Yielded willingly to a proposition from someone for sex/oral sex +Had sex with someone whose name you didn't know +Had sex with someone whose face you never saw +Been a participant in a who's-physically-better-equipped contest +Been a judge in a contest such as above +Gave money or favors for sex, oral sex, or mutual masturbation +Received money or favors for sex/oral sex or mutual masturbation +Fondled someone who was asleep +Attempted to seduce someone +Allowed yourself to be seduced +Had an orgasm while petting +Gave your partner an orgasm while petting +Had an orgasm at all +Had sex/oral sex or mutual masturbation with more than 10 people +Stroked or fondled the clothed legs of someone +Stroked or fondled the bare legs of someone +Stroked or fondled the clothed chest/torso region of someone +Stroked or fondled the bare chest/torso region of someone +Fondled or handled the clothed genitals of someone else +Stroked/fondled or handled the bare genitals of someone else +Had sex/mutual masturbation with someone not of your own race +Been in a menage-a-trois of people of the same sex +Been involved in group sex/with all participants of the same sex +*PURITY-7.ASC +Been decidedly heterosexual +Been decidedly homosexual +Been decidedly bisexual +Practiced bestiality (avec les animaux) +Practiced transvesticism +Practiced sadism +Practiced masochism +Practiced bondage +Practiced domination +Practiced submission +Practiced sodomy (anal intercourse) +Practiced cocrophilia (a marked interest in excrement) +Practiced frotteurism +Practiced infantilism(a dependency on diapers) +Practiced klismaphilia (a dependency on being given an enema) +Practiced necrophilia (copulation with a corpse) +Practiced mysophilia (a dependency on something soiled) +Practiced scoptophilia ( as in voyeurism) +Practiced urophilia (being responsive to urine ) +Practiced role-playing +Owned an underwear collection of underwear not belonging to you +Been a foot fetishist to any degree +Been a leather fetishist to any degree +Been a rubber/latex fetishist to any degree +Been a voyeur +Been an exhibitionist +Listened to dirty jokes in mixed company +*PURITY-8.ASC +Told dirty jokes in mixed company +Discussed masturbation +Watched a porn movie in mixed company +Watched a porn movie with your own or someone else's parents +Played a game which may require you or others to disrobe +Played a game which may require you to perform action on others +Been in contact with more than one person while all were nude +Had oral sex with more than 10 people (not nec. at one time) +Had sex with more than 10 people (not necessarily at one time) +Had sex with more than 1 person in a 24 hour period +Had sex with both genders in a 24 hour period +Been in a menage-a-trois (MFM OR FMF) +Walked in on others having sex (oops) and then joined in +Had sex or oral sex with a person and his/her parent +Had sex/mutual masturbation, with a person and his/her sibling +Been involved in a two (or more) in one +Been involved in a gang bang +Been in a circle of fuck +Been in a 69 circle +Been to a (cooking, baby, Wesson) oil party +Played naked Twister [tm] (with or without oil) +Participated in a hetro orgy or been involved in group sex +Participated in a bisexual orgy or group sex +Propositioned a person or group of people for group sex +Been propositioned for group sex +Participated in a fuck-a-thon +*PURITY-9.ASC +Used a foreign object or something for masturbation +Masturbated using the aid of food +Eaten the food used in masturbation after masturbation +Eaten a lab dissection +Inserted food into your or someone else's anus +Eaten food after it was extracted from your or someone's anus +Received an enema for a purpose other than medical +Received an enema consisting on a non-normal enema solution +Actually measured your own or someone else's penis +Used a mechanical device in aiding or replacing masturbation +Used a feather or other device for the purpose of tickling +Used tickling as a form of *arousal* +Used ice for sexual purposes +Used ice for something frozen as a dildo +Used a strap-on dildo or male extension sheath +Used whipped cream for sexual purposes +Used hot/melted wax for sexual purposes +Had sex in front of or under a mirror +Put food on your partner's body, and then eaten it +Used household syrup/etc or any like substance for sex purposes +Used ropes, cuffs or any other such device for bondage purposes +Used a whip, cat-o-nine-tails, or something similar for pain +Worn edible underwear/lingerie +Eaten edible underwear/lingerie off of someone +Worn a leather or rubber suit +Worn diapers for a sexual or masturbatory purpose +Been diapered by someone else for a sex or masturbatory purpose +Used a ball gag or other manufactured gag +Worn a collar and/or leash +Been completely tied down (spreadeagled, hogtied, etc.) +Tied someone down completely +Had sex while you or your partner was tied up +Used nipple clips (clothespins count) +Pierced a part of your body other than your ears or nose +Found a prepubescent child sexually attractive/arousing +Had sexual contact of any kind with a prepubescent child +Used an inflatable doll +Humped an inanimate object like a pillow, banana, etc +Had sex or oral sex with a dead person +Inserted a small animal or creature into your rectum +Had sex or oral sex with your (dead) dinner animal +Watched animals having sex +Been aroused by the sight of animals having sex +Attempted to have sex with a live animal, but failed +Had sex/oral sex or (mutual) masturbation with smallish animal +Had sex/oral sex or masturbation with domesticated farm animal +Mutilated or killed any living animal for your pleasures +Had sex with a live animal (Any size.) +Received oral sex from a live animal (Any size.) +Gave oral sex to a live animal (Any size.) +Had sex or (mutual) masturbation with a animal more than once +Had sex or masturbation with an animal in presence of others +Cross dressed in the *undergarments* of the opposite sex +Cross dressed in presence of others +Stuffed your pants or bra while you were cross-dressed +Had your head inserted into a urinal or toilet bowl willingly +Worn groinal underwear on your head (Panties/jock-strap/etc.) +Inserted a piece of groinal underwear into your mouth +Deliberately sniffed or smelled a piece of groinal underwear +Been gagged with someone's underwear (not your own) +Played in or with shit +Worn or used a used condom or feminine hygiene contraption +*PURITY-A.ASC +Necked or petted in a place of religion +Had sex or been involved in a place of religion +Necked or petted in a place of the dead (mortuary) +Had sex or been involved in oral sex in a place of the dead +Necked or petted in a contraption of the dead (hearse/etc) +Had sex in a contraption of the dead +Had sex in/on a construction site (house, office, etc.) +Necked or petted in a vehicle of LESS THAN 30,000 pounds net +Had sex in a vehicle of LESS THAN 30,000 pounds net +Necked or petted in a vehicle of MORE THAN 30,000 pounds net +Had sex in a vehicle of MORE THAN 30,000 pounds net +Had sex in a land-based, non road dependant vehicle +Necked in a water, manual powered vehicular transport medium +Petted in a water/wind or prop driven transport medium +Had sex in a water/wind driven transport MORE THAN 80 feet +Had sex or oral sex in an aircraft +Had sex in a household room other than a bedroom +Had sex on the floor (but not the roof) +Had sex on any furniture that is indoors but not a bed or table +Had sex telephone booth, voting booth/etc +Had sex in an elevator, people-mover, escalator, dumbwaiter +Had sex up a tree but not in a tree house or similar structure +Had sex in a suspension device of some kind (hammock) +Had sex on the roof of a building in excess of 5 floors +Had sex within the confines of a hedge, bush/etc +Had sex, oral sex, or mutual masturbation in the snow +Had sex in a place with the ambient temperature below freezing +Had sex in a place where you could have been discovered +Had sex in a water-filled bathtub, hot tub/etc +Had sex, oral sex, or mutual masturbation in a body of water +Had sex on the beach +Had sex or mutual masturbation in a bathroom of the opposite sex +Gone to a motel for the sole purpose of having sex +*PURITY-B.ASC +Watched while someone else masturbated +Been watched while masturbating +Orgasmed on somebody +Orgasmed in somebody (male) or in you (female) +Had more than one person orgasm on you at once +Used a penis as a leash or bludgeoning device +Been involved in oxygen deprivation for sexual enhancement +Willingly made video tapes or pictures taken while having sex +Physically watched others having sex +Watched your partner of choice having sex with someone else +Taken pictures of your partner having sex with someone else +Willingly made audio recordings while having sex +Talked dirty while having sex, oral sex, or mutual masturbation +Intentionally made more noise than necessary while having sex +Intentionally made 'animal' noises during sex +Had a pet walk over you or your partner while during sex +Had a general emergency arise while you were steeped in sex +Had your sexual technique/style/skill openly praised by someone +Taken nude pictures of someone else +Had nude pictures of you taken +Placed a personal ad +Answered a personal ad +Been involved in breast fucking (The Hawaiian Muscle Fuck) +Participated in fist-fucking (see 'Caligula') +Shaved someone's pubic hair (or had yours) as part of sex +Had sex for more than three hours in a single session of sex +Been bruised during sex, oral sex, or mutual masturbation +Bruised someone else during sex, oral sex, or mutual masturbation +Been injured during sex, oral sex, or mutual masturbation +Orgasmed more than three times in one session of sex +Had sex so many times or for so long that one involved runs dry +Disturbed other people by making excessive noise during sex +Had sex or received oral sex while you were driving +Had sex doggie fashion +Had sex in the female superior position +Had sex sitting up +Had sex standing up +Had sex upside-down +Gone through several sexual positions without need for re-entry +Fallen asleep during sex +Woken up to someone having sex with you +Had sex while one person was passed out or unconscious +Given or received a hickey on your upper inner thigh +Been on the receiving of anal sex +Been on the ramming end of anal sex (a dildo counts) +Had sex more than 10 times with 1 person +Had sex more than 5 times in a 24 hour period +Had sex more than 10 times in a 24 hour period +Had sex while someone other than your partner was watching +Had sex while one or both were playing a musical instrument +Performed oral sex after intercourse without washing or douching +Kissed your partner on the lips after oral sex without rinsing +Inflicted pain during sex +Been involved in cunnilingus during the woman's period +Had sex during the woman's period +Foot masturbated someone +Been foot masturbated +Tongue bathed someone +Been tongue bathed +Licked or sucked on someone else's feet and/or toes +Had your feet and/or toes licked or sucked by someone else +Licked someone's anus +Licked someone's anus while they were defecating +Performed oral sex while the person was urinating +Drank your own urine +Tasted or drank someone else's urine +Drank/drained an entire bladder-full of someone else's urine +Drank human blood +Tasted someone else's nasal mucous +Been involved in a golden shower +Swallowed your partner's orgasmic secretions +Used the Purity Test as a checklist of things you could do +Ever done something for purpose of lowering your Purity score +Bought/read books to enhance sexual technique +Participated in Purity Testing with an ulterior motive +Become interested in person after hearing their Purity score diff --git a/xtrn/smm/purity.asc b/xtrn/smm/purity.asc new file mode 100644 index 0000000000000000000000000000000000000000..3aae420c0007303289cce4c9a9ae8ef84d580b1d --- /dev/null +++ b/xtrn/smm/purity.asc @@ -0,0 +1,31 @@ +nch THE UNISEX, OMNISEXUAL + +y P U R I T Y T E S T +nc_______________________________________________________________________________ + + rhiWARNINGnrh: THIS TEST MAY EASILY OFFEND YOU + +chInstructions for Use: +nc +This is a fairly long test consisting of hone hundred questionsnc. It starts out +tame and gets progressively worse (or better, depending on your viewpoint). + +hDefinitions +nc +Any references to hMOSnc are references to a hMncember of the hOncpposite hSncex. + +All questions in this test pertain to events that have happened to you +subsequent to your weaning and babyhood/infancy. Anything that may have +happened before that time is considered not standing and void. + +The term mutual masturbation refers to someone masturbating you AND/OR you +masturbating someone else, not exclusively both at the same time. + +We would also like to define having sex in the homosexual case; homosexual sex +has occurred when both partners are of the same sex and one of the partners has +an orgasm while there is some contact between the genitals of both partners. + +We would now like to bring to your attention that there is no passing nor +failing score. Therefore, one really shouldn't worry too much about getting a +high score... even if you do get giggled at for the rest of your life. + diff --git a/xtrn/smm/purity.que b/xtrn/smm/purity.que new file mode 100644 index 0000000000000000000000000000000000000000..c97b56bea11a7bd40fdf3adfd7c99c4de4744912 --- /dev/null +++ b/xtrn/smm/purity.que @@ -0,0 +1,100 @@ +Had a date +Been out on a date past 4 am +Had a blind date +Kissed a MOS +Been french kissed +Kissed a MOS in the horizontal position +French kissed three or more MOS's in 24 hours +Kissed a MOS in the last three months +Necked for more than 2 hours consecutively +Slow danced cheek-to-cheek +Had an alcoholic drink +Been drunk +Driven while under the influence of alcohol or drugs +Had a lapse of memory due to drinking or drugs +Used alcohol or drugs to lower a MOS's resistance +Smoked tobacco +Smoked pot or hashish +Used a stronger drug +Taken 4 or more "recreational" drugs within 24 hours +Read a pornographic book or magazine +Seen a pornographic movie +Seen a stripper +Been arrested +Been convicted of a crime +Had an erection/clitoral erection +Had an orgasm +Had an orgasm in a dream +Fondled a MOS's ass +Caressed a MOS's thigh +Fondled a breast or had your breast fondled +Wrestled with a MOS +Showered, bathed, jacuzzied, or saunaed with a MOS +Gone coed skinny-dipping +Gone through the motions of intercourse while fully clothed +Spent the night in a MOS's room +Slept in the same bed with a MOS +Seen a naked post-pubescent MOS +Been seen naked by a MOS after puberty +Undressed or been undressed by a MOS +Kissed a MOS on the breast or been kissed on the breast +Fondled a MOS's genitals or had your genitals fondled by a MOS +Had an orgasm due to manipulation by a MOS +Kissed a MOS on the thigh +Engaged in cunnilingus +Engaged in fellatio +Had sexual intercourse at a parents house while they were home +Engaged in definitely sexual activity on the first date +Masturbated +Masturbated to a picture +Masturbated with another person in the room +Watched another person masturbate +Been caught masturbating +Simulated intercourse with an inanimate object +Committed an act of voyeurism +Committed an act of exhibitionism +Massaged or been massaged by a MOS +Unintentionally interrupted a couple in a significant state of undress +Participated in a tickle orgy, gross out, truth or dare, etc. +Experimented sexually before puberty +Purchased contraceptives in a drug store +Had sexual intercourse +Had sexual intercourse more than 10 times +Had sexual intercourse continuously for 1/2 hour +Had sexual intercourse within the last 3 months +Had sexual intercourse 3 or more times in 1 night +Had sexual intercourse in 3 or more positions +Had sexual intercourse in a car +Had sexual intercourse using a condom +Done sixty-nine +Had sexual intercourse outdoors +Had sexual intercourse with 3 different people +Had sexual intercourse with a virgin +Had sexual intercourse during menstruation +Had sexual intercourse without using birth control +Had sexual intercourse with 2 MOSs in 24 hours +Had sexual intercourse in a public place +Described a sexual experience to a separate party +Committed statutory rape +Been the object of travel or traveled 100 miles or more for sexual activity +Impregnated a woman or been pregnant +Arranged or had an abortion +Displaced a roommate by staying with a MOS for 1 or more nights +Shacked up with a MOS for a month or more +Tasted semen +Been propositioned by a prostitute or pimp +Accepted +Had anal intercourse +Been tested for V.D. due to reasonable suspicion +Had V.D. +Picked up a strange MOS for sexual purposes +Engaged in group sex +Engaged in sadism or masochism for sexual enjoyment +Been propositioned by a member of the same sex +Accepted a proposition by a member of the same sex +Been masturbated by a member of the same sex +Been orally stimulated by a member of the same sex +Committed incest +Fondled a pre-pubescent MOS +Engaged in transvestitism for sexual enjoyment +Committed bestiality diff --git a/xtrn/smm/que.lst b/xtrn/smm/que.lst new file mode 100644 index 0000000000000000000000000000000000000000..95018ef15d5c40f4492698eb705092733f0d5aa3 --- /dev/null +++ b/xtrn/smm/que.lst @@ -0,0 +1,12 @@ +BASIC +Basic Personality +0 +APPEAR +Appearance +0 +MATERIAL +Material +0 +ADULT +Adult Sexuality +18 diff --git a/xtrn/smm/smm.can b/xtrn/smm/smm.can new file mode 100644 index 0000000000000000000000000000000000000000..503ab7da423f090b526c1ca28cef26a0e5dcc34c --- /dev/null +++ b/xtrn/smm/smm.can @@ -0,0 +1,4 @@ +l +p +digital man +fuck diff --git a/xtrn/smm/smm.cfg b/xtrn/smm/smm.cfg new file mode 100644 index 0000000000000000000000000000000000000000..334011d05ec08c4f055ec6ce0adfe6da12461542 --- /dev/null +++ b/xtrn/smm/smm.cfg @@ -0,0 +1,22 @@ +18 +15 +0 + + + + +0 +0 +30 +1 + +0 +0 +0 +0 +0 +%!dsz portx %u,%i sz %f +0 + + +90 diff --git a/xtrn/smm/smm.doc b/xtrn/smm/smm.doc new file mode 100644 index 0000000000000000000000000000000000000000..37939ac6251347c2c5170880f9ab1ec4995ef654 --- /dev/null +++ b/xtrn/smm/smm.doc @@ -0,0 +1,594 @@ + + + + + + + + + + + + + + + + + + + + + + + + Synchronet Match Maker Version 2.10 Copyright 1996 Digital Dynamics + -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + + "Perhaps the most comprehensive Match Maker ever." + + +Synchronet Installation (if you are using Synchronet BBS Software) +================================================================== + +Synchronet Match Maker (SMM) comes pre-installed in Synchronet BBS v2.1 and +later. If match maker has been pre-installed in your system, see the file +UPGRADE.DOC for details on installing a newer version over an older version +(upgrading). + +Create the following sub-directory off of your main Synchronet directory +(e.g. C:\SBBS): + +XTRN\SMM (The XTRN directory should already exist) + +(example: C:\SBBS\XTRN\SMM) + +Copy the files included in the archive or on the floppy disk into this +directory. The DEMO and registered versions of this program are identical. +The registration number must be obtained from Digital Dynamics and entered +into the Match Maker configuration program (SMMCFG) to convert the DEMO into +a registered copy. + +Licenses for registered use of Synchronet Match Maker are sold separately from +Synchronet BBS Software. Once a registration number has been issued, no refunds +or returns of Synchronet Match Maker will be accepted. + +Run SCFG (Synchronet Configuration Program) and add the Match Maker to one +of your External Program Sections and configure as follows: + + ����������������������������������������������������������ͻ + � Synchronet Match Maker � + ���������������������������������������������������������� + � �Name Synchronet Match Maker � + � �Internal Code SMM � + � �Start-up Directory ..\XTRN\SMM � + � �Command Line smm � + � �Clean-up Command Line � + � �Multiple Concurrent Users Yes � + � �Intercept I/O Interrupts No <-- Important � + � �Swap BBS out of Memory Yes � + � �Modify User Data Yes � + � �Execute on Event No � + � �BBS Drop File Type Synchronet XTRN.DAT � + � �Place Drop File In Node Directory � + ����������������������������������������������������������ͼ + +If you wish to have old profile entries and wall writings automatically deleted +from your match maker, you will need to run the SMMUTIL program periodically to +remove profiles that haven't been updated in a certain number of days +(specified on the SMMUTIL command line). To set up a timed event in SCFG-> +External Programs->Timed Events for SMMUTIL: + + ��������������������������������������������������������������������ͻ + � SMMUTIL Timed Event � + �������������������������������������������������������������������� + � �Internal Code SMMUTIL � + � �Start-up Directory ..\XTRN\SMM � + � �Command Line smmutil 90 7 > SMMSTATS.TXT � + � �Execution Node 1 � + � �Execution Days Sun Mon Tue Wed Thu Fri Sat � + � �Execution Time 00:00 � + � �Requires Exclusive Execution Yes � + � �Force Users Off-line For Event No � + ��������������������������������������������������������������������ͼ + +This would have SMMUTIL remove all profiles that haven't been updated in the +past 90 days and all wall writings older than 7 days. + +It will also create the file SMMSTATS.TXT in your XTRN\SMM directory with +detailed statistics on the demographics of the current SMM profile database. +You may want to make this file available for download or as a viewable bulletin +on your BBS. + +If you are currently on DOVE-Net or FidoNet and you carry the "Synchronet Data" +(SYNCDATA) message area and wish to link your match maker database with other +BBSs through this message area, set up the following two Timed Events in SCFG: + + ��������������������������������������������������������������������ͻ + � SMB2SMM Timed Event � + �������������������������������������������������������������������� + � �Internal Code SMB2SMM � + � �Start-up Directory ..\XTRN\SMM � + � �Command Line smb2smm %jsubs\syncdata smm.dab � + � �Execution Node 1 � + � �Execution Days Sun Mon Tue Wed Thu Fri Sat � + � �Execution Time 00:00 � + � �Requires Exclusive Execution No � + � �Force Users Off-line For Event No � + ��������������������������������������������������������������������ͼ + + ��������������������������������������������������������������������ͻ + � SMM2SMB Timed Event � + �������������������������������������������������������������������� + � �Internal Code SMM2SMB � + � �Start-up Directory ..\XTRN\SMM � + � �Command Line smm2smb smm.dab %jsubs\syncdata � + � �Execution Node 1 � + � �Execution Days Sun Mon Tue Wed Thu Fri Sat � + � �Execution Time 00:00 � + � �Requires Exclusive Execution No � + � �Force Users Off-line For Event No � + ��������������������������������������������������������������������ͼ + +Change "syncdata" in the above examples to the internal code you have used +for the "Synchronet Data" echo. Also, if you are not running v2.1+ of +Synchronet, you must specify the full path to the DATA directory instead of +using the %j. If your "Synchronet Data" echo is stored on a different +drive or in a different directory than SBBS, then you must specify that drive +and path on the above command lines. + +To get your match maker database active immediately, you may want to reset +your message pointers for the "Synchronet Data" echo on your hub BBS. If +using QWKnet, you would accomplish this by posting the message in the +"Synchronet Data" echo on your BBS to "SBBS" with a title of "RESET". The +message body does not matter. + +Swapping +-------- +If you get memory allocation errors during the execution of any of the above +event command lines, add that program name to your Global Swap List in SCFG. + +DOOR.SYS BBS Installation (if you are using BBS software OTHER than Synchronet) +=============================================================================== + +Your BBS software must be able to create the industry standard DOOR.SYS drop +file (35 lines or more). If you wish to charge credits for specific match maker +functions (adding profile, sending telegrams, etc) your BBS software must be +able to READ BACK in the modified DOOR.SYS drop file (e.g. GAP BBS software). +Credits are read from line 31 of the DOOR.SYS file (in K) and credits used +while in SMM are written to line 30 of the DOOR.SYS (in K) and total credits +after adjustment (in K) are written back to line 31 of the DOOR.SYS. Since the +DOOR.SYS format only supports one set of flags (line 23), flag set 1 will be +the only valid flag set to use for the security options in SMMCFG (i.e. flag +sets 2-4 will not be used). + +Create a directory for Synchronet Match Maker (SMM) and copy all the files +into it (example: C:\BBS\DOORS\SMM). + +Copy the files included in the archive or on the floppy disk into this +directory. The DEMO and registered versions of this program are identical. +The registration number must be obtained from Digital Dynamics and entered +into the Match Maker configuration program (SMMCFG) to convert the DEMO into +a registered copy. + +Once a registration number has been issued, no refunds or returns of Synchronet +Match Maker will be accepted. + +If you are running a multinode BBS, you will need to have the DOOR.SYS created +in a separate directory for each node (i.e. NOT the directory where SMM has +been installed). This will prevent drop file collisions if two users enter SMM +at the same time. The complete path to the DOOR.SYS must be specified on the +command line, so each node must have a different path specified. Example: + +Node 1 Command Line: SMM C:\BBS\NODE1\DOOR.SYS +Node 2 Command Line: SMM C:\BBS\NODE2\DOOR.SYS + +SHARE must be loaded in your CONFIG.SYS or AUTOEXEC.BAT for SMM to function +(in single node or multinode environments). + +If non-standard IRQs or I/O addresses are used, they must be specified on the +SMM command line using the Command Line Options. IRQs 2-15 are fully supported. +Shared IRQs are not supported in UART mode. + +16550 FIFO buffered UARTs are detected and enabled. + +DTE rates up to 115200 baud are supported (higher with proprietary hardware). + +Command Line Options: +==================== + +Command line options override the values (if present) in the DOOR.SYS file. +No command line options are required when used with Synchronet BBS software. + + /P# Set the COM port (0=local only) (normally not necessary) + + Example: /P1 to specify COM1 + /P0 to specify no COM port (local use) + + /C# Set the COM port type or I/O (D:DigiBoard, F:FOSSIL, E:EBIOS) + + Example: /CF to specify FOSSIL + /C3e8 to specify I/O address 3e8 (hexadecimal) + + /I# Set the COM port IRQ or channel (only required if non-standard) + + Example: /I5 to specify IRQ 5 + /I0 to specify FOSSIL/Digi Channel 0 + + /R# Set the COM port DTE rate (normally not necessary) + + Example: /R57600 to specify a DTE rate of 57600 baud + + /T# Set time-slice APIs supported (default: DESQview if detected) + + Example: /T1 to use INT28 time-slice API + /T2 to use Win/OS2 time-slice API + /T4 to disable DESQview detection and time-slice API + +If a user name is specified on the command line, that user's profile will be +automatically looked up and displayed. + + Example (Synchronet): SMM JOHN DOE + + Example (non-Synchronet): SMM C:\BBS\NODE1\DOOR.SYS JOHN DOE + +The current directory MUST be the directory where SMM has been installed +(e.g. C:\BBS\DOORS\SMM) when SMM is executed. Some non-Synchronet BBS packages +may require a batch file to change drive and/or directory before running SMM +and may require the same batch file re-load the BBS software. Example: + + @ECHO OFF + CD \BBS\DOORS\SMM + SMM \BBS\NODE1\DOOR.SYS + REM The following may not be necessary with some BBS packages + CD \BBS\NODE1 + BBS + +Configuration +============= + +SMMCFG +------ +SMMCFG.EXE is used to modify your SMM.CFG (Configuration) file. Hitting the F1 +key will display a help page on the currently selected menu or option. + + ����������������������������������������������������������ͻ + � Synchronet Match Maker Configuration � + ���������������������������������������������������������� + � �System Name MY BBS � + � �Wall Security... � + � �Profile Database Security... � + � �Credit Cost for Adding Profile 0k � + � �Credit Cost for Sending Telegram 0k � + � �Credit Cost for Writing on the Wall 0k � + � �Credit Cost for Reading Questionnaire 0k � + � �Minimum Level to Send Telegrams 0 � + � �Minimum Level to Read Questionnaires 0 � + � �Sysop Level 90 � + � �Minor Segregation (Protection) Age Disabled � + � �Auto-Update Profiles 30 � + � �Notify User of Activity 1 � + � �Use Metric System No � + � �Zmodem Send Command %!dsz portx %u,� + � �Local Photo Viewer dvpeg %f � + � �Registration Number UNREGISTERED � + ����������������������������������������������������������ͼ + +System Name +----------- +The most important option in this program is your System Name (BBS Name). If +you are running Synchronet BBS Software, this option does not have to be set +here (it is automatically passed to SMM in the XTRN.DAT drop file from +Synchronet). If it is set, it will override the name specified in SCFG->System +->BBS Name. + +If you have registered SMM for non-Synchronet BBS Software, this option must be +set to the exact BBS name you registered SMM for (not case sensitive). + +Once you have setup SMM and your BBS users have entered their profiles, it is +important that you DO NOT change your BBS name, or you will lose those +profiles (and likely upset your users). If you are networking your match maker +database with other BBSs, it is important that you do not have the same System +Name as another BBS in the network. Only the first 25 characters of the BBS +name are used and every BBS in an SMM network must have a unique BBS name. Your +System Name (configured in SMMCFG) does not have to match your actual BBS name +(as configured in your BBS software). This allows you to change your System +Name for match maker networks where your real BBS name is already in use. + +Profile Database Security +------------------------- + �����������������������������������������������ͻ + � Profile Database Security � + ����������������������������������������������� + � �Minimum User Age to Add Profile 15 � + � �Minimum User Age to Take Purity Test 18 � + � �Minimum Security Level to Add Profile 30 � + � �Required Flags (Set 1) to Add Profile � + � �Required Flags (Set 2) to Add Profile � + � �Required Flags (Set 3) to Add Profile � + � �Required Flags (Set 4) to Add Profile � + �����������������������������������������������ͼ + +The Profile Database Security sub-menu allows you to define who can add +profiles by security level, age, and flags as well as the minimum age for +the purity test. Flag sets 2-4 are used only with Synchronet BBS software. + +Minimum Levels +-------------- +From the SMMCFG main menu you can change the minimum levels required to +send telegrams, write on the wall, read questionnaires, and perform sysop +functions. + +Minor Segregation (Protection) Age +---------------------------------- +This option separates all users into Minors (those users below the specified +age) and Adults (those users at or above the specified age). When this option +is used, adults cannot see minors' profiles or send them telegrams (and vice +versa). This feature does not keep adult users on other non-segregated +networked BBSs from sending telegrams to minors on your BBS (or minors on other +BBSs from sending telegrams to adults on your BBS) - this can lead to confusion +among users receiving telegrams from users that don't appear to be in the +database (due to segregation on your system). This option is disabled by +default. + +Auto-Update Profiles +-------------------- +This option allows you to change the number of days between automatic +profile updates across a match maker network. Normally a user's profile will +not be sent out across the network unless the user makes a change to their +profile. This option allows you to have their profile automatically sent +every so many days as long as the user is active in the match maker (enters +the match maker and uses it). This is useful for keeping profile databases +up-to-date across the network as new systems come online. Setting this option +to 0 disables this feature. The default value (30) should be fine for most +configurations. + +Notify User of Activity +----------------------- +This is the number of the user who will be notified of match maker activity +(profiles added, telegrams sent, wall writings, etc). Normally this option will +be set to 1 (for user #1, the sysop). Setting this option to 0 disables this +feature. + +Use Metric System +----------------- +If you want all heights and weights to be displayed in centimeters and +kilograms instead of inches and pounds, set this option to "Yes". Since all +measurements are internally stored in inches and pounds, those (English) +measurements are the most accurate. Some measurements may change slightly +when converting from metric to English and back. + +Zmodem Send Command +------------------- +This is the command line to execute to send a file via Zmodem to the remote +user. The default command line (%!dsz portx %u,%i sz %f) should work for most +system configurations (assuming DSZ is in your Synchronet EXEC directory or +DOS search path and using UART serial ports on all nodes). The percent codes +in the command line are called "Command Line Specifiers" and are explained +later in this document. + +Local Photo Viewer +------------------ +This is the command line to execute to view photos when running SMM locally. +The percent codes in the command line are called "Command Line Specifiers" and +are explained later in this document. + +Command Line Specifiers +----------------------- +%A User name +%B Baud (DTE) Rate +%C Connect (DCE) Rate +%F File path +%G Temp directory (blank if non-SBBS) +%I UART IRQ Line +%J DATA directory (blank if non-SBBS) +%K CTRL directory (blank if non-SBBS) +%N Node Directory (blank if non-SBBS) +%O Sysop's name +%P COM Port +%Q System QWK ID (blank if non-SBBS) +%R Users Screen Rows +%S File Spec +%T Time left in seconds +%U UART I/O Address (in hex) +%W Time-slice API type +%Z TEXT Directory (blank if non-SBBS) +%! EXEC Directory (blank if non-SBBS) +%# Node number +%* Node number (zero padded to three digits) +%$ Credits +%% %% for percent sign +%1 User number +%2 User number (zero padded to two digits) +%3 User number (zero padded to three digits) +%4 etc.. + +SMM.CAN +------- + +The trash can file (SMM.CAN) can be used to specify a list of words or word +combinations (one word or word combination per line) that will not be allowed +in user information and wall entries. + +QUE.LST +------- + +The questionnaire list file (QUE.LST) can be edited with any ASCII text editor. +The following is the stock QUE.LST containing the four stock questionnaires. + +BASIC +Basic Personality +0 +APPEAR +Appearance +0 +MATERIAL +Material +0 +ADULT +Adult Sexuality +18 + +For each questionnaire, a code (up to eight valid DOS filename chars), +a description (up to 25 chars), and minimum age are specified. A maximum +of five questionnaires can be configured. If you are linked to the Synchronet +Data echo, it is suggested you leave the four stock questionnaires intact +(unmodified). If you change any of these questionnaires, you MUST change the +code to something other than "BASIC, APPEAR, MATERIAL, or ADULT" as these codes +are reserved specifically for the stock questionnaires. If you are not linked +to the Synchronet Data echo, you can modify and remove any questionnaires you +wish and use whatever code you wish except "PURITY" and "MB-TYPE" as these +questionnaire names are specifically reserved by the Match Maker. + +The questionnaires are stored in files with the code for the name and .QUE +as the file extension (e.g. BASIC.QUE, APPEAR.QUE, MATERIAL.QUE, etc). + +*.QUE Format +------------ + +A: First line is total number of questions (max: 20). + All lines following are question and answers groups. + +B: Each group starts with the actual question (max: 79 characters). + +C: The next line in the group consists of the total number of answers + (max: 16). + +D: The next line consists of the maximum number of answers this user can select + for this question. + +E: A single line for each answer (total answers from line C). + +F: Repeat lines B-E for each question (total questions from line A). + +Special Questionnaire Files +--------------------------- + +Two questionnaire files (MB-TYPE.QUE and PURITY.QUE) are unique in that they +don't follow the above format at all and should need no modification. + +The MB-TYPE.QUE is used for the Myers-Briggs personality test and is a pretty +standard questionnaire. The files MB-*.ASC are descriptions of the various +personality types. The file MB-INTRO.ASC is displayed before the test and +MB-TYPE.ASC is displayed when seeking descriptions of the various types. + +The PURITY.QUE is used for the purity test and the format is simply one +"Have you ever" question per line. The default PURITY.QUE is a 100 question +test of an adult nature. An optional 500 question purity test is also included +as PURITY.500. To use this test in place of the 100 question version, copy +PURITY.500 to PURITY.QUE. The 100 question version is also included as +PURITY.100 as a back-up, in case you want to return to the 100 question +version. The PURITY*.ASC files are displayed before and during the testing +procedure. + +Sysop Commands +============== + +From the Match Maker main menu, the sysop (any user with sysop security level) +can use the (D)elete command to remove any profile from the database. Profiles +can be undeleted with the '*' command (available only to sysops). + +When viewing profiles, sysops are shown the user name, number, and system +name at the top of the profile. Normal users are not shown this information +to maintain the anonymity of the users in the database. + +Hitting '!' will display a list of all networked BBSs that have contributed to +the current profile database. If you see your BBS name in the list, either +someone else is using the same BBS name as you (which is bad), or something has +gone wrong in your network and you should contact Digital Dynamics to remedy +the situation immediately. If someone else is using the exact same BBS name +(not considering upper/lower case differences), one of you must change your BBS +name by at least one character or you will definitely have problems with your +users' Match Maker profiles and telegrams. + +Hitting '\' will rebuild the database index. If your database is corrupted, +you should down all your nodes and use SMMUTIL instead of this command. If +your SMM.IXB file disappears or becomes out-of-sync with your SMM.DAB file +(which is unlikely to occur), you can use this command to quickly recreate +it. + +Photographs +=========== + +You may use the included ADDPHOTO.EXE utility to import photographs into your +local match maker database. The current directory must be the directory where +SMM is installed when ADDPHOTO is run. The usage is: + +ADDPHOTO filename.ext user_number system_name + +where filename.ext is the path, filename, and extension of the photograph file +to import (preferably, but not necessarily, a JPEG file with a .JPG extension). +User_number is the user's number and system_name is the name of the system the +user created their profile on. + +ADDPHOTO will create a directory called PHOTO off of the directory where SMM +is installed (e.g. C:\SBBS\XTRN\SMM\PHOTO or C:\BBS\DOORS\SMM\PHOTO) and move +the photograph file into this directory (changing the name, but leaving the +extension (e.g. JPG, GIF, TIF, etc) intact. + +Example: + + ADDPHOTO JAMIEFAR.JPG 1 M.A.S.H BBS + +The DELPHOTO.EXE utility is used to remove photographs from your local match +maker database. The usage is: + +DELPHOTO user_number system_name + +Example: + DELPHOTO 1 M.A.S.H BBS + +The LSTPHOTO.EXE utility may be used to create a list of all users with photos +in your local match maker database. + +Example: + LSTPHOTO > PHOTO.LST + +PHOTO.ZIP +--------- +You can optionally, zip (using PKZIP) all the files in the PHOTO directory +into a file called PHOTO.ZIP (in the SMM directory) and delete them from the +PHOTO directory (to save disk space). When the photo is viewed or downloaded +from SMM, it will be automatically extracted from the PHOTO.ZIP into the PHOTO +directory (PKUNZIP.EXE must be in your DOS search path or your Synchronet +EXEC directory). The ADDPHOTO utility will not automatically add new images to +the PHOTO.ZIP (if you wish to use that storage method). Also, the files will +not be automatically deleted from the PHOTO directory after download/viewing +in SMM. This is so that popular image files will not have to be extracted each +time. You may wish to periodically re-zip and delete the PHOTO directory +(perhaps with an event) to preserve disk space. + +SYNCDATA Echo +------------- +If your match maker is linked (via DOVE-Net or FidoNet) to the SYNCDATA echo, +you do not need a scanner or the ADDPHOTO utility to get your users' photos +into the database. Simply have your users send their photos along with your +full and correct BBS name, their user number, and a xerox-copy of a current +formal photo-ID (to verify identity only, IDs will not be scanned and all +ID information will remain completely confidential) to Digital Dynamics. + +The photos must have a 2 inch square drawn around the area to be scanned. The +photos will be scanned and distributed in JPEG format (with monthly +redistribution) on the SYNCDATA echo by Digital Dynamics. This service is +available to all users of SMM free of charge (this free offer _may_ expire +on Feb 14th, 1996). + +Digital Dynamics reserves the right to refuse to scan and distribute any +photos for any reason. Nudity or vulgarities will not be allowed. + +Photos and IDs included with a self-addressed _stamped_ enveloped will be +returned. + +DEMO Version +============ + +The unregistered "DEMO" version of Synchronet Match Maker will not allow +users to send Telegrams to other users in the database (through the +message network), write on the Match Maker wall, or read other users' +questionnaires. + +To register your copy of Synchronet Match Maker, complete the ORDER.TXT form +included in this archive/directory and send it to Digital Dynamics, or call +714-529-6328 (voice) or 714-529-9525 (BBS) to order with a credit card for +faster processing. + +/* End of SMM.DOC */ diff --git a/xtrn/smm/smm_help.asc b/xtrn/smm/smm_help.asc new file mode 100644 index 0000000000000000000000000000000000000000..c969ab434c583892813e19e505d1801208d2a3b4 --- /dev/null +++ b/xtrn/smm/smm_help.asc @@ -0,0 +1,27 @@ +yhOverall Match (General Explanation):nc + +The overal match is a highly refined algorithm used to compute a percentage of +preference match between a user and a prospective mate. The user's preferences +are weighed more heavily than those of the prospective mate. More specific +preferences will result in a higher match percentage potential and a wider +range of match percentages. More vague preferences will result in a rather +narrow range of match percentages, so it is best to keep your "hideal matenc" +in mind when completing the preferred mate sections of your profile and +questionnaires. + +yhGlobal Database:nc + +If your sysop has taken the steps to link this profile database with the +international hSyncDatanc network, your profile will be automatically included +in this global database for users on other BBSs around the world to view. The +profiles you see in this database may very well be users in other counties, +states, or countries and you can view their information here and communicate +with them via hTelegramnc using this program. + +yhCredits:nc + +hPurity Test ncOriginal version from MIT's Baker House. + +hMyers-Briggs Type Indicator ncAdapted from the book "Please Understand Me" + by David Keirsey and Marilyn Bates + diff --git a/xtrn/smm/smm_logo.asc b/xtrn/smm/smm_logo.asc new file mode 100644 index 0000000000000000000000000000000000000000..c60c944dfc74384bdf6b04a08c09052ee0472738 --- /dev/null +++ b/xtrn/smm/smm_logo.asc @@ -0,0 +1,3 @@ + nhrn h7������������������������������������������������n hr + n k7nk7 nk7Find your mate or just a date, electronically! n hr + nhrn hk7������������������������������������������������n hrn diff --git a/xtrn/smm/smm_main.asc b/xtrn/smm/smm_main.asc new file mode 100644 index 0000000000000000000000000000000000000000..b453ada7f35f8c3dd8a0d094f263283b686a7c32 --- /dev/null +++ b/xtrn/smm/smm_main.asc @@ -0,0 +1,9 @@ +� nk7������������������������������������������������������������������0 +� 7 b[hRnb7] Read Profiles [hHnb7] Help/Info hk�0 +� 7 nb7[hLnb7] List Profiles [hMnb7] Myers-Briggs Types hk�0 +� 7 nb7[hUnb7] Update Your Profile [hPnb7] Toggle Screen Pause hk�0 +� 7 nb7[hDnb7] Delete Your Profile [hTnb7] Read Telegrams hk�0 +� 7 nb7[hNnb7] Scan for New Profiles [hSnb7] Send Telegrams hk�0 +� 7 nb7[hGnb7] Go to a Specific Profile [hVnb7] Visit the Wall hk�0 +� 7 nb7[hFnb7] Find Text in Profiles [hOnb7] Log-off (Hang-up) hk�0 +� nk7�h������������������������������������������������������������������n diff --git a/xtrn/smm/upgrade.doc b/xtrn/smm/upgrade.doc new file mode 100644 index 0000000000000000000000000000000000000000..be87c35f6229bc64df1869b8e140df213115ec87 --- /dev/null +++ b/xtrn/smm/upgrade.doc @@ -0,0 +1,241 @@ +Upgrading from Synchronet Match Maker +------------------------------------- + +If you are a registered owner of SMM and upgrading from v1.10 or earlier, +you'll need to optain your registration number from Digital Dynamics by calling +voice at 714-529-6328. You will need to have your Synchronet registration +number and control code on hand when you call. + +The most important change (in upgrading to v2.0) is to change "Intercept +I/O Interrupts" in SCFG from "Yes" to "No". Example: + + ����������������������������������������������������������ͻ + � Synchronet Match Maker � + ���������������������������������������������������������� + � �Name Synchronet Match Maker � + � �Internal Code SMM � + � �Start-up Directory ..\XTRN\SMM � + � �Command Line smm � + � �Clean-up Command Line � + � �Multiple Concurrent Users Yes � + � �Intercept I/O Interrupts No <-- Important � + � �Swap BBS out of Memory Yes � + � �Modify User Data Yes � + � �Execute on Event No � + � �BBS Drop File Type Synchronet XTRN.DAT � + � �Place Drop File In Node Directory � + ����������������������������������������������������������ͼ + +The only files you need to update when converting from v2.01/2.02 to v2.10 are: + +SMM.DOC Sysop Documentation (v2.10) +SMM.EXE Match Maker Program (v2.10) +SMMCFG.EXE Match Maker Configuration Program (v2.10) +SMMUTIL.EXE Repair/Maintenance Program (v2.01) + +The only files you need to update when converting from v2.00 to v2.10 are: + +SMM.DOC Sysop Documentation (v2.10) +SMMCFG.EXE Match Maker Configuration Program (v2.10) +SMMUTIL.EXE Repair/Maintenance Program (v2.01) +SMB2SMM.EXE Import Program (v2.01) +SMM2SMB.EXE Export Program (v2.01) +ADDPHOTO.EXE Import Photographs locally (v1.01) +DELPHOTO.EXE Delete Photographs locally (v1.00) +LSTPHOTO.EXE List Profiles with Photographs (v1.00) + +The only files you need to update when converting from v1.x to v2.0 are: + +*.EXE Executables +*.DOC Documentation +LIST_HDR.ASC Condensed Listing Header + +If upgrading from v1.00 or v1.10, you will also need to update the following +files: + +SMM_MAIN.ASC Main Menu +SMM_HELP.ASC Help Screen (if upgrading from v1.00) +PURITY.ASC Purity Explanation (if upgrading from v1.00) + +New in version 2.10 +~~~~~~~~~~~~~~~~~~~ +o Minor segregation (protection) now supported. This option separates all users + into Adults and Minors (configurable separation age), disallowing adults to + see minors' profiles or send them telegrams (and vice versa) +o Minimum Age to access the wall now configurable in SMMCFG +o XSDK v2.42 feature: Ctrl-T now displays current time, time used, and time + left (similar to SBBS) +o XSDK v2.42 feature: User is now warned on each of their last 5 minutes left + +New in version 2.02a +~~~~~~~~~~~~~~~~~~~~ +o Fixed bug in SMM.EXE when using DOOR.SYS (non-Synchronet BBSs) + +New in version 2.02 +~~~~~~~~~~~~~~~~~~~ +o Low priority input now correctly supported (for giving up multitasker time + slices even while accepting string input from the user) - this was an + indirect bug fix in XSDK v2.41 most notably effecting OS/2 systems +o "Searching..." text now displayed before possibly long searches to indicate + to the user the system is not crashed +o Sysop text searches now search user real names, system names and user numbers + in addition to the normal user-viewable text fields + +New in version 2.01 +~~~~~~~~~~~~~~~~~~~ +o New DELPHOTO.EXE utility to delete photos from the database +o New LSTPHOTO.EXE utility to create a list of all profiles with attached + photos +o SMB2SMM/SMM2SMB updated to detect and not import/export corrupted profiles +o ADDPHOTO 1.01 now copies (instead of renames/moves) photo image files +o SMB2SMM no longer deletes existing photo if CRC error detected on new photo +o Wall security level (configured in SMMCFG) now correctly keeps users below + that level from writing on the wall +o FOSSIL channel number automatically determined by subtracting 1 from the + COM port number (e.g. COM 1 is FOSSIL/Digi channel 0) + /I command line switch may be used to set non-standard channel +o New SMM, SMMCFG, and SMMUTIL fix 25 character BBS name limit +o SMMUTIL (v2.00) now removes old photos (tallys photos and networked profiles) + +New in version 2.00 +~~~~~~~~~~~~~~~~~~~ +o Optionally reads from and writes to DOOR.SYS drop file + (for compatibility with other [non-Synchronet] BBS programs) +o MSG, UTI, and possibly JAM message base import/export utilities will be + available soon (for match maker networking with non-SMB compatible BBSs) +o Optional command line switches for com port configuration and time-slice APIs + (for non-standard COM ports with other BBS programs) +o Photographs (in any size or format) can be added to the database locally + (with Zmodem download and local viewing) +o Photographs are automatically imported from the SYNCDATA echo with SMB2SMM + (other match maker networks will need to use their own distribution methods) +o System name separately configurable in SMMCFG (to work around duplicate BBS + names in a match maker network) +o Metric measurements (centimeters and kilograms) can be enabled in SMMCFG +o Sysop level defined in SMMCFG (no longer hard-coded at level 90) +o Low priority input supported (based on SCFG Node toggle option if Synchronet, + automatically enabled with other BBS programs) +o Trailing spaces from user names are automatically removed + +New in version 1.31 +~~~~~~~~~~~~~~~~~~~ +o Ability to specify a user to search for on the command line + displays extended profile on the user and then exits (just "SMM user name") +o Messages can now be sent from Digital Dynamics to you (sysops, users, or + both) inside SMM (not telegrams, but similar) to inform sysops and users of + Match Maker progressions/news. All messages have pre-determined expiration + dates and will automatically disappear when the date is reached. Sysop-only + messages can be deleted immediately after they are read if the sysop wishes. + Special ONE-time messages are displayed to users only once, while others + may be displayed each time they enter SMM. (SMB2SMM v1.30 required) +o New SMMUTIL (v1.15) fixes 4095 user limitation. + +New in version 1.30 +~~~~~~~~~~~~~~~~~~~ +o Ability to send telegrams directly from condensed user listings +o Wall new-scans now correctly scan by date/time imported instead of the + date/time written (must use SMB2SMM 1.22, SMM2SMB 1.12, and SMMUTIL 1.14) +o Condensed Wall listings now clear the screen between each screen-full + (faster screen draws) with a prompt allowing the user to read a profile, + send a telegram, move backwards through the wall writings, or quit at the + bottom of each screen-full (more intuitive and convenient) +o Extended Wall listings now display wall writing in magenta if the author + is female, green if the author is male (instant gender recognition) + wall writings who can't be found in the database +o Extended Wall listings allow sending telegrams directly (without reading + profile first) and moving backwards through the wall writings +o Extended Wall listings stay on current wall writing after reading profile + or sending telegram +o XSDK v2.33 fixes problem with flashing screen loops when a user hangs up + with keys in the modem buffer +o XSDK v2.33 fixes problem with sending double carriage returns at the end + of each line (making captures difficult) +o Fixed problem with selecting races above E +o If the sysop hits '!' from the main menu, all systems connected to the + database are listed +o When reading a user's questionnaire, (P)revious and (Q)uit commands are now + available on the pause prompt +o Updated sysop documentation + +New in version 1.22 +~~~~~~~~~~~~~~~~~~~ +o New option for those seeking "any-sex non-romantic friendly matches" allows + matches with both romantic/intimate mates and non-romantic mates (friends) +o When displaying long user information, preference ranges (age, weight, etc) + and specifics (hair color, marital status, etc) are high intensity (bright + colors) if the preferencees are considered requirements by the user +o The Wall was revamped to allow new-scans for new writings since a specific + date only and optional display of extended user information allowing reading + of questionnaires and sending of telegrams +o Wall writings will now disallow any text in SMM.CAN (same as user aliases + profiles, etc.) + +New in version 1.21 +~~~~~~~~~~~~~~~~~~~ +o Credits can be charged or given for reading questionnaires +o New WALL inside Match Maker for public discussion +o Credits can be charged or given for writing on the wall +o Minimum level can be specified to allow writing on the wall +o SMM2SMB v1.11 now creates unique profile messages that won't be deleted by + duplicate message checking +o SMM2SMB v1.11 and SMB2SMM v1.21 read/write wall writings from message base +o SMMUTIL v1.11 now allows command line specification of maximum wall writing + age before auto-deletion +o Telegrams and Profile Personal Text no longer word wrap on last line (bugfix) +o Telegrams now ask to Save (Y/n) when completed to allow last minute abort + +New in version 1.20 +~~~~~~~~~~~~~~~~~~~ +o DEMO and registered versions use the same executable files, unlocked with + registration number obtained from Digital Dynamics (entered in SMMCFG) +o Minimum level can be specified to allow the sending of telegrams +o Minimum level can be specified to allow the reading of questionnaires +o Sysops deleting their own profile, will not have to exit and re-enter + before SMM will report their profile does not exist +o Match Maker telegrams are stored in SMM and users are notified via BBS + telegram of newly received SMM telegrams +o Users can read awaiting telegrams and send telegrams from the SMM main menu +o New customizable main menu (SMM_MAIN.ASC) +o (W)rite Profile command changed to (U)pdate Profile, although 'W' can still + be used +o When sending telegrams, the destination user's detail is displayed to prevent + users from sending telegrams to a wrong user (with the same name) +o Automatically corrects user sex when not set to (M)ale or (F)emale +o Questionnaire answers are aligned so they can be visually compared easily +o SMMUTIL v1.10 generates statistics, run "SMMUTIL > stats.txt" to create file + for display on your BBS + +New in version 1.10 +~~~~~~~~~~~~~~~~~~~ +o New configuration program (SMMCFG) instead of editing SMM.CFG with an + ASCII editor. +o Optional trash can file for keeping users from using profanity in profiles + and users names. +o SMB2SMM will not import profiles if the user age is less than you have + specified in SMMCFG for minimum user age. +o SMB2SMM will not import profiles that contains words found in your TRASH.CAN + file (if it exists). +o When listing profiles in SMM, you can go backwards to previous screens and + read profiles directly from the listing. The (R)ead profile key automatically + puts the user with the highest percentage on the current screen in the + user name field. +o User's can enter "Non-disclosed" for their yearly income, by hitting ENTER + when asked. +o User's can specify if they REQUIRE their matches to fall within certain + ranges or REQUIRE specific features. +o Profile screens were condensed to get all information on one page whenever + possible. +o SMMUTIL will scan for duplicate profiles or if specified, delete profiles + that haven't been updated in a certain number of days. SMMUTIL also + automatically condenses the data file, removing any deleted profiles and + rebuilds the index file. +o Users can be charged credits or given credits for adding profiles and + sending telegrams. If a user adds a profile and then deletes it, the credit + charges are reversed. +o Auto-update feature will automatically re-hatch a users entry into the + Global Database after a certain number of days, if the user is active in + the match maker but hasn't made any profile changes. +o Sysop can be notified automatically of added profiles and sent telegrams + from the match maker + +/* End of UPGRADE.DOC */