Annotation of sbbs/sbbs2/smm/smm.c, revision 1.1.1.2

1.1       root        1: /* SMM.C */
                      2: 
                      3: /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */
                      4: 
                      5: /* Synchronet Match Maker */
                      6: 
                      7: #include "xsdk.h"
                      8: #include "crc32.h"
                      9: #include "smmdefs.h"
                     10: #include "smmvars.c"
                     11: 
                     12: /* RCIOLL.ASM */
                     13: 
                     14: int  rioini(int com,int irq);          /* initialize com,irq */
                     15: int  setbaud(int rate);                /* set baud rate */
                     16: int  rioctl(int action);               /* remote i/o control */
                     17: int  dtr(char onoff);                  /* set/reset dtr */
                     18: int  outcom(int ch);                   /* send character */
                     19: int  incom(void);                      /* receive character */
                     20: int  ivhctl(int intcode);              /* local i/o redirection */
                     21: 
                     22: /************************/
                     23: /* Remote I/O Constants */
                     24: /************************/
                     25: 
                     26:                                                        /* i/o mode and state flags */
                     27: #define CTSCK 0x1000           /* check cts (mode only) */
                     28: #define RTSCK 0x2000           /* check rts (mode only) */
                     29: #define TXBOF 0x0800           /* transmit buffer overflow (outcom only) */
                     30: #define ABORT 0x0400           /* check for ^C (mode), aborting (state) */
                     31: #define PAUSE 0x0200           /* check for ^S (mode), pausing (state) */
                     32: #define NOINP 0x0100           /* input buffer empty (incom only) */
                     33: 
                     34:                                                        /* status flags */
                     35: #define RIODCD 0x80            /* DCD on */
                     36: #define RI             0x40            /* Ring indicate */
                     37: #define DSR    0x20            /* Dataset ready */
                     38: #define CTS    0x10            /* CTS on */
                     39: #define FERR   0x08            /* Frameing error */
                     40: #define PERR   0x04            /* Parity error */
                     41: #define OVRR   0x02            /* Overrun */
                     42: #define RXLOST         0x01            /* Receive buffer overflow */
                     43: 
                     44: /* rioctl() arguments */
                     45: /* returns mode or state flags in high 8 bits, status flags in low 8 bits */
                     46: 
                     47:                                                        /* the following return mode in high 8 bits */
                     48: #define IOMODE 0               /* no operation */
                     49: #define IOSM 1                 /* i/o set mode flags */
                     50: #define IOCM 2                 /* i/o clear mode flags */
                     51:                                                        /* the following return state in high 8 bits */
                     52: #define IOSTATE 4              /* no operation */
                     53: #define IOSS 5                 /* i/o set state flags */
                     54: #define IOCS 6                 /* i/o clear state flags */
                     55: #define IOFB 0x308             /* i/o buffer flush */
                     56: #define IOFI 0x208             /* input buffer flush */
                     57: #define IOFO 0x108             /* output buffer flush */
                     58: #define IOCE 9                 /* i/o clear error flags */
                     59: 
                     60:                                                        /* return count (16bit) */
                     61: #define RXBC   0x0a            /* get receive buffer count */
                     62: #define TXBC   0x0b            /* get transmit buffer count */
                     63: #define TXSYNC  0x0c        /* sync transmition (seconds<<8|0x0c) */
                     64: #define IDLE   0x0d            /* suspend communication routines */
                     65: #define RESUME  0x10d          /* return from suspended state */
                     66: #define RLERC  0x000e          /* read line error count and clear */
                     67: #define CPTON  0x0110          /* set input translation flag for ctrl-p on */
                     68: #define CPTOFF 0x0010          /* set input translation flag for ctrl-p off */
                     69: #define GETCPT 0x8010          /* return the status of ctrl-p translation */
                     70: #define MSR    0x0011          /* read modem status register */
                     71: #define FIFOCTL 0x0012         /* FIFO UART control */
                     72: #define TSTYPE 0x0013          /* Time-slice API type */
                     73: #define GETTST  0x8013      /* Get Time-slice API type */
                     74: 
                     75: 
                     76: #define I14DB  0x001d          /* DigiBoard int 14h driver */
                     77: #define I14PC  0x011d          /* PC int 14h driver */
                     78: #define I14PS  0x021d          /* PS/2 int 14h driver */
                     79: #define I14FO   0x031d      /* FOSSIL int 14h driver */
                     80: 
                     81: 
                     82:                                                        /* ivhctl() arguments */
                     83: #define INT29R 1               /* copy int 29h output to remote */
                     84: #define INT29L 2                       /* Use _putlc for int 29h */
                     85: #define INT16  0x10            /* return remote chars to int 16h calls */
                     86: #define INTCLR 0            /* release int 16h, int 29h */
                     87: 
                     88: #define CLREOL         256     /* Character to erase to end of line            */
                     89: #define HIGH        8       /* High intensity for curatr             */
                     90: 
                     91: extern uint riobp;
                     92: extern int mswtyp;
                     93: 
                     94: unsigned _stklen=16000;        /* Set stack size in code, not header */
                     95: 
                     96: int cbreakh(void);                     /* ctrl-break handler */
                     97: 
                     98: char getage(char *birth);
                     99: char long_user_info(user_t user);
                    100: void main_user_info(user_t user);
                    101: 
                    102: char *nulstr="";
                    103: char *wday[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
                    104: char *mon[]={"Jan","Feb","Mar","Apr","May","Jun"
                    105:             ,"Jul","Aug","Sep","Oct","Nov","Dec"};
                    106: char tmp[256],door_sys[128];
                    107: 
                    108: char io_int=0;
                    109: struct date date;
                    110: struct time curtime;
                    111: time_t now;
                    112: int smm_pause=1,node_scrnlen;
                    113: questionnaire_t *que[5];
                    114: int total_ques;
                    115: user_t useron,tmpuser;
                    116: ixb_t ixb;
                    117: ulong useron_record,system_crc;
                    118: FILE *stream,*index,*trashfile;
                    119: 
                    120: char *PrevReadSendQuitOrMore="\r\n\1n\1b\1h[\1cP\1b]revious screen, "
                    121:        "[\1cR\1b]ead profile, [\1cS\1b]end telegram, [\1cQ\1b]uit, or "
                    122:        "[\1cM\1b]ore: \1w";
                    123: 
                    124: int intocm(int in)
                    125: {
                    126: return(in*2.538071);
                    127: }
                    128: 
                    129: int cmtoin(int cm)
                    130: {
                    131:        int i;
                    132: 
                    133: i=cm*0.394;
                    134: if(((float)cm*0.394)-(float)i>=.5)
                    135:        i++;
                    136: return(i);
                    137: }
                    138: 
                    139: int kgtolp(int kg)
                    140: {
                    141: return(kg*2.2046);
                    142: }
                    143: 
                    144: int lptokg(int lp)
                    145: {
                    146:        int i;
                    147: 
                    148: i=lp*0.453597;
                    149: if(((float)lp*0.453597)-(float)i>=.5)
                    150:        i++;
                    151: return(i);
                    152: }
                    153: 
                    154: /****************************************************************************/
                    155: /* Performs printf() through local assembly routines                        */
                    156: /* Called from everywhere                                                   */
                    157: /****************************************************************************/
                    158: int lprintf(char *fmat, ...) {
                    159:        char sbuf[256];
                    160:        int chcount;
                    161: 
                    162: chcount=vsprintf(sbuf,fmat,_va_ptr);
                    163: lputs(sbuf);
                    164: return(chcount);
                    165: }
                    166: 
                    167: /*****************************************************************************/
                    168: /* Returns command line generated from instr with %c replacments             */
                    169: /*****************************************************************************/
                    170: char *cmdstr(char *instr, char *fpath, char *fspec, char *outstr)
                    171: {
                    172:        static char static_cmd[128];
                    173:        char str[256],str2[128],*cmd;
                    174:     int i,j,len;
                    175: 
                    176: if(outstr==NULL)
                    177:        cmd=static_cmd;
                    178: else
                    179:        cmd=outstr;
                    180: len=strlen(instr);
                    181: for(i=j=0;i<len && j<128;i++) {
                    182:     if(instr[i]=='%') {
                    183:         i++;
                    184:         cmd[j]=0;
                    185:         switch(toupper(instr[i])) {
                    186:             case 'A':   /* User alias */
                    187:                                strcat(cmd,user_name);
                    188:                 break;
                    189:             case 'B':   /* Baud (DTE) Rate */
                    190:                                strcat(cmd,ultoa(com_rate,str,10));
                    191:                 break;
                    192:             case 'C':   /* Connect Description */
                    193:                                strcat(cmd,ultoa(user_dce,str,10));
                    194:                 break;
                    195:             case 'F':   /* File path */
                    196:                 strcat(cmd,fpath);
                    197:                 break;
                    198:             case 'G':   /* Temp directory */
                    199:                                strcat(cmd,temp_dir);
                    200:                 break;
                    201:             case 'I':   /* UART IRQ Line */
                    202:                 strcat(cmd,itoa(com_irq,str,10));
                    203:                 break;
                    204:             case 'J':
                    205:                                strcat(cmd,data_dir);
                    206:                 break;
                    207:             case 'K':
                    208:                                strcat(cmd,ctrl_dir);
                    209:                 break;
                    210:             case 'N':   /* Node Directory (same as SBBSNODE environment var) */
                    211:                 strcat(cmd,node_dir);
                    212:                 break;
                    213:             case 'O':   /* SysOp */
                    214:                 strcat(cmd,sys_op);
                    215:                 break;
                    216:             case 'P':   /* COM Port */
                    217:                                strcat(cmd,itoa(com_port,str,10));
                    218:                 break;
                    219:             case 'Q':   /* QWK ID */
                    220:                 strcat(cmd,sys_id);
                    221:                 break;
                    222:             case 'R':   /* Rows */
                    223:                                strcat(cmd,itoa(user_rows,str,10));
                    224:                 break;
                    225:             case 'S':   /* File Spec */
                    226:                 strcat(cmd,fspec);
                    227:                 break;
                    228:             case 'T':   /* Time left in seconds */
                    229:                                strcat(cmd,itoa(time(NULL)-starttime,str,10));
                    230:                 break;
                    231:             case 'U':   /* UART I/O Address (in hex) */
                    232:                 strcat(cmd,itoa(com_base,str,16));
                    233:                 break;
                    234:             case 'W':   /* Time-slice API type (mswtype) */
                    235: #ifndef __OS2__
                    236:                 strcat(cmd,itoa(mswtyp,str,10));
                    237: #endif
                    238:                 break;
                    239:             case '&':   /* Address of msr */
                    240:                                sprintf(str,"%lu",&riobp-1);
                    241:                 strcat(cmd,str);
                    242:                 break;
                    243:                        case 'Z':
                    244:                                strcat(cmd,text_dir);
                    245:                 break;
                    246:             case '!':   /* EXEC Directory */
                    247:                                strcat(cmd,exec_dir);
                    248:                 break;
                    249:             case '#':   /* Node number (same as SBBSNNUM environment var) */
                    250:                 sprintf(str,"%d",node_num);
                    251:                 strcat(cmd,str);
                    252:                 break;
                    253:             case '*':
                    254:                 sprintf(str,"%03d",node_num);
                    255:                 strcat(cmd,str);
                    256:                 break;
                    257:             case '$':   /* Credits */
                    258:                                strcat(cmd,ultoa(user_cdt,str,10));
                    259:                 break;
                    260:             case '%':   /* %% for percent sign */
                    261:                 strcat(cmd,"%");
                    262:                 break;
                    263:             default:    /* unknown specification */
                    264:                 if(isdigit(instr[i])) {
                    265:                                        sprintf(str,"%0*d",instr[i]&0xf,user_number);
                    266:                     strcat(cmd,str); }
                    267:                 break; }
                    268:         j=strlen(cmd); }
                    269:     else
                    270:         cmd[j++]=instr[i]; }
                    271: cmd[j]=0;
                    272: 
                    273: return(cmd);
                    274: }
                    275: 
                    276: char *base41(unsigned int i, char *str)
                    277: {
                    278:        char c;
                    279:        unsigned int j=41*41,k;
                    280: 
                    281: for(c=0;c<3;c++) {
                    282:        k=i/j;
                    283:        str[c]='0'+k;
                    284:        i-=(k*j);
                    285:        j/=41;
                    286:        if(str[c]>=':')
                    287:                str[c]='A'+(str[c]-':');
                    288:        if(str[c]>='[')
                    289:                str[c]='#'+(str[c]-'['); }
                    290: str[c]=0;
                    291: return(str);
                    292: }
                    293: 
                    294: /****************************************************************************/
                    295: /* Updates 16-bit "rcrc" with character 'ch'                                */
                    296: /****************************************************************************/
                    297: void ucrc16(uchar ch, ushort *rcrc) {
                    298:     ushort i, cy;
                    299:     uchar nch=ch;
                    300:  
                    301: for (i=0; i<8; i++) {
                    302:     cy=*rcrc & 0x8000;
                    303:     *rcrc<<=1;
                    304:     if (nch & 0x80) *rcrc |= 1;
                    305:     nch<<=1;
                    306:     if (cy) *rcrc ^= 0x1021; }
                    307: }
                    308: 
                    309: /****************************************************************************/
                    310: /* Returns 16-crc of string (not counting terminating NULL)                 */
                    311: /****************************************************************************/
                    312: ushort crc16(char *str)
                    313: {
                    314:     int     i=0;
                    315:     ushort  crc=0;
                    316: 
                    317: ucrc16(0,&crc);
                    318: while(str[i])
                    319:     ucrc16(str[i++],&crc);
                    320: ucrc16(0,&crc);
                    321: ucrc16(0,&crc);
                    322: return(crc);
                    323: }
                    324: 
                    325: 
                    326: int cdt_warning(long cdt)
                    327: {
                    328: if(cdt==0)
                    329:        return(1);
                    330: if(cdt>0) {
                    331:        bprintf("\1m\1hYou will receive \1w%luk\1m in credits for this action!\r\n"
                    332:                ,cdt/1024L);
                    333:        return(1); }
                    334: 
                    335: bprintf("\1m\1hThis action will cost you \1w%luk\1m in credits.",(-cdt)/1024L);
                    336: if(user_cdt+cdt_adjustment<-cdt) {
                    337:        bprintf("\r\n\r\n\1r\1hSorry, you only have \1w%luk\1m in credits.\r\n"
                    338:                ,(user_cdt+cdt_adjustment)/1024L);
                    339:        return(0); }
                    340: return(!noyes(" Continue"));
                    341: }
                    342: 
                    343: void adjust_cdt(long cdt)
                    344: {
                    345: if(cdt==0)
                    346:        return;
                    347: cdt_adjustment+=cdt;
                    348: }
                    349: 
                    350: int got_flags(char *req, char *got)
                    351: {
                    352:        int i,j;
                    353: 
                    354: for(i=0;req[i];i++) {
                    355:        for(j=0;got[j];j++)
                    356:                if(req[i]==got[j])
                    357:                        break;
                    358:        if(!got[j])
                    359:                break; }
                    360: if(!req[i])
                    361:        return(1);
                    362: return(0);
                    363: }
                    364: 
                    365: int can_add()
                    366: {
                    367:        uchar age=getage(user_birth);
                    368: 
                    369: if(user_level<min_level || (age && getage(user_birth)<min_age)
                    370:        || !got_flags(req_flags1,user_flags1)
                    371:        || !got_flags(req_flags2,user_flags2)
                    372:        || !got_flags(req_flags3,user_flags3)
                    373:        || !got_flags(req_flags4,user_flags4)
                    374:        )
                    375:        return(0);
                    376: return(1);
                    377: }
                    378: 
                    379: 
                    380: int trash(char *instr)
                    381: {
                    382:        char str[128],word[128];
                    383: 
                    384: if(!trashfile)
                    385:        return(0);
                    386: strcpy(str,instr);
                    387: strupr(str);
                    388: rewind(trashfile);
                    389: while(!ferror(trashfile)) {
                    390:        if(!fgets(word,125,trashfile))
                    391:                break;
                    392:        truncsp(word);
                    393:        if(!word[0])
                    394:                continue;
                    395:        strupr(word);
                    396:        if(strstr(str,word))
                    397:                return(1); }
                    398: return(0);
                    399: }
                    400: 
                    401: long fdate_dir(char *filespec)
                    402: {
                    403:     struct ffblk f;
                    404:     struct date fd;
                    405:     struct time ft;
                    406: 
                    407: if(findfirst(filespec,&f,FA_RDONLY|FA_HIDDEN|FA_SYSTEM|FA_DIREC)==NULL) {
                    408:        fd.da_day=f.ff_fdate&0x1f;
                    409:        fd.da_mon=(f.ff_fdate>>5)&0xf;
                    410:        fd.da_year=1980+((f.ff_fdate>>9)&0x7f);
                    411:        ft.ti_hour=(f.ff_ftime>>11)&0x1f;
                    412:        ft.ti_min=(f.ff_ftime>>5)&0x3f;
                    413:        ft.ti_sec=(f.ff_ftime&0xf)*2;
                    414:     return(dostounix(&fd,&ft)); }
                    415: else return(NULL);
                    416: }
                    417: 
                    418: /****************************************************************************/
                    419: /* Generates a 24 character ASCII string that represents the time_t pointer */
                    420: /* Used as a replacement for ctime()                                        */
                    421: /****************************************************************************/
                    422: char *timestr(time_t *intime)
                    423: {
                    424:     static char str[256];
                    425:     char mer[3],hour;
                    426:     struct tm *gm;
                    427: 
                    428: gm=localtime(intime);
                    429: if(gm->tm_hour>=12) {
                    430:     if(gm->tm_hour==12)
                    431:         hour=12;
                    432:     else
                    433:         hour=gm->tm_hour-12;
                    434:     strcpy(mer,"pm"); }
                    435: else {
                    436:     if(gm->tm_hour==0)
                    437:         hour=12;
                    438:     else
                    439:         hour=gm->tm_hour;
                    440:     strcpy(mer,"am"); }
                    441: sprintf(str,"%s %s %02d %4d %02d:%02d %s"
                    442:     ,wday[gm->tm_wday],mon[gm->tm_mon],gm->tm_mday,1900+gm->tm_year
                    443:     ,hour,gm->tm_min,mer);
                    444: return(str);
                    445: }
                    446: 
                    447: 
                    448: void puttgram(int usernumber, char *strin)
                    449: {
                    450:        char str[256];
                    451:        int file,i;
                    452: 
                    453: sprintf(str,"%4.4u.MSG",usernumber);
                    454: if((file=nopen(str,O_WRONLY|O_CREAT|O_APPEND))==-1) {
                    455:        printf("\7Error opening/creating %s for creat/append access\n",str);
                    456:        return; }
                    457: i=strlen(strin);
                    458: if(write(file,strin,i)!=i) {
                    459:        close(file);
                    460:        printf("\7Error writing %u bytes to %s\n",i,str);
                    461:        return; }
                    462: close(file);
                    463: }
                    464: 
                    465: 
                    466: int send_telegram(user_t user)
                    467: {
                    468:        uchar str[256],line[256],buf[1024];
                    469:        int i;
                    470: 
                    471: if(!useron.number) {
                    472:        bputs("\r\n\1h\1rYou must create a profile first.\r\n");
                    473:        pause();
                    474:        return(1); }
                    475: 
                    476: if(user_level<telegram_level) {
                    477:        bputs("\r\n\1h\1rYou have insufficient access to send telegrams."
                    478:                "\r\n");
                    479:        pause();
                    480:        return(1); }
                    481: 
                    482: main_user_info(user);
                    483: CRLF;
                    484: if(!cdt_warning(telegram_cdt))
                    485:        return(0);
                    486: if(telegram_cdt)
                    487:        CRLF;
                    488: bprintf("\1n\1hSending a telegram to \1y%s\1w:\r\n\r\n"
                    489:        ,user.name);
                    490: now=time(NULL);
                    491: memset(buf,0,512);
                    492: sprintf(buf,"\1n\1c\1hMatch Maker\1b telegram from \1c%s\1b "
                    493:        "on %s:\1y\r\n"
                    494:        ,useron.name,timestr(&now));
                    495: for(i=0;i<5 && !aborted;i++) {
                    496:        bprintf("\1n\1h\1g%u of 5: \1n\1g",i+1);
                    497:        if(!getstr(line,70,i==4 ? K_MSG:K_MSG|K_WRAP))
                    498:                break;
                    499:        sprintf(str,"\1n\1g%4s%s\r\n",nulstr,line);
                    500:        strcat(buf,str); }
                    501: if(!i || aborted || !yesno("\r\nSave"))
                    502:        return(0);
                    503: if(!(user.misc&USER_FROMSMB)) {
                    504:        putsmsg(user.number,TGRAM_NOTICE);
                    505:        puttgram(user.number,buf); }
                    506: else {
                    507:        if((i=nopen("TELEGRAM.DAB",O_WRONLY|O_CREAT|O_APPEND|SH_DENYNO))
                    508:                ==-1) {
                    509:                bprintf("\r\n\1r\1h\1iError writing telegram!\r\n");
                    510:                pause();
                    511:                return(1); }
                    512:        write(i,useron.system,sizeof(useron.system));
                    513:        write(i,user.system,sizeof(user.system));
                    514:        write(i,&user.number,sizeof(user.number));
                    515:        write(i,buf,512);
                    516:        close(i); }
                    517: adjust_cdt(telegram_cdt);
                    518: if(notify_user && notify_user!=user_number) {
                    519:        sprintf(str,"\1n\1hSMM: \1y%s\1m sent a telegram to \1y%s\1m "
                    520:                "from the Match Maker\r\n",user_name,user.name);
                    521:        if(node_dir[0])
                    522:                putsmsg(notify_user,str);
                    523:        else
                    524:                puttgram(notify_user,str); }
                    525: return(1);
                    526: }
                    527: 
                    528: /****************************************************************************/
                    529: /* Returns 32-crc of string (not counting terminating NULL)                            */
                    530: /****************************************************************************/
                    531: ulong crc32(char *str)
                    532: {
                    533:        int i=0;
                    534:        ulong crc=0xffffffffUL;
                    535: 
                    536:        while(str[i])
                    537:                crc=ucrc32(str[i++],crc);
                    538:        crc=~crc;
                    539:        return(crc);
                    540: }
                    541: 
                    542: 
                    543: /****************************************************************************/
                    544: /* Converts unix time format (long - time_t) into a char str MM/DD/YY          */
                    545: /****************************************************************************/
                    546: char *unixtodstr(time_t unix, char *str)
                    547: {
                    548: 
                    549: if(!unix)
                    550:        strcpy(str,"00/00/00");
                    551: else {
                    552:        unixtodos(unix,&date,&curtime);
                    553:        if((unsigned)date.da_mon>12) {    /* DOS leap year bug */
                    554:                date.da_mon=1;
                    555:                date.da_year++; }
                    556:        if((unsigned)date.da_day>31)
                    557:                date.da_day=1;
                    558:        sprintf(str,"%02u/%02u/%02u",date.da_mon,date.da_day
                    559:                ,date.da_year>=2000 ? date.da_year-2000 : date.da_year-1900); }
                    560: return(str);
                    561: }
                    562: 
                    563: /****************************************************************************/
                    564: /* Converts a date string in format MM/DD/YY into unix time format                     */
                    565: /****************************************************************************/
                    566: time_t dstrtounix(char *str)
                    567: {
                    568: 
                    569: if(!strcmp(str,"00/00/00") || !str[0])
                    570:        return(NULL);
                    571: curtime.ti_hour=curtime.ti_min=curtime.ti_sec=0;
                    572: if(str[6]<'7')
                    573:        date.da_year=2000+((str[6]&0xf)*10)+(str[7]&0xf);
                    574: else
                    575:        date.da_year=1900+((str[6]&0xf)*10)+(str[7]&0xf);
                    576: date.da_mon=((str[0]&0xf)*10)+(str[1]&0xf);
                    577: date.da_day=((str[3]&0xf)*10)+(str[4]&0xf);
                    578: return(dostounix(&date,&curtime));
                    579: }
                    580: 
                    581: /****************************************************************************/
                    582: /* Returns the age derived from the string 'birth' in the format MM/DD/YY      */
                    583: /****************************************************************************/
                    584: char getage(char *birth)
                    585: {
                    586:        char age;
                    587: 
                    588: if(birth[0]<=SP)
                    589:        return(0);
                    590: getdate(&date);
                    591: age=(date.da_year-1900)-(((birth[6]&0xf)*10)+(birth[7]&0xf));
1.1.1.2 ! root      592: if(age>90)
        !           593:        age-=90;
1.1       root      594: if(atoi(birth)>12 || atoi(birth+3)>31)
                    595:        return(0);
                    596: if(((birth[0]&0xf)*10)+(birth[1]&0xf)>date.da_mon ||
                    597:        (((birth[0]&0xf)*10)+(birth[1]&0xf)==date.da_mon &&
                    598:        ((birth[3]&0xf)*10)+(birth[4]&0xf)>date.da_day))
                    599:        age--;
                    600: if(age<0)
                    601:        return(0);
                    602: return(age);
                    603: }
                    604: 
                    605: char marital_ch(char user_marital)
                    606: {
                    607: switch(user_marital) {
                    608:        case MARITAL_SINGLE:
                    609:                return('S');
                    610:        case MARITAL_DIVORCED:
                    611:                return('D');
                    612:        case MARITAL_MARRIED:
                    613:                return('M');
                    614:        case MARITAL_WIDOWED:
                    615:                return('W');
                    616:        case MARITAL_OTHER:
                    617:                return('O'); }
                    618: if(user_marital)
                    619:        return('*');
                    620: return(SP);
                    621: }
                    622: 
                    623: char race_ch(char user_race)
                    624: {
                    625: switch(user_race) {
                    626:        case RACE_WHITE:
                    627:                return('W');
                    628:        case RACE_BLACK:
                    629:                return('B');
                    630:        case RACE_HISPANIC:
                    631:                return('H');
                    632:        case RACE_AMERINDIAN:
                    633:                return('I');
                    634:        case RACE_ASIAN:
                    635:                return('A');
                    636:        case RACE_MIDEASTERN:
                    637:                return('M');
                    638:        case RACE_OTHER:
                    639:                return('O'); }
                    640: if(user_race)
                    641:        return('*');
                    642: return(SP);
                    643: }
                    644: 
                    645: char *hair(char user_hair)
                    646: {
                    647: switch(user_hair) {
                    648:        case HAIR_BLONDE:
                    649:                return("BLN");
                    650:        case HAIR_BROWN:
                    651:                return("BRN");
                    652:        case HAIR_RED:
                    653:                return("RED");
                    654:        case HAIR_BLACK:
                    655:                return("BLK");
                    656:        case HAIR_GREY:
                    657:                return("GRY");
                    658:        case HAIR_OTHER:
                    659:                return("OTH"); }
                    660: if(user_hair)
                    661:        return("*");
                    662: return(nulstr);
                    663: }
                    664: 
                    665: char *eyes(char user_eyes)
                    666: {
                    667: switch(user_eyes) {
                    668:        case EYES_BLUE:
                    669:                return("BLU");
                    670:        case EYES_BROWN:
                    671:                return("BRN");
                    672:        case EYES_GREEN:
                    673:                return("GRN");
                    674:        case EYES_HAZEL:
                    675:                return("HAZ");
                    676:        case EYES_OTHER:
                    677:                return("OTH"); }
                    678: if(user_eyes)
                    679:        return("*");
                    680: return(nulstr);
                    681: }
                    682: 
                    683: char *marital(char user_marital)
                    684: {
                    685: switch(user_marital) {
                    686:     case MARITAL_SINGLE:
                    687:                return("Single");
                    688:     case MARITAL_MARRIED:
                    689:                return("Married");
                    690:     case MARITAL_DIVORCED:
                    691:                return("Divorced");
                    692:     case MARITAL_WIDOWED:
                    693:                return("Widowed");
                    694:        case MARITAL_OTHER:
                    695:                return("Other"); }
                    696: if(user_marital)
                    697:        return("*");
                    698: return(nulstr);
                    699: }
                    700: 
                    701: char *race(char user_race)
                    702: {
                    703: switch(user_race) {
                    704:        case RACE_WHITE:
                    705:                return("White");
                    706:        case RACE_BLACK:
                    707:                return("Black");
                    708:        case RACE_HISPANIC:
                    709:                return("Hispanic");
                    710:        case RACE_ASIAN:
                    711:                return("Asian");
                    712:        case RACE_AMERINDIAN:
                    713:                return("American Indian");
                    714:        case RACE_MIDEASTERN:
                    715:                return("Middle Eastern");
                    716:        case RACE_OTHER:
                    717:                return("Other"); }
                    718: if(user_race)
                    719:        return("*");
                    720: return(nulstr);
                    721: }
                    722: 
                    723: ushort getzodiac(char *birth)
                    724: {
                    725: if((!strncmp(birth,"03",2) && atoi(birth+3)>=21)
                    726:        || (!strncmp(birth,"04",2) && atoi(birth+3)<=19))
                    727:     return(ZODIAC_ARIES);
                    728: if((!strncmp(birth,"04",2) && atoi(birth+3)>=20)
                    729:        || (!strncmp(birth,"05",2) && atoi(birth+3)<=20))
                    730:        return(ZODIAC_TAURUS);
                    731: if((!strncmp(birth,"05",2) && atoi(birth+3)>=21)
                    732:        || (!strncmp(birth,"06",2) && atoi(birth+3)<=20))
                    733:        return(ZODIAC_GEMINI);
                    734: if((!strncmp(birth,"06",2) && atoi(birth+3)>=21)
                    735:        || (!strncmp(birth,"07",2) && atoi(birth+3)<=22))
                    736:        return(ZODIAC_CANCER);
                    737: if((!strncmp(birth,"07",2) && atoi(birth+3)>=23)
                    738:        || (!strncmp(birth,"08",2) && atoi(birth+3)<=22))
                    739:        return(ZODIAC_LEO);
                    740: if((!strncmp(birth,"08",2) && atoi(birth+3)>=23)
                    741:        || (!strncmp(birth,"09",2) && atoi(birth+3)<=22))
                    742:        return(ZODIAC_VIRGO);
                    743: if((!strncmp(birth,"09",2) && atoi(birth+3)>=23)
                    744:        || (!strncmp(birth,"10",2) && atoi(birth+3)<=22))
                    745:        return(ZODIAC_LIBRA);
                    746: if((!strncmp(birth,"10",2) && atoi(birth+3)>=23)
                    747:        || (!strncmp(birth,"11",2) && atoi(birth+3)<=21))
                    748:        return(ZODIAC_SCORPIO);
                    749: if((!strncmp(birth,"11",2) && atoi(birth+3)>=22)
                    750:        || (!strncmp(birth,"12",2) && atoi(birth+3)<=21))
                    751:        return(ZODIAC_SAGITTARIUS);
                    752: if((!strncmp(birth,"12",2) && atoi(birth+3)>=22)
                    753:        || (!strncmp(birth,"01",2) && atoi(birth+3)<=19))
                    754:        return(ZODIAC_CAPRICORN);
                    755: if((!strncmp(birth,"01",2) && atoi(birth+3)>=20)
                    756:        || (!strncmp(birth,"02",2) && atoi(birth+3)<=18))
                    757:        return(ZODIAC_AQUARIUS);
                    758: if((!strncmp(birth,"02",2) && atoi(birth+3)>=19)
                    759:        || (!strncmp(birth,"03",2) && atoi(birth+3)<=20))
                    760:        return(ZODIAC_PISCES);
                    761: return(0xff);
                    762: }
                    763: 
                    764: char *zodiac(short user_zodiac)
                    765: {
                    766: switch(user_zodiac)
                    767: {
                    768:        case ZODIAC_ARIES:
                    769:                return("Aries");
                    770:        case ZODIAC_TAURUS:
                    771:                return("Taurus");
                    772:        case ZODIAC_GEMINI:
                    773:                return("Gemini");
                    774:        case ZODIAC_CANCER:
                    775:                return("Cancer");
                    776:        case ZODIAC_LEO:
                    777:                return("Leo");
                    778:        case ZODIAC_VIRGO:
                    779:                return("Virgo");
                    780:        case ZODIAC_LIBRA:
                    781:                return("Libra");
                    782:        case ZODIAC_SCORPIO:
                    783:                return("Scorpio");
                    784:        case ZODIAC_SAGITTARIUS:
                    785:                return("Sagittarius");
                    786:        case ZODIAC_CAPRICORN:
                    787:                return("Capricorn");
                    788:        case ZODIAC_AQUARIUS:
                    789:                return("Aquarius");
                    790:        case ZODIAC_PISCES:
                    791:                return("Pisces"); }
                    792: return(nulstr);
                    793: }
                    794: 
                    795: short ans2bits(char *str)
                    796: {
                    797:        int i,j;
                    798:        ushort bits=0;
                    799: 
                    800: j=strlen(str);
                    801: for(i=0;i<j;i++) {
                    802:        if(str[i]=='*')
                    803:                return(0xffff);
                    804:        bits|=(1<<str[i]-'A'); }
                    805: return(bits);
                    806: }
                    807: 
                    808: uchar ans2uchar(char *str)
                    809: {
                    810:        int i,j;
                    811:        uchar bits=0;
                    812: 
                    813: j=strlen(str);
                    814: for(i=0;i<j;i++) {
                    815:        if(str[i]=='*')
                    816:                return(0xff);
                    817:        bits|=(1<<str[i]-'A'); }
                    818: return(bits);
                    819: }
                    820: 
                    821: 
                    822: void bits2ans(ushort bits, char *str)
                    823: {
                    824:        char    tmp[25];
                    825:        int     i;
                    826: 
                    827: str[0]=0;
                    828: if(bits==0xffff) {
                    829:        strcpy(str,"*");
                    830:        return; }
                    831: for(i=0;i<16;i++)
                    832:        if(bits&(1<<i)) {
                    833:                tmp[0]='A'+i;
                    834:                tmp[1]=0;
                    835:                strcat(str,tmp); }
                    836: }
                    837: 
                    838: void bits2str(ushort user, char *str)
                    839: {
                    840:        int     i;
                    841: 
                    842: str[0]=0;
                    843: if(user==0xffff) {
                    844:        strcpy(str,"*");
                    845:        return; }
                    846: for(i=0;i<16;i++)
                    847:        if(user&(1<<i))
                    848:                str[i]='A'+i;
                    849:        else
                    850:                str[i]=SP;
                    851: str[i]=0;
                    852: }
                    853: 
                    854: void uchar2ans(uchar bits, char *str)
                    855: {
                    856:        char    tmp[25];
                    857:        int     i;
                    858: 
                    859: str[0]=0;
                    860: if(bits==0xff) {
                    861:        strcpy(str,"*");
                    862:        return; }
                    863: for(i=0;i<8;i++)
                    864:        if(bits&(1<<i)) {
                    865:                tmp[0]='A'+i;
                    866:                tmp[1]=0;
                    867:                strcat(str,tmp); }
                    868: }
                    869: 
                    870: int basic_match(user_t user, user_t mate)
                    871: {
                    872:        int max=0,match=0,age=getage(mate.birth),zodiac=getzodiac(mate.birth);
                    873: 
                    874: if(user.pref_sex!='*' && user.pref_sex!=mate.sex
                    875:        && !(user.misc&USER_FRIEND))
                    876:        return(0);
                    877: 
                    878: if(zodiac&user.pref_zodiac) match++;
                    879: else if(user.misc&USER_REQZODIAC)
                    880:        return(0);
                    881: if(zodiac==user.pref_zodiac) match++;
                    882: max+=2;
                    883: 
                    884: if(stricmp(mate.zipcode,user.min_zipcode)>=0
                    885:        && stricmp(mate.zipcode,user.max_zipcode)<=0) match+=2;
                    886: else if(user.misc&USER_REQZIP) return(0);
                    887: max+=2;
                    888: 
                    889: if(mate.marital&user.pref_marital) match++;
                    890: else if(user.misc&USER_REQMARITAL)
                    891:        return(0);
                    892: if(mate.marital==user.pref_marital) match++;
                    893: max+=2;
                    894: 
                    895: if(mate.race&user.pref_race) match++;
                    896: else if(user.misc&USER_REQRACE)
                    897:        return(0);
                    898: if(mate.race==user.pref_race) match++;
                    899: max+=2;
                    900: 
                    901: if(mate.hair&user.pref_hair) match++;
                    902: else if(user.misc&USER_REQHAIR)
                    903:        return(0);
                    904: if(mate.hair==user.pref_hair) match++;
                    905: max+=2;
                    906: 
                    907: if(mate.eyes&user.pref_eyes) match++;
                    908: else if(user.misc&USER_REQEYES)
                    909:        return(0);
                    910: if(mate.eyes==user.pref_eyes) match++;
                    911: max+=2;
                    912: 
                    913: if(age>=user.min_age
                    914:        && (!user.max_age || age<=user.max_age)) match+=2;
                    915: else {
                    916:        if(user.misc&USER_REQAGE) return(0);
                    917:        if(age<user.min_age-((user.max_age-user.min_age)/2)
                    918:                || (user.max_age && age>user.max_age+((user.max_age-user.min_age)/2)))
                    919:                match-=4;
                    920:        else if(age<user.min_age-((user.max_age-user.min_age)/3)
                    921:                || (user.max_age && age>user.max_age+((user.max_age-user.min_age)/3)))
                    922:                match-=3;
                    923:        else if(age<user.min_age-((user.max_age-user.min_age)/4)
                    924:                || (user.max_age && age>user.max_age+((user.max_age-user.min_age)/4)))
                    925:                match-=2;
                    926:        else if(age<user.min_age-((user.max_age-user.min_age)/5)
                    927:                || (user.max_age && age>user.max_age+((user.max_age-user.min_age)/5)))
                    928:                match--; }
                    929: 
                    930: max+=2;
                    931: 
                    932: if(mate.weight>=user.min_weight
                    933:        && (!user.max_weight || mate.weight<=user.max_weight)) match+=2;
                    934: else {
                    935:        if(user.misc&USER_REQWEIGHT) return(0);
                    936:        if(mate.weight<user.min_weight-((user.max_weight-user.min_weight)/2)
                    937:                || (user.max_weight
                    938:                && mate.weight>user.max_weight+((user.max_weight-user.min_weight)/2)))
                    939:                match-=4;
                    940:        else if(mate.weight<user.min_weight-((user.max_weight-user.min_weight)/3)
                    941:                || (user.max_weight
                    942:                && mate.weight>user.max_weight+((user.max_weight-user.min_weight)/3)))
                    943:                match-=3;
                    944:        else if(mate.weight<user.min_weight-((user.max_weight-user.min_weight)/4)
                    945:                || (user.max_weight
                    946:                && mate.weight>user.max_weight+((user.max_weight-user.min_weight)/4)))
                    947:                match-=2;
                    948:        else if(mate.weight<user.min_weight-((user.max_weight-user.min_weight)/5)
                    949:                || (user.max_weight
                    950:                && mate.weight>user.max_weight+((user.max_weight-user.min_weight)/5)))
                    951:                match--; }
                    952: max+=2;
                    953: 
                    954: if(mate.height>=user.min_height
                    955:        && (!user.max_height || mate.height<=user.max_height)) match+=2;
                    956: else {
                    957:        if(user.misc&USER_REQHEIGHT) return(0);
                    958:        if(mate.height<user.min_height-((user.max_height-user.min_height)/2)
                    959:                || (user.max_height
                    960:                && mate.height>user.max_height+((user.max_height-user.min_height)/2)))
                    961:                match-=4;
                    962:        else if(mate.height<user.min_height-((user.max_height-user.min_height)/3)
                    963:                || (user.max_height
                    964:                && mate.height>user.max_height+((user.max_height-user.min_height)/3)))
                    965:                match-=3;
                    966:        else if(mate.height<user.min_height-((user.max_height-user.min_height)/4)
                    967:                || (user.max_height
                    968:                && mate.height>user.max_height+((user.max_height-user.min_height)/4)))
                    969:                match-=2;
                    970:        else if(mate.height<user.min_height-((user.max_height-user.min_height)/5)
                    971:                || (user.max_height
                    972:                && mate.height>user.max_height+((user.max_height-user.min_height)/5)))
                    973:                match--; }
                    974: max+=2;
                    975: 
                    976: if(mate.income>=user.min_income
                    977:        && (!user.max_income || mate.income==0xffffffffUL
                    978:        || mate.income<=user.max_income)) match++;
                    979: else {
                    980:        if(user.misc&USER_REQINCOME) return(0);
                    981:        if(mate.income<user.min_income-((user.max_income-user.min_income)/2)
                    982:                || (user.max_income
                    983:                && mate.income>user.max_income+((user.max_income-user.min_income)/2)))
                    984:                match-=4;
                    985:        else if(mate.income<user.min_income-((user.max_income-user.min_income)/3)
                    986:                || (user.max_income
                    987:                && mate.income>user.max_income+((user.max_income-user.min_income)/3)))
                    988:                match-=3;
                    989:        else if(mate.income<user.min_income-((user.max_income-user.min_income)/4)
                    990:                || (user.max_income
                    991:                && mate.income>user.max_income+((user.max_income-user.min_income)/4)))
                    992:                match-=2;
                    993:        else if(mate.income<user.min_income-((user.max_income-user.min_income)/5)
                    994:                || (user.max_income
                    995:                && mate.income>user.max_income+((user.max_income-user.min_income)/5)))
                    996:                match--; }
                    997: max++;
                    998: 
                    999: if(match<=0)
                   1000:        return(0);
                   1001: 
                   1002: return(((float)match/max)*100.0);
                   1003: }
                   1004: 
                   1005: int sys_quenum(char *name)
                   1006: {
                   1007:        int i;
                   1008: 
                   1009: for(i=0;i<total_ques;i++)
                   1010:        if(!stricmp(que[i]->name,name))
                   1011:                break;
                   1012: if(i<total_ques)
                   1013:        return(i);
                   1014: return(-1);
                   1015: }
                   1016: 
                   1017: int user_quenum(char *name, user_t user)
                   1018: {
                   1019:        int i;
                   1020: 
                   1021: for(i=0;i<5;i++)
                   1022:        if(!stricmp(user.queans[i].name,name))
                   1023:                break;
                   1024: if(i<5)
                   1025:        return(i);
                   1026: return(-1);
                   1027: }
                   1028: 
                   1029: int total_match(user_t user, user_t mate)
                   1030: {
                   1031:        int i,j,s,u,match1,match2,quematches=0,quemax=0,quematch;
                   1032: 
                   1033: match1=basic_match(user,mate);
                   1034: if(!match1) return(0);
                   1035: match2=basic_match(mate,user);
                   1036: if(!match2) return(0);
                   1037: 
                   1038: for(i=0;i<5;i++) {
                   1039:        if(!user.queans[i].name[0])
                   1040:                continue;
                   1041:        s=sys_quenum(user.queans[i].name);
                   1042:        if(s==-1)
                   1043:                continue;
                   1044:        u=user_quenum(user.queans[i].name,mate);
                   1045:        if(u==-1)
                   1046:                continue;
                   1047:        for(j=0;j<que[s]->total_ques;j++) {
                   1048:                if(user.queans[u].pref[j]&mate.queans[i].self[j]) quematches+=4;
                   1049:                if(user.queans[u].pref[j]==mate.queans[i].self[j]) quematches+=2;
                   1050:                if(user.queans[u].self[j]&mate.queans[i].pref[j]) quematches+=2;
                   1051:                if(user.queans[u].self[j]==mate.queans[i].pref[j]) quematches++;
                   1052:                quemax+=9; } }
                   1053: 
                   1054: if(!quemax)    /* no questionnaires in common */
                   1055:        return((match1+match1+match1+match1+match2+match2)/6);
                   1056: 
                   1057: quematch=((float)quematches/quemax)*100.0;
                   1058: return((match1+match1+match1+match1+match2+match2+quematch)/7);
                   1059: }
                   1060: 
                   1061: 
                   1062: void main_user_info(user_t user)
                   1063: {
                   1064:        char str[128],min[64],max[64];
                   1065:        int i;
                   1066: 
                   1067: attr(LIGHTGRAY);
                   1068: cls();
                   1069: if(SYSOP)
                   1070:        bprintf("\1n\1gReal: \1h%.25s #%lu (%.40s)\r\n"
                   1071:                ,user.realname,user.number,user.system);
                   1072: bprintf("\1n\1gName: \1h%-25.25s     \1b%-10s   \1c%-15s  \1m%s\r\n"
                   1073:        ,user.name
                   1074:        ,marital(user.marital),race(user.race)
                   1075:        ,user.sex=='M' ? "Male":"Female");
                   1076: if(smm_misc&SMM_METRIC)
                   1077:        sprintf(str," %-4u",intocm(user.height));
                   1078: else
                   1079:        sprintf(str,"%2u'%-2u",user.height/12,user.height%12);
                   1080: bprintf("\1n\1gHair: \1h%3s  \1n\1gEyes: \1h%3s  \1n\1gHeight:"
                   1081:        "\1h%s  \1n\1gWeight: \1h%-3u  \1n\1gAge: \1h%-3u "
                   1082:     "\1n\1gZodiac: \1h%s\r\n"
                   1083:        ,hair(user.hair),eyes(user.eyes),str
                   1084:        ,smm_misc&SMM_METRIC ? lptokg(user.weight) : user.weight
                   1085:        ,getage(user.birth),zodiac(getzodiac(user.birth)));
                   1086: bprintf("\1n\1gFrom: \1h%-30.30s   \1n\1gZip: \1h%-10.10s    "
                   1087:        "\1n\1gIncome: \1h$%sK\1n\1g/year\r\n"
                   1088:        ,user.location,user.zipcode
                   1089:        ,user.income==0xffffffffUL ? "?":ultoa(user.income/1000UL,tmp,10));
                   1090: if(smm_misc&SMM_METRIC) {
                   1091:        sprintf(min,"%u",intocm(user.min_height));
                   1092:        sprintf(max,"%u",intocm(user.max_height)); }
                   1093: else {
                   1094:        sprintf(min,"%u'%u",user.min_height/12,user.min_height%12);
                   1095:        sprintf(max,"%u'%u",user.max_height/12,user.max_height%12); }
                   1096: bprintf("\1n\1gPref: \1h\1%c%c\1%c%c\1m%c \1%c%3u\1n\1g-\1h\1%c%u\1n\1h  "
                   1097:        "\1%c%s \1n\1ghair  \1h\1%c%s \1n\1geyes  \1h\1%c%s\1n\1g-\1h\1%c%s  "
                   1098:        "\1%c%u\1n\1g-\1h\1%c%u\1n\1glbs  \1h\1%c$%luK\1n\1g-\1h\1%c%luK\1n\1%c  "
                   1099:        "\1h%.3s\r\n"
                   1100:        ,user.misc&USER_REQMARITAL ? 'w':'b'
                   1101:        ,marital_ch(user.pref_marital)
                   1102:        ,user.misc&USER_REQRACE ? 'w':'g'
                   1103:        ,race_ch(user.pref_race)
                   1104:        ,user.pref_sex
                   1105:        ,user.misc&USER_REQAGE  ? 'w':'g'
                   1106:        ,user.min_age
                   1107:        ,user.misc&USER_REQAGE  ? 'w':'g'
                   1108:        ,user.max_age
                   1109:        ,user.misc&USER_REQHAIR  ? 'w':'g'
                   1110:        ,hair(user.pref_hair)
                   1111:        ,user.misc&USER_REQEYES  ? 'w':'g'
                   1112:        ,eyes(user.pref_eyes)
                   1113:        ,user.misc&USER_REQHEIGHT  ? 'w':'g'
                   1114:        ,min
                   1115:        ,user.misc&USER_REQHEIGHT  ? 'w':'g'
                   1116:        ,max
                   1117:        ,user.misc&USER_REQWEIGHT  ? 'w':'g'
                   1118:        ,smm_misc&SMM_METRIC ? lptokg(user.min_weight) : user.min_weight
                   1119:        ,user.misc&USER_REQWEIGHT  ? 'w':'g'
                   1120:        ,smm_misc&SMM_METRIC ? lptokg(user.max_weight) : user.max_weight
                   1121:        ,user.misc&USER_REQINCOME  ? 'w':'g'
                   1122:        ,user.min_income/1000L
                   1123:        ,user.misc&USER_REQINCOME  ? 'w':'g'
                   1124:        ,user.max_income/1000L
                   1125:        ,user.misc&USER_REQZODIAC  ? 'w':'g'
                   1126:     ,zodiac(user.pref_zodiac));
                   1127: 
                   1128: bprintf("\1r\1i%s\1n\1w\1h\r\n",user.misc&USER_PHOTO ? "PHOTO":nulstr);
                   1129: for(i=0;i<5;i++) {
                   1130:     if(!user.note[i][0])
                   1131:         break;
                   1132:        bprintf("%15s%.50s\r\n",nulstr,user.note[i]); }
                   1133: }
                   1134: 
                   1135: char long_user_info(user_t user)
                   1136: {
                   1137:        char str[128],fname[128],path[128],ch;
                   1138:        int i,j,k,s,u,max,match1,match2,user_match,mate_match;
                   1139: 
                   1140: while(1) {
                   1141: checkline();
                   1142: main_user_info(user);
                   1143: 
                   1144: CRLF;
                   1145: /**
                   1146: if(user.misc&USER_FROMSMB)
                   1147:        bprintf("\1r\1hImported via message base from \1w%s\1r.\r\n"
                   1148:                ,user.system);
                   1149: **/
                   1150: bprintf("\1h\1mThis user meets your profile preferences:\1w%3u%%            "
                   1151:        ,match1=basic_match(useron,user));
                   1152: bprintf("\1n\1gCreated: \1h%s\r\n",unixtodstr(user.created,str));
                   1153: bprintf("\1h\1mYou meet this user's profile preferences:\1w%3u%%            "
                   1154:        ,match2=basic_match(user,useron));
                   1155: bprintf("\1n\1gUpdated: \1h%s\r\n",unixtodstr(user.updated,str));
                   1156: 
                   1157: if(!smm_pause)
                   1158:        lncntr=0;
                   1159: 
                   1160: CRLF;
                   1161: bputs("\1n\1b\1hQuestionnaires:\r\n");
                   1162: for(i=0;i<5;i++) {
                   1163:        max=mate_match=user_match=0;
                   1164:        if(!user.queans[i].name[0])
                   1165:                continue;
                   1166:        s=sys_quenum(user.queans[i].name);
                   1167:        if(s==-1)
                   1168:                continue;
                   1169:        if(que[s]->req_age>getage(useron.birth))
                   1170:                continue;
                   1171:        if(match1 && match2)
                   1172:                u=user_quenum(user.queans[i].name,useron);
                   1173:        else
                   1174:                u=-1;
                   1175:        bprintf("\1h\1c%-25s ",que[s]->desc);
                   1176:        if(u==-1) {
                   1177:                CRLF;
                   1178:                continue; }
                   1179:        for(j=0;j<que[s]->total_ques;j++) {
                   1180:                if(useron.queans[u].pref[j]&user.queans[i].self[j]) user_match+=2;
                   1181:                if(useron.queans[u].pref[j]==user.queans[i].self[j]) user_match++;
                   1182:                if(useron.queans[u].self[j]&user.queans[i].pref[j]) mate_match+=2;
                   1183:                if(useron.queans[u].self[j]==user.queans[i].pref[j]) mate_match++;
                   1184:                max+=3; }
                   1185:        bprintf("\1n\1c%s matches your pref:\1h%3u%%  "
                   1186:                        "\1n\1cYou match %s pref:\1h%3u%%\r\n"
                   1187:                        ,user.sex=='M' ? "He":"She"
                   1188:                        ,(int)(((float)user_match/max)*100.0)
                   1189:                        ,user.sex=='M' ? "his":"her"
                   1190:                        ,(int)(((float)mate_match/max)*100.0)); }
                   1191: 
                   1192: bprintf("\r\n\1r\1hOverall match: \1w%u%%",total_match(useron,user));
                   1193: if(user.purity)
                   1194:        bprintf("        \1r\1hPurity test: \1w%u%%",user.purity);
                   1195: if(user.mbtype[0])
                   1196:        bprintf("        \1r\1hPersonality type: \1w%s",user.mbtype);
                   1197: CRLF;
                   1198: 
                   1199: if(aborted) {
                   1200:        aborted=0;
                   1201:        return(0); }
                   1202: if(!smm_pause) {
                   1203:        if(kbhit())
                   1204:                return(0);
                   1205:        return(1); }
                   1206: nodesync();
                   1207: if(lncntr>=user_rows-2)
                   1208:     lncntr=0;
                   1209: CRLF;
                   1210: bputs("\1h\1b[\1cV\1b]iew questionnaires, ");
                   1211: if(user.misc&USER_PHOTO)
                   1212:        bputs("[\1cD\1b]ownload photo, ");
                   1213: bputs("[\1cS\1b]end telegram, [\1cQ\1b]uit, or [Next]: \1c");
                   1214: strcpy(str,"VSQN\r");
                   1215: if(user.misc&USER_PHOTO)
                   1216:        strcat(str,"D");
                   1217: if(SYSOP)
                   1218:        strcat(str,"+");
                   1219: switch(getkeys(str,0)) {
                   1220:        case '+':
                   1221:                user.misc|=USER_PHOTO;
                   1222:                break;
                   1223:        case 'Q':
                   1224:                return(0);
                   1225:        case CR:
                   1226:        case 'N':
                   1227:                return(1);
                   1228:        case 'D':
                   1229:                if(!useron.number) {
                   1230:                        bputs("\r\n\1h\1rYou must create a profile first.\r\n");
                   1231:                        pause();
                   1232:                        break; }
                   1233:                if(!(useron.misc&USER_PHOTO)) {
                   1234:                        bputs("\r\n\1h\1rYou cannot download photos until your photo is "
                   1235:                                "added.\r\n");
                   1236:                        pause();
                   1237:                        break; }
                   1238:                for(i=0;user.system[i];i++)
                   1239:                        if(isalnum(user.system[i]))
                   1240:                                break;
                   1241:                if(!user.system[i])
                   1242:                        fname[0]='~';
                   1243:                else
                   1244:                        fname[0]=user.system[i];
                   1245:                for(i=strlen(user.system)-1;i>0;i--)
                   1246:                        if(isalnum(user.system[i]))
                   1247:                                break;
                   1248:                if(i<=0)
                   1249:                        fname[1]='~';
                   1250:                else
                   1251:                        fname[1]=user.system[i];
                   1252:                fname[2]=0;
                   1253:                strupr(user.system);
                   1254:                strcat(fname,base41(crc16(user.system),tmp));
                   1255:                strcat(fname,base41(user.number,tmp));
                   1256:                strcat(fname,".JPG");
                   1257:                strupr(fname);
                   1258:                sprintf(path,"PHOTO\\%s",fname);
                   1259:                if(!fexist(path)) {
                   1260:                        bputs("\r\n\1n\1hUnpacking...");
                   1261:                        sprintf(str,"%spkunzip photo %s photo",exec_dir,fname);
                   1262:                        system(str);
                   1263:                        bputs("\r\n");
                   1264:                        if(!fexist(path)) {
                   1265:                                bputs("\r\n\1n\1h\1i\1rUnpacking failed!\1n\r\n");
                   1266:                                pause();
                   1267:                                break; } }
                   1268:                if(com_port) {
                   1269:                        cmdstr(zmodem_send,path,path,str);
                   1270:                        ivhctl(INTCLR);
                   1271:                        ivhctl(INT29L);
                   1272:                        system(str);
                   1273:                        ivhctl(INTCLR);
                   1274:                        i=INT29L;
                   1275:                        i|=(INT29R|INT16);
                   1276:                        ivhctl(i); }
                   1277:                else
                   1278:                        system(cmdstr(local_view,path,path,str));
                   1279:                pause();
                   1280:                break;
                   1281: 
                   1282: 
                   1283:        case 'S':
                   1284:                send_telegram(user);
                   1285:                break;
                   1286:        case 'V':
                   1287: 
                   1288:                if(user_level<que_level) {
                   1289:                        bputs("\r\n\1h\1rYou have insufficient access to read "
                   1290:                                "questoinnaires.\r\n");
                   1291:                        pause();
                   1292:             break; }
                   1293: 
                   1294:                for(i=0;i<5;i++) {
                   1295:                        aborted=0;
                   1296:                        if(!user.queans[i].name[0])
                   1297:                                continue;
                   1298:                        s=sys_quenum(user.queans[i].name);
                   1299:                        if(s==-1)
                   1300:                                continue;
                   1301:                        if(que[s]->req_age>getage(useron.birth))
                   1302:                                continue;
                   1303:                        if(match1 && match2)
                   1304:                                u=user_quenum(user.queans[i].name,useron);
                   1305:                        else
                   1306:                                u=-1;
                   1307:                        sprintf(str,"\r\nDo you wish to view the \1w%s\1b questionnaire"
                   1308:                                ,que[s]->desc);
                   1309:                        if(!yesno(str))
                   1310:                                continue;
                   1311:                        if(!cdt_warning(que_cdt))
                   1312:                                continue;
                   1313:                        adjust_cdt(que_cdt);
                   1314:                        for(j=0;j<que[s]->total_ques && !aborted;) {
                   1315:                                cls();
                   1316:                                bprintf("\1n\1m\1hQuestionnaire: \1y%-25s \1mQuestion: "
                   1317:                                        "\1y%d \1mof \1y%d  \1h\1b(Ctrl-C to Abort)\r\n\r\n"
                   1318:                                        ,que[s]->desc,j+1,que[s]->total_ques);
                   1319:                                bprintf("\1w\1h%s\r\n\r\n",que[s]->que[j].txt);
                   1320:                                for(k=0;k<que[s]->que[j].answers;k++)
                   1321:                                        bprintf("\1h\1b%c\1w) \1g%s\r\n",'A'+k
                   1322:                                                ,que[s]->que[j].ans[k]);
                   1323:                                bits2str(user.queans[i].self[j],str);
                   1324:                                bprintf("\1n\1g\r\n%25s: \1h%-16s "
                   1325:                                        ,user.name,str);
                   1326:                                bits2str(user.queans[i].pref[j],str);
                   1327:                                bprintf("\1n\1g %15s: \1h%s","Preferred mate",str);
                   1328:                                if(u!=-1) {
                   1329:                                        bits2str(useron.queans[u].pref[j],str);
                   1330:                                        bprintf("\1n\1g\r\n%25s: \1h%-16s "
                   1331:                                                ,"Your preferred mate",str);
                   1332:                                        bits2str(useron.queans[u].self[j],str);
                   1333:                                        bprintf("\1n\1g %15s: \1h%s","You",str); }
                   1334:                                CRLF;
                   1335:                                if(!aborted) {
                   1336:                                        lncntr=0;
                   1337:                                        bputs("\r\n\1h\1b[\1cP\1b]revious, [\1cQ\1b]uit, "
                   1338:                                                "or [Next]: \1c");
                   1339:                                        ch=getkeys("PQN\r",0);
                   1340:                                        if(ch=='P') {
                   1341:                                                if(j) j--;
                   1342:                                                continue; }
                   1343:                                        if(ch=='Q')
                   1344:                                                break;
                   1345:                                        j++; } } }
                   1346:                break;
                   1347: 
                   1348:        } }
                   1349: return(0);
                   1350: }
                   1351: 
                   1352: 
                   1353: /* Returns 0 if aborted, 1 if continue, negative if previous */
                   1354: int short_user_info(user_t user)
                   1355: {
                   1356:        char str[128],height[64],ch;
                   1357:     int i,match;
                   1358:     int records;
                   1359:     ulong  name_crc;
                   1360:        static char name[26],lastname[26],highmatch;
                   1361:     static long topixb,topdab,lastixb,lastdab;
                   1362:     static int count;
                   1363: 
                   1364: if(!lncntr && smm_pause) {
                   1365:        topdab=ftell(stream)-sizeof(user_t);
                   1366:        topixb=ftell(index)-sizeof(ixb_t);
                   1367:     if(!topdab)
                   1368:         lastdab=lastixb=0;
                   1369:     count=0;
                   1370:        printfile("LIST_HDR.ASC");
                   1371:        strcpy(lastname,name);
                   1372:        name[0]=highmatch=0; }
                   1373: if(user.number) {
                   1374:        match=total_match(useron,user);
                   1375:     if(!match) str[0]=0;
                   1376:     else if(match>=90) sprintf(str,"\1w%u%%",match);
                   1377:     else if(match>=80) sprintf(str,"\1c%u%%",match);
                   1378:     else if(match>=70) sprintf(str,"\1y%u%%",match);
                   1379:     else if(match>=60) sprintf(str,"\1g%u%%",match);
                   1380:     else if(match>=50) sprintf(str,"\1m%u%%",match);
                   1381:     else if(match>=40) sprintf(str,"\1r%u%%",match);
                   1382:     else if(match>=30) sprintf(str,"\1b%u%%",match);
                   1383:     else if(match>=20) sprintf(str,"\1n\1g%u%%",match);
                   1384:     else if(match>=10) sprintf(str,"\1n\1c%u%%",match);
                   1385:     else sprintf(str,"\1n%u%%",match);
                   1386:        if(smm_misc&SMM_METRIC)
                   1387:                sprintf(height," %-4u",intocm(user.height));
                   1388:        else
                   1389:                sprintf(height,"%2u'%-2u",user.height/12,user.height%12);
                   1390:        bprintf("\1n\1h%c\1n\1g%c\1h\1c%c\1b%3u \1g%3s \1m%3s\1r%s \1y%-3u "
                   1391:                "\1n\1g%-25.25s\1r\1h\1i%c\1n\1h%-25.25s%s\r\n"
                   1392:         ,user.sex==user.pref_sex ? 'G':user.sex=='*' ? 'B'
                   1393:             : marital_ch(user.marital)
                   1394:         ,race_ch(user.race)
                   1395:         ,user.sex
                   1396:         ,getage(user.birth)
                   1397:         ,hair(user.hair)
                   1398:         ,eyes(user.eyes)
                   1399:                ,height
                   1400:                ,smm_misc&SMM_METRIC ? lptokg(user.weight) : user.weight
                   1401:         ,user.location
                   1402:                ,user.misc&USER_PHOTO ? '+':SP
                   1403:         ,user.name
                   1404:         ,str
                   1405:         );
                   1406:        if(match &&
                   1407:                (!name[0] || !stricmp(name,lastname)
                   1408:                || (stricmp(user.name,lastname) && match>highmatch))) {
                   1409:                highmatch=match;
                   1410:         sprintf(name,"%.25s",user.name);
                   1411:         strupr(name); }
                   1412:        }
                   1413: 
                   1414: if(lncntr>=user_rows-2 || !user.number) {
                   1415:     lncntr=0;
                   1416:        bputs(PrevReadSendQuitOrMore);
                   1417:        ch=getkey(K_UPPER);
                   1418:        if(ch=='Q') {
                   1419:                cls();
                   1420:                aborted=1; }
                   1421:     else if(ch=='P') {
                   1422:                cls();
                   1423:         records=((ftell(stream)-topdab)/sizeof(user_t));
                   1424:                fseek(stream,lastdab,SEEK_SET);
                   1425:                fseek(index,lastixb,SEEK_SET);
                   1426:                lastdab-=(records)*sizeof(user_t);
                   1427:                lastixb-=(records)*sizeof(ixb_t);
                   1428:         if(lastdab<0) lastdab=0;
                   1429:         if(lastixb<0) lastixb=0;
                   1430:         return(-count); }
                   1431:        else if(ch=='R' || ch=='G' || ch=='S') {
                   1432:         bprintf("\1n\r\1>\1y\1hUser name: ");
                   1433:         if(getstr(name,25,K_NOCRLF|K_LINE|K_EDIT|K_AUTODEL|K_UPPER)) {
                   1434:                        truncsp(name);
                   1435:             name_crc=crc32(name);
                   1436:             cls();
                   1437:             rewind(index);
                   1438:             while(!feof(index)) {
                   1439:                 if(!fread(&ixb,sizeof(ixb_t),1,index))
                   1440:                     break;
                   1441:                 if(!ixb.number)    /* DELETED */
                   1442:                     continue;
                   1443:                 if(ixb.name!=name_crc)
                   1444:                     continue;
                   1445:                 fseek(stream
                   1446:                     ,((ftell(index)-sizeof(ixb_t))/sizeof(ixb_t))
                   1447:                     *sizeof(user_t),SEEK_SET);
                   1448:                 if(!fread(&user,sizeof(user_t),1,stream))
                   1449:                     continue;
                   1450:                                if(ch=='S' && send_telegram(user))
                   1451:                                        break;
                   1452:                                if(ch!='S' && !long_user_info(user))
                   1453:                     break; } }
                   1454:         fseek(stream,topdab,SEEK_SET);
                   1455:         fseek(index,topixb,SEEK_SET);
                   1456:                cls();
                   1457:                return(-1); }
                   1458:     else {
                   1459:         lastixb=topixb;
                   1460:                lastdab=topdab;
                   1461:                cls(); } }
                   1462: 
                   1463: count++;
                   1464: if(aborted)
                   1465:     return(0);
                   1466: return(1);
                   1467: }
                   1468: 
                   1469: 
                   1470: int get_your_det(user_t *user)
                   1471: {
                   1472:        char    str[128],*p,*hdr;
                   1473:        int     i;
                   1474: 
                   1475: while(1) {
                   1476: checkline();
                   1477: cls();
                   1478: bputs("\1h\0014 Your Detailed Personal Information \1n  \1h\1b"
                   1479:     "(Ctrl-C to Abort)\r\n\r\n");
                   1480: 
                   1481: nodesync();
                   1482: bputs("\1h\1bPlease enter your name or alias: ");
                   1483: strcpy(str,user->name);
                   1484: if(!getstr(str,25,K_LINE|K_EDIT|K_AUTODEL|K_UPRLWR))
                   1485:        return(0);
                   1486: truncsp(str);
                   1487: if(trash(str)) {
                   1488:        bprintf("\r\n\1h\1rSorry, you can't use that name.\r\n\r\n\1p");
                   1489:        continue; }
                   1490: strcpy(user->name,str);
                   1491: 
                   1492: CRLF;
                   1493: nodesync();
                   1494: bprintf("\1h\1gPlease enter your height in %s: "
                   1495:        ,smm_misc&SMM_METRIC ? "centimeters" : "feet'inches (example: 5'7)");
                   1496: if(user->height) {
                   1497:        if(smm_misc&SMM_METRIC)
                   1498:                sprintf(str,"%u",intocm(user->height));
                   1499:        else
                   1500:                sprintf(str,"%u'%u",user->height/12,user->height%12); }
                   1501: else
                   1502:     str[0]=0;
                   1503: if(!getstr(str,4,K_LINE|K_EDIT|K_AUTODEL))
                   1504:        return(0);
                   1505: if(smm_misc&SMM_METRIC)
                   1506:        user->height=cmtoin(atoi(str));
                   1507: else {
                   1508:        user->height=atoi(str)*12;
                   1509:        p=strchr(str,'\'');
                   1510:        if(p) user->height+=atoi(p+1); }
                   1511: 
                   1512: CRLF;
                   1513: nodesync();
                   1514: bprintf("\1h\1mPlease enter your weight (in %s): "
                   1515:        ,smm_misc&SMM_METRIC ? "kilograms":"pounds");
                   1516: if(user->weight)
                   1517:        sprintf(str,"%u"
                   1518:                ,smm_misc&SMM_METRIC ? lptokg(user->weight) : user->weight);
                   1519: else
                   1520:     str[0]=0;
                   1521: if(!getstr(str,3,K_NUMBER|K_EDIT|K_AUTODEL|K_LINE))
                   1522:        return(0);
                   1523: if(smm_misc&SMM_METRIC)
                   1524:        user->weight=kgtolp(atoi(str));
                   1525: else
                   1526:        user->weight=atoi(str);
                   1527: 
                   1528: CRLF;
                   1529: nodesync();
                   1530: bputs("\1h\1rPlease enter your annual income in dollars (ENTER=undisclosed): ");
                   1531: if(user->income && user->income!=0xffffffff)
                   1532:        sprintf(str,"%luK",user->income/1000);
                   1533: else
                   1534:     str[0]=0;
                   1535: getstr(str,6,K_UPPER|K_EDIT|K_AUTODEL|K_LINE);
                   1536: if(aborted)
                   1537:        return(0);
                   1538: if(strchr(str,'K'))
                   1539:        user->income=atol(str)*1000L;
                   1540: else if(str[0]==0)
                   1541:        user->income=0xffffffffUL;
                   1542: else
                   1543:        user->income=atol(str);
                   1544: 
                   1545: CRLF;
                   1546: nodesync();
                   1547: bputs("\1h\1cPlease enter your location (city, state): ");
                   1548: strcpy(str,user->location);
                   1549: if(!getstr(str,30,K_LINE|K_EDIT|K_AUTODEL|K_UPRLWR))
                   1550:        return(0);
                   1551: truncsp(str);
                   1552: if(trash(str)) {
                   1553:        bprintf("\r\n\1r\1hSorry, you can't use that location.\r\n\r\n\1p");
                   1554:        continue; }
                   1555: strcpy(user->location,str);
                   1556: 
                   1557: 
                   1558: CRLF;
                   1559: nodesync();
                   1560: bputs("\1h\1gPlease enter your zip/postal code: ");
                   1561: if(!getstr(user->zipcode,10,K_LINE|K_EDIT|K_AUTODEL))
                   1562:        return(0);
                   1563: 
                   1564: CRLF;
                   1565: nodesync();
                   1566: for(i=0;i<5;i++) {
                   1567:     bprintf("\1n\1gPersonal text - Line %u of 5: ",i+1);
                   1568:     if(wordwrap[0])
                   1569:         user->note[i][0]=0;
                   1570:        strcpy(str,user->note[i]);
                   1571:        if(!getstr(str,50,i==4 ? K_LINE|K_EDIT:K_LINE|K_EDIT|K_WRAP))
                   1572:                break;
                   1573:        if(trash(str)) {
                   1574:                bprintf("\r\n\1r\1hSorry, you can't use that text.\r\n\r\n");
                   1575:                i--;
                   1576:                continue; }
                   1577:        strcpy(user->note[i],str); }
                   1578: while(i++<5)
                   1579:     user->note[i][0]=0;
                   1580: aborted=0;
                   1581: nodesync();
                   1582: if(yesno("\r\nIs the above information correct"))
                   1583:     break; }
                   1584: return(1);
                   1585: }
                   1586: 
                   1587: int get_pref_det(user_t *user)
                   1588: {
                   1589:        char str[128],*p,*hdr;
                   1590:        int i;
                   1591: 
                   1592: while(1) {
                   1593: checkline();
                   1594: cls();
                   1595: bputs("\1h\0014 Detailed Information on Your Preferred Mate \1n  "
                   1596:     "\1h\1b(Ctrl-C to Abort)\r\n\r\n");
                   1597: 
                   1598: nodesync();
                   1599: bputs("\1n\1cPlease enter the minimum age of your preferred mate: \1h");
                   1600: if(user->min_age)
                   1601:     sprintf(str,"%u",user->min_age);
                   1602: else
                   1603:     str[0]=0;
                   1604: getstr(str,3,K_NUMBER|K_EDIT|K_AUTODEL);
                   1605: if(aborted)
                   1606:        return(0);
                   1607: user->min_age=atoi(str);
                   1608: 
                   1609: nodesync();
                   1610: bputs("\1h\1cPlease enter the maximum age of your preferred mate: \1h");
                   1611: if(user->max_age)
                   1612:     sprintf(str,"%u",user->max_age);
                   1613: else
                   1614:     str[0]=0;
                   1615: getstr(str,3,K_NUMBER|K_EDIT|K_AUTODEL);
                   1616: if(aborted)
                   1617:        return(0);
                   1618: user->max_age=atoi(str);
                   1619: if(user->min_age) {
                   1620:        strcpy(str,"Do you require your mate's age fall within this range");
                   1621:        if(user->misc&USER_REQAGE)
                   1622:                i=yesno(str);
                   1623:        else
                   1624:                i=!noyes(str);
                   1625:        if(i)
                   1626:                user->misc|=USER_REQAGE;
                   1627:        else
                   1628:                user->misc&=~USER_REQAGE; }
                   1629: else
                   1630:        user->misc&=~USER_REQAGE;
                   1631: if(aborted)
                   1632:        return(0);
                   1633: 
                   1634: CRLF;
                   1635: nodesync();
                   1636: bprintf("\1n\1gPlease enter the minimum height of your preferred mate "
                   1637:        "in %s: \1w\1h",smm_misc&SMM_METRIC ? "centimeters":"feet'inches");
                   1638: if(user->min_height) {
                   1639:        if(smm_misc&SMM_METRIC)
                   1640:                sprintf(str,"%u",intocm(user->min_height));
                   1641:        else
                   1642:                sprintf(str,"%u'%u",user->min_height/12,user->min_height%12); }
                   1643: else
                   1644:     str[0]=0;
                   1645: getstr(str,4,K_EDIT|K_AUTODEL);
                   1646: if(aborted)
                   1647:        return(0);
                   1648: if(smm_misc&SMM_METRIC)
                   1649:        user->min_height=cmtoin(atoi(str));
                   1650: else {
                   1651:        user->min_height=atoi(str)*12;
                   1652:        p=strchr(str,'\'');
                   1653:        if(p) user->min_height+=atoi(p+1); }
                   1654: nodesync();
                   1655: bprintf("\1h\1gPlease enter the maximum height of your preferred mate "
                   1656:        "in %s: \1w",smm_misc&SMM_METRIC ? "centimeters":"feet'inches");
                   1657: if(user->max_height) {
                   1658:        if(smm_misc&SMM_METRIC)
                   1659:                sprintf(str,"%u",intocm(user->max_height));
                   1660:     else
                   1661:                sprintf(str,"%u'%u",user->max_height/12,user->max_height%12); }
                   1662: else
                   1663:     str[0]=0;
                   1664: getstr(str,4,K_EDIT|K_AUTODEL);
                   1665: if(aborted)
                   1666:        return(0);
                   1667: if(smm_misc&SMM_METRIC)
                   1668:        user->max_height=cmtoin(atoi(str));
                   1669: else {
                   1670:        user->max_height=atoi(str)*12;
                   1671:        p=strchr(str,'\'');
                   1672:        if(p) user->max_height+=atoi(p+1); }
                   1673: strcpy(str,"Do you require your mate's height fall within this range");
                   1674: if(user->misc&USER_REQHEIGHT)
                   1675:        i=yesno(str);
                   1676: else
                   1677:        i=!noyes(str);
                   1678: if(i)
                   1679:     user->misc|=USER_REQHEIGHT;
                   1680: else
                   1681:     user->misc&=~USER_REQHEIGHT;
                   1682: if(aborted)
                   1683:     return(0);
                   1684: 
                   1685: 
                   1686: CRLF;
                   1687: nodesync();
                   1688: bprintf("\1n\1mPlease enter the minimum weight of your preferred mate in %s:"
                   1689:        " \1w\1h",smm_misc&SMM_METRIC ? "kilograms":"pounds");
                   1690: if(user->min_weight) {
                   1691:        if(smm_misc&SMM_METRIC)
                   1692:                sprintf(str,"%u",lptokg(user->min_weight));
                   1693:        else
                   1694:                sprintf(str,"%u",user->min_weight); }
                   1695: else
                   1696:     str[0]=0;
                   1697: getstr(str,3,K_NUMBER|K_EDIT|K_AUTODEL);
                   1698: if(aborted)
                   1699:        return(0);
                   1700: if(smm_misc&SMM_METRIC)
                   1701:        user->min_weight=kgtolp(atoi(str));
                   1702: else
                   1703:        user->min_weight=atoi(str);
                   1704: 
                   1705: nodesync();
                   1706: bprintf("\1h\1mPlease enter the maximum weight of your preferred mate in %s:"
                   1707:        " \1w",smm_misc&SMM_METRIC ? "kilograms":"pounds");
                   1708: if(user->max_weight) {
                   1709:        if(smm_misc&SMM_METRIC)
                   1710:                sprintf(str,"%u",lptokg(user->max_weight));
                   1711:        else
                   1712:                sprintf(str,"%u",user->max_weight); }
                   1713: else
                   1714:     str[0]=0;
                   1715: getstr(str,3,K_NUMBER|K_EDIT|K_AUTODEL);
                   1716: if(aborted)
                   1717:        return(0);
                   1718: if(smm_misc&SMM_METRIC)
                   1719:        user->max_weight=kgtolp(atoi(str));
                   1720: else
                   1721:        user->max_weight=atoi(str);
                   1722: if(user->max_weight) {
                   1723:        strcpy(str,"Do you require your mate's weight fall within this range");
                   1724:        if(user->misc&USER_REQWEIGHT)
                   1725:                i=yesno(str);
                   1726:        else
                   1727:                i=!noyes(str);
                   1728:        if(i)
                   1729:                user->misc|=USER_REQWEIGHT;
                   1730:        else
                   1731:                user->misc&=~USER_REQWEIGHT; }
                   1732: else
                   1733:        user->misc&=~USER_REQWEIGHT;
                   1734: if(aborted)
                   1735:     return(0);
                   1736: 
                   1737: 
                   1738: CRLF;
                   1739: nodesync();
                   1740: bputs("\1h\1cPlease enter the lowest zip/postal code of your preferred "
                   1741:     "mate: \1w");
                   1742: getstr(user->min_zipcode,10,K_EDIT|K_AUTODEL|K_UPPER);
                   1743: if(aborted)
                   1744:        return(0);
                   1745: bputs("\1h\1bPlease enter the highest zip/postal code of your preferred "
                   1746:     "mate: \1w");
                   1747: getstr(user->max_zipcode,10,K_EDIT|K_AUTODEL|K_UPPER);
                   1748: if(aborted)
                   1749:        return(0);
                   1750: strcpy(str,"Do you require your mate's zip/postal code fall within this range");
                   1751: if(user->misc&USER_REQZIP)
                   1752:        i=yesno(str);
                   1753: else
                   1754:        i=!noyes(str);
                   1755: if(i)
                   1756:        user->misc|=USER_REQZIP;
                   1757: else
                   1758:        user->misc&=~USER_REQZIP;
                   1759: if(aborted)
                   1760:     return(0);
                   1761: 
                   1762: 
                   1763: CRLF;
                   1764: nodesync();
                   1765: bputs("\1h\1gPlease enter the minimum annual income of your "
                   1766:     "mate in dollars: \1w");
                   1767: if(user->min_income)
                   1768:     sprintf(str,"%lu",user->min_income);
                   1769: else
                   1770:     str[0]=0;
                   1771: getstr(str,6,K_NUMBER|K_EDIT|K_AUTODEL);
                   1772: if(aborted) return(0);
                   1773: user->min_income=atol(str);
                   1774: 
                   1775: nodesync();
                   1776: bputs("\1h\1yPlease enter the maximum annual income of your "
                   1777:     "mate in dollars: \1w");
                   1778: if(user->max_income)
                   1779:     sprintf(str,"%lu",user->max_income);
                   1780: else
                   1781:     str[0]=0;
                   1782: getstr(str,6,K_NUMBER|K_EDIT|K_AUTODEL);
                   1783: if(aborted) return(0);
                   1784: user->max_income=atol(str);
                   1785: if(user->min_income) {
                   1786:        strcpy(str,"Do you require that your mate's income fall within this range");
                   1787:        if(user->misc&USER_REQINCOME)
                   1788:                i=yesno(str);
                   1789:        else
                   1790:                i=!noyes(str);
                   1791:        if(i)
                   1792:                user->misc|=USER_REQINCOME;
                   1793:        else
                   1794:                user->misc&=~USER_REQINCOME; }
                   1795: else
                   1796:        user->misc&=~USER_REQINCOME;
                   1797: if(aborted)
                   1798:     return(0);
                   1799: 
                   1800: 
                   1801: nodesync();
                   1802: if(yesno("\r\nIs the above information correct"))
                   1803:     break; }
                   1804: return(1);
                   1805: }
                   1806: 
                   1807: int get_your_multi(user_t *user)
                   1808: {
                   1809:        char str[128],*hdr,*p;
                   1810: 
                   1811: while(1) {
                   1812: checkline();
                   1813: hdr="\1n\1l\1h\0014 Your Profile \1n  \1h\1b(Ctrl-C to Abort)\r\n\r\n";
                   1814: bputs(hdr);
                   1815: bputs("\1n\1h\1cYour Marital Status:\r\n\r\n");
                   1816: mnemonics("~A) Single\r\n~B) Married\r\n~C) Divorced\r\n~D) Widowed\r\n"
                   1817:     "~E) Other\r\n");
                   1818: nodesync();
                   1819: bputs("\r\n\1y\1hWhich: \1w");
                   1820: uchar2ans(user->marital,str);
                   1821: if(!getstr(str,1,K_ALPHA|K_LINE|K_EDIT|K_AUTODEL|K_UPPER))
                   1822:        return(0);
                   1823: if(str[0]<='E')
                   1824:        break; }
                   1825: user->marital=ans2uchar(str);
                   1826: 
                   1827: while(1) {
                   1828: checkline();
                   1829: bputs(hdr);
                   1830: bputs("\1n\1h\1cYour Race:\r\n\r\n");
                   1831: mnemonics("~A) White\r\n~B) Black\r\n~C) Hispanic\r\n~D) Asian\r\n"
                   1832:        "~E) American Indian\r\n~F) Middle Eastern\r\n~G) Other\r\n");
                   1833: nodesync();
                   1834: bputs("\r\n\1y\1hWhich: \1w");
                   1835: uchar2ans(user->race,str);
                   1836: if(!getstr(str,1,K_ALPHA|K_LINE|K_EDIT|K_AUTODEL|K_UPPER))
                   1837:        return(0);
                   1838: if(str[0]<='G')
                   1839:     break; }
                   1840: user->race=ans2uchar(str);
                   1841: 
                   1842: while(1) {
                   1843: checkline();
                   1844: bputs(hdr);
                   1845: bputs("\1n\1h\1cYour Hair Color:\r\n\r\n");
                   1846: mnemonics("~A) Blonde\r\n~B) Brown\r\n~C) Red\r\n~D) Black\r\n"
                   1847:     "~E) Grey\r\n~F) Other\r\n");
                   1848: nodesync();
                   1849: bputs("\r\n\1y\1hWhich: \1w");
                   1850: uchar2ans(user->hair,str);
                   1851: if(!getstr(str,1,K_ALPHA|K_LINE|K_EDIT|K_AUTODEL|K_UPPER))
                   1852:        return(0);
                   1853: if(str[0]<='F')
                   1854:     break; }
                   1855: user->hair=ans2uchar(str);
                   1856: 
                   1857: while(1) {
                   1858: checkline();
                   1859: bputs(hdr);
                   1860: bputs("\1n\1h\1cYour Eye Color:\r\n\r\n");
                   1861: mnemonics("~A) Blue\r\n~B) Green\r\n~C) Hazel\r\n~D) Brown\r\n"
                   1862:     "~E) Other\r\n");
                   1863: nodesync();
                   1864: bputs("\r\n\1y\1hWhich: \1w");
                   1865: uchar2ans(user->eyes,str);
                   1866: if(!getstr(str,1,K_ALPHA|K_LINE|K_EDIT|K_AUTODEL|K_UPPER))
                   1867:        return(0);
                   1868: if(str[0]<='E')
                   1869:     break; }
                   1870: user->eyes=ans2uchar(str);
                   1871: return(1);
                   1872: }
                   1873: 
                   1874: int get_pref_multi(user_t *user)
                   1875: {
                   1876:        char str[128],*hdr,*p;
                   1877:        int i;
                   1878: 
                   1879: while(1) {
                   1880: checkline();
                   1881: hdr="\1n\1l\1h\0014 Profile of Your Preferred Mate \1n  \1h\1b"
                   1882:     "(Ctrl-C to Abort)\r\n\r\n";
                   1883: bputs(hdr);
                   1884: bputs("\1n\1h\1cSex of Your Preferred (Intimate/Romantic) Mate:\r\n\r\n");
                   1885: mnemonics("~M) Male\r\n~F) Female\r\n~*) Either\r\n");
                   1886: nodesync();
                   1887: bputs("\r\n\1y\1hWhich: ");
                   1888: str[0]=user->pref_sex;
                   1889: str[1]=0;
                   1890: if(!getstr(str,1,K_UPPER|K_EDIT|K_AUTODEL|K_LINE))
                   1891:     break;
                   1892: if(user->sex==str[0] && noyes("\r\nYou are homosexual"))
                   1893:        continue;
                   1894: if(str[0]=='M' || str[0]=='F' || str[0]=='*')
                   1895:     break; }
                   1896: user->pref_sex=str[0];
                   1897: if(aborted) return(0);
                   1898: 
                   1899: strcpy(str,"\r\nAre you seeking an any-sex (non-romantic) friendship");
                   1900: if(user->misc&USER_FRIEND)
                   1901:        i=yesno(str);
                   1902: else
                   1903:        i=!noyes(str);
                   1904: if(i)
                   1905:        user->misc|=USER_FRIEND;
                   1906: else
                   1907:        user->misc&=~USER_FRIEND;
                   1908: 
                   1909: bputs(hdr);
                   1910: bputs("\1n\1h\1cMarital Status of Your Preferred Mate:\r\n\r\n");
                   1911: mnemonics("~A) Single\r\n~B) Married\r\n~C) Divorced\r\n~D) Widowed\r\n"
                   1912:     "~E) Other\r\n~*) Any of the above\r\n");
                   1913: nodesync();
                   1914: bputs("\r\n\1y\1hPlease enter up to 4 answers: ");
                   1915: uchar2ans(user->pref_marital,str);
                   1916: if(!getstr(str,4,K_UPPER|K_LINE|K_EDIT|K_AUTODEL))
                   1917:        return(0);
                   1918: user->pref_marital=ans2uchar(str);
                   1919: if(user->pref_marital!=0xff) {
                   1920:        strcpy(str,"\r\nDo you require your mate have the martial status you "
                   1921:                "indicated");
                   1922:        if(user->misc&USER_REQMARITAL)
                   1923:                i=yesno(str);
                   1924:        else
                   1925:                i=!noyes(str);
                   1926:        if(i)
                   1927:         user->misc|=USER_REQMARITAL;
                   1928:        else
                   1929:                user->misc&=~USER_REQMARITAL; }
                   1930: else
                   1931:        user->misc&=~USER_REQMARITAL;
                   1932: if(aborted) return(0);
                   1933: 
                   1934: bputs(hdr);
                   1935: bputs("\1n\1h\1cRace of Your Preferred Mate:\r\n\r\n");
                   1936: mnemonics("~A) White\r\n~B) Black\r\n~C) Hispanic\r\n~D) Asian\r\n"
                   1937:     "~E) American Indian\r\n~F) Middle Eastern\r\n~G) Other\r\n"
                   1938:     "~*) Any of the above\r\n");
                   1939: nodesync();
                   1940: bputs("\r\n\1y\1hPlease enter up to 6 answers: ");
                   1941: uchar2ans(user->pref_race,str);
                   1942: if(!getstr(str,6,K_UPPER|K_LINE|K_EDIT|K_AUTODEL))
                   1943:        return(0);
                   1944: user->pref_race=ans2uchar(str);
                   1945: if(user->pref_race!=0xff) {
                   1946:        strcpy(str,"\r\nDo you require your mate be of the race"
                   1947:                " you indicated");
                   1948:        if(user->misc&USER_REQRACE)
                   1949:                i=yesno(str);
                   1950:        else
                   1951:                i=!noyes(str);
                   1952:        if(i)
                   1953:                user->misc|=USER_REQRACE;
                   1954:        else
                   1955:                user->misc&=~USER_REQRACE; }
                   1956: else
                   1957:        user->misc&=~USER_REQRACE;
                   1958: if(aborted) return(0);
                   1959: 
                   1960: bputs(hdr);
                   1961: bputs("\1n\1h\1cHair Color of Your Preferred Mate:\r\n\r\n");
                   1962: mnemonics("~A) Blonde\r\n~B) Brown\r\n~C) Red\r\n~D) Black\r\n"
                   1963:     "~E) Grey\r\n~F) Other\r\n~*) Any of the Above\r\n");
                   1964: nodesync();
                   1965: bputs("\r\n\1y\1hPlease enter up to 5 answers: ");
                   1966: uchar2ans(user->pref_hair,str);
                   1967: if(!getstr(str,5,K_UPPER|K_LINE|K_EDIT|K_AUTODEL))
                   1968:        return(0);
                   1969: user->pref_hair=ans2uchar(str);
                   1970: if(user->pref_hair!=0xff) {
                   1971:        strcpy(str,"\r\nDo you require your mate have the hair color"
                   1972:                " you indicated");
                   1973:        if(user->misc&USER_REQHAIR)
                   1974:                i=yesno(str);
                   1975:        else
                   1976:                i=!noyes(str);
                   1977:        if(i)
                   1978:                user->misc|=USER_REQHAIR;
                   1979:        else
                   1980:                user->misc&=~USER_REQHAIR; }
                   1981: else
                   1982:        user->misc&=~USER_REQHAIR;
                   1983: if(aborted) return(0);
                   1984: 
                   1985: 
                   1986: bputs(hdr);
                   1987: bputs("\1n\1h\1cEye Color of Your Preferred Mate:\r\n\r\n");
                   1988: mnemonics("~A) Blue\r\n~B) Green\r\n~C) Hazel\r\n~D) Brown\r\n"
                   1989:     "~E) Other\r\n~*) Any of the above\r\n");
                   1990: nodesync();
                   1991: bputs("\r\n\1y\1hPlease enter up to 4 answers: ");
                   1992: uchar2ans(user->pref_eyes,str);
                   1993: if(!getstr(str,4,K_UPPER|K_LINE|K_EDIT|K_AUTODEL))
                   1994:        return(0);
                   1995: user->pref_eyes=ans2uchar(str);
                   1996: if(user->pref_eyes!=0xff) {
                   1997:        strcpy(str,"\r\nDo you require your mate have the eye color"
                   1998:                " you indicated");
                   1999:        if(user->misc&USER_REQEYES)
                   2000:                i=yesno(str);
                   2001:        else
                   2002:                i=!noyes(str);
                   2003:        if(i)
                   2004:                user->misc|=USER_REQEYES;
                   2005:        else
                   2006:                user->misc&=~USER_REQEYES; }
                   2007: else
                   2008:        user->misc&=~USER_REQEYES;
                   2009: if(aborted) return(0);
                   2010: 
                   2011: bputs(hdr);
                   2012: bputs("\1n\1h\1cZodiac Sign of Your Preferred Mate:\r\n\r\n");
                   2013: mnemonics("~A) Aries\r\n~B) Taurus\r\n~C) Gemini\r\n~D) Cancer\r\n"
                   2014:     "~E) Leo\r\n~F) Virgo\r\n~G) Libra\r\n~H) Scorpio\r\n");
                   2015: mnemonics("~I) Sagittarius\r\n~J) Capricorn\r\n~K) Aquarius\r\n"
                   2016:     "~L) Pisces\r\n~*) Any of the above\r\n");
                   2017: nodesync();
                   2018: bputs("\r\n\1y\1hPlease enter up to 11 answers: ");
                   2019: bits2ans(user->pref_zodiac,str);
                   2020: if(!getstr(str,11,K_UPPER|K_LINE|K_EDIT|K_AUTODEL))
                   2021:        return(0);
                   2022: user->pref_zodiac=ans2bits(str);
                   2023: if(user->pref_zodiac!=0xffff) {
                   2024:        strcpy(str,"\r\nDo you require your mate have the zodiac sign"
                   2025:                " you indicated");
                   2026:        if(user->misc&USER_REQZODIAC)
                   2027:                i=yesno(str);
                   2028:        else
                   2029:                i=!noyes(str);
                   2030:        if(i)
                   2031:                user->misc|=USER_REQZODIAC;
                   2032:        else
                   2033:                user->misc&=~USER_REQZODIAC; }
                   2034: else
                   2035:        user->misc&=~USER_REQZODIAC;
                   2036: if(aborted) return(0);
                   2037: 
                   2038: return(1);
                   2039: }
                   2040: 
                   2041: void mbtype_desc(char *mbtype)
                   2042: {
                   2043:        char str[128],type[128];
                   2044: 
                   2045: while(1) {
                   2046:        checkline();
                   2047:        cls();
                   2048:        printfile("MB-TYPE.ASC");
                   2049:        nodesync();
                   2050:        bprintf("\r\n\1y\1hYour Type: \1w%s\r\n",mbtype);
                   2051:        bputs("\1y\1hLetter or Type to define: ");
                   2052:        memset(type,0,5);
                   2053:        if(!getstr(type,4,K_ALPHA|K_UPPER|K_LINE))
                   2054:                break;
                   2055:        sprintf(str,"MB-%s.ASC",type);
                   2056:        if(!fexist(str)) {
                   2057:                bputs("\r\nInvalid Letter or Type!\r\n\r\n");
                   2058:                pause();
                   2059:                continue; }
                   2060:        cls();
                   2061:        printfile(str);
                   2062:        if(lncntr && !aborted)
                   2063:                pause(); }
                   2064: }
                   2065: 
                   2066: 
                   2067: int get_mbtype(user_t *user)
                   2068: {
                   2069:        char str[256];
                   2070:        int file,i=0,e=0,n=0,s=0,f=0,t=0,p=0,j=0,q=0,ch;
                   2071:        FILE *stream;
                   2072: 
                   2073: aborted=0;
                   2074: cls();
                   2075: printfile("MB-INTRO.ASC");
                   2076: if(aborted)
                   2077:        return(0);
                   2078: bputs("\1n\1hYour answers will be kept secret.\r\n\r\n"
                   2079:        "Only your personality type will be visible to other users.\r\n\r\n");
                   2080: nodesync();
                   2081: if(!yesno("Continue with test"))
                   2082:     return(0);
                   2083: 
                   2084: if((file=nopen("MB-TYPE.QUE",O_RDONLY))==-1 ||
                   2085:        (stream=fdopen(file,"r"))==NULL) {
                   2086:        bputs("\7\r\i\hCan't open MBTYPE.QUE\r\n\1p");
                   2087:        return(0); }
                   2088: while(!feof(stream)) {
                   2089:        if(!fgets(str,200,stream))
                   2090:         break;
                   2091:        str[57]=0;
                   2092:        truncsp(str);
                   2093:        if(!str[0])
                   2094:                break;
                   2095:        cls();
                   2096:        nodesync();
                   2097:        bprintf("\1y\1hMyers-Briggs Personality Test  \1bQuestion #\1w%u  "
                   2098:                "\1b(Ctrl-C to Abort)\r\n"
                   2099:                "\r\n%s:\r\n\r\n"
                   2100:                "[\1wA\1b] %.44s\r\n"
                   2101:                "[\1wB\1b] %.44s\r\n"
                   2102:                "[\1wC\1b] cannot decide\r\n\r\n"
                   2103:                "Which: \1w"
                   2104:                ,q+1,str,str+58,str+102);
                   2105:        ch=getkeys("ABC",0);
                   2106:        if(aborted) {
                   2107:                fclose(stream);
                   2108:                return(0); }
                   2109:        if(ch=='C') {
                   2110:                q++;
                   2111:                continue; }
                   2112: 
                   2113:        if(ch=='A')
                   2114:                ch=str[146];
                   2115:        else
                   2116:                ch=str[147];
                   2117: 
                   2118:        switch(ch) {
                   2119:                case 'E':
                   2120:                        e++;
                   2121:                        break;
                   2122:                case 'I':
                   2123:                        i++;
                   2124:                        break;
                   2125:                case 'S':
                   2126:                        s++;
                   2127:                        break;
                   2128:                case 'N':
                   2129:                        n++;
                   2130:                        break;
                   2131:                case 'T':
                   2132:                        t++;
                   2133:                        break;
                   2134:                case 'F':
                   2135:                        f++;
                   2136:                        break;
                   2137:                case 'J':
                   2138:                        j++;
                   2139:                        break;
                   2140:                case 'P':
                   2141:                        p++;
                   2142:                        break; }
                   2143:        q++; }
                   2144: 
                   2145: fclose(stream);
                   2146: 
                   2147: if(i>e)
                   2148:        user->mbtype[0]='I';
                   2149: else if(i==e)
                   2150:        user->mbtype[0]='*';
                   2151: else
                   2152:        user->mbtype[0]='E';
                   2153: 
                   2154: if(s>n)
                   2155:        user->mbtype[1]='S';
                   2156: else if(s==n)
                   2157:        user->mbtype[1]='*';
                   2158: else
                   2159:        user->mbtype[1]='N';
                   2160: 
                   2161: if(t>f)
                   2162:        user->mbtype[2]='T';
                   2163: else if(t==f)
                   2164:        user->mbtype[2]='*';
                   2165: else
                   2166:        user->mbtype[2]='F';
                   2167: 
                   2168: if(p>j)
                   2169:        user->mbtype[3]='P';
                   2170: else if(p==j)
                   2171:        user->mbtype[3]='*';
                   2172: else
                   2173:        user->mbtype[3]='J';
                   2174: 
                   2175: bprintf("\1l\1y\1hYour Myers-Briggs Personality Type is \1w%s\r\n\r\n"
                   2176:        ,user->mbtype);
                   2177: 
                   2178: if(yesno("Would you like to see the personality type descriptions"))
                   2179:        mbtype_desc(user->mbtype);
                   2180: return(1);
                   2181: }
                   2182: 
                   2183: 
                   2184: int get_purity(user_t *user)
                   2185: {
                   2186:        char str[128];
                   2187:        int file,no_ans=0,pos_ans=0;
                   2188:        FILE *stream;
                   2189: 
                   2190: aborted=0;
                   2191: if(!fexist("PURITY.QUE") || purity_age>getage(user->birth))
                   2192:        return(0);
                   2193: cls();
                   2194: printfile("PURITY.ASC");
                   2195: if(aborted)
                   2196:        return(0);
                   2197: bputs("\1n\1hYour answers will be kept secret.\r\n\r\n"
                   2198:        "Only your purity score will be visible to other users.\r\n\r\n");
                   2199: nodesync();
                   2200: if(!yesno("Continue with test"))
                   2201:        return(0);
                   2202: if((file=nopen("PURITY.QUE",O_RDONLY))==-1 ||
                   2203:        (stream=fdopen(file,"r"))==NULL) {
                   2204:        bputs("\7\r\i\hCan't open PURITY.QUE\r\n\1p");
                   2205:        return(0); }
                   2206: while(!feof(stream)) {
                   2207:        if(!fgets(str,81,stream))
                   2208:                break;
                   2209:        truncsp(str);
                   2210:        cls();
                   2211:        if(str[0]=='*') {
                   2212:                printfile(str+1);
                   2213:                if(lncntr && !aborted)
                   2214:                        pause();
                   2215:                if(aborted)
                   2216:                        break;
                   2217:                continue; }
                   2218:        nodesync();
                   2219:        bprintf("\1y\1hPurity Test  \1bQuestion #\1w%u  \1b(Ctrl-C to Abort)\r\n"
                   2220:                "\r\nHave you ever:\r\n\r\n"
                   2221:                ,++pos_ans);
                   2222:        if(noyes(str))
                   2223:                no_ans++;
                   2224:        if(aborted)
                   2225:                break; }
                   2226: 
                   2227: fclose(stream);
                   2228: if(aborted)
                   2229:        return(0);
                   2230: 
                   2231: user->purity=((float)no_ans/pos_ans)*100.0;
                   2232: bprintf("\1l\1y\1hCongratulations, you are \1w%u%%\1y pure!\r\n\r\n"
                   2233:        ,user->purity);
                   2234: pause();
                   2235: return(1);
                   2236: }
                   2237: 
                   2238: int get_que(int i, user_t *inuser)
                   2239: {
                   2240:        char str[128];
                   2241:        int j,k,x,y,u;
                   2242:        user_t user=*inuser;
                   2243: 
                   2244: if(que[i]->req_age>getage(inuser->birth))
                   2245:        return(0);
                   2246: for(j=0;j<que[i]->total_ques && !aborted;j++) {
                   2247: 
                   2248:        u=user_quenum(que[i]->name,user);
                   2249:        if(u==-1) {                     /* not already answered */
                   2250:                for(u=0;u<5;u++)        /* search for unused questionnaire slot */
                   2251:                        if(sys_quenum(user.queans[u].name)==-1)
                   2252:                                break;
                   2253:                if(u==5) {              /* All questionnaire slots used!?? */
                   2254:                        bputs("\r\n\7Questionnaire error, inform sysop!\r\n");
                   2255:                        pause();
                   2256:                        return(0); } }
                   2257:        strcpy(user.queans[u].name,que[i]->name);
                   2258:        cls();
                   2259:        bprintf("\1n\1m\1hQuestionnaire: \1y%-25s \1mQuestion: "
                   2260:                "\1y%d \1mof \1y%d  \1h\1b(Ctrl-C to Abort)\r\n\r\n"
                   2261:                ,que[i]->desc,j+1,que[i]->total_ques);
                   2262:        bprintf("\1w\1h%s\r\n\r\n",que[i]->que[j].txt);
                   2263:        for(k=0;k<que[i]->que[j].answers;k++)
                   2264:                bprintf("\1h\1b%c\1w) \1g%s\r\n",'A'+k,que[i]->que[j].ans[k]);
                   2265:        nodesync();
                   2266:        bprintf("\1n\1g\r\nChoose %s%d answer%s to describe "
                   2267:                "\1hyourself\1n\1g%s: "
                   2268:                ,que[i]->que[j].allowed > 1 ? "up to ":""
                   2269:                ,que[i]->que[j].allowed,que[i]->que[j].allowed > 1 ? "s":""
                   2270:                ,j ? " or \1h-\1n\1g to go back" : "");
                   2271:        bits2ans(user.queans[u].self[j],str);
                   2272:        getstr(str,que[i]->que[j].allowed,K_UPPER|K_LINE|K_EDIT|K_AUTODEL);
                   2273:        if(aborted)
                   2274:                return(0);
                   2275:        truncsp(str);
                   2276:        if(!str[0]) {
                   2277:                j--;
                   2278:                continue; }
                   2279:        if(str[0]=='-') {
                   2280:                if(j) j-=2;
                   2281:                else j--;
                   2282:                continue; }
                   2283:        y=strlen(str);
                   2284:        for(x=0;x<y;x++)
                   2285:                if(!isalpha(str[x]) || str[x]-'A'>que[i]->que[j].answers-1)
                   2286:                        break;
                   2287:        if(x<y) {
                   2288:                j--;
                   2289:                continue; }
                   2290:        user.queans[u].self[j]=ans2bits(str);
                   2291:        nodesync();
                   2292:        bprintf("\1n\1g\r\n%s%d answer%s to describe your \1hpreferred mate"
                   2293:                "\1n\1g or \1h*\1n\1g for any: "
                   2294:                ,que[i]->que[j].answers > 1 ? "Up to ":""
                   2295:                ,que[i]->que[j].answers,que[i]->que[j].answers > 1 ? "s":"");
                   2296:        if(user.queans[u].pref[j])
                   2297:                bits2ans(user.queans[u].pref[j],str);
                   2298:        getstr(str,que[i]->que[j].answers,K_UPPER|K_LINE|K_EDIT|K_AUTODEL);
                   2299:        if(aborted)
                   2300:                return(0);
                   2301:        truncsp(str);
                   2302:        if(!str[0]) {
                   2303:                j--;
                   2304:                continue; }
                   2305:        y=strlen(str);
                   2306:        for(x=0;x<y;x++)
                   2307:                if(isalpha(str[x]) && str[x]-'A'>que[i]->que[j].answers-1)
                   2308:                        break;
                   2309:        if(x<y) {
                   2310:                j--;
                   2311:                continue; }
                   2312:        user.queans[u].pref[j]=ans2bits(str); }
                   2313: *inuser=user;
                   2314: return(1);
                   2315: }
                   2316: 
                   2317: /* Gets/updates profile from user. Returns 0 if aborted. */
                   2318: 
                   2319: char get_user_info(user_t *user)
                   2320: {
                   2321:        char str[128],*p,*hdr;
                   2322:        int i,j,k,x,y;
                   2323: 
                   2324: while(1) {
                   2325:        checkline();
                   2326:        timeleft=0xffff;
                   2327:        aborted=0;
                   2328:        main_user_info(*user);
                   2329:        CRLF;
                   2330:        bputs("\1n\1h");
                   2331:        bputs("\1b[\1wA\1b] Your name, height, weight, income, location, and "
                   2332:                        "text\r\n"
                   2333:                  "\1b[\1wB\1b] Your marital status, race, hair color, and eye "
                   2334:                        "color\r\n"
                   2335:                  "\1b[\1wC\1b] Preferred age, height, weight, location, and income\r\n"
                   2336:                  "\1b[\1wD\1b] Preferred sex, marital status, race, hair color, eye "
                   2337:                        "color, and zodiac\r\n"
                   2338:                  );
                   2339:        for(i=0;i<total_ques;i++) {
                   2340:                if(que[i]->req_age>getage(user->birth))
                   2341:                        continue;
                   2342:                bprintf("\1b[\1w%u\1b] \1w%s \1bquestionnaire\1b (%u questions) \1w%s\r\n"
                   2343:                        ,i+1,que[i]->desc,que[i]->total_ques
                   2344:                        ,user_quenum(que[i]->name,*user)==-1 ? "[Unanswered]":"[Answered]");
                   2345:                        }
                   2346:        bprintf("\1b[\1wM\1b] Myers-Briggs personality test (70 questions) "
                   2347:                "\1w[%s]\r\n",user->mbtype[0] ? user->mbtype : "Unanswered");
                   2348:        if(fexist("PURITY.QUE") && purity_age<=getage(user->birth))
                   2349:                bprintf("\1b[\1wP\1b] Purity test \1w(%u%% pure)\r\n"
                   2350:                        ,user->purity);
                   2351:        bputs("\r\n\1bWhich or [\1wQ\1b]uit: \1w");
                   2352:        i=getkeys("ABCDMPQ",total_ques);
                   2353:        if(i&0x8000) {
                   2354:                i&=~0x8000;
                   2355:                i--;
                   2356:                get_que(i,user);
                   2357:                continue; }
                   2358: 
                   2359:        switch(i) {
                   2360:                case 'A':
                   2361:                        get_your_det(user);
                   2362:                        break;
                   2363:                case 'C':
                   2364:                        get_pref_det(user);
                   2365:                        break;
                   2366:                case 'B':
                   2367:                        get_your_multi(user);
                   2368:                        break;
                   2369:                case 'D':
                   2370:                        get_pref_multi(user);
                   2371:                        break;
                   2372:                case 'M':
                   2373:                        get_mbtype(user);
                   2374:                        break;
                   2375:                case 'P':
                   2376:                        get_purity(user);
                   2377:                        break;
                   2378:                case 'Q':
                   2379:                        return(1); } }
                   2380: }
                   2381: 
                   2382: void write_user()
                   2383: {
                   2384:     char str[256];
                   2385: 
                   2386: if(auto_update && time(NULL)-useron.updated>(long)auto_update*24L*60L*60L)
                   2387:        useron.updated=time(NULL);
                   2388: fseek(stream,useron_record*sizeof(user_t),SEEK_SET);
                   2389: fwrite(&useron,sizeof(user_t),1,stream);
                   2390: fflush(stream);
                   2391: 
                   2392: ixb.updated=useron.updated;
                   2393: if(useron.misc&USER_DELETED)
                   2394:     ixb.number=0;
                   2395: else
                   2396:     ixb.number=useron.number;
                   2397: strcpy(str,useron.name);
                   2398: strupr(str);
                   2399: ixb.name=crc32(str);
                   2400: ixb.system=system_crc;
                   2401: fseek(index,useron_record*sizeof(ixb_t),SEEK_SET);
                   2402: fwrite(&ixb,sizeof(ixb_t),1,index);
                   2403: fflush(index);
                   2404: if(!ixb.number) {
                   2405:        sprintf(str,"%04u.MSG",useron.number);
                   2406:        remove(str); }
                   2407: }
                   2408: 
                   2409: 
                   2410: void add_userinfo()
                   2411: {
                   2412:        static user_t user;
                   2413:        char str[128];
                   2414:        ushort tleft=timeleft;
                   2415:        int i;
                   2416: 
                   2417: if(!cdt_warning(profile_cdt))
                   2418:        return;
                   2419: timeleft=0xffff;
                   2420: user.number=user_number;
                   2421: user.sex=user_sex;
                   2422: strcpy(user.name,user_name);
                   2423: strcpy(user.realname,user_name);
                   2424: strcpy(user.system,system_name);
                   2425: strcpy(user.birth,user_birth);
                   2426: strcpy(user.zipcode,user_zipcode);
                   2427: sprintf(user.min_zipcode,"%c0000",user_zipcode[0]);
                   2428: sprintf(user.max_zipcode,"%c9999",user_zipcode[0]);
                   2429: strcpy(user.location,user_location);
                   2430: if(user.sex!='M' && user.sex!='F') {
                   2431:        if(yesno("Are you of male gender"))
                   2432:                user.sex='M';
                   2433:        else
                   2434:                user.sex='F'; }
                   2435: if(!getage(user.birth))
                   2436:        while(1) {
                   2437:                checkline();
                   2438:                cls();
                   2439:                bputs("\1l\1y\1hYour birthdate (MM/DD/YY): ");
                   2440:                if(!getstr(user.birth,8,K_UPPER|K_LINE))
                   2441:                        return;
                   2442:                if(getage(user.birth))
                   2443:                        break; }
                   2444: 
                   2445: user.pref_sex=user.sex=='M' ? 'F' : 'M';
                   2446: user.created=time(NULL);
                   2447: if(!get_your_det(&user) || !get_your_multi(&user) || !get_pref_multi(&user)
                   2448:        || !get_pref_det(&user)) {
                   2449:        timeleft=tleft;
                   2450:        return; }
                   2451: for(i=0;i<total_ques;i++) {
                   2452:        aborted=0;
                   2453:        if(que[i]->req_age>getage(user.birth))
                   2454:                continue;
                   2455:        timeleft=0xffff;
                   2456:        cls();
                   2457:        bprintf("\1w\1h%s Questionnaire: \1y%u questions\r\n\r\n"
                   2458:                "\1cAnswers will be viewable by other users.\r\n\r\n"
                   2459:                ,que[i]->desc,que[i]->total_ques);
                   2460:        if(yesno("Continue with questionnaire"))
                   2461:                get_que(i,&user); }
                   2462: timeleft=0xffff;
                   2463: get_mbtype(&user);
                   2464: timeleft=0xffff;
                   2465: get_purity(&user);
                   2466: if(!get_user_info(&user)) {
                   2467:        timeleft=tleft;
                   2468:        return; }
                   2469: user.updated=time(NULL);
                   2470: useron=user;
                   2471: bputs("\1n\1h\r\nSaving...");
                   2472: rewind(index);
                   2473: while(!feof(index)) {
                   2474:        if(!fread(&ixb,sizeof(ixb_t),1,index))
                   2475:                break;
                   2476:        if(!ixb.number) {         /* Deleted User */
                   2477:                fseek(index,ftell(index)-sizeof(ixb_t),SEEK_SET);
                   2478:                break; } }
                   2479: 
                   2480: useron_record=ftell(index)/sizeof(ixb_t);
                   2481: 
                   2482: write_user();
                   2483: adjust_cdt(profile_cdt);
                   2484: 
                   2485: if(notify_user && notify_user!=user_number) {
                   2486:        sprintf(str,"\1n\1hSMM: \1y%s \1madded %s profile to the Match Maker.\r\n"
                   2487:                ,user_name,user_sex=='M' ? "his":"her");
                   2488:        if(node_dir[0])
                   2489:                putsmsg(notify_user,str);
                   2490:        else
                   2491:                puttgram(notify_user,str); }
                   2492: 
                   2493: timeleft=tleft;
                   2494: }
                   2495: 
                   2496: void delphoto(user_t user)
                   2497: {
                   2498:        char fname[64],path[128];
                   2499:        int i;
                   2500:        struct ffblk ff;
                   2501: 
                   2502: if(!(user.misc&USER_PHOTO))
                   2503:        return;
                   2504: for(i=0;user.system[i];i++)
                   2505:        if(isalnum(user.system[i]))
                   2506:         break;
                   2507: if(!user.system[i])
                   2508:        fname[0]='~';
                   2509: else
                   2510:        fname[0]=user.system[i];
                   2511: for(i=strlen(user.system)-1;i>0;i--)
                   2512:        if(isalnum(user.system[i]))
                   2513:                break;
                   2514: if(i<=0)
                   2515:        fname[1]='~';
                   2516: else
                   2517:        fname[1]=user.system[i];
                   2518: fname[2]=0;
                   2519: strupr(user.system);
                   2520: strcat(fname,base41(crc16(user.system),tmp));
                   2521: strcat(fname,base41(user.number,tmp));
                   2522: strcat(fname,".*");
                   2523: strupr(fname);
                   2524: sprintf(path,"PHOTO\\%s",fname);
                   2525: i=findfirst(path,&ff,0);
                   2526: if(i)
                   2527:        return;
                   2528: sprintf(path,"PHOTO\\%s",ff.ff_name);
                   2529: if(remove(path))
                   2530:        bprintf("\1r\1h\7%s couldn't be removed!\1n\r\n",path);
                   2531: else
                   2532:        bprintf("\1r\1hPhoto removed.\r\n");
                   2533: }
                   2534: 
                   2535: 
                   2536: void smm_exit()
                   2537: {
                   2538:        char str[128];
                   2539:        int i;
                   2540:        FILE *in,*out;
                   2541: 
                   2542: if(io_int) {
                   2543:        io_int=0;
                   2544:        ivhctl(0); }
                   2545: if(com_port) {
                   2546:        for(i=0;i<5;i++)
                   2547:                if(!rioctl(TXBC))               /* wait for rest of output */
                   2548:                        break;
                   2549:                else
                   2550:                        mswait(1000);
                   2551:     rioini(0,0); }
                   2552: if(useron.number) {
                   2553:        useron.lastin=time(NULL);
                   2554:        write_user(); }
                   2555: if(stream)
                   2556:        fclose(stream);
                   2557: if(cdt_adjustment) {
                   2558:        if(node_dir[0]) {
                   2559:                sprintf(str,"%sMODUSER.DAT",node_dir);
                   2560:                if((out=fopen(str,"wt"))==NULL) {
                   2561:                        bprintf("Error opening %s for write\r\n",str);
                   2562:                        return; }
                   2563:                fprintf(out,"%ld",cdt_adjustment);
                   2564:                fclose(out); }
                   2565:        else {                                                  /* Write back credits to DOOR.SYS */
                   2566:                strcpy(str,door_sys);
                   2567:                str[strlen(str)-1]='_';
                   2568:                remove(str);
                   2569:                rename(door_sys,str);
                   2570:                if((in=fopen(str,"rb"))==NULL) {
                   2571:                        bprintf("Error opening %s for read\r\n",str);
                   2572:             return; }
                   2573:                if((out=fopen(door_sys,"wb"))==NULL) {
                   2574:                        bprintf("Error opening %s for write\r\n",door_sys);
                   2575:                        return; }
                   2576:                for(i=0;!feof(in);i++) {
                   2577:                        if(!fgets(tmp,128,in))
                   2578:                                break;
                   2579:                        if(i+1==30)
                   2580:                                fprintf(out,"%ld\r\n",-(cdt_adjustment/1024L));
                   2581:                        else if(i+1==31)
                   2582:                                fprintf(out,"%ld\r\n",(user_cdt+cdt_adjustment)/1024L);
                   2583:                        else
                   2584:                                fprintf(out,"%s",tmp); }
                   2585:                fclose(in);
                   2586:                fclose(out);
                   2587:                remove(str);
                   2588:                } }
                   2589: }
                   2590: 
                   2591: time_t checktime()
                   2592: {
                   2593:        struct tm tm;
                   2594: 
                   2595: memset(&tm,0,sizeof(tm));
                   2596: tm.tm_year=94;
                   2597: tm.tm_mday=1;
                   2598: return(mktime(&tm)^0x2D24BD00L);
                   2599: }
                   2600: 
                   2601: void statusline(void)
                   2602: {
                   2603:        int col,row;
                   2604: 
                   2605: col=lclwx();
                   2606: row=lclwy();
                   2607: lclxy(1,node_scrnlen);
                   2608: lclatr(CYAN|HIGH|(BLUE<<4));
                   2609: lputs("  ");
                   2610: lprintf("%-25.25s %02d %-25.25s  %02d %c %s"
                   2611:     ,user_name,user_level,user_realname[0] ? user_realname : user_location
                   2612:     ,getage(user_birth)
                   2613:     ,user_sex ? user_sex : SP
                   2614:     ,user_phone);
                   2615: lputc(CLREOL);
                   2616: lclatr(LIGHTGRAY);
                   2617: lclxy(col,row);
                   2618: }
                   2619: 
                   2620: 
                   2621: int minor_protection(user_t user)
                   2622: {
                   2623: if(!user_number || !age_split || SYSOP)
                   2624:        return(0);
                   2625: if(getage(user_birth)<age_split && getage(user.birth)>=age_split)
                   2626:        return(1);
                   2627: if(getage(user_birth)>=age_split && getage(user.birth)<age_split)
                   2628:        return(1);
                   2629: return(0);
                   2630: }
                   2631: 
                   2632: void main(int argc, char **argv)
                   2633: {
                   2634:        char    str[512],name[128],desc[128],gotoname[128],*p,ext,ch;
                   2635:        int     i,j,k,file,match,found;
                   2636:        uint    base=0xffff;
                   2637:        ushort  tleft;
                   2638:        long    l,offset;
                   2639:        ulong   name_crc,sys_crc,*crc_lst,ul;
                   2640:        FILE    *fp,*que_lst;
                   2641:        user_t  user;
                   2642:        wall_t  wall;
                   2643:        struct  ffblk ff;
                   2644: 
                   2645: nodefile=-1;
                   2646: node_misc=NM_LOWPRIO;
                   2647: com_port=-1;
                   2648: com_base=0;
                   2649: com_irq=com_rate=0;
                   2650: node_dir[0]=exec_dir[0]=temp_dir[0]=ctrl_dir[0]=door_sys[0]=system_name[0]=0;
                   2651: sys_name[0]=0;
                   2652: 
                   2653: p=getenv("SBBSNODE");
                   2654: if(p) {
                   2655:        strcpy(node_dir,p);
                   2656:        if(node_dir[strlen(node_dir)-1]!='\\')
                   2657:                strcat(node_dir,"\\");
                   2658:        initdata(); }
                   2659: 
                   2660: gotoname[0]=0;
                   2661: for(i=1;i<argc;i++) {
                   2662:        if(argv[i][0]=='/') {
                   2663:                switch(toupper(argv[i][1])) {
                   2664:                        case 'P':
                   2665:                                com_port=atoi(argv[i]+2);
                   2666:                                break;
                   2667:                        case 'I':
                   2668:                                com_irq=atoi(argv[i]+2);
                   2669:                                break;
                   2670:                        case 'C':
                   2671:                                com_base=ahtoul(argv[i]+2);
                   2672:                                break;
                   2673:                        case 'R':
                   2674:                                com_rate=atol(argv[i]+2);
                   2675:                                break;
                   2676:                        case 'T':
                   2677:                                mswtyp=atoi(argv[i]+2);
                   2678:                                break;
                   2679:                        case 'N':
                   2680:                                node_dir[0]=0;
                   2681:                                break;
                   2682:                        default:
                   2683:                                printf("\nusage: SMM [DOOR.SYS] [/option] [/option] [...] [user name]\n");
                   2684:                                printf("\n");
                   2685:                                printf("where:\n");
                   2686:                                printf("       DOOR.SYS is the path and filename of DOOR.SYS\n");
                   2687:                                printf("\n");
                   2688:                                printf("       /p# sets com port\n");
                   2689:                                printf("       /i# sets com irq\n");
                   2690:                                printf("       /c# sets com I/O address (or DIGI or FOSSIL)\n");
                   2691:                                printf("       /r# sets com rate\n");
                   2692:                                printf("       /t# sets time-slice API support\n");
                   2693:                                printf("\n");
                   2694:                                printf("       user name (if specified) is user to look-up\n");
                   2695:                                exit(1); }
                   2696:                continue; }
                   2697:        if(!node_dir[0] && !door_sys[0]) {
                   2698:                strcpy(door_sys,argv[i]);
                   2699:                continue; }
                   2700:        if(gotoname[0])
                   2701:                strcat(gotoname," ");
                   2702:        strcat(gotoname,argv[i]); }
                   2703: 
                   2704: if(!node_dir[0] && !door_sys[0]) {
                   2705:        printf("\n\7SBBSNODE environment variable not set and DOOR.SYS not "
                   2706:                "specified.\n");
                   2707:        exit(1); }
                   2708: 
                   2709: if(door_sys[0]) {
                   2710:        #ifdef __TURBOC__
                   2711:                ctrlbrk(cbreakh);
                   2712:        #endif
                   2713: 
                   2714:        #ifdef __WATCOMC__
                   2715:                putenv("TZ=UCT0");
                   2716:                setvbuf(stdout,NULL,_IONBF,0);
                   2717:                setvbuf(stderr,NULL,_IONBF,0);
                   2718:        #endif
                   2719: 
                   2720:        if(setmode(fileno(stderr),O_BINARY)==-1) {       /* eliminate LF expansion */
                   2721:                printf("\n\7Can't set stderr to BINARY\n");
                   2722:                exit(1); }
                   2723: 
                   2724:        starttime=time(NULL);                   /* initialize start time stamp */
                   2725:        wordwrap[0]=0;                                  /* set wordwrap to null */
                   2726:        attr(LIGHTGRAY);                                /* initialize color and curatr to plain */
                   2727:        mnehigh=LIGHTGRAY|HIGH;                 /* mnemonics highlight color */
                   2728:        mnelow=GREEN;                                   /* mnemonics normal text color */
                   2729:        sec_warn=180;                                   /* seconds till inactivity warning */
                   2730:        sec_timeout=300;                                /* seconds till inactivity timeout */
                   2731:        tos=lncntr=0;                                   /* init topofscreen and linecounter to 0 */
                   2732:        lastnodemsg=0;                                  /* Last node to send message to */
                   2733:        aborted=0;                                              /* Ctrl-C hit flag */
                   2734: 
                   2735:        fp=fopen(door_sys,"rb");
                   2736:        if(!fp) {
                   2737:                printf("\n\7ERROR opening %s\n",door_sys);
                   2738:                exit(2); }
                   2739:        user_misc=user_flags2[0]=user_flags3[0]=user_flags4[0]=0;
                   2740:        user_rest[0]=user_exempt[0]=0;
                   2741:        user_sex=user_address[0]=user_zipcode[0]=user_realname[0]=0;
                   2742:        str[0]=0;
                   2743:        fgets(str,81,fp);                               // 01: COM port - if local
                   2744:        if(com_port==-1)
                   2745:                com_port=atoi(str+3);
                   2746:        str[0]=0;
                   2747:        fgets(str,81,fp);                               // 02: DCE Rate
                   2748:        user_dce=atoi(str);
                   2749:        fgets(str,81,fp);                               // 03: Data bits
                   2750:        str[0]=0;
                   2751:        fgets(str,81,fp);                               // 04: Node num
                   2752:        node_num=atoi(str);
                   2753:        str[0]=0;
                   2754:        fgets(str,81,fp);                               // 05: DTE rate
                   2755:        if(!com_rate)
                   2756:                com_rate=atol(str);
                   2757:        fgets(str,81,fp);                               // 06: Screen display
                   2758:        fgets(str,81,fp);                               // 07: Printer toggle
                   2759:        fgets(str,81,fp);                               // 08: Page bell
                   2760:        fgets(str,81,fp);                               // 09: Caller alarm
                   2761:        str[0]=0;
                   2762:        fgets(str,81,fp);                               // 10: User name
                   2763:        sprintf(user_name,"%.25s",str);
                   2764:        truncsp(user_name);
                   2765:        str[0]=0;
                   2766:        fgets(str,81,fp);                               // 11: User location
                   2767:        sprintf(user_location,"%.30s",str);
                   2768:        truncsp(user_location);
                   2769:        str[0]=0;
                   2770:        fgets(str,81,fp);                               // 12: Home phone
                   2771:        sprintf(user_phone,"%.12s",str);
                   2772:        truncsp(user_phone);
                   2773:        fgets(str,81,fp);                               // 13: Work phone
                   2774:        fgets(str,81,fp);                               // 14: Password
                   2775:        str[0]=0;
                   2776:        fgets(str,81,fp);                               // 15: Security Level
                   2777:        user_level=atoi(str);
                   2778:        fgets(str,81,fp);                               // 16: Total logons
                   2779:        fgets(str,81,fp);                               // 17: Last on date
                   2780:        str[0]=0;
                   2781:        fgets(str,81,fp);                               // 18: Time left in seconds
                   2782:        timeleft=atoi(str);
                   2783:        fgets(str,81,fp);                               // 19: Time left in minutes
                   2784:        str[0]=0;
                   2785:        fgets(str,81,fp);                               // 20: Graphics
                   2786:        if(!strnicmp(str,"GR",2))
                   2787:                user_misc|=(COLOR|ANSI);
                   2788:        str[0]=0;
                   2789:        fgets(str,81,fp);                               // 21: Screen length
                   2790:        user_rows=atoi(str);
                   2791:        if(user_rows<10)
                   2792:                user_rows=24;
                   2793:        fgets(str,81,fp);                               // 22: Expert?
                   2794:        str[0]=0;
                   2795:        fgets(str,81,fp);                               // 23: Registered conferences
                   2796:        sprintf(user_flags1,"%.26s",str);
                   2797:        truncsp(user_flags1);
                   2798:        fgets(str,81,fp);                               // 24: Conference came from
                   2799:        str[0]=0;
                   2800:        fgets(str,81,fp);                               // 25: User's expiration date
                   2801:        user_expire=dstrtounix(str);
                   2802:        str[0]=0;
                   2803:        fgets(str,81,fp);                               // 26: User's number
                   2804:        user_number=atoi(str);
                   2805:        fgets(str,81,fp);                               // 27: Default protocol
                   2806:        fgets(str,81,fp);                               // 28: Total uploads
                   2807:        fgets(str,81,fp);                               // 29: Total downloads
                   2808:        fgets(str,81,fp);                               // 30: Kbytes downloaded today
                   2809:        str[0]=0;
                   2810:        fgets(str,81,fp);                               // 31: Max Kbytes to download today
                   2811:        user_cdt=atol(str)*1024UL;
                   2812:        str[0]=0;
                   2813:        fgets(str,81,fp);                               // 32: Birthday
                   2814:        truncsp(str);
                   2815:        sprintf(user_birth,"%.8s",str);
                   2816:        fgets(str,81,fp);                               // 33: Path to MAIN
                   2817:        fgets(str,81,fp);                               // 34: Path to GEN
                   2818:        str[0]=0;
                   2819:        fgets(str,81,fp);                                // 35: Sysop's name
                   2820:        sprintf(sys_op,"%.40s",str);
                   2821:        truncsp(sys_op);
                   2822:        fclose(fp);
                   2823:        con_fp=stderr;
                   2824:        if(setmode(fileno(con_fp),O_BINARY)==-1) {       /* eliminate LF expansion */
                   2825:                printf("Can't set console output to BINARY\n");
                   2826:                exit(1); }
                   2827:        }
                   2828: 
                   2829: if(!user_number) {
                   2830:        printf("\7\nERROR: Invalid user number (%u)\n",user_number);
                   2831:        exit(5); }
                   2832: 
                   2833: if(*(&riobp-1)!=23) {
                   2834:     printf("Wrong rciol.obj\n");
                   2835:     exit(1); }
                   2836: 
                   2837: node_scrnlen=lclini(0xd<<8);     /* Tab expansion, no CRLF expansion */
                   2838: lclini(node_scrnlen-1);
                   2839: 
                   2840: if(com_port) {
                   2841:        lprintf("\r\nInitializing COM port %u: ",com_port);
                   2842:        switch(com_base) {
                   2843:                case 0xb:
                   2844:                        lputs("PC BIOS");
                   2845:                        rioctl(I14PC);
                   2846:                        if(!com_irq) com_irq=com_port-1;
                   2847:                        break;
                   2848:                case 0xffff:
                   2849:                case 0xd:
                   2850:                        lputs("DigiBoard");
                   2851:                        rioctl(I14DB);
                   2852:                        if(!com_irq) com_irq=com_port-1;
                   2853:                        break;
                   2854:                case 0xe:
                   2855:                        lputs("PS/2 BIOS");
                   2856:                        rioctl(I14PS);
                   2857:                        if(!com_irq) com_irq=com_port-1;
                   2858:                        break;
                   2859:                case 0xf:
                   2860:                        lputs("FOSSIL");
                   2861:                        rioctl(I14FO);
                   2862:                        if(!com_irq) com_irq=com_port-1;
                   2863:                        break;
                   2864:                case 0:
                   2865:                        base=com_port;
                   2866:                        lputs("UART I/O (BIOS), ");
                   2867:                        if(com_irq)
                   2868:                                lprintf("IRQ %d",com_irq);
                   2869:                        else lputs("default IRQ");
                   2870:                        break;
                   2871:                default:
                   2872:                        base=com_base;
                   2873:                        lprintf("UART I/O %Xh, ",com_base);
                   2874:                        if(com_irq)
                   2875:                                lprintf("IRQ %d",com_irq);
                   2876:                        else lputs("default IRQ");
                   2877:                        break; }
                   2878: 
                   2879:        if(base==0xffff)
                   2880:                lprintf(" channel %u",com_irq);
                   2881:        i=rioini(base,com_irq);
                   2882:        if(i) {
                   2883:                lprintf(" - Failed! (%d)\r\n",i);
                   2884:                exit(1); }
                   2885:        if(mdm_misc&MDM_FLOWCTRL)
                   2886:                rioctl(IOSM|CTSCK|RTSCK); /* set rts/cts chk */
                   2887:        if(com_rate)
                   2888:                setbaud((uint)(com_rate&0xffffL));
                   2889:        msr=&riobp-1; }
                   2890: 
                   2891: /* STATUS LINE */
                   2892: statusline();
                   2893: 
                   2894: rioctl(TSTYPE|mswtyp);  /* set time-slice API type */
                   2895: 
                   2896: rioctl(CPTON);                 /* ctrl-p translation */
                   2897: 
                   2898: i=INT29L;
                   2899: if(com_port)
                   2900:        i|=(INT29R|INT16);
                   2901: ivhctl(i);
                   2902: io_int=1;
                   2903: 
                   2904: atexit(smm_exit);
                   2905: 
                   2906: printf("\r\nSynchronet Match Maker  v%s  Developed 1995-1997 Rob Swindell\n\n"
                   2907:     ,SMM_VER);
                   2908: 
                   2909: if(checktime()) {
                   2910:     printf("Time problem!\n");
                   2911:     return; }
                   2912: 
                   2913: if((file=nopen("SMM.CFG",O_RDONLY))==-1) {
                   2914:        bprintf("\r\n\7Error opening/creating SMM.DAB\r\n");
                   2915:     exit(1); }
                   2916: if((stream=fdopen(file,"w+b"))==NULL) {
                   2917:        bprintf("\r\n\7Error converting SMM.DAB file handle to stream\r\n");
                   2918:     exit(1); }
                   2919: str[0]=0;
                   2920: fgets(str,128,stream);
                   2921: purity_age=atoi(str);
                   2922: str[0]=0;
                   2923: fgets(str,128,stream);
                   2924: min_age=atoi(str);
                   2925: str[0]=0;
                   2926: fgets(str,128,stream);
                   2927: min_level=atoi(str);
                   2928: 
                   2929: req_flags1[0]=0;
                   2930: fgets(req_flags1,128,stream);
                   2931: req_flags1[27]=0;
                   2932: truncsp(req_flags1);
                   2933: 
                   2934: req_flags2[0]=0;
                   2935: fgets(req_flags2,128,stream);
                   2936: req_flags2[27]=0;
                   2937: truncsp(req_flags2);
                   2938: 
                   2939: req_flags3[0]=0;
                   2940: fgets(req_flags3,128,stream);
                   2941: req_flags3[27]=0;
                   2942: truncsp(req_flags3);
                   2943: 
                   2944: req_flags4[0]=0;
                   2945: fgets(req_flags4,128,stream);
                   2946: req_flags4[27]=0;
                   2947: truncsp(req_flags4);
                   2948: 
                   2949: str[0]=0;
                   2950: fgets(str,128,stream);
                   2951: profile_cdt=atol(str);
                   2952: str[0]=0;
                   2953: fgets(str,128,stream);
                   2954: telegram_cdt=atol(str);
                   2955: str[0]=0;
                   2956: fgets(str,128,stream);
                   2957: auto_update=atoi(str);
                   2958: str[0]=0;
                   2959: fgets(str,128,stream);
                   2960: notify_user=atoi(str);
                   2961: 
                   2962: fgets(str,128,stream);         // regnum
                   2963: 
                   2964: str[0]=0;
                   2965: fgets(str,128,stream);
                   2966: telegram_level=atoi(str);
                   2967: 
                   2968: str[0]=0;
                   2969: fgets(str,128,stream);
                   2970: que_level=atoi(str);
                   2971: 
                   2972: str[0]=0;
                   2973: fgets(str,128,stream);
                   2974: wall_level=atoi(str);
                   2975: 
                   2976: str[0]=0;
                   2977: fgets(str,128,stream);
                   2978: wall_cdt=atol(str);
                   2979: 
                   2980: str[0]=0;
                   2981: fgets(str,128,stream);
                   2982: que_cdt=atol(str);
                   2983: 
                   2984: fgets(zmodem_send,128,stream);
                   2985: if(!zmodem_send[0])
                   2986:     strcpy(zmodem_send,DEFAULT_ZMODEM_SEND);
                   2987: truncsp(zmodem_send);
                   2988: 
                   2989: str[0]=0;
                   2990: fgets(str,128,stream);
                   2991: smm_misc=atol(str);
                   2992: 
                   2993: fgets(str,128,stream);
                   2994: sprintf(system_name,"%.40s",str);
                   2995: truncsp(system_name);
                   2996: 
                   2997: fgets(local_view,128,stream);
                   2998: truncsp(local_view);
                   2999: 
                   3000: str[0]=0;
                   3001: fgets(str,128,stream);
                   3002: sysop_level=atoi(str);
                   3003: if(!sysop_level)
                   3004:     sysop_level=90;
                   3005: 
                   3006: str[0]=0;
                   3007: fgets(str,128,stream);
                   3008: wall_age=atoi(str);
                   3009: 
                   3010: str[0]=0;
                   3011: fgets(str,128,stream);
                   3012: age_split=atoi(str);
                   3013: 
                   3014: fclose(stream);
                   3015: 
                   3016: if(!system_name[0] && sys_name[0])
                   3017:        strcpy(system_name,sys_name);
                   3018: if(!system_name[0]) {
                   3019:     printf("\7\nERROR: System name not specified\n");
                   3020:     exit(3) ; }
                   3021: 
                   3022: sprintf(str,"%.25s",system_name);
                   3023: strupr(str);
                   3024: system_crc=crc32(str);
                   3025: 
                   3026: if((file=open("SMM.DAB",O_RDWR|O_BINARY|SH_DENYNO|O_CREAT
                   3027:     ,S_IWRITE|S_IREAD))==-1) {
                   3028:        bprintf("\r\n\7Error opening/creating SMM.DAB\r\n");
                   3029:     exit(1); }
                   3030: if((stream=fdopen(file,"w+b"))==NULL) {
                   3031:        bprintf("\r\n\7Error converting SMM.DAB file handle to stream\r\n");
                   3032:     exit(1); }
                   3033: setvbuf(stream,0L,_IOFBF,4096);
                   3034: 
                   3035: if((file=open("SMM.IXB",O_RDWR|O_BINARY|SH_DENYNO|O_CREAT
                   3036:     ,S_IWRITE|S_IREAD))==-1) {
                   3037:        bprintf("\r\n\7Error opening/creating SMM.IXB\r\n");
                   3038:     exit(1); }
                   3039: if((index=fdopen(file,"w+b"))==NULL) {
                   3040:        bprintf("\r\n\7Error converting SMM.IXB file handle to stream\r\n");
                   3041:     exit(1); }
                   3042: setvbuf(stream,0L,_IOFBF,1024);
                   3043: 
                   3044: trashfile=NULL;
                   3045: if((file=open("SMM.CAN",O_RDONLY|SH_DENYNO))!=-1) {
                   3046:        trashfile=fdopen(file,"rb");
                   3047:        setvbuf(trashfile,NULL,_IOFBF,4096); }
                   3048: 
                   3049: total_ques=0;
                   3050: i=nopen("QUE.LST",O_RDONLY);
                   3051: if(i!=-1)
                   3052:        que_lst=fdopen(i,"rb");
                   3053: else
                   3054:        que_lst=NULL;
                   3055: i=0;
                   3056: while(que_lst && !feof(que_lst) && i<5) {
                   3057:        if(!fgets(name,81,que_lst))
                   3058:                break;
                   3059:        truncsp(name);
                   3060:        strupr(name);
                   3061:        sprintf(str,"%s.QUE",name);
                   3062:        if(!fgets(desc,81,que_lst))
                   3063:                break;
                   3064:        truncsp(desc);
                   3065:        if(!fgets(tmp,81,que_lst))
                   3066:                break;
                   3067:        truncsp(tmp);
                   3068:        if((file=nopen(str,O_RDONLY))!=-1) {
                   3069:                fp=fdopen(file,"rb");
                   3070:                total_ques++;
                   3071:                if((que[i]=(questionnaire_t *)MALLOC(sizeof(questionnaire_t)))==NULL) {
                   3072:                        bprintf("Can't malloc questionnaires!\r\n");
                   3073:                        exit(1); }
                   3074:                sprintf(que[i]->name,"%.8s",name);
                   3075:                sprintf(que[i]->desc,"%.25s",desc);
                   3076:                que[i]->req_age=atoi(tmp);
                   3077:                fgets(str,128,fp);
                   3078:                que[i]->total_ques=atoi(str);
                   3079:                if(que[i]->total_ques<1 || que[i]->total_ques>20) {
                   3080:                        bprintf("Invalid number of questions (%d) in questionnaire #%d\r\n"
                   3081:                                ,que[i]->total_ques,i+1);
                   3082:                        exit(1); }
                   3083:                for(j=0;j<que[i]->total_ques;j++) {
                   3084:                        if(!fgets(str,128,fp))
                   3085:                                break;
                   3086:                        truncsp(str);
                   3087:                        if(!str[0])
                   3088:                                break;
                   3089:                        str[80]=0;
                   3090:                        strcpy(que[i]->que[j].txt,str);
                   3091:                        fgets(str,128,fp);
                   3092:                        que[i]->que[j].answers=atoi(str);
                   3093:                        if(que[i]->que[j].answers<1 || que[i]->que[j].answers>16) {
                   3094:                                bprintf("Invalid number of answers (%d) in question #%d "
                   3095:                                        "of questionnaire #%d\r\n"
                   3096:                                        ,que[i]->que[j].answers,j+1,i+1);
                   3097:                                exit(1); }
                   3098:                        fgets(str,128,fp);
                   3099:                        que[i]->que[j].allowed=atoi(str);
                   3100:                        for(k=0;k<que[i]->que[j].answers;k++) {
                   3101:                                if(!fgets(str,128,fp))
                   3102:                                        break;
                   3103:                                truncsp(str);
                   3104:                                if(!str[0])
                   3105:                                        break;
                   3106:                                str[60]=0;
                   3107:                                strcpy(que[i]->que[j].ans[k],str); }
                   3108:                        que[i]->que[j].answers=k; }
                   3109: 
                   3110:                que[i]->total_ques=j; }
                   3111:        fclose(fp);
                   3112:        i++; }
                   3113: fclose(que_lst);
                   3114: 
                   3115: lncntr=0;
                   3116: getsmsg(user_number);
                   3117: if(lncntr)
                   3118:        pause();
                   3119: 
                   3120: memset(&useron,0,sizeof(user_t));
                   3121: 
                   3122: atexit(smm_exit);
                   3123: 
                   3124: bputs("\1n\1hSearching for your profile...");
                   3125: rewind(index);
                   3126: while(!feof(index)) {
                   3127:        if(!fread(&ixb,sizeof(ixb_t),1,index))
                   3128:                break;
                   3129:        if(ixb.system==system_crc && ixb.number==user_number) {
                   3130:                useron_record=(ftell(index)-sizeof(ixb_t))/sizeof(ixb_t);
                   3131:                fseek(stream,useron_record*sizeof(user_t),SEEK_SET);
                   3132:                fread(&user,sizeof(user_t),1,stream);
                   3133:                if(stricmp(user.realname,user_name)) {  /* new name, so delete it */
                   3134:                        user.misc|=USER_DELETED;
                   3135:                        fseek(stream,ftell(stream)-sizeof(user_t),SEEK_SET);
                   3136:                        fwrite(&user,sizeof(user_t),1,stream);
                   3137:                        fseek(stream,0,SEEK_CUR);
                   3138:                        fseek(index,ftell(index)-sizeof(ixb_t),SEEK_SET);
                   3139:                        ixb.number=0;
                   3140:                        fwrite(&ixb,sizeof(ixb_t),1,index);
                   3141:                        sprintf(str,"%04u.MSG",user_number);
                   3142:                        remove(str);
                   3143:                        continue; }
                   3144:                useron=user;            /* name matches, same user */
                   3145:                break; } }
                   3146: fflush(stream);
                   3147: fflush(index);
                   3148: CRLF;
                   3149: 
                   3150: if(useron.number && useron.sex!='M' && useron.sex!='F') {
                   3151:        if(yesno("Are you of male gender"))
                   3152:                useron.sex='M';
                   3153:        else
                   3154:                useron.sex='F';
                   3155:        write_user();
                   3156:        user_sex=useron.sex; }
                   3157: 
                   3158: if(!useron.number && user_sex!='M' && user_sex!='F' && can_add()) {
                   3159:        if(yesno("Are you of male gender"))
                   3160:                user_sex='M';
                   3161:        else
                   3162:                user_sex='F'; }
                   3163: 
                   3164: if(!useron.number && can_add()) {
                   3165:        sprintf(str,"%04u.MSG",user_number);
                   3166:        remove(str);
                   3167:        printfile("SMM_LOGO.ASC");
                   3168:        if(yesno("\r\nYour profile doesn't exist. Create it now"))
                   3169:                add_userinfo(); }
                   3170: 
                   3171: if(gotoname[0]) {
                   3172:        strupr(gotoname);
                   3173:        name_crc=crc32(gotoname);
                   3174:        rewind(index);
                   3175:        i=0;
                   3176:        while(!feof(index)) {
                   3177:                if(!fread(&ixb,sizeof(ixb_t),1,index))
                   3178:                        break;
                   3179:                if(!ixb.number)    /* DELETED */
                   3180:                        continue;
                   3181:                if(ixb.name!=name_crc)
                   3182:                        continue;
                   3183:                fseek(stream
                   3184:                        ,((ftell(index)-sizeof(ixb_t))/sizeof(ixb_t))
                   3185:                        *sizeof(user_t),SEEK_SET);
                   3186:                if(!fread(&user,sizeof(user_t),1,stream))
                   3187:                        continue;
                   3188:                if(minor_protection(user))
                   3189:                        continue;
                   3190:                i=1;
                   3191:                if(!long_user_info(user))
                   3192:                        break; }
                   3193:        if(!i) {
                   3194:                bprintf("\r\n\1n\1h%s \1rnot found.\r\n",gotoname);
                   3195:                pause(); }
                   3196:        return; }
                   3197: 
                   3198: /*********************************************/
                   3199: /* ALL User Messages (from Digital Dynamics) */
                   3200: /*********************************************/
                   3201: for(i=findfirst("ALL*.MSG",&ff,0);!i;i=findnext(&ff)) {
                   3202:        if((j=nopen(ff.ff_name,O_RDONLY))==-1) {
                   3203:                bprintf("\1n\1r\1hCan't open \1w%s\r\n",ff.ff_name);
                   3204:                pause();
                   3205:                continue; }
                   3206:        if((fp=fdopen(j,"rb"))==NULL) {
                   3207:                bprintf("\1n\1r\1hCan't fdopen \1w%s\r\n",ff.ff_name);
                   3208:                pause();
                   3209:                continue; }
                   3210:        str[0]=0;
                   3211:        fgets(str,128,fp);
                   3212:        truncsp(str);
                   3213:        ul=ahtoul(str);    /* Expiration date */
                   3214:        ul^=0x305F6C81UL;
                   3215:        attr(LIGHTGRAY);
                   3216:        cls();
                   3217:        while(!feof(fp)) {
                   3218:                if(!fgets(str,128,fp))
                   3219:                        break;
                   3220:                bputs(str); }
                   3221:        fclose(fp);
                   3222:        CRLF;
                   3223:        if(ul<=time(NULL))
                   3224:                remove(ff.ff_name); }
                   3225: 
                   3226: /**************************************************/
                   3227: /* One-time User Messages (from Digital Dynamics) */
                   3228: /**************************************************/
                   3229: for(i=findfirst("ONE*.MSG",&ff,0);!i;i=findnext(&ff)) {
                   3230:        if(fdate_dir(ff.ff_name)<useron.lastin)
                   3231:                continue;
                   3232:        if((j=nopen(ff.ff_name,O_RDONLY))==-1) {
                   3233:                bprintf("\1n\1r\1hCan't open \1w%s\r\n",ff.ff_name);
                   3234:                pause();
                   3235:                continue; }
                   3236:        if((fp=fdopen(j,"rb"))==NULL) {
                   3237:                bprintf("\1n\1r\1hCan't fdopen \1w%s\r\n",ff.ff_name);
                   3238:                pause();
                   3239:                continue; }
                   3240:        str[0]=0;
                   3241:        fgets(str,128,fp);
                   3242:        truncsp(str);
                   3243:        ul=ahtoul(str);    /* Expiration date */
                   3244:        ul^=0x305F6C81UL;
                   3245:        attr(LIGHTGRAY);
                   3246:        cls();
                   3247:        while(!feof(fp)) {
                   3248:                if(!fgets(str,128,fp))
                   3249:                        break;
                   3250:                bputs(str); }
                   3251:        fclose(fp);
                   3252:        CRLF;
                   3253:        if(ul<=time(NULL))
                   3254:         remove(ff.ff_name); }
                   3255: 
                   3256: /******************************************/
                   3257: /* Sysop Messages (from Digital Dynamics) */
                   3258: /******************************************/
                   3259: for(i=findfirst("SYS*.MSG",&ff,0);SYSOP && !i;i=findnext(&ff)) {
                   3260:        if((j=nopen(ff.ff_name,O_RDONLY))==-1) {
                   3261:                bprintf("\1n\1r\1hCan't open \1w%s\r\n",ff.ff_name);
                   3262:                pause();
                   3263:                continue; }
                   3264:        if((fp=fdopen(j,"rb"))==NULL) {
                   3265:                bprintf("\1n\1r\1hCan't fdopen \1w%s\r\n",ff.ff_name);
                   3266:                pause();
                   3267:                continue; }
                   3268:        str[0]=0;
                   3269:        fgets(str,128,fp);
                   3270:        truncsp(str);
                   3271:        ul=ahtoul(str);    /* Expiration date */
                   3272:        ul^=0x305F6C81UL;
                   3273:        attr(LIGHTGRAY);
                   3274:        cls();
                   3275:        while(!feof(fp)) {
                   3276:                if(!fgets(str,128,fp))
                   3277:                        break;
                   3278:                bputs(str); }
                   3279:        fclose(fp);
                   3280:        CRLF;
                   3281:        if(ul<=time(NULL) || !noyes("Delete message"))
                   3282:         remove(ff.ff_name); }
                   3283: 
                   3284: statusline();
                   3285: while(1) {
                   3286:        checkline();
                   3287:        aborted=0;
                   3288:        attr(LIGHTGRAY);
                   3289:        cls();
                   3290: 
                   3291:        bprintf("\1n  \1b\1hSynchronet \1cMatch Maker  \1bv%s (XSDK v%s)  "
                   3292:                "Developed 1995-1997 Rob Swindell\1n\r\n\r\n",SMM_VER,xsdk_ver);
                   3293:        printfile("SMM_LOGO.ASC");
                   3294:        CRLF;
                   3295: 
                   3296:        l=filelength(fileno(stream));
                   3297:        if(l<0) l=0;
                   3298:        sprintf(str,"\1n\1cThere are \1h%lu\1n\1c entries in the user profile "
                   3299:                "database.\r\n",l/(long)sizeof(user_t));
                   3300:        center(str);
                   3301: 
                   3302:        sprintf(str,"%04u.MSG",user_number);
                   3303:        if(fexist(str))
                   3304:                center("\1h\1mYou have awaiting telegrams!\r\n");
                   3305: 
                   3306:        if(flength("WALL.DAB")>0)
                   3307:                center("\1h\1cThere is writing on the Wall.\r\n");
                   3308: 
                   3309:        if(!useron.number)
                   3310:                center("\1h\1rYou have not yet created a profile!\r\n");
                   3311: 
                   3312:        printfile("SMM_MAIN.ASC");
                   3313: 
                   3314:        nodesync();                     /* Display any waiting messages */
                   3315: 
                   3316:        bprintf("\r\n%32s\1b\1hWhich or [\1wQ\1b]uit: \1h\1w",nulstr);
                   3317:        ch=getkey(K_UPPER);
                   3318: //       bprintf("%c\r\n",ch);
                   3319:        bputs("\r\1>");
                   3320:        switch(ch) {
                   3321:                case '?':
                   3322:                        break;
                   3323:                case '*':
                   3324:                        if(!SYSOP)
                   3325:                                break;
                   3326:                        bputs("\1n\1hSearching...");
                   3327:                        rewind(stream);
                   3328:                        while(!feof(stream) && !aborted) {
                   3329:                                if(!fread(&user,sizeof(user_t),1,stream))
                   3330:                                        break;
                   3331:                                if(user.misc&USER_DELETED) {
                   3332:                                        sprintf(str,"\r\nUndelete \1c%s \1b(\1c%s@%s\1b)"
                   3333:                                                ,user.name,user.realname,user.system);
                   3334:                                        if(!yesno(str))
                   3335:                                                continue;
                   3336:                                        fseek(stream,ftell(stream)-sizeof(user_t),SEEK_SET);
                   3337:                                        user.misc&=~USER_DELETED;
                   3338:                                        fwrite(&user,sizeof(user_t),1,stream);
                   3339:                                        fseek(stream,0,SEEK_CUR);
                   3340:                                        fseek(index
                   3341:                                                ,((ftell(stream)-sizeof(user_t))/sizeof(user_t))
                   3342:                                                *sizeof(ixb_t),SEEK_SET);
                   3343:                                        strcpy(str,user.name);
                   3344:                                        strupr(str);
                   3345:                                        ixb.name=crc32(str);
                   3346:                                        sprintf(str,"%.25s",user.system);
                   3347:                                        strupr(str);
                   3348:                                        ixb.system=crc32(str);
                   3349:                                        ixb.updated=user.updated;
                   3350:                                        ixb.number=user.number;
                   3351:                                        fwrite(&ixb,sizeof(ixb_t),1,index);
                   3352:                                        } }
                   3353:                        fflush(stream);
                   3354:                        fflush(index);
                   3355:                        break;
                   3356:                case '!':
                   3357:                        if(!SYSOP)
                   3358:                                break;
                   3359:                        cls();
                   3360:                        bputs("\1n\1hSystems Participating in Your Database:\r\n\r\n\1m");
                   3361:                        crc_lst=NULL;
                   3362:                        j=0;
                   3363:                        rewind(stream);
                   3364:                        while(!feof(stream) && !aborted) {
                   3365:                                if(!fread(&user,sizeof(user_t),1,stream))
                   3366:                     break;
                   3367:                                if(user.misc&USER_DELETED || !(user.misc&USER_FROMSMB))
                   3368:                                        continue;
                   3369:                                if(!smm_pause)
                   3370:                                        lncntr=0;
                   3371:                                sprintf(str,"%.25s",user.system);
                   3372:                                strupr(str);
                   3373:                                sys_crc=crc32(str);
                   3374:                                for(i=0;i<j;i++)
                   3375:                                        if(sys_crc==crc_lst[i])
                   3376:                                                break;
                   3377:                                if(i==j) {
                   3378:                                        crc_lst=REALLOC(crc_lst,(j+1)*sizeof(ulong));
                   3379:                                        if(crc_lst==NULL) {
                   3380:                                                printf("REALLOC error!\n");
                   3381:                                                pause();
                   3382:                                                break; }
                   3383:                                        crc_lst[j++]=sys_crc;
                   3384:                                        bprintf("%s\r\n",user.system); } }
                   3385:                        if(crc_lst)
                   3386:                                FREE(crc_lst);
                   3387:                        if(j)
                   3388:                                bprintf("\1n\r\n\1h%u systems listed.\r\n",j);
                   3389:                        pause();
                   3390:                        break;
                   3391:                case '\\':
                   3392:                        if(!SYSOP)
                   3393:                                break;
                   3394:                        bprintf("Rebuilding Index...");
                   3395:                        rewind(stream);
                   3396:                        rewind(index);
                   3397:                        while(!feof(stream)) {
                   3398:                                if(!fread(&user,sizeof(user_t),1,stream))
                   3399:                                        break;
                   3400:                                if(user.misc&USER_DELETED)
                   3401:                                        ixb.number=0;
                   3402:                                else
                   3403:                                        ixb.number=user.number;
                   3404:                                strupr(user.name);
                   3405:                                ixb.name=crc32(user.name);
                   3406:                                strupr(user.system);
                   3407:                                user.system[25]=0;
                   3408:                                ixb.system=crc32(user.system);
                   3409:                                ixb.updated=user.updated;
                   3410:                                fwrite(&ixb,sizeof(ixb_t),1,index); }
                   3411:                        break;
                   3412:                case 'R':
                   3413:                        if(useron.number) {
                   3414:                                bputs("\1y\1hMinimum match percentage: \1w");
                   3415:                                sprintf(str,"%u",useron.min_match);
                   3416:                                if(!getstr(str,3,K_NUMBER|K_EDIT|K_AUTODEL) || aborted)
                   3417:                                        break;
                   3418:                                useron.min_match=atoi(str);
                   3419:                                if(useron.min_match>100)
                   3420:                                        useron.min_match=100; }
                   3421:                        rewind(stream);
                   3422:                        bprintf("\1n\1l\1hSearching...");
                   3423:                        while(!feof(stream) && !aborted) {
                   3424:                                if(!fread(&user,sizeof(user_t),1,stream))
                   3425:                                        break;
                   3426:                                if(user.misc&USER_DELETED)
                   3427:                                        continue;
                   3428:                                if(minor_protection(user))
                   3429:                                        continue;
                   3430:                                if(useron.min_match && useron.number) {
                   3431:                                        match=total_match(useron,user);
                   3432:                                        if(match<useron.min_match)
                   3433:                                                continue; }
                   3434:                                if(!long_user_info(user))
                   3435:                                        break;
                   3436:                                if(!smm_pause)
                   3437:                                        lncntr=0;
                   3438:                                bprintf("\1n\1l\1hSearching..."); }
                   3439:                        break;
                   3440:                case 'F':
                   3441:                        bputs("\1y\1hText to search for: ");
                   3442:                        if(!getstr(str,25,K_UPPER|K_LINE))
                   3443:                 break;
                   3444:                        ext=yesno("\r\nDisplay extended profiles");
                   3445:                        cls();
                   3446:                        if(!smm_pause && !ext)
                   3447:                                printfile("LIST_HDR.ASC");
                   3448:                        rewind(stream);
                   3449:                        i=0;
                   3450:                        while(!aborted) {
                   3451:                                bprintf("\1n\1l\1hSearching...");
                   3452:                                while(!feof(stream) && !aborted) {
                   3453:                                        if(!fread(&user,sizeof(user_t),1,stream))
                   3454:                                                break;
                   3455:                                        if(user.misc&USER_DELETED)
                   3456:                                                continue;
                   3457:                                        if(minor_protection(user))
                   3458:                                                continue;
                   3459:                                        tmpuser=user;
                   3460:                                        sprintf(tmp,"%lu",user.number);
                   3461:                                        strupr(user.name);
                   3462:                                        strupr(user.realname);
                   3463:                                        strupr(user.system);
                   3464:                                        strupr(user.location);
                   3465:                                        strupr(user.note[0]);
                   3466:                                        strupr(user.note[1]);
                   3467:                                        strupr(user.note[2]);
                   3468:                                        strupr(user.note[3]);
                   3469:                                        strupr(user.note[4]);
                   3470:                                        if(strstr(user.name,str)
                   3471:                                                || strstr(user.location,str)
                   3472:                                                || strstr(user.mbtype,str)
                   3473:                                                || strstr(user.note[0],str)
                   3474:                                                || strstr(user.note[1],str)
                   3475:                                                || strstr(user.note[2],str)
                   3476:                                                || strstr(user.note[3],str)
                   3477:                                                || strstr(user.note[4],str)
                   3478:                                                || (SYSOP && strstr(user.realname,str))
                   3479:                                                || (SYSOP && strstr(user.system,str))
                   3480:                                                || (SYSOP && !strcmp(tmp,str))
                   3481:                                                ) {
                   3482:                                                i=1;
                   3483:                                                if(ext && !long_user_info(tmpuser))
                   3484:                                                        break;
                   3485:                                                if(!ext && short_user_info(tmpuser)==0)
                   3486:                                                        break;
                   3487:                                                if(!smm_pause)
                   3488:                                                        lncntr=0; } }
                   3489:                                if(aborted || ext || !lncntr)
                   3490:                                        break;
                   3491:                                user.number=0;
                   3492:                                if(short_user_info(user)>=0)
                   3493:                                        break; }
                   3494:                        if(!i)
                   3495:                                bprintf("\r\n\1n\1h%s \1rnot found.\r\n",str);
                   3496:             break;
                   3497:                case 'G':
                   3498:                        bputs("\1y\1hUser name: ");
                   3499:                        if(!getstr(str,25,K_UPPER|K_LINE))
                   3500:                 break;
                   3501:                        truncsp(str);
                   3502:                        name_crc=crc32(str);
                   3503:                        rewind(index);
                   3504:                        i=0;
                   3505:                        while(!feof(index)) {
                   3506:                                if(!fread(&ixb,sizeof(ixb_t),1,index))
                   3507:                                        break;
                   3508:                                if(!ixb.number)    /* DELETED */
                   3509:                                        continue;
                   3510:                                if(ixb.name!=name_crc)
                   3511:                                        continue;
                   3512:                                fseek(stream
                   3513:                                        ,((ftell(index)-sizeof(ixb_t))/sizeof(ixb_t))
                   3514:                                        *sizeof(user_t),SEEK_SET);
                   3515:                                if(!fread(&user,sizeof(user_t),1,stream))
                   3516:                                        continue;
                   3517:                                if(minor_protection(user))
                   3518:                     continue;
                   3519:                                i=1;
                   3520:                                if(!long_user_info(user))
                   3521:                                        break; }
                   3522:                        if(!i)
                   3523:                                bprintf("\r\n\1n\1h%s \1rnot found.\r\n",str);
                   3524:             break;
                   3525:                case 'L':
                   3526:                        if(useron.number) {
                   3527:                                bputs("\1y\1hMinimum match percentage: \1w");
                   3528:                                sprintf(str,"%u",useron.min_match);
                   3529:                                if(!getstr(str,3,K_NUMBER|K_EDIT|K_AUTODEL) || aborted)
                   3530:                                        break;
                   3531:                                useron.min_match=atoi(str);
                   3532:                                if(useron.min_match>100)
                   3533:                                        useron.min_match=100; }
                   3534:                        cls();
                   3535:                        if(!smm_pause)
                   3536:                                printfile("LIST_HDR.ASC");
                   3537:                        rewind(stream);
                   3538:                        while(!aborted) {
                   3539:                                while(!feof(stream) && !aborted) {
                   3540:                                        if(!fread(&user,sizeof(user_t),1,stream))
                   3541:                                                break;
                   3542:                                        if(user.misc&USER_DELETED)
                   3543:                                                continue;
                   3544:                                        if(minor_protection(user))
                   3545:                                                continue;
                   3546:                                        if(useron.min_match && useron.number) {
                   3547:                                                match=total_match(useron,user);
                   3548:                                                if(match<useron.min_match)
                   3549:                                                        continue; }
                   3550:                                        if(!short_user_info(user))
                   3551:                                                break;
                   3552:                                        if(!smm_pause)
                   3553:                                                lncntr=0; }
                   3554:                                if(aborted || !lncntr)
                   3555:                                        break;
                   3556:                                user.number=0;
                   3557:                                if(short_user_info(user)>=0)
                   3558:                                        break; }
                   3559:             break;
                   3560: 
                   3561:                case 'N':
                   3562:                        while(1) {
                   3563:                                checkline();
                   3564:                                bputs("\1y\1hLast update (MM/DD/YY): ");
                   3565:                                if(useron.number)
                   3566:                                        unixtodstr(useron.lastin,str);
                   3567:                                else
                   3568:                                        str[0]=0;
                   3569:                                if(!getstr(str,8,K_UPPER|K_LINE|K_EDIT|K_AUTODEL))
                   3570:                                        break;
                   3571:                                if(isdigit(str[0]) && isdigit(str[1]) && str[2]=='/'
                   3572:                                        && isdigit(str[3]) && isdigit(str[4]) && str[5]=='/'
                   3573:                                        && isdigit(str[6]) && isdigit(str[7]))
                   3574:                                        break;
                   3575:                                bputs("\r\n\1h\1rInvalid date!\r\n\r\n"); }
                   3576:                        if(!str[0] || aborted)
                   3577:                                break;
                   3578:                        l=dstrtounix(str);
                   3579:                        if(useron.number) {
                   3580:                                bputs("\1y\1h\r\nMinimum match percentage: \1w");
                   3581:                                sprintf(str,"%u",useron.min_match);
                   3582:                                if(!getstr(str,3,K_NUMBER|K_EDIT|K_AUTODEL) || aborted)
                   3583:                                        break;
                   3584:                                useron.min_match=atoi(str);
                   3585:                                if(useron.min_match>100)
                   3586:                                        useron.min_match=100; }
                   3587:                        ext=!noyes("\r\nDisplay extended profiles");
                   3588:                        if(aborted)
                   3589:                                break;
                   3590:                        cls();
                   3591:                        if(!ext && !smm_pause)
                   3592:                                printfile("LIST_HDR.ASC");
                   3593:                        rewind(index);
                   3594:                        while(!aborted) {
                   3595:                                while(!feof(index) && !aborted) {
                   3596:                                        if(!smm_pause)
                   3597:                                                lncntr=0;
                   3598:                                        if(!fread(&ixb,sizeof(ixb_t),1,index))
                   3599:                                                break;
                   3600:                                        if(!ixb.number)         /* DELETED */
                   3601:                                                continue;
                   3602:                                        if(ixb.updated>=l) {
                   3603:                                                fseek(stream
                   3604:                                                        ,((ftell(index)-sizeof(ixb_t))/sizeof(ixb_t))
                   3605:                                                        *sizeof(user_t),SEEK_SET);
                   3606:                                                if(!fread(&user,sizeof(user_t),1,stream))
                   3607:                                                        continue;
                   3608:                                                if(minor_protection(user))
                   3609:                                                        continue;
                   3610:                                                if(useron.min_match && useron.number) {
                   3611:                                                        match=total_match(useron,user);
                   3612:                                                        if(match<useron.min_match)
                   3613:                                                                continue; }
                   3614:                                                if(ext && !long_user_info(user))
                   3615:                                                        break;
                   3616:                                                if(!ext && short_user_info(user)==0)
                   3617:                                                        break;
                   3618:                                                continue; } }
                   3619:                                if(aborted || ext || !lncntr)
                   3620:                                        break;
                   3621:                                user.number=0;
                   3622:                                if(short_user_info(user)>=0)
                   3623:                                        break; }
                   3624:             break;
                   3625: 
                   3626:                case 'U':
                   3627:                case 'W':       /* Create/Edit Profile */
                   3628:                        if(!can_add()) {
                   3629:                                bprintf("\1h\1rYou have insufficient access to create a "
                   3630:                                        "profile.\r\n\r\n");
                   3631:                                break; }
                   3632: 
                   3633:                        if(!useron.number) {
                   3634:                                add_userinfo();
                   3635:                                break; }
                   3636: 
                   3637:                        user=useron;
                   3638:                        tleft=timeleft;
                   3639:                        if(!get_user_info(&user)) {
                   3640:                                timeleft=tleft;
                   3641:                                break; }
                   3642: 
                   3643:                        if(!memcmp(&user,&useron,sizeof(user_t))) {
                   3644:                                timeleft=tleft;
                   3645:                                break; }
                   3646: 
                   3647:                        if(!yesno("Save changes")) {
                   3648:                                timeleft=tleft;
                   3649:                                break; }
                   3650:                        timeleft=tleft;
                   3651:                        user.updated=time(NULL);
                   3652:                        useron=user;
                   3653:                        write_user();
                   3654:             break;
                   3655: 
                   3656:                case 'D':
                   3657:                        if(SYSOP) {
                   3658:                                bputs("Name to Delete: ");
                   3659:                                if(useron.number) {
                   3660:                                        strcpy(str,useron.name);
                   3661:                                        strupr(str); }
                   3662:                                else
                   3663:                                        str[0]=0;
                   3664:                                getstr(str,25,K_UPPER|K_LINE|K_EDIT|K_AUTODEL);
                   3665:                                rewind(stream);
                   3666:                                while(!feof(stream)) {
                   3667:                                        if(!fread(&user,sizeof(user_t),1,stream))
                   3668:                                                break;
                   3669:                                        strcpy(tmp,user.name);
                   3670:                                        strupr(tmp);
                   3671:                                        if(!(user.misc&USER_DELETED) && strstr(tmp,str)) {
                   3672:                                                sprintf(tmp,"Delete %s (%s@%s)"
                   3673:                                                        ,user.name,user.realname,user.system);
                   3674:                                                i=noyes(tmp);
                   3675:                                                if(aborted)
                   3676:                                                        break;
                   3677:                                                if(i)
                   3678:                                                        continue;
                   3679:                                                fseek(stream,ftell(stream)-sizeof(user_t),SEEK_SET);
                   3680:                                                fseek(index
                   3681:                                                        ,((ftell(stream)-sizeof(user_t))/sizeof(user_t))
                   3682:                                                        *sizeof(ixb_t),SEEK_SET);
                   3683:                                                user.misc|=USER_DELETED;
                   3684:                                                fwrite(&user,sizeof(user_t),1,stream);
                   3685:                                                fseek(stream,0,SEEK_CUR);
                   3686:                                                memset(&ixb,0,sizeof(ixb_t));
                   3687:                                                fwrite(&ixb,sizeof(ixb_t),1,index);
                   3688:                                                fflush(stream);
                   3689:                                                fflush(index);
                   3690:                                                delphoto(user);
                   3691:                                                if(user.number==user_number
                   3692:                                                        && !stricmp(user.system,system_name))
                   3693:                                                        useron.number=0;
                   3694:                                                break; } }
                   3695:                                if(aborted)
                   3696:                                        break;
                   3697:                                break; }
                   3698:                        if(!useron.number) {
                   3699:                                bputs("\1h\1rYour profile doesn't exist.\r\n\r\n");
                   3700:                 break; }
                   3701:                        if(noyes("Are you sure you want to delete your profile"))
                   3702:                 break;
                   3703:                        if(!cdt_warning(-profile_cdt))
                   3704:                                break;
                   3705:                        sprintf(str,"%04u.MSG",user_number);
                   3706:                        remove(str);
                   3707:                        fseek(stream,useron_record*sizeof(user_t),SEEK_SET);
                   3708:                        useron.misc|=USER_DELETED;
                   3709:                        fwrite(&useron,sizeof(user_t),1,stream);
                   3710:                        fflush(stream);
                   3711:                        memset(&ixb,0,sizeof(ixb_t));
                   3712:                        fseek(index,useron_record*sizeof(ixb_t),SEEK_SET);
                   3713:                        fwrite(&ixb,sizeof(ixb_t),1,index);
                   3714:                        fflush(index);
                   3715:                        delphoto(user);
                   3716:                        useron.number=0;
                   3717:                        aborted=0;
                   3718:                        bputs("\r\n\1h\1r\1iProfile deleted.\r\n");
                   3719:                        adjust_cdt(-profile_cdt);
                   3720:             break;
                   3721:                case 'P':
                   3722:                        smm_pause=!smm_pause;
                   3723:                        bprintf("\1r\1hScreen pause is now \1w%s\r\n\r\n"
                   3724:                                ,smm_pause ? "ON":"OFF");
                   3725:             break;
                   3726:                case 'M':
                   3727:                        mbtype_desc(useron.mbtype);
                   3728:                        break;
                   3729:                case 'H':
                   3730:                        cls();
                   3731:                        printfile("SMM_HELP.ASC");
                   3732:                        break;
                   3733:                case 'O':
                   3734:                        if(noyes("Hang-up now"))
                   3735:                                break;
                   3736:                        dtr(5);
                   3737:                        if(node_dir) {
                   3738:                                sprintf(str,"%sHANGUP.NOW",node_dir);
                   3739:                                fopen(str,"wb");
                   3740:                                nodesync(); }
                   3741:                        return;
                   3742:                case 'S':
                   3743:                        bputs("\1y\1hUser name: ");
                   3744:                        if(!getstr(str,25,K_UPPER|K_LINE))
                   3745:                 break;
                   3746:                        truncsp(str);
                   3747:                        name_crc=crc32(str);
                   3748:                        rewind(index);
                   3749:                        i=0;
                   3750:                        while(!feof(index)) {
                   3751:                                if(!fread(&ixb,sizeof(ixb_t),1,index))
                   3752:                                        break;
                   3753:                                if(!ixb.number)    /* DELETED */
                   3754:                                        continue;
                   3755:                                if(ixb.name!=name_crc)
                   3756:                                        continue;
                   3757:                 fseek(stream
                   3758:                                        ,((ftell(index)-sizeof(ixb_t))/sizeof(ixb_t))
                   3759:                                        *sizeof(user_t),SEEK_SET);
                   3760:                                if(!fread(&user,sizeof(user_t),1,stream))
                   3761:                                        continue;
                   3762:                                if(minor_protection(user))
                   3763:                     continue;
                   3764:                                i=1;
                   3765:                                if(send_telegram(user))
                   3766:                                        break; }
                   3767:                        if(!i)
                   3768:                                bprintf("\r\n\1n\1h%s \1rnot found.\r\n",str);
                   3769:             break;
                   3770:                case 'T':
                   3771:                        sprintf(str,"%04u.MSG",user_number);
                   3772:                        if(!fexist(str)) {
                   3773:                                bputs("\1r\1hYou have no telegrams waiting.\r\n\r\n");
                   3774:                                break; }
                   3775:                        cls();
                   3776:                        printfile(str);
                   3777:                        if(noyes("\r\nDelete all telegrams waiting for you"))
                   3778:                                break;
                   3779:                        remove(str);
                   3780:                        break;
                   3781:                case 'V':   /* Visit the wall */
                   3782:                        if(getage(user_birth)<wall_age && !SYSOP) {
                   3783:                                bputs("\1r\1hSorry, you're too young to view the wall.\r\n");
                   3784:                                pause();
                   3785:                                break; }
                   3786:                        while(1) {
                   3787:                                checkline();
                   3788:                                bputs("\1y\1hView writing since (MM/DD/YY): ");
                   3789:                 if(useron.number)
                   3790:                     unixtodstr(useron.lastin,str);
                   3791:                 else
                   3792:                     str[0]=0;
                   3793:                 if(!getstr(str,8,K_UPPER|K_LINE|K_EDIT|K_AUTODEL))
                   3794:                     break;
                   3795:                 if(isdigit(str[0]) && isdigit(str[1]) && str[2]=='/'
                   3796:                     && isdigit(str[3]) && isdigit(str[4]) && str[5]=='/'
                   3797:                     && isdigit(str[6]) && isdigit(str[7]))
                   3798:                     break;
                   3799:                 bputs("\r\n\1h\1rInvalid date!\r\n\r\n"); }
                   3800:                        if(aborted)
                   3801:                 break;
                   3802:                        l=dstrtounix(str);
                   3803:                        ext=yesno("\r\nDisplay extended information when available");
                   3804:                        if(aborted)
                   3805:                 break;
                   3806:                        strcpy(str,"WALL.DAB");
                   3807:                        if((file=sopen(str,O_RDWR|O_BINARY|O_CREAT,SH_DENYNO
                   3808:                                ,S_IREAD|S_IWRITE))==-1) {
                   3809:                                bprintf("\r\nError opening %s\r\n",str);
                   3810:                                break; }
                   3811:                        cls();
                   3812:                        offset=0L;
                   3813:                        while(!eof(file) && !aborted) {
                   3814:                                if(read(file,&wall,sizeof(wall_t))!=sizeof(wall_t))
                   3815:                                        break;
                   3816:                                if(wall.imported<l)
                   3817:                                        continue;
                   3818:                                strcpy(str,wall.name);
                   3819:                                strupr(str);
                   3820:                                name_crc=crc32(str);
                   3821:                                sprintf(str,"%.25s",wall.system);
                   3822:                                strupr(str);
                   3823:                                sys_crc=crc32(str);
                   3824:                                rewind(index);
                   3825:                                i=0;
                   3826:                                user.sex=0;
                   3827:                                while(ext && !feof(index) && !aborted) {
                   3828:                                        if(!fread(&ixb,sizeof(ixb_t),1,index))
                   3829:                                                break;
                   3830:                                        if(!ixb.number)    /* DELETED */
                   3831:                                                continue;
                   3832:                                        if(ixb.name!=name_crc || ixb.system!=sys_crc)
                   3833:                                                continue;
                   3834:                                        fseek(stream
                   3835:                                                ,((ftell(index)-sizeof(ixb_t))/sizeof(ixb_t))
                   3836:                                                *sizeof(user_t),SEEK_SET);
                   3837:                                        if(!fread(&user,sizeof(user_t),1,stream))
                   3838:                                                continue;
                   3839:                                        if(minor_protection(user))
                   3840:                                                break;
                   3841:                                        main_user_info(user);
                   3842:                                        if(useron.number) {
                   3843:                                                CRLF;
                   3844:                                                bprintf("\1h\1mThis user meets your profile "
                   3845:                                                        "preferences:\1w%3u%%            "
                   3846:                                                        ,basic_match(useron,user));
                   3847:                                                bprintf("\1n\1gCreated: \1h%s\r\n"
                   3848:                                                        ,unixtodstr(user.created,str));
                   3849:                                                bprintf("\1h\1mYou meet this user's profile "
                   3850:                                                        "preferences:\1w%3u%%            "
                   3851:                                                        ,basic_match(user,useron));
                   3852:                                                bprintf("\1n\1gUpdated: \1h%s\r\n"
                   3853:                                                        ,unixtodstr(user.updated,str)); }
                   3854: 
                   3855:                                        i=1;
                   3856:                                        CRLF;
                   3857:                                        break; }
                   3858:                                if(!i) {
                   3859:                                        if(ext)
                   3860:                                                cls();
                   3861:                                        bprintf("\1n\1h%s ",wall.name); }
                   3862:                                bprintf("\1n\1h\1cWrote on %s:\r\n"
                   3863:                                        ,timestr(&wall.written));
                   3864:                                for(j=0;j<5;j++) {
                   3865:                                        if(!wall.text[j][0])
                   3866:                                                break;
                   3867:                                        bprintf("\1n\1%c%5s%s\r\n"
                   3868:                                                ,user.sex=='F'?'m':'g',"",wall.text[j]); }
                   3869:                                if(aborted)
                   3870:                                        break;
                   3871:                                if(ext) {
                   3872:                                        nodesync();
                   3873:                                        if(i) {
                   3874:                                                bputs(PrevReadSendQuitOrMore);
                   3875:                                                ch=getkey(K_UPPER);
                   3876:                                                if(ch=='R')
                   3877:                                                        long_user_info(user);
                   3878:                                                if(ch=='S')
                   3879:                                                        send_telegram(user);
                   3880:                                                if(ch=='R' || ch=='S')  /* Don't move forward */
                   3881:                                                        lseek(file,tell(file)-sizeof(wall_t),SEEK_SET); }
                   3882:                                        else {
                   3883:                                                bputs("\r\n\1n\1hProfile not found.\r\n\r\n");
                   3884:                                                bputs("\1b[\1cP\1b]revious, [\1cQ\1b]uit, "
                   3885:                                                        "or [\1cM\1b]ore: \1c");
                   3886:                                                ch=getkey(K_UPPER); }
                   3887:                                        if(ch=='P') {
                   3888:                                                lseek(file,offset,SEEK_SET);
                   3889:                                                if(tell(file))
                   3890:                                                        lseek(file,tell(file)-sizeof(wall_t),SEEK_SET);
                   3891:                                                offset=tell(file);
                   3892:                                                continue; }
                   3893:                                        if(ch=='Q') {
                   3894:                                                cls();
                   3895:                                                break; }
                   3896:                                        offset=tell(file); }
                   3897:                                else if(lncntr+7>=user_rows || eof(file)) {
                   3898:                                        lncntr=0;
                   3899:                                        bputs(PrevReadSendQuitOrMore);
                   3900:                                        ch=getkey(K_UPPER);
                   3901:                                        if(ch=='Q')
                   3902:                                                break;
                   3903:                                        else if(ch=='S' || ch=='R') {
                   3904:                                                bprintf("\1n\r\1>\1y\1hUser name: ");
                   3905:                                                if(getstr(name,25,K_UPPER|K_LINE|K_NOCRLF)) {
                   3906:                                                        truncsp(name);
                   3907:                                                        name_crc=crc32(name);
                   3908:                                                        rewind(index);
                   3909:                                                        i=0;
                   3910:                                                        while(!feof(index)) {
                   3911:                                                                if(!fread(&ixb,sizeof(ixb_t),1,index))
                   3912:                                                                        break;
                   3913:                                                                if(!ixb.number)    /* DELETED */
                   3914:                                                                        continue;
                   3915:                                                                if(ixb.name!=name_crc)
                   3916:                                                                        continue;
                   3917:                                                                fseek(stream
                   3918:                                                                        ,((ftell(index)
                   3919:                                                                                -sizeof(ixb_t))/sizeof(ixb_t))
                   3920:                                                                        *sizeof(user_t),SEEK_SET);
                   3921:                                                                if(!fread(&user,sizeof(user_t),1,stream))
                   3922:                                                                        continue;
                   3923:                                                                if(minor_protection(user))
                   3924:                                                                        continue;
                   3925:                                                                i=1;
                   3926:                                                                if(ch=='S' && send_telegram(user))
                   3927:                                                                        break;
                   3928:                                                                if(ch=='R' && !long_user_info(user))
                   3929:                                                                        break;  }
                   3930:                                                        if(!i)
                   3931:                                                                bprintf("\r\n\1n\1h%s \1rnot found.\r\n",name);
                   3932:                                                                }
                   3933:                                                lseek(file,offset,SEEK_SET); }
                   3934:                                        else if(ch=='P') {
                   3935:                                                lseek(file,offset,SEEK_SET);
                   3936:                                                for(i=0;i<4;i++)
                   3937:                                                        if(tell(file))
                   3938:                                                                lseek(file,tell(file)-sizeof(wall_t),SEEK_SET);
                   3939:                                                }
                   3940:                                        cls();
                   3941:                                        offset=tell(file); } }
                   3942:                        cls();
                   3943:                        if(user_level<wall_level) {
                   3944:                                close(file);
                   3945:                 bputs("\r\n\1h\1rYou have insufficient access to write on the "
                   3946:                     "wall.\r\n");
                   3947:                 pause();
                   3948:                 break; }
                   3949:                        if(aborted || noyes("Write on the Wall")) {
                   3950:                                close(file);
                   3951:                                break; }
                   3952:                        if(!useron.number) {
                   3953:                                bputs("\r\n\1h\1rYou must create a profile first.\r\n");
                   3954:                                close(file);
                   3955:                                break; }
                   3956:                        if(!cdt_warning(wall_cdt)) {
                   3957:                                close(file);
                   3958:                                break; }
                   3959:                        memset(&wall,0,sizeof(wall_t));
                   3960:                        strcpy(wall.name,useron.name);
                   3961:                        strcpy(wall.system,system_name);
                   3962:                        wall.written=wall.imported=time(NULL);
                   3963:                        bputs("\1l\1n\1hWriting on the Wall:\r\n\r\n");
                   3964:                        for(i=0;i<5 && !aborted;i++) {
                   3965:                                bprintf("\1n\1h\1%c%u of 5: \1n\1%c"
                   3966:                                        ,useron.sex=='F'?'m':'g',i+1,useron.sex=='F'?'m':'g');
                   3967:                                if(!getstr(wall.text[i],70,i==4 ? K_MSG:K_MSG|K_WRAP))
                   3968:                                        break;
                   3969:                                if(trash(wall.text[i])) {
                   3970:                                        bprintf("\r\n\1r\1hSorry, you can't use that text."
                   3971:                                                "\r\n\r\n");
                   3972:                                        i--;
                   3973:                                        continue; } }
                   3974:                        if(!i || aborted || !yesno("\r\nSave")) {
                   3975:                                close(file);
                   3976:                                break; }
                   3977:                        lseek(file,0L,SEEK_END);
                   3978:                        write(file,&wall,sizeof(wall_t));
                   3979:                        close(file);
                   3980:                        adjust_cdt(wall_cdt);
                   3981:                        if(notify_user && notify_user!=user_number) {
                   3982:                                sprintf(str,"\1n\1hSMM: \1y%s\1m wrote on the Match Maker "
                   3983:                                        "Wall\r\n",user_name);
                   3984:                                if(node_dir[0])
                   3985:                                        putsmsg(notify_user,str);
                   3986:                                else
                   3987:                                        puttgram(notify_user,str); }
                   3988:                        break;
                   3989:                case 'Q':
                   3990:                        return; } }
                   3991: }
                   3992: 
                   3993: /* End of SMM.C */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.