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

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