Annotation of pmsdk/samples/comtalk/comtalk.c, revision 1.1.1.1

1.1       root        1: /*
                      2:    comtalk.c -- Main routines
                      3:    Created by Microsoft Corporation, 1989
                      4: 
                      5:    This file contains the sources for the dialog box manipulation, and menu
                      6:    managment, and other aspects of interfacing with the user.
                      7: */
                      8: #define INCL_WIN
                      9: #include <os2.h>
                     10: #include "comtalk.h"   /* definition of COM from Global, and Resource IDs */
                     11: #include "avio.h"      /* Routines needed to manage AVIO Presentation Space */
                     12: #include "threads.h"   /* Thread initialization and control routines */
                     13: #include <stdio.h>     /* Only needed for file I/O */
                     14: #include <string.h>    /* one strcpy call */
                     15: /*
                     16:     Variables
                     17: */
                     18: CHAR           szCaption[] = "";
                     19: HAB            hAB;
                     20: COM            comTerm;
                     21: COM            comTemp;
                     22: HWND           hWndMenu;
                     23: CLASSINFO      clsi;
                     24: PFNWP          pfnOldFrameWndProc;
                     25: BOOL           fConnected      = FALSE;
                     26: BOOL           fPaging;
                     27: int            iUpdate;
                     28: BOOL           fFreeze         = TRUE;
                     29: int            iError;
                     30: /*
                     31:     Macros
                     32: */
                     33: #define InRange(x, a, b) ((a <= x) && (x <= b))
                     34: 
                     35: /*
                     36:     Shorthand for sending messages, querying
                     37: */
                     38: #define Parent(h) \
                     39:     WinQueryWindow(h, QW_PARENT, FALSE)
                     40: 
                     41: #define EnableMenuItem(id) \
                     42:     WinSendMsg(hWndMenu, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE), \
                     43:               MPFROM2SHORT(MIA_DISABLED,0))
                     44: 
                     45: #define DisableMenuItem(id) \
                     46:     WinSendMsg(hWndMenu, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE), \
                     47:               MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED))
                     48: 
                     49: #define CheckMenuItem(id) \
                     50:     WinSendMsg(hWndMenu, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE), \
                     51:               MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED)) 
                     52: 
                     53: #define UnCheckMenuItem(id) \
                     54:     WinSendMsg(hWndMenu, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE), \
                     55:               MPFROM2SHORT(MIA_CHECKED, 0))
                     56: 
                     57: #define PushButton(h, id) \
                     58:     WinSendDlgItemMsg(h, id, BM_SETCHECK, MPFROM2SHORT(TRUE, 0), 0L) 
                     59: 
                     60: #define Valid(bData, bStop) \
                     61:     (((bData == IDD_FIVE) && (bStop != IDD_TWOSTOP)) \
                     62:     || ((bData != IDD_FIVE) && (bStop != IDD_ONEFIVE)))
                     63: 
                     64: #define ErrMsg(h, s) \
                     65:     WinMessageBox(HWND_DESKTOP, h, s, NULL, NULL, MB_OK | MB_ICONEXCLAMATION)
                     66: 
                     67: char Ctrl(char ch) {
                     68:     return (('a' <= ch) && (ch <= 'z')) ? (ch - 'a' + '\001') :
                     69:          ((('A' <= ch) && (ch <= 'Z')) ? (ch - 'A' + '\001') : ch);
                     70: }
                     71: 
                     72: /*
                     73:     Local/Private routines
                     74: */
                     75: void ReadOpts(HWND);
                     76: void InitTerm(void);
                     77: void Initialize(HWND);
                     78: void ChangeSystemMenu(HWND);
                     79: BOOL Filter(USHORT, char, USHORT);
                     80: 
                     81: void main (void) {
                     82:      static CHAR szClientClass[] = "Terminal";
                     83:      HMQ       hmq;
                     84:      HWND      hWndClient, hWndFrame;
                     85:      QMSG      qmsg;
                     86:      ULONG     flFrameFlags = FCF_STANDARD | FCF_HORZSCROLL | FCF_VERTSCROLL;
                     87:      ULONG     flFrameStyle = WS_VISIBLE | FS_SCREENALIGN;
                     88:      
                     89:      hAB = WinInitialize(0);
                     90:      hmq = WinCreateMsgQueue(hAB, 0);
                     91: 
                     92:      WinRegisterClass(hAB, szClientClass, ClientWndProc, CS_SYNCPAINT, 0);
                     93: 
                     94:      hWndFrame = WinCreateStdWindow(HWND_DESKTOP, flFrameStyle,
                     95:                                     &flFrameFlags, szClientClass, szCaption,
                     96:                                      0L, NULL, ID_RESOURCE, &hWndClient);
                     97: 
                     98:      /* Setup AVIO PS and force a paint */
                     99:      AvioInit(hWndFrame, hWndClient);
                    100:      WinSendMsg(hWndClient, WM_PAINT, NULL, NULL);
                    101: 
                    102:      /* Try to subclass the Frame window... */
                    103:      pfnOldFrameWndProc = WinSubclassWindow(hWndFrame, NewFrameWndProc);
                    104: 
                    105:      while (WinGetMsg(hAB, &qmsg, NULL, 0, 0)) WinDispatchMsg(hAB, &qmsg);
                    106: 
                    107:      /* Blast the AVIO PS */
                    108:      AvioClose();
                    109: 
                    110:      WinDestroyWindow(hWndFrame);
                    111:      WinDestroyMsgQueue(hmq);
                    112:      WinTerminate(hAB);
                    113:      DosExit(EXIT_PROCESS, 0);
                    114: }
                    115: 
                    116: MRESULT CALLBACK ClientWndProc(HWND hWnd, USHORT msg, MPARAM mp1, MPARAM mp2) {
                    117: /*
                    118:      Window Procedure which traps messages to the Client area
                    119: */
                    120:      switch (msg) {
                    121:          case WM_AVIOUPDATE:
                    122:                fNoUpdate = AvioUpdateLines(FALSE, &fPaging);
                    123:                if (fConnected && fPaging) {
                    124:                    CheckMenuItem(IDM_PAGING);
                    125:                }
                    126:                break;
                    127: 
                    128:          case WM_MSGBOX:
                    129:                iUpdate = (int) mp2;
                    130:                switch ((int) mp1) {
                    131:                    case (int) MBE_COMREAD:
                    132:                        if (iError = iUpdate) EnableMenuItem(IDM_ERRORS);
                    133:                        iUpdate = 0;
                    134:                        break;
                    135: 
                    136:                    default:
                    137:                        ErrMsg(hWnd, aszMessage[(int) mp1]);
                    138:                        break;
                    139:                }
                    140:                if (iUpdate) {  /* Page down because queue is full */
                    141:                    fNoUpdate = AvioUpdateLines(TRUE, &fPaging);
                    142:                    if (fConnected && fPaging) CheckMenuItem(IDM_PAGING);
                    143:                    else UnCheckMenuItem(IDM_PAGING);
                    144:                    ThdReset();
                    145:                }
                    146:                break;
                    147: 
                    148:          case WM_CREATE:
                    149:                ChangeSystemMenu(hWnd);
                    150:                /*
                    151:                    Initialize the Dialog Options
                    152:                */
                    153:                Initialize(hWnd);
                    154:                /*
                    155:                    Get the Handle so you can enable/disable menu items
                    156:                    Thanks again to Charles Petzold
                    157:                */
                    158:                hWndMenu = WinWindowFromID(Parent(hWnd), FID_MENU);
                    159:                /*
                    160:                    Disable some entries (can do this in the resource file)
                    161:                */
                    162:                DisableMenuItem(IDM_CLOSE);
                    163:                DisableMenuItem(IDM_BREAK);
                    164:                DisableMenuItem(IDM_COMMANDMENU);
                    165:                break;
                    166: 
                    167:          case WM_PAINT:                /* Paint the AVIO way! */
                    168:                AvioPaint(hWnd);
                    169:                break;
                    170: 
                    171:          case WM_SIZE:                 /* Size the AVIO way!  */
                    172:                fNoUpdate = AvioUpdateLines(FALSE, &fPaging);
                    173:                if (fConnected && fPaging) {
                    174:                    CheckMenuItem(IDM_PAGING);
                    175:                }
                    176:                return AvioSize(hWnd, msg, mp1, mp2);
                    177:                break;
                    178: 
                    179:          case WM_HSCROLL:
                    180:                AvioScroll(HIUSHORT(mp2), LOUSHORT(mp2), TRUE);
                    181:                break;
                    182: 
                    183:          case WM_VSCROLL:
                    184:                AvioScroll(HIUSHORT(mp2), LOUSHORT(mp2), FALSE);
                    185:                break;
                    186: 
                    187:          case WM_ERASEBACKGROUND:
                    188:                return 0;
                    189:                break;
                    190: 
                    191:          case WM_COMMAND:
                    192:                switch (COMMANDMSG(&msg)->cmd) {
                    193:                    case IDM_ABOUT:
                    194:                        WinDlgBox(HWND_DESKTOP, hWnd, AboutDlgProc,
                    195:                                  NULL, IDD_ABOUT, NULL);
                    196:                         return 0;
                    197: 
                    198:                    case IDM_HELP:
                    199:                        WinDlgBox(HWND_DESKTOP, hWnd, AboutDlgProc,
                    200:                                  NULL, IDD_MAINHELPBOX, NULL);
                    201:                        return 0;
                    202: 
                    203:                    case IDM_SETTINGS:
                    204:                        WinDlgBox(HWND_DESKTOP, hWnd, SetDlgProc,
                    205:                                  NULL, IDD_SET, NULL);
                    206:                        return 0;
                    207: 
                    208:                    case IDM_CONNECT:
                    209:                        AvioStartup(hWnd);
                    210:                        ThdInitialize(hWnd, comTerm);   /* Spawn 3 threads  */
                    211:                        /*
                    212:                            Disable/Enable Menu Items
                    213:                        */
                    214:                        DisableMenuItem(IDM_CONNECT);
                    215:                        DisableMenuItem(IDM_SETTINGS);
                    216:                        DisableMenuItem(IDM_ERRORS);
                    217: 
                    218:                        EnableMenuItem(IDM_CLOSE);
                    219:                        EnableMenuItem(IDM_BREAK);
                    220:                        EnableMenuItem(IDM_COMMANDMENU);
                    221:                        fConnected = TRUE;
                    222:                        return 0;
                    223: 
                    224:                    case IDM_CLOSE:
                    225:                        fConnected = FALSE;
                    226:                        ThdTerminate();         /* Might have to wait? */
                    227:                        /*
                    228:                            Update menu items
                    229:                        */
                    230:                        UnCheckMenuItem(IDM_BREAK);
                    231: 
                    232:                        DisableMenuItem(IDM_CLOSE);
                    233:                        DisableMenuItem(IDM_BREAK);
                    234:                        DisableMenuItem(IDM_COMMANDMENU);
                    235: 
                    236:                        EnableMenuItem(IDM_CONNECT);
                    237:                        EnableMenuItem(IDM_SETTINGS);
                    238: 
                    239:                        return 0;
                    240: 
                    241:                    case IDM_BREAK:
                    242:                        ThdDoBreak();
                    243:                        return 0;
                    244: 
                    245:                    case IDM_ERRORS:
                    246:                        if (iError & 1)
                    247:                            ErrMsg(hWnd, "Receive Queue Overrun");
                    248:                        if (iError & 2)
                    249:                            ErrMsg(hWnd, "Receive Hardware Overrun");
                    250:                        if (iError & 4)
                    251:                            ErrMsg(hWnd, "Parity Error");
                    252:                        if (iError & 8)
                    253:                            ErrMsg(hWnd, "Framing Error");
                    254:                        DisableMenuItem(IDM_ERRORS);
                    255:                        return 0;
                    256: 
                    257:                    case IDM_PAGE:
                    258:                        fNoUpdate = AvioUpdateLines(TRUE, &fPaging);
                    259:                        if (fPaging) CheckMenuItem(IDM_PAGING);
                    260:                        else UnCheckMenuItem(IDM_PAGING);
                    261:                        return 0;
                    262: 
                    263:                    case IDM_UP:
                    264:                        AvioPageUp();
                    265:                        return 0;
                    266: 
                    267:                    case IDM_PAGING:
                    268:                        if (fPaging = !fPaging) {
                    269:                            CheckMenuItem(IDM_PAGING);
                    270:                        } else {
                    271:                            UnCheckMenuItem(IDM_PAGING);
                    272:                        }
                    273:                        return 0;
                    274: 
                    275:                    default: return 0;
                    276:                }
                    277: 
                    278:          case WM_CHAR:         /* Put characters in typeahead buffer */
                    279:                if (fConnected && !(CHARMSG(&msg)->fs & KC_KEYUP)) 
                    280:                    if (Filter( CHARMSG(&msg)->fs,
                    281:                         (char) CHARMSG(&msg)->chr,
                    282:                                CHARMSG(&msg)->vkey))
                    283:                        ErrMsg(hWnd, "Error Writing COM Port");
                    284:                break;
                    285: 
                    286:          case WM_TRACKFRAME:
                    287:                AvioTrackFrame(hWnd, mp1);
                    288:                break;
                    289: 
                    290:          case WM_MINMAXFRAME: /* Trap MAXIMIZE messages */
                    291:                AvioMinMax((PSWP) mp1);
                    292: 
                    293:          default: return WinDefWindowProc(hWnd, msg, mp1, mp2);
                    294:      }
                    295:      return 0;
                    296: }
                    297: 
                    298: MRESULT CALLBACK AboutDlgProc(HWND hDlg, USHORT msg, MPARAM mp1, MPARAM mp2) {
                    299: /*
                    300:     Dialog box control for the ABOUT COMTALK... dialog box
                    301: */
                    302:     switch(msg) {
                    303:        case WM_COMMAND:
                    304:            switch(COMMANDMSG(&msg)->cmd) {
                    305:                case DID_OK: WinDismissDlg(hDlg, TRUE); break;
                    306:                default: break;
                    307:            }
                    308:        default: return WinDefDlgProc(hDlg, msg, mp1, mp2);
                    309:     }
                    310:     return FALSE;
                    311: }
                    312: 
                    313: void WriteOpts(void) {
                    314: /*
                    315:     Write Settings to file COMTALK.INI
                    316: */
                    317:     FILE *fp;
                    318: 
                    319:     fp = fopen("comtalk.ini", "w+");
                    320:     fprintf(fp, "%d %d %d %d %d %d %d %s\n", comTerm.usBaud, comTerm.bParity,
                    321:                comTerm.bData, comTerm.bStop, comTerm.fWrap,
                    322:                comTerm.fHardware, comTerm.fSoftware, comTerm.szPort);
                    323:     fclose(fp);
                    324: }
                    325: 
                    326: void ReadOpts(HWND hWnd) {
                    327: /*
                    328:     Read Settings from COMTALK.INI
                    329: */
                    330:     FILE *fp;
                    331: 
                    332:     /* Use InitTerm() if we have reading problems */
                    333:     if ((fp = fopen("comtalk.ini", "r")) == NULL) InitTerm();
                    334:     else if (fscanf(fp, "%d%d%d%d%d%d%d%s", &comTerm.usBaud, &comTerm.bParity,
                    335:        &comTerm.bData, &comTerm.bStop, &comTerm.fWrap,
                    336:        &comTerm.fHardware, &comTerm.fSoftware, comTerm.szPort) == EOF)
                    337:        InitTerm();
                    338:     if (!Valid(comTerm.bData, comTerm.bStop)) {
                    339:        ErrMsg(hWnd, "Invalid terminal setting");
                    340:        InitTerm();
                    341:     }
                    342:     fclose(fp);
                    343: }
                    344: 
                    345: void InitTerm(void) {
                    346: /*
                    347:     Initialize the TERM structure to DosDevIOCtl defaults
                    348: */
                    349:     strcpy(comTerm.szPort, "com1");
                    350:     comTerm.usBaud = 9600; comTerm.bParity = IDD_EVENP;
                    351:     comTerm.bData = IDD_SEVEN; comTerm.bStop = IDD_ONESTOP;
                    352:     comTerm.fWrap = comTerm.fSoftware = TRUE; comTerm.fHardware = FALSE;
                    353: }
                    354: 
                    355: MRESULT CALLBACK SetDlgProc(HWND hDlg, USHORT msg, MPARAM mp1, MPARAM mp2) {
                    356: /*
                    357:     The Settings Dialog Box control routine
                    358: */
                    359:     BOOL       rc;
                    360:     BYTE       bTemp;
                    361: 
                    362:     switch(msg) {
                    363:         case WM_INITDLG:
                    364:            WinSetDlgItemText(hDlg, IDD_PORT, comTerm.szPort);
                    365:            WinSetDlgItemShort(hDlg, IDD_BAUD, comTerm.usBaud, FALSE);
                    366: 
                    367:            PushButton(hDlg, comTerm.bParity);
                    368:            PushButton(hDlg, comTerm.bData);
                    369:            PushButton(hDlg, comTerm.bStop);
                    370:            if (comTerm.fWrap) PushButton(hDlg, IDD_WRAP);
                    371:            if (comTerm.fHardware) PushButton(hDlg, IDD_HW);
                    372:            if (comTerm.fSoftware) PushButton(hDlg, IDD_SW);
                    373: 
                    374:            comTemp.bParity     = comTerm.bParity;
                    375:            comTemp.bData       = comTerm.bData;
                    376:            comTemp.bStop       = comTerm.bStop;
                    377:            comTemp.fWrap       = comTerm.fWrap;
                    378:            comTemp.fHardware   = comTerm.fHardware;
                    379:            comTemp.fSoftware   = comTerm.fSoftware;
                    380:            break; 
                    381: 
                    382:        case WM_HELP:
                    383:            WinDlgBox(HWND_DESKTOP, hDlg, AboutDlgProc,
                    384:                      NULL, IDD_SETHELPBOX, NULL);
                    385:            break;
                    386: 
                    387:        case WM_CONTROL:
                    388:            /*
                    389:                The fact that these are AutoRadioButtons makes life easy.
                    390:            */
                    391:            bTemp = (BYTE) SHORT1FROMMP(mp1);   /* Which button pushed? */
                    392:            if InRange(bTemp, IDD_NOP, IDD_SPACEP) {
                    393:                comTemp.bParity = bTemp; 
                    394:            } else if InRange(bTemp, IDD_FIVE, IDD_EIGHT) {
                    395:                comTemp.bData = bTemp;
                    396:            } else if InRange(bTemp, IDD_ONESTOP, IDD_TWOSTOP) {
                    397:                comTemp.bStop = bTemp;
                    398:            } else switch (bTemp) {
                    399:                case IDD_WRAP: comTemp.fWrap     = !comTemp.fWrap;     break;
                    400:                case IDD_HW  : comTemp.fHardware = !comTemp.fHardware; break;
                    401:                case IDD_SW  : comTemp.fSoftware = !comTemp.fSoftware; break;
                    402:                default:                                               break;
                    403:            }
                    404:            break;
                    405:        case WM_COMMAND:        /* Ready to exit... */
                    406:            switch(COMMANDMSG(&msg)->cmd) {
                    407:                case IDD_SAVE:
                    408:                case DID_OK:
                    409:                    if (!Valid(comTemp.bData, comTemp.bStop)) {
                    410:                        ErrMsg(hDlg,"Data and Stop Bits Incompatible");
                    411:                        break;  /* No-op...Dialog not dismissed */
                    412:                    }
                    413:                    WinQueryDlgItemText(hDlg, IDD_PORT, 5, comTerm.szPort);
                    414:                    WinQueryDlgItemShort(hDlg, IDD_BAUD, &comTerm.usBaud, rc);
                    415:                    comTerm.bParity     = comTemp.bParity;
                    416:                    comTerm.bData       = comTemp.bData;
                    417:                    comTerm.bStop       = comTemp.bStop;
                    418:                    comTerm.fWrap       = comTemp.fWrap;
                    419:                    comTerm.fHardware   = comTemp.fHardware;
                    420:                    comTerm.fSoftware   = comTemp.fSoftware;
                    421:                    if (COMMANDMSG(&msg)->cmd == IDD_SAVE) WriteOpts();
                    422:                case DID_CANCEL: WinDismissDlg(hDlg, FALSE);
                    423:                default: break;
                    424:            }
                    425:            break;
                    426:        default: return WinDefDlgProc(hDlg, msg, mp1, mp2);
                    427:     }
                    428:     return FALSE;
                    429: }
                    430: 
                    431: void Initialize(HWND hWnd) {
                    432:     ReadOpts(hWnd);
                    433:     fPaging = FALSE;
                    434: }
                    435: 
                    436: void ChangeSystemMenu(HWND hWnd) {
                    437: /*
                    438:     Insert items into the System Menu (with thanks to Charles Petzold)
                    439: */
                    440:     static CHAR *x[2] = { NULL, "~About ComTalk..." }; /* Items to add */
                    441:     static MENUITEM mi[2] = {  /* The RESOURCE definitions */
                    442:        MIT_END, MIS_SEPARATOR, 0x0000, NULL, NULL, NULL,
                    443:        MIT_END, MIS_TEXT, 0x0000, IDM_ABOUT, NULL, NULL
                    444:     };
                    445:     HWND       hSM, hSSM;      /* Menu and submenu handles */
                    446:     MENUITEM   miSM;           /* System Menu Menuitem     */
                    447:     SHORT      idSM;           /* ID of the System Menu    */
                    448:     /*
                    449:        Get ahold of the system menu
                    450:     */
                    451:     hSM = WinWindowFromID(Parent(hWnd), FID_SYSMENU);
                    452:     idSM = (SHORT) WinSendMsg(hSM, MM_ITEMIDFROMPOSITION, NULL, NULL);
                    453:     WinSendMsg(hSM, MM_QUERYITEM, MPFROM2SHORT(idSM, FALSE), MPFROMP(&miSM));
                    454:     /*
                    455:        Manipulate the System SubMenu
                    456:     */
                    457:     hSSM = miSM.hwndSubMenu;
                    458:     WinSendMsg(hSSM, MM_INSERTITEM, MPFROMP(mi), MPFROMP(x[0]));
                    459:     WinSendMsg(hSSM, MM_INSERTITEM, MPFROMP(mi+1), MPFROMP(x[1]));
                    460: }
                    461: 
                    462: MRESULT CALLBACK NewFrameWndProc(HWND hWnd, USHORT msg, MPARAM mp1, MPARAM mp2) {
                    463: /*
                    464:     Force the frame to stay small enough
                    465: */
                    466:     BOOL rc;           /* Return code for WM_QueryTrackInfo */
                    467: 
                    468:     switch(msg) {
                    469:        case WM_ADJUSTWINDOWPOS:        /* Calculate, then show scrollbars */
                    470:            AvioAdjustFrame(mp1);
                    471:            break;
                    472:        case WM_QUERYTRACKINFO:
                    473:            rc = (BOOL) (*pfnOldFrameWndProc)(hWnd, msg, mp1, mp2);
                    474:             AvioQueryTrackInfo((PTRACKINFO) mp2);
                    475:            return rc;
                    476:        default: break;
                    477:     }
                    478:     return (*pfnOldFrameWndProc)(hWnd, msg, mp1, mp2);
                    479: }
                    480: 
                    481: BOOL Filter(USHORT fs, char ch, USHORT vkey) {
                    482:     BOOL rc = FALSE;
                    483: 
                    484:     if (fs & KC_VIRTUALKEY) {
                    485:        switch(vkey) {
                    486:            case VK_HOME:
                    487:                if (fs & KC_CTRL) rc = ThdPutString("\033[2J",4);
                    488:                return (rc || ThdPutString("\033[H", 3));
                    489:            case VK_UP:
                    490:                return ThdPutString("\033[A", 3);
                    491:            case VK_DOWN:
                    492:                return ThdPutString("\033[B", 3);
                    493:            case VK_RIGHT:
                    494:                return ThdPutString("\033[C", 3);
                    495:            case VK_LEFT:
                    496:                return ThdPutString("\033[D", 3);
                    497:            default: break;
                    498:        }
                    499:     }
                    500: 
                    501:     if (fs & KC_CTRL) {
                    502:        switch (ch) {
                    503:            case 'l':
                    504:            case 'L': AvioRedraw();
                    505:            case '\0': return FALSE; break;
                    506:            default: ch = Ctrl(ch); break;
                    507:        }
                    508:     } else {
                    509:        switch (ch) {
                    510:            case '\0': return FALSE; break;
                    511:            default: break;
                    512:        }
                    513:     }
                    514:     return(rc || ThdPutChar(ch));
                    515: }

unix.superglobalmegacorp.com

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