Annotation of sbbs/sbbs3/dosxtrn/dosxtrn.c, revision 1.1

1.1     ! root        1: /* dosxtrn.c */
        !             2: 
        !             3: /* Synchronet External DOS Program Launcher (16-bit MSVC 1.52c project) */
        !             4: 
        !             5: /* $Id: dosxtrn.c,v 1.1.1.1 2000/10/10 11:27:07 rswindell Exp $ */
        !             6: 
        !             7: /****************************************************************************
        !             8:  * @format.tab-size 4          (Plain Text/Source Code File Header)                    *
        !             9:  * @format.use-tabs true       (see http://www.synchro.net/ptsc_hdr.html)              *
        !            10:  *                                                                                                                                                     *
        !            11:  * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html         *
        !            12:  *                                                                                                                                                     *
        !            13:  * This program is free software; you can redistribute it and/or                       *
        !            14:  * modify it under the terms of the GNU General Public License                         *
        !            15:  * as published by the Free Software Foundation; either version 2                      *
        !            16:  * of the License, or (at your option) any later version.                                      *
        !            17:  * See the GNU General Public License for more details: gpl.txt or                     *
        !            18:  * http://www.fsf.org/copyleft/gpl.html                                                                                *
        !            19:  *                                                                                                                                                     *
        !            20:  * Anonymous FTP access to the most recent released source is available at     *
        !            21:  * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net     *
        !            22:  *                                                                                                                                                     *
        !            23:  * Anonymous CVS access to the development source and modification history     *
        !            24:  * is available at cvs.synchro.net:/cvsroot/sbbs, example:                                     *
        !            25:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs login                       *
        !            26:  *     (just hit return, no password is necessary)                                                     *
        !            27:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src                *
        !            28:  *                                                                                                                                                     *
        !            29:  * For Synchronet coding style and modification guidelines, see                                *
        !            30:  * http://www.synchro.net/source.html                                                                          *
        !            31:  *                                                                                                                                                     *
        !            32:  * You are encouraged to submit any modifications (preferably in Unix diff     *
        !            33:  * format) via e-mail to [email protected]                                                                      *
        !            34:  *                                                                                                                                                     *
        !            35:  * Note: If this box doesn't appear square, then you need to fix your tabs.    *
        !            36:  ****************************************************************************/
        !            37: 
        !            38: #include <stdio.h>
        !            39: #include <stdlib.h>
        !            40: #include <string.h>
        !            41: #include <process.h>
        !            42: #include <dos.h>                       /* _dos_set/getvect() */
        !            43: #include <windows.h>           /* BOOL, etc. */
        !            44: #include "vdd_func.h"
        !            45: #include "execvxd.h"
        !            46: #include "isvbop.h"                    /* ddk\inc */
        !            47: 
        !            48: /****************************************************************************/
        !            49: /* Truncates white-space chars off end of 'str' and terminates at first tab */
        !            50: /****************************************************************************/
        !            51: static void truncsp(char *str)
        !            52: {
        !            53:        size_t c;
        !            54: 
        !            55: str[strcspn(str,"\t")]=0;
        !            56: c=strlen(str);
        !            57: while(c && (unsigned char)str[c-1]<=' ') c--;
        !            58: str[c]=0;
        !            59: }
        !            60: 
        !            61: short  vdd=0;
        !            62: BYTE   node_num=0;
        !            63: int            mode=0;
        !            64: 
        !            65: void (interrupt *oldint14)();
        !            66: void (interrupt *oldint16)();
        !            67: void (interrupt *oldint29)();
        !            68: 
        !            69: static int vdd_buf(BYTE op, int count, WORD buf_seg, WORD buf_off)
        !            70: {
        !            71:        int retval;
        !            72: 
        !            73:        _asm {
        !            74:                push    bx
        !            75:                push    cx
        !            76:                push    es
        !            77:                push    di
        !            78:                mov             ax,     vdd
        !            79:                mov             bh,     node_num
        !            80:                mov             bl,     op
        !            81:                mov             cx,     count
        !            82:                mov             es, buf_seg
        !            83:                mov             di, buf_off
        !            84:        }
        !            85:        DispatchCall();
        !            86:        _asm {
        !            87:                mov             retval, ax
        !            88:                pop             di
        !            89:                pop             es
        !            90:                pop             cx
        !            91:                pop             bx
        !            92:        }
        !            93:        return(retval);
        !            94: }
        !            95: 
        !            96: static int vdd_op(BYTE op)
        !            97: {
        !            98:        int retval;
        !            99: 
        !           100:        _asm {
        !           101:                push    bx
        !           102:                mov             ax,     vdd
        !           103:                mov             bh,     node_num
        !           104:                mov             bl,     op
        !           105:        }
        !           106:        DispatchCall();
        !           107:        _asm {
        !           108:                mov             retval, ax
        !           109:                pop             bx
        !           110:        }
        !           111:        return(retval);
        !           112: }
        !           113: 
        !           114: char win95int14[]={
        !           115:         0xCF   // IRET
        !           116:        ,0x90   // NOP
        !           117:        ,0x90
        !           118:        ,0x90
        !           119:        ,0x90
        !           120:        ,0x90
        !           121:        ,0x54   // FOSSIL sig
        !           122:        ,0x19   // FOSSIL sig
        !           123:        ,0x1B   // FOSSIL highest func supported
        !           124: };
        !           125: 
        !           126: void vdd_getstatus(vdd_status_t* status)
        !           127: {
        !           128:        WORD                    buf_seg;
        !           129: 
        !           130:        _asm mov buf_seg, ss;
        !           131:        if(vdd_buf(VDD_STATUS, sizeof(vdd_status_t), buf_seg, (WORD)status)!=0)
        !           132:                memset(status,0,sizeof(vdd_status_t));
        !           133: }
        !           134: 
        !           135: #if 1
        !           136: 
        !           137: WORD PortStatus()
        !           138: {
        !           139:        WORD                    status=0x0008;                  // AL bit 3 (change in DCD) always set
        !           140:        vdd_status_t    vdd_status;
        !           141: 
        !           142:        vdd_getstatus(&vdd_status);
        !           143: 
        !           144:        if(vdd_status.online)                   // carrier detect
        !           145:                status|=0x0080;                         // DCD
        !           146: 
        !           147:        if(vdd_status.inbuf_full)               // receive data ready 
        !           148:                status|=0x0100;                         // RDA
        !           149: 
        !           150: //     if(vm->overrun)                                 // overrun error detected
        !           151: //             status|=0x0200;                         // OVRN
        !           152: 
        !           153:        if(vdd_status.outbuf_full
        !           154:                <vdd_status.outbuf_size/2)      // room available in output buffer
        !           155:                status|=0x2000;                         // THRE
        !           156: 
        !           157:        if(!vdd_status.outbuf_full)             // output buffer is empty
        !           158:                status|=0x4000;                         // TSRE
        !           159: 
        !           160:        return(status);
        !           161: }
        !           162: 
        !           163: #else
        !           164: 
        !           165: WORD PortStatus()
        !           166: {
        !           167:        WORD    status=0x0008;                  // AL bit 3 (change in DCD) always set
        !           168:        static  poll;
        !           169:        static  online=1;
        !           170:        static  outbuf_full;
        !           171:        static  outbuf_size;
        !           172: 
        !           173:        if(!poll)
        !           174:                outbuf_size=vdd_op(VDD_OUTBUF_SIZE);
        !           175: 
        !           176:        if(!(poll%500)) {
        !           177:                online=vdd_op(VDD_ONLINE);
        !           178:                outbuf_full=vdd_op(VDD_OUTBUF_FULL);
        !           179:        }
        !           180: 
        !           181:        if(online)                                              // carrier detect
        !           182:                status|=0x0080;                         // DCD
        !           183: 
        !           184:        if(vdd_op(VDD_INBUF_FULL))              // receive data ready 
        !           185:                status|=0x0100;                         // RDA
        !           186: 
        !           187: //     if(vm->overrun)                                 // overrun error detected
        !           188: //             status|=0x0200;                         // OVRN
        !           189: 
        !           190:        if(outbuf_full
        !           191:                <outbuf_size/2)                         // room available in output buffer
        !           192:                status|=0x2000;                         // THRE
        !           193: 
        !           194:        if(!outbuf_full)                                // output buffer is empty
        !           195:                status|=0x4000;                         // TSRE
        !           196: 
        !           197:        poll++;
        !           198: 
        !           199:        return(status);
        !           200: }
        !           201: 
        !           202: #endif
        !           203: 
        !           204: void interrupt winNTint14(
        !           205:        unsigned _es, unsigned _ds,
        !           206:        unsigned _di, unsigned _si,
        !           207:        unsigned _bp, unsigned _sp,
        !           208:        unsigned _bx, unsigned _dx,
        !           209:        unsigned _cx, unsigned _ax,
        !           210:        )
        !           211: {
        !           212:        BYTE                    ch;
        !           213:        BYTE far*               p;
        !           214:        WORD                    buf_seg;
        !           215:        int                             wr;
        !           216:        vdd_status_t    vdd_status;
        !           217:     struct {
        !           218:         WORD    info_size;
        !           219:         BYTE   curr_fossil;
        !           220:         BYTE   curr_rev;
        !           221:         DWORD  id_string;
        !           222:         WORD   inbuf_size;
        !           223:         WORD   inbuf_free;
        !           224:         WORD   outbuf_size;
        !           225:         WORD   outbuf_free;
        !           226:         BYTE   screen_width;
        !           227:         BYTE   screen_height;
        !           228:         BYTE   baud_rate;
        !           229:     } info= { sizeof(info), 5, 1, 0
        !           230:                                ,0,0
        !           231:                                ,0,0
        !           232:                        ,80,25
        !           233:                        ,1 // 38400
        !           234:                        };
        !           235: 
        !           236:        switch(_ax>>8) {
        !           237:                case 0x00:      /* Initialize/Set baud rate */
        !           238:                        _ax = PortStatus();
        !           239:                        break;
        !           240:                case 0x01: /* write char to com port */
        !           241:                        ch=_ax&0xff;
        !           242:                        _asm mov buf_seg, ss;
        !           243:                        vdd_buf(VDD_WRITE, 1, buf_seg, (WORD)&ch);
        !           244:                        _ax = PortStatus();
        !           245:                        break;
        !           246:                case 0x02: /* read char from com port */
        !           247:                        _asm mov buf_seg, ss;
        !           248:                        _ax = vdd_buf(VDD_READ, 1, buf_seg, (WORD)&ch);
        !           249:                        if(!_ax)
        !           250:                                _ax = 0x8000;   /* timed-out */
        !           251:                        else
        !           252:                                _ax = ch;
        !           253:                        break;
        !           254:                case 0x03:      /* request status */
        !           255:                        _ax=PortStatus();
        !           256:                        break;
        !           257:                case 0x04:      /* initialize */
        !           258:                        _ax=0x1954;     /* magic number = success */
        !           259:                        _bx=0x051B;     /* FOSSIL rev/maximum FOSSIL func supported */
        !           260:                        break;
        !           261:         case 0x08:     /* flush output buffer  */
        !           262:                        break;
        !           263:         case 0x09:     /* purge output buffer  */
        !           264:                        vdd_op(VDD_OUTBUF_PURGE);
        !           265:                        break;
        !           266:         case 0x0A:     /* purge input buffer   */
        !           267:                        vdd_op(VDD_INBUF_PURGE);
        !           268:                        break;
        !           269:                case 0x0B:      /* write char to com port, no wait */
        !           270:                if(0 /*RingBufFree(&vm->out)<2 */) {
        !           271:                _ax=0; // char was not accepted
        !           272:                 break;
        !           273:             }
        !           274:                        ch=_ax&0xff;
        !           275:                        _asm mov buf_seg, ss;
        !           276:                        _ax = vdd_buf(VDD_WRITE, 1, buf_seg, (WORD)&ch);
        !           277:                        break;
        !           278:         case 0x0C:     // non-destructive read-ahead
        !           279:                        vdd_getstatus(&vdd_status);
        !           280:                        if(!vdd_status.inbuf_full) {
        !           281:                                _ax=0xffff;     // no char available
        !           282:                                break;
        !           283:                        }
        !           284:                        _asm mov buf_seg, ss;
        !           285:                        _ax = vdd_buf(VDD_PEEK, 1, buf_seg, (WORD)&ch);
        !           286:                        break;
        !           287:         case 0x18:     /* read bock */
        !           288:             _ax = vdd_buf(VDD_READ, _cx, _es, _di);
        !           289:                        break;
        !           290:         case 0x19:     /* write block */
        !           291:                        _ax = vdd_buf(VDD_WRITE, _cx, _es, _di);
        !           292:                        break;
        !           293:         case 0x1B:     /* driver info */
        !           294:                        vdd_getstatus(&vdd_status);
        !           295:                        info.inbuf_size=vdd_status.inbuf_size;
        !           296:                        info.inbuf_free=info.inbuf_size-vdd_status.inbuf_full;
        !           297:                        info.outbuf_size=vdd_status.outbuf_size;
        !           298:                        info.outbuf_free=info.outbuf_size-vdd_status.outbuf_full;
        !           299: 
        !           300:                        p = _MK_FP(_es,_di);
        !           301:             wr=sizeof(info);
        !           302:             if(wr>_cx)
        !           303:                wr=_cx;
        !           304:             _fmemcpy(p, &info, wr);
        !           305:                _ax=wr;
        !           306:             break;
        !           307:        }
        !           308: }
        !           309: 
        !           310: void interrupt winNTint16(
        !           311:        unsigned _es, unsigned _ds,
        !           312:        unsigned _di, unsigned _si,
        !           313:        unsigned _bp, unsigned _sp,
        !           314:        unsigned _bx, unsigned _dx,
        !           315:        unsigned _cx, unsigned _ax,
        !           316:        unsigned _ip, unsigned _cs,
        !           317:     unsigned flags )
        !           318: {
        !           319:        BYTE                    ch;
        !           320:        WORD                    buf_seg;
        !           321:        vdd_status_t    status;
        !           322: 
        !           323:        vdd_getstatus(&status);
        !           324:        switch(_ax>>8) {
        !           325:        case 0x00:      // Read char from keyboard
        !           326:         case 0x10:     // Read char from enhanced keyboard
        !           327:                        if(status.inbuf_full) {
        !           328:                                _asm mov buf_seg, ss;
        !           329:                                vdd_buf(VDD_READ, 1, buf_seg, (WORD)&ch);
        !           330:                                _ax=ch;
        !           331:                                return;
        !           332:                        }
        !           333:                        break;
        !           334:        case 0x01:      // Get keyboard status
        !           335:         case 0x11:     // Get enhanced keyboard status
        !           336:                        if(status.inbuf_full) {
        !           337:                                _asm mov buf_seg, ss;
        !           338:                                vdd_buf(VDD_PEEK, 1, buf_seg, (WORD)&ch);
        !           339:                 flags&=~(1<<6);        // clear zero flag
        !           340:                 _ax=ch;
        !           341:                                return;
        !           342:            }
        !           343:                break;
        !           344:        }
        !           345: 
        !           346:        _chain_intr(oldint16);          
        !           347: }
        !           348: 
        !           349: void interrupt winNTint29(
        !           350:        unsigned _es, unsigned _ds,
        !           351:        unsigned _di, unsigned _si,
        !           352:        unsigned _bp, unsigned _sp,
        !           353:        unsigned _bx, unsigned _dx,
        !           354:        unsigned _cx, unsigned _ax,
        !           355:        )
        !           356: {
        !           357:        char    ch;
        !           358:        WORD    buf_seg;
        !           359: 
        !           360:        ch=_ax&0xff;
        !           361:        _asm mov buf_seg, ss
        !           362:        vdd_buf(VDD_WRITE, 1, buf_seg, (WORD)&ch);
        !           363: 
        !           364:        _chain_intr(oldint29);
        !           365: }
        !           366: 
        !           367: char * DllName         ="SBBSEXEC.DLL";
        !           368: char * InitFunc        ="VDDInitialize";
        !           369: char * DispFunc        ="VDDDispatch";
        !           370: 
        !           371: int main(int argc, char **argv)
        !           372: {
        !           373:        char    str[128];
        !           374:        char    cmdline[128],*p;
        !           375:        char    dll[512];
        !           376:        char*   envvar[10];
        !           377:        char*   arg[16];
        !           378:        int             i,c,d,envnum=0;
        !           379:        FILE*   fp;
        !           380:        BOOL    NT=FALSE;
        !           381:        BOOL    success=FALSE;
        !           382:        WORD    seg;
        !           383: 
        !           384:        if(argc<2) {
        !           385:                fprintf(stderr
        !           386:                        ,"This program is for the internal use of Synchronet BBS only\n");
        !           387:                return(1);
        !           388:        }
        !           389: #if 1
        !           390:        strcpy(dll,argv[0]);
        !           391:        p=strrchr(dll,'\\');
        !           392:        if(p!=NULL) *(p+1)=0;
        !           393:        strcat(dll,"SBBSEXEC.DLL");
        !           394:        DllName=dll;
        !           395: #endif
        !           396: 
        !           397:        if(argc>2 && !strcmp(argv[2],"NT")) {
        !           398:                NT=TRUE;
        !           399:                if(argc>3)
        !           400:                        node_num=atoi(argv[3]);
        !           401:                if(argc>4)
        !           402:                        mode=atoi(argv[4]);
        !           403:        }
        !           404: 
        !           405:        if((fp=fopen(argv[1],"r"))==NULL) {
        !           406:                fprintf(stderr,"!Error opening %s\n",argv[1]);
        !           407:                return(2);
        !           408:        }
        !           409: 
        !           410:        fgets(cmdline, sizeof(cmdline), fp);
        !           411:        truncsp(cmdline);
        !           412: 
        !           413:        arg[0]=cmdline; /* point to the beginning of the string */
        !           414:        for(c=0,d=1;cmdline[c];c++)     /* Break up command line */
        !           415:                if(cmdline[c]==' ') {
        !           416:                        cmdline[c]=0;                   /* insert nulls */
        !           417:                        arg[d++]=cmdline+c+1; } /* point to the beginning of the next arg */
        !           418:        arg[d]=0;
        !           419: 
        !           420:        while(!feof(fp)) {
        !           421:                if(!fgets(str, sizeof(str), fp))
        !           422:                        break;
        !           423:                truncsp(str);
        !           424:                envvar[envnum]=malloc(strlen(str)+1);
        !           425:                if(envvar[envnum]==NULL) {
        !           426:                        fprintf(stderr,"!MALLOC ERROR\n");
        !           427:                        return(4);
        !           428:                }
        !           429:                strcpy(envvar[envnum],str);
        !           430:                _putenv(envvar[envnum++]);
        !           431:        }
        !           432:        fclose(fp);
        !           433: 
        !           434:        /* Save int14 handler */
        !           435:        oldint14=_dos_getvect(0x14);
        !           436: 
        !           437:        if(NT) {        /* Windows NT/2000 */
        !           438: 
        !           439:                /* Register VDD */
        !           440:                _asm {
        !           441:                        push    es
        !           442:                        push    ds
        !           443:                        pop             es
        !           444:                        mov     si, DllName             ; ds:si = dll name
        !           445:                    mov     di, InitFunc    ; es:di = init routine
        !           446:                        mov     bx, DispFunc    ; ds:bx = dispatch routine
        !           447:                };
        !           448:                RegisterModule();
        !           449:                _asm {
        !           450:                        mov             vdd, ax
        !           451:                        jc              err
        !           452:                        mov             success, TRUE
        !           453:                        err:
        !           454:                        pop             es
        !           455:                }
        !           456:                if(!success) {
        !           457:                        fprintf(stderr,"Error %d loading %s\n",vdd,DllName);
        !           458:                        return(-1);
        !           459:                }
        !           460: #if 0
        !           461:                fprintf(stderr,"vdd handle=%d\n",vdd);
        !           462:                fprintf(stderr,"mode=%d\n",mode);
        !           463: #endif
        !           464: 
        !           465:                i=vdd_op(VDD_OPEN);
        !           466:                if(i) {
        !           467:                        fprintf(stderr,"!VDD_OPEN ERROR: %d\n",i);
        !           468:                        UnRegisterModule();
        !           469:                        return(-1);
        !           470:                }
        !           471: 
        !           472:                oldint16=_dos_getvect(0x16);
        !           473:                oldint29=_dos_getvect(0x29);
        !           474:                if(mode==SBBSEXEC_MODE_FOSSIL)
        !           475:                        _dos_setvect(0x14,(void(interrupt *)())winNTint14); 
        !           476:                if(mode&SBBSEXEC_MODE_DOS_IN)
        !           477:                        _dos_setvect(0x16,winNTint16); 
        !           478:                if(mode&SBBSEXEC_MODE_DOS_OUT) 
        !           479:                        _dos_setvect(0x29,winNTint29); 
        !           480:        }
        !           481:        else            /* Windows 95/98/Millennium */
        !           482:                _dos_setvect(0x14,(void(interrupt *)())win95int14); 
        !           483: 
        !           484:        _heapmin();
        !           485:        i=_spawnvp(_P_WAIT, arg[0], arg);
        !           486: 
        !           487:        p=argv[1]+(strlen(argv[1])-3);
        !           488:        strcpy(p,"RET");
        !           489:        if((fp=fopen(argv[1],"w+"))==NULL) {
        !           490:                fprintf(stderr,"!Error opening %s\n",argv[1]);
        !           491:                return(3);
        !           492:        }
        !           493:        fprintf(fp,"%d",i);
        !           494: 
        !           495:        /* Restore original ISRs */
        !           496:        _dos_setvect(0x14,oldint14);
        !           497: 
        !           498:        if(NT) {
        !           499:                vdd_op(VDD_CLOSE);
        !           500: 
        !           501:                _dos_setvect(0x16,oldint16);
        !           502:                _dos_setvect(0x29,oldint29);
        !           503: 
        !           504:                /* Unregister VDD */
        !           505:                _asm mov ax, vdd;
        !           506:                UnRegisterModule();
        !           507:        }
        !           508:        return(i);
        !           509: }

unix.superglobalmegacorp.com

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