/* ----- DISVER PORTFOLIO ---------------------------------------------- * * BESCHREIBUNG: DISVER PORTFOLIO stellt ein universelles Hilfsmittel * zum Verwalten der Portfolio-RAM-Karten. * * BEMERKUNGEN: DISVER PORTFOLIO ist eine abgemagerte Version der * Programme DISVER AMIGA und DISVER PC, die auf den * jeweiligen Rechnern auch die Verwaltung der Disketten- * inhalte erleichtern. * * ŽNDERUNGEN: Version 1.0 90/08/07 schuschk * * INCLUDE-DATEIEN: */ #include #include #include #include #include #include #include #include #include #include #include #include #include "typedef.h" /* * DEFINES: */ /* ----- globale Defines -------------------------------------------- */ /*#define DEBUG*/ #define MAXFILES 500 #define MAXDIRS 200 #define MAXDIRSTACKS 50 #define FILES 0 #define DIR 1 #define DIRSTACK 2 /* ----- Defines fr den File-Requester ----------------------------- */ #define MO_LESEN 0 #define MO_SCHREIBEN 1 /* ----- Defines fr die Scroll-Routinen ---------------------------- */ #define HOME 0 #define PAGEUP -8 #define UP -1 #define DOWN 1 #define PAGEDOWN 8 #define END 999 /* * VARIABLEN: */ /* ----- Men-Definitionen ------------------------------------------ */ static CHAR *MainMenu[] = { "psedo", " Hauptmen ", "Projekt", "Sortieren", "Editieren", "Drucken", "Optionen"}; static CHAR *ProjectMenu[] = { "nlske", " Projekt ", "Neu", "Laden", "Speichern", "Karte einlesen", "šber", "Ende"}; static CHAR *SortMenu[] = { "nbk", " Sortieren ", "nach Namen", "nach Bytes", "nach Karte"}; static CHAR *EditMenu[] = { "huenl", " Editieren ", "Hauptprogramm", "Unterprogramm", "Editieren", "Neues File", "L”schen"}; static CHAR *OptionsMenu[] = { "abc", " Optionen ", "ûLesen von A:", " Lesen von B:", " Lesen von C:"}; /* ----- Variable fr die Statusmeldungen --------------------------- */ CHAR *PrintAllMsg = "Alle Daten werden gedruckt...", *DataLoadMsg = "Daten werden geladen...", *DataSaveMsg = "Daten werden gespeichert...", *SortMsg = "Sortiervorgang l„uft...", *DirReadMsg = "Directory wird eingelesen..."; CHAR *pcStatusWinPtr; /* ----- Variable fr die Fehlermeldungen --------------------------- */ CHAR *DirErr = "!! Directory existiert nicht !!", *NoPlaceErr = "!! Kein Platz fr mehr Eintr„ge !!", *NoFileErr = "!! Datei nicht vorhanden !!", *NotADisverFileErr = "!! Keine DISVER-Datei !!", *FileNotOpenErr = "!! Kann Datei nicht ”ffnen !!", *FileNotSavedErr = "!! Kann Daten nicht schreiben !!", *DriveNotReadyErr = "!! Keine Karte eingesteckt !!", *NoFileClickedErr = "!! Kein File markiert !!", *NoMemoryErr = "!! Kein Speicher mehr frei !!", *DiskNotReadableErr = "!! Karte kann nicht gelesen werden !!", *PrinterNotReadyErr = "!! Drucker nicht ansprechbar !!"; /* ----- globale Variable ------------------------------------------- */ /* Struktur der File-Liste */ struct FileEntries { CHAR acName[13]; /* Name */ LONG lBytes; /* L„nge in Bytes */ CHAR cSelect, /* Selektierung */ acDisk[11]; /* Karte, auf der sich das File befindet */ }; struct FileEntries *File[MAXFILES]; /* Struktur der Directory-Liste */ struct DirEntries { CHAR acName[28]; /* Name des Directory-Eintrages */ LONG lBytes; /* L„nge in Bytes */ CHAR cSelect; /* Markierungsflag */ }; struct DirEntries *Dir[200]; /* Struktur der Liste des Directory-Stapels */ struct DirStackEntries { CHAR acName[128]; /* Pfad der Directory */ INT iLevel; /* Grad der Verschachtelung */ }; struct DirStackEntries *DirStack[50]; BYTE bModify = 0, /* Žnderungen-Flag */ bEnde = 0, /* Ende-Flag im File-Fenster */ bEnde1, bEnde2; /* Ende-Flags im Disk-Fenster */ CHAR acDiskName[13], /* Name der eingelesenen Karte */ acDrive[4] = "A:\\", /* Laufwerk, dessen Directory gelesen wird */ acDirName[31]; /* Name des einzulesenden Verzeichnisses */ INT iFilesTop = -1, /* obere Grenze der allok. File-Eintr„ge */ iDirTop = -1, /* obere Grenze der all. Directory-Eintr. */ iDirStackTop = -1, /* obere Grenze der all. Dir.stapel-Eintr. */ iDirPtr = 0, /* Erster angezeigter Dir-Eintrag */ iDirStackAnz = 0, /* Anzahl Directories im Stapel */ iDirStackPtr = 0, /* Zeiger auf einzulesende Directory */ iDirAnz = -0, /* Anzahl eingelesener Directory-Eintr„ge */ iLevel = 0, /* aktuelle Verschachtelungsebene */ iFileAnz = -1, /* Anzahl gespeicherter Files */ iFilePtr, /* Nummer des ersten angezeigten Files */ iHauptPrgPtr = -1, /* Nummer der markierten HauptProgrammes */ iDirCursorPos = 0, /* Cursor-Position im Dir-Fenster */ iFileCursorPos = 0; /* Cursor-Position im File-Fenster */ LONG lHauptPrgBytes; /* Bytesumme des Hauptprogrammes */ union REGS Regs; /* Registersatz */ /* ---------------------------------------------------------------------- */ /* ----- Fensterhintergrund retten ---------------------------------- */ CHAR *StoreWindow(iLeft, iTop, iWidth, iLength) INT iLeft, iTop, /* XY-Koordinaten der oberen linken Ecke */ iWidth, iLength; /* Breite und H”he des Fensters */ { CHAR *pcPtr, *pcBufPtr; /* Zeiger auf den Fensterpuffer */ CHAR far *pcScrPtr; /* Zeiger in Bildschirmspeicher */ INT i, j, /* Z„hler */ iSize; /* Gr”áe des Puffers */ pcPtr = NULL; /* Gr”áe des Bereiches berechnen, dabei 4 Bytes fr Koordinaten */ iSize = 4 + (2 * iLength * iWidth); /* Puffer belegen und Zeiger retten */ pcPtr = malloc(iSize); pcBufPtr = pcPtr; /* Koordinaten in den Puffer bringen */ *pcBufPtr++ = (CHAR)iLeft; *pcBufPtr++ = (CHAR)iTop; *pcBufPtr++ = (CHAR)iWidth; *pcBufPtr++ = (CHAR)iLength; /* Fensterinhalt sichern */ for(i = 0; i < iLength; i++){ pcScrPtr = MK_FP(0xB000, ((iTop + i) * 160) + (iLeft * 2)); for(j = 0; j < (2 * iWidth); j++) *pcBufPtr++ = *pcScrPtr++; } return(pcPtr); } /* ----- Fenster schlieáen ------------------------------------------ */ void CloseWindow(pcPtr) CHAR *pcPtr; /* Zeiger auf Fensterpuffer */ { CHAR *pcBufPtr, /* Zeiger in Fensterpuffer */ cLeft, cTop, /* linke obere Ecke des Fensters */ cWidth, cLength, /* Breite und L„nge des Fensters */ i, j; /* Z„hler */ CHAR far *pcScrPtr; /* Zeiger in Bildschirmspeicher */ /* Pufferzeiger retten */ pcBufPtr = pcPtr; /* Koordinaten in den Puffer bringen */ cLeft = *pcBufPtr++; cTop = *pcBufPtr++; cWidth = *pcBufPtr++; cLength = *pcBufPtr++; /* Fensterinhalt zurckschreiben */ for(i = 0; i < cLength; i++){ pcScrPtr = MK_FP(0xB000, ((cTop + i) * 160) + (cLeft * 2)); for(j = 0; j < (2 * cWidth); j++) *pcScrPtr++ = *pcBufPtr++; } /* Pufferspeicher wieder freigeben */ free(pcPtr); /* Bildschirm refreshen */ #ifndef DEBUG Regs.x.ax = 0x1200; int86(97, &Regs, &Regs); #endif return; } /* ----- Rechteckigen Bildschirmbereich l”schen --------------------- */ void ClearArea(iLeft, iTop, iWidth, iLength) INT iLeft, iTop, /* linke obere Ecke des Bereiches */ iWidth, iLength; /* Breite und L„nge (H”he) */ { INT far *piPtr; /* Zeiger in Bildschirmspeicher */ INT i, j; /* Z„hler */ /* Bereich l”schen */ for(i = 0; i < iLength; i++){ piPtr = (INT far *)MK_FP(0xB000, ((iTop + i) * 160) + (iLeft * 2)); for(j = 0; j < iWidth; j++) *piPtr++ = 0x0720; } /* Bildschirm refreshen */ #ifndef DEBUG Regs.x.ax = 0x1200; int86(97, &Regs, &Regs); #endif return; } /* ----- Doppelten Rahmen zeichnen ------------------- */ void DrawBorder(iLeft, iTop, iWidth, iLength) INT iLeft, iTop, /* linke obere Ecke des Rahmens */ iWidth, iLength; /* Breite und H”he des Rahmens */ { INT far *piPtr; /* Zeiger in Bildschirmspeicher */ INT i; /* Z„hler */ piPtr = (INT far *)MK_FP(0xB000, (iTop * 160) + (iLeft * 2)); *piPtr++ = 0x07c9; for(i = 0; i <= (iWidth-3); i++) *piPtr++ = 0x07cd; *piPtr = 0x07bb; piPtr += 80; for(i = 0; i <= (iLength-3); i++, piPtr += 80) *piPtr = 0x07ba; *piPtr-- = 0x07bc; for(i = 0; i <= (iWidth-3); i++) *piPtr-- = 0x07cd; *piPtr = 0x07c8; piPtr -= 80; for(i = 0; i <= (iLength-3); i++, piPtr -= 80) *piPtr = 0x07ba; /* Bildschirm refreshen */ #ifndef DEBUG Regs.x.ax = 0x1200; int86(97, &Regs, &Regs); #endif return; } /* ----- Fenster ”ffnen --------------------------------------------- */ CHAR *OpenWindow(iLeft, iTop, iWidth, iLength) INT iLeft, iTop, /* linke obere Ecke des Fensters */ iWidth, iLength; /* Breite und H”he des Fensters */ { CHAR *pcPtr; /* Hintergrund retten */ pcPtr = StoreWindow(iLeft, iTop, iWidth, iLength); if(pcPtr != NULL){ /* Hintergrund l”schen */ ClearArea(iLeft, iTop, iWidth, iLength); /* Rahmen zeichnen */ DrawBorder(iLeft, iTop, iWidth, iLength); } return(pcPtr); } /* ----- Taste holen und ASCII- sowie ------------------------------- ----- erweiterten Tastaturcode zurckgeben ----------------------- */ void GetKey(pcKey, pcKeyExt) CHAR *pcKey, /* ASCII-Code */ *pcKeyExt; /* erweiterter Tastaturcode */ { Regs.h.ah = 0x0; int86(0x16, &Regs, &Regs); *pcKey = Regs.h.al; *pcKeyExt = Regs.h.ah; return; } /* ----- Eingabe-Routine -------------------------------------------- */ INT Input(iXPos, iYPos, iWidth, pcString) INT iXPos, iYPos, /* Koordinaten der linken Ecke des Eingabefeldes */ iWidth; /* Breite des Eingabefeldes */ CHAR *pcString; /* Zeiger auf den Eingabestring (Vorgabe m”glich) */ { BYTE bEnde; /* Ende-Flag */ INT iEscape, /* Abbruch-Flag */ iRelCursor, /* Cursor-Position im String */ iLength; /* aktuelle L„nge der Eingabe */ CHAR *pcText, /* Eingabepuffer */ *pcPreset, /* Vorgabepuffer */ cKey, cKeyExt; /* ASCII- und erweiterter Tastencode */ /* Pufferspeicher fr die Vorgabe und die Eingabe reservieren */ pcText = malloc(iWidth + 2); pcPreset = malloc(iWidth + 2); /* Vorgabe retten */ strcpy(pcPreset, pcString); /* Cursor auf Koordinaten setzen */ iRelCursor = 1; gotoxy(iXPos + iRelCursor - 1, iYPos); /* Vorgabe in Eingabepuffer kopieren */ strcpy(pcText, pcString); strcat(pcText, " "); /* Platz freimachen */ printf("%*s", iWidth + 1, " "); /* Eingabeschleife */ bEnde = 0; iEscape = 0; do{ iLength = strlen(pcText); /* aktuellen Stand ausgeben */ gotoxy(iXPos, iYPos); printf("%-*s", iWidth, pcText); gotoxy(iXPos + iRelCursor - 1, iYPos); /* Taste holen */ GetKey(&cKey, &cKeyExt); /* Auswerten */ if(cKey == 0){ /* Sondertaste gedrckt */ switch(cKeyExt){ /* Cursor links */ case 75: if(iRelCursor > 1) iRelCursor--; break; /* Cursor rechts */ case 77: if(iRelCursor < iLength) iRelCursor++; break; /* Home oder Pos1 */ case 71: iRelCursor = 1; break; /* Ende */ case 79: iRelCursor = iLength; break; /* Delete oder Entf */ case 83: if(iLength > 1){ memcpy(pcText + iRelCursor - 1, pcText + iRelCursor, iLength - iRelCursor + 1); } break; default: break; } } else{ /* ASCII-Taste gedrckt */ switch(cKey){ /* Escape */ case 27: strcpy(pcText, pcPreset); bEnde = 1; iEscape = 1; break; /* Backspace */ case 8: if((iLength > 1)&&(iRelCursor > 1)){ memcpy(pcText + iRelCursor - 2, pcText + iRelCursor - 1, iLength - iRelCursor + 2); iRelCursor--; } break; /* Return */ case 13: *(pcText + strlen(pcText) - 1) = 0; bEnde = 1; break; /* normales Textzeichen */ default: if ((cKey > 31) && (iLength <= iWidth)){ memmove(pcText + iRelCursor, pcText + iRelCursor - 1, iLength - iRelCursor + 2); *(pcText + iRelCursor - 1) = cKey; iRelCursor++; } break; } } }while(bEnde == 0); /* Ergebnis anzeigen */ gotoxy(iXPos, iYPos); printf("%-*s", iWidth, pcText); /* Eingabepuffer kopieren */ strcpy(pcString, pcText); /* Speicher wieder freigeben */ free(pcPreset); free(pcText); return(iEscape); } /* ----- Fehlermeldung ausgeben ------------------------------------- */ void Error(iErrNum) INT iErrNum; /* Fehlernummer */ { CHAR *pcErrMsg, /* Zeiger auf die Fehlermeldung */ *pcWinPtr; /* Zeiger auf Fensterpuffer */ INT iLeft, iTop, /* Dimensionen des zu ”ffnenden Fensters */ iWidth, iLength; /* Fehlermeldung holen */ switch(iErrNum){ case 2: pcErrMsg = DirErr; break; case 3: pcErrMsg = NoPlaceErr; break; case 4: pcErrMsg = NoFileErr; break; case 5: pcErrMsg = NoPlaceErr; break; case 6: pcErrMsg = NotADisverFileErr; break; case 7: pcErrMsg = FileNotOpenErr; break; case 8: pcErrMsg = FileNotSavedErr; break; case 9: pcErrMsg = PrinterNotReadyErr; break; case 11: pcErrMsg = DriveNotReadyErr; break; case 14: pcErrMsg = NoFileClickedErr; break; case 15: pcErrMsg = NoMemoryErr; break; case 16: pcErrMsg = DiskNotReadableErr; break; default: pcErrMsg = NULL; break; } if(pcErrMsg == NULL) return; /* Breite und H”he des Fensters festlegen */ iWidth = strlen(pcErrMsg) + 4; iLength = 3; /* Spalte und Zeile der oberen linken Ecke bestimmen */ iLeft = (40 - iWidth) / 2; iTop = (8 - iLength) / 2; /* Fenster aufmachen */ pcWinPtr = OpenWindow(iLeft, iTop, iWidth, iLength); if(pcWinPtr == NULL) return; /* Fehlermeldung ausgeben */ gotoxy(iLeft + 3, iTop + 2); printf("%s", pcErrMsg); /* Taste holen und Fenster schlieáen */ while(!kbhit()); getchar(); CloseWindow(pcWinPtr); return; } /* ----- Statusmeldung ausgeben ------------------------------------- */ void Status(iStatus) INT iStatus; /* Nummer der Statusmeldung */ { CHAR *pcStatusMsg; /* Zeiger auf die Statusmeldung */ INT iLeft, iTop, /* Dimensionen des zu ”ffnenden Fensters */ iWidth, iLength; /* evtl. Statusmeldung entfernen */ if((iStatus == 0) && (pcStatusWinPtr != NULL)) CloseWindow(pcStatusWinPtr); /* Statusmeldung zuweisen */ switch(iStatus){ case 200: pcStatusMsg = PrintAllMsg; break; case 203: pcStatusMsg = DataLoadMsg; break; case 204: pcStatusMsg = DataSaveMsg; break; case 205: pcStatusMsg = SortMsg; break; case 206: pcStatusMsg = DirReadMsg; break; default: pcStatusMsg = NULL; break; } if(pcStatusMsg == NULL) return; /* Breite und H”he des Fensters festlegen */ iWidth = strlen(pcStatusMsg) + 4; iLength = 3; /* Spalte und Zeile der oberen linken Ecke bestimmen */ iLeft = (40 - iWidth) / 2; iTop = (8 - iLength) / 2; /* Fenster aufmachen */ pcStatusWinPtr = OpenWindow(iLeft, iTop, iWidth, iLength); if(pcStatusWinPtr == NULL) return; /* Fehlermeldung ausgeben */ gotoxy(iLeft + 3, iTop + 2); printf("%s", pcStatusMsg); return; } /* ----- Speicherverwaltungsroutine --------------------------------- */ INT AllocEntry(iPtr, iChoice) INT iPtr, /* Position fr die Speicher angefordert wird */ iChoice; /* Array, fr das der Speicher sein soll */ { switch(iChoice){ case FILES: if (iPtr > iFilesTop && iPtr <= MAXFILES){ /* Speicher anfordern */ File[iPtr] = (struct FileEntries *)calloc(1, sizeof(struct FileEntries)); /* kein Speicher mehr frei ? */ if (File[iPtr] == NULL){ Error(5); return(1); } /* obere Grenze erh”hen */ iFilesTop++; } return(0); case DIR: if (iPtr > iDirTop && iPtr <= MAXDIRS){ /* Speicher anfordern */ Dir[iPtr] = (struct DirEntries *)calloc(1, sizeof(struct DirEntries)); /* kein Speicher mehr frei ? */ if (Dir[iPtr] == NULL){ Error(5); return(1); } /* obere Grenze erh”hen */ iDirTop++; } return(0); case DIRSTACK: if (iPtr > iDirStackTop && iPtr <= MAXDIRSTACKS){ /* Speicher anfordern */ DirStack[iPtr] = (struct DirStackEntries *)calloc(1, sizeof(struct DirStackEntries)); /* kein Speicher mehr frei ? */ if (DirStack[iPtr] == NULL){ Error(5); return(1); } /* obere Grenze erh”hen */ iDirStackTop++; } return(0); default: return(1); } } /* ----- Directory-Bildschirm aufbauen ------------------------------ */ void SetupDiskScreen() { clrscr(); printf(" ³(H)auptprg.\n"); printf(" ³(U)nterprg.\n"); printf(" ³(š)bernehmen\n"); printf(" ³(E)ditieren\n"); printf(" ³(A)lle\n"); printf(" ³(S)torno\n"); printf(" ³(N)„chste\n"); printf(" ³(B)eenden"); return; } /* ----- Sortieren der Directory-Eintr„ge im Bereich ---------------- */ /* ----- von iAnfang bis iEnde -------------------------------------- */ void DirSort(iAnfang, iEnde) INT iAnfang, iEnde; { INT i, j; /* Z„hler */ struct DirEntries *SwapPtr; /* scratch pointer */ for (i = iAnfang; i <= iEnde - 1; i++){ for (j = i + 1; j <= iEnde; j++){ if (strcmp(Dir[i]->acName, Dir[j]->acName) > 0){ /* Zeiger auf die Strukturen vertauschen */ SwapPtr = Dir[i]; Dir[i] = Dir[j]; Dir[j] = SwapPtr; } } } return; } /* ----- Directory "pcVerzeichnis" einlesen, ab Position ------------ */ /* ----- "iCounter" in die Liste der Directory-Eintr„ge ------------- */ /* ----- bringen und Endwert zurckgeben ---------------------------- */ INT LeseDir(pcVerzeichnis, iCounter) CHAR *pcVerzeichnis; INT iCounter; { struct ffblk Eintrag; /* Dateiinfo-Struktur */ INT iSuccess; /* Funktionsergebnis */ /* Namen des aktuellen und bergeordneten Verzeichnisses ermitteln */ strcpy(acDirName, pcVerzeichnis); /* Abschlieáenden Backslash entfernen */ *(acDirName + strlen(acDirName) - 1) = 0; /* Speicherplatz reservieren */ if (AllocEntry(iCounter, DIR) == 1) return(iCounter); /* Namen des aktuellen Verzeichnisses isolieren */ if (iLevel > 1) sprintf(Dir[iCounter]->acName, "Dir: %-s", strrchr(acDirName,'\\')); else sprintf(Dir[iCounter]->acName, "Dir: %-s", acDirName); /* Directory einlesen */ Dir[iCounter]->lBytes = 0; strcat(acDirName, "\\*.*"); iSuccess = findfirst(acDirName, &Eintrag, 0x37); while(iSuccess == 0){ /* Alle Eintr„ge bis auf "." und ".." einlesen */ if ((strcmp(Eintrag.ff_name, ".")) && (strcmp(Eintrag.ff_name, ".."))){ iCounter++; /* Speicherplatz reservieren */ if (AllocEntry(iCounter, DIR) == 1){ iSuccess = -1; iCounter--; break; } sprintf(Dir[iCounter]->acName, "- %-s", Eintrag.ff_name); if (Eintrag.ff_attrib & 0x10) /* Eintrag ist ein Unterdirectory */ Dir[iCounter]->lBytes = -1; else /* Eintrag ist ein File */ Dir[iCounter]->lBytes = Eintrag.ff_fsize; } iSuccess = findnext(&Eintrag); } return(iCounter); } /* ----- Kopf fr eine neue Verschachtelungsebene ------------------- */ void LevelKopf() { if (AllocEntry(iDirAnz, DIR) == 1) return; strcpy(Dir[iDirAnz]->acName, "--------------------------"); Dir[iDirAnz]->lBytes = -3; iDirAnz++; if (AllocEntry(iDirAnz, DIR) == 1) return; sprintf(Dir[iDirAnz]->acName, "Level: %1d", iLevel); Dir[iDirAnz]->lBytes = -2; iDirAnz++; if (AllocEntry(iDirAnz, DIR) == 1) return; strcpy(Dir[iDirAnz]->acName, " "); Dir[iDirAnz]->lBytes = -4; iDirAnz++; return; } /* ----- Kompletten Directory-Baum des Laufwerkes einlesen ---------- */ /* ----- und die Anzahl der Eintr„ge zurckgeben -------------------- */ INT DiskIn() { INT iAnz, /* gelesene Eintr„ge eines Unterverzeichnisses */ iDummy, /* Funktionsergebnis */ i; /* Z„hler */ BYTE bDrv; /* Nummer des Laufwerkes (0=A:, 1=B:, ...) */ CHAR acBuffer[512], /* Lesepuffer */ *pcPtr; /* scratch pointer */ struct ffblk Eintrag; /* Dateiinfoblock */ /* Laufwerksnummer setzen */ bDrv = acDrive[0] - 65; /* Testen, ob Laufwerk bereit */ iDummy = absread(bDrv, 1, 1, acBuffer); if (iDummy == -1){ Error(11); return(iDirAnz - 1); } Status(206); /* Diskettennamen lesen */ strcpy(acBuffer, acDrive); iDummy = findfirst(acBuffer, &Eintrag, FA_LABEL); if (iDummy == 0){ strcpy(acDiskName, Eintrag.ff_name); /* evtl. Punkt aus dem Namen entfernen */ pcPtr = strchr(acDiskName, 46); if (pcPtr != NULL){ while(*pcPtr != '\0'){ *pcPtr = *(pcPtr + 1); pcPtr++; } } } else strcpy(acDiskName, ""); LevelKopf(); /* Speicherplatz reservieren */ if (AllocEntry(0, DIRSTACK) == 1) return(iDirAnz - 1); strcpy(DirStack[0]->acName, acDrive); /* Directory-Baum einlesen */ while (iDirStackPtr <= iDirStackAnz){ if (DirStack[iDirStackPtr]->iLevel < 10){ if (DirStack[iDirStackPtr]->iLevel > iLevel){ iLevel++; LevelKopf(); } /* Directory einlesen und sortieren */ iAnz = LeseDir(DirStack[iDirStackPtr]->acName, iDirAnz); DirSort(iDirAnz + 1, iAnz); if (iAnz > 0){ /* Diskettennamen in DirStack schreiben */ if (iDirStackPtr == 0){ strcpy(DirStack[0]->acName, acDrive); DirStack[0]->iLevel = 0; } /* Nach Unterdirectories suchen */ for (i = iDirAnz + 1; i <= iAnz; i++){ if (Dir[i]->lBytes == -1){ iDirStackAnz++; if (AllocEntry(iDirStackAnz, DIRSTACK) == 1){ iDirStackAnz--; break; } strcpy(DirStack[iDirStackAnz]->acName, DirStack[iDirStackPtr]->acName); strcat(DirStack[iDirStackAnz]->acName, (Dir[i]->acName) + 2); strcat(DirStack[iDirStackAnz]->acName, "\\"); DirStack[iDirStackAnz]->iLevel = iLevel + 1; } } /* Leerzeile einfgen */ if (AllocEntry(iAnz + 1, DIR) == 1) break; strcpy(Dir[iAnz + 1]->acName, ""); Dir[iAnz + 1]->lBytes = -4; iDirAnz = iAnz + 2; } else Error(2); } iDirStackPtr++; } Status(0); return(iDirAnz - 1); } /* ----- Einen Eintrag aus der Directory-Liste in der --------------- */ /* ----- angegebenen Zeile ausgeben --------------------------------- */ void ShowOneDirEntry(iNumber, iRow) INT iNumber, /* lfd. Nummer des Eintrages */ iRow; /* Zeile, in der ausgegeben wird */ { CHAR cMarker, /* Markierung */ acDirEntry[27]; /* Ausgabepuffer */ if (iNumber >= iDirAnz){ sprintf(acDirEntry, "%26s", " "); return; } switch(Dir[iNumber]->lBytes){ /* Eintrag ist eine Leerzeile */ case -4: sprintf(acDirEntry, "%-26s", " "); break; /* Eintrag ist ein Trennstrich */ case -3: sprintf(acDirEntry, "--------------------------"); break; /* Eintrag ist eine Level-šberschrift */ case -2: sprintf(acDirEntry, "%-26s", Dir[iNumber]->acName); break; /* Eintrag ist ein Unterdirectory */ case -1: sprintf(acDirEntry, "%-14.14s (DIR) ", Dir[iNumber]->acName); break; /* Eintrag ist eine Directory-šberschrift */ case 0: sprintf(acDirEntry, "%-26s", Dir[iNumber]->acName); break; /* Eintrag ist ein File */ default: switch(Dir[iNumber]->cSelect){ case 1: cMarker = 16; break; case 2: cMarker = 175; break; default: cMarker = '-'; break; } sprintf(acDirEntry, "%-14.14s %6ld ", Dir[iNumber]->acName, Dir[iNumber]->lBytes); *acDirEntry = cMarker; break; } gotoxy(1, iRow); printf("%s", acDirEntry); return; } /* ----- Elemente der Directory-Liste ab Position "iDirPtr" ------- */ /* ----- auf dem Bildschirm ausgeben -------------------------------- */ void ShowEntries() { INT i; /* Z„hler */ if (iDirPtr + 8 > iDirAnz) iDirPtr = iDirAnz - 7; if (iDirPtr < 0) iDirPtr = 0; /* Eintr„ge ausgeben */ for (i = 0; i < 8; i++){ ShowOneDirEntry(iDirPtr + i, i + 1); } return; } /* ----- Eintr„ge der Directory-Liste ------------------------------- */ /* ----- entsprechend dem Argument scrollen ------------------------- */ void DirScroll(iNum) INT iNum; /* Anzahl Zeilen, um die gerollt wird */ { INT i; /* Z„hler */ switch (iNum){ case HOME: iDirPtr = 0; ShowEntries(); break; case END: iDirPtr = iDirAnz - 7; ShowEntries(); break; case DOWN: if (iDirPtr < iDirAnz - 8){ iDirPtr++; Regs.x.ax = 0x0601; Regs.x.cx = 0; Regs.x.dx = 0x0719; Regs.h.bh = 0; int86(0x10, &Regs, &Regs); ShowOneDirEntry(iDirPtr + 7, 8); } break; case UP: if (iDirPtr > 0){ iDirPtr--; Regs.x.ax = 0x0701; Regs.x.cx = 0; Regs.x.dx = 0x0719; Regs.h.bh = 0; int86(0x10, &Regs, &Regs); ShowOneDirEntry(iDirPtr, 1); } break; case PAGEUP: for (i = 0; i < 8; i++){ if (iDirPtr > 0){ iDirPtr--; Regs.x.ax = 0x0701; Regs.x.cx = 0; Regs.x.dx = 0x0719; Regs.h.bh = 0; int86(0x10, &Regs, &Regs); ShowOneDirEntry(iDirPtr, 1); } } break; case PAGEDOWN: for (i = 0; i < 8; i++){ if (iDirPtr < iDirAnz - 8){ iDirPtr++; Regs.x.ax = 0x0601; Regs.x.cx = 0; Regs.x.dx = 0x0719; Regs.h.bh = 0; int86(0x10, &Regs, &Regs); ShowOneDirEntry(iDirPtr + 7, 8); } } break; default: iDirPtr += iNum; ShowEntries(); break; } return; } /* ----- Alle Selektierungen rckg„ngig machen ---------------------- */ void DirHighlightClear() { INT i; /* Z„hler */ for (i = 0; i <= iDirAnz; i++) Dir[i]->cSelect = 0; return; } /* ----- Diskettennamen anzeigen und evtl. editieren lassen --------- */ void TestDiskName() { CHAR *pcWinPtr; /* Zeiger auf Fensterpuffer */ /* Requester ”ffnen und neuen Kartennamen abfragen */ pcWinPtr = OpenWindow(9, 2, 22, 4); gotoxy(11, 4); printf("Kartennamen eingeben"); gotoxy(13, 5); printf("Name:"); Input(19, 5, 10, acDiskName); CloseWindow(pcWinPtr); ShowEntries(); return; } /* ----- Markierten Eintrag zum Hauptprogramm machen ---------------- */ void MainProgram() { INT i; /* Z„hler */ /* evtl. vorherige Hauptprogrammmarkierungen l”schen */ for (i = 0; i <= iDirAnz; i++) if (Dir[i]->cSelect == 2) Dir[i]->cSelect = 0; /* erstes markierten Eintrag suchen */ for (i = 0; (Dir[i]->cSelect == 0) && (i <= iDirAnz); i++); /* Eintrag markieren und Hauptprogrammpointer bergeben */ iHauptPrgPtr = i; Dir[i]->cSelect = 2; /* Byteanzahl fr sp„tere Addition merken */ lHauptPrgBytes = Dir[i]->lBytes; /* Markierung anzeigen */ ShowEntries(); return; } /* ----- Bytes aller markierten Eintr„ge zum Hauptprogramm addieren - */ void SubProgram() { INT i, j; /* Z„hler */ j = -1; if (iHauptPrgPtr != -1){ for (i = 0; i <= iDirAnz; i++){ if (Dir[i]->cSelect == 1){ lHauptPrgBytes += Dir[i]->lBytes; Dir[iHauptPrgPtr]->lBytes = lHauptPrgBytes; bModify = 1; } else{ j++; if (i == iHauptPrgPtr) iHauptPrgPtr = j; strcpy(Dir[j]->acName, Dir[i]->acName); Dir[j]->lBytes = Dir[i]->lBytes; Dir[j]->cSelect = 0; } } for (i = j + 1; i <= iDirAnz; i++) Dir[i]->cSelect = 0; iDirAnz = j; Dir[iHauptPrgPtr]->cSelect = 1; if (iDirAnz < 19) iDirPtr = 0; else iDirPtr = iHauptPrgPtr - 4; iHauptPrgPtr = -1; ShowEntries(); } return; } /* ----- Alle markierten Eintr„ge in die Liste ---------------------- */ /* ----- der Files bernehmen --------------------------------------- */ void AddEntry() { INT i, j; /* Z„hler */ if (iHauptPrgPtr < 1){ /* alle markierten Eintr„ge bernehmen */ j = 2; for (i = 3; i <= iDirAnz; i++){ if (Dir[i]->cSelect > 0){ if (iFileAnz < MAXFILES){ /* Speicherplatz reservieren */ iFileAnz++; if (AllocEntry(iFileAnz, FILES) == 1){ iFileAnz--; break; } /* Inhalte bertragen, beim Namen "- " weglassen */ strcpy(File[iFileAnz]->acName, (CHAR *)(Dir[i]->acName) + 2); File[iFileAnz]->lBytes = Dir[i]->lBytes; strcpy(File[iFileAnz]->acDisk, acDiskName); File[iFileAnz]->cSelect = 0; bModify = 1; } else Error(3); } else{ j++; strcpy(Dir[j]->acName, Dir[i]->acName); Dir[j]->lBytes = Dir[i]->lBytes; Dir[j]->cSelect = Dir[i]->cSelect; } } iDirAnz = j; } if (iDirAnz < 8) iDirPtr = 0; else if (iDirPtr + 7 > iDirAnz) iDirPtr = iDirAnz - 8; ShowEntries(); return; } /* ----- Initialisierung der Variablen ------------------------------ */ void InitDirVars() { iDirStackPtr = iLevel = iDirPtr = iDirCursorPos = 0; iDirAnz = iDirStackAnz = 0; bEnde1 = bEnde2 = 0; iHauptPrgPtr = -1; return; } /* ----- Markierung mit der Space-Taste entsprechend ---------------- */ /* ----- der Position auswerten ------------------------------------- */ void ClickOnEntries(iNumber) INT iNumber; /* Nummer des markierten Eintrages */ { INT j; /* Z„hler */ if (iNumber != iHauptPrgPtr){ if (Dir[iNumber]->lBytes > 0){ /* Eintrag ist ein File -> Markierung umschalten */ if (Dir[iNumber]->cSelect == 1) Dir[iNumber]->cSelect = 0; else if (Dir[iNumber]->cSelect == 0) Dir[iNumber]->cSelect = 1; } else{ /* Eintrag ist Directory-šberschrift -> Markierungen aller Eintr„ge innerhalb des Directories umschalten */ if (Dir[iNumber]->lBytes == 0){ for (j = iNumber + 1; Dir[j]->lBytes > -2; j++){ if ((Dir[j]->cSelect == 0) && (Dir[j]->lBytes > 0)) Dir[j]->cSelect = 1; else if (Dir[j]->cSelect == 1) Dir[j]->cSelect = 0; } } } } ShowEntries(); return; } /* ----- Tastendruck auswerten -------------------------------------- */ void ActionOnDiskKey(cKey, cKeyExt) CHAR cKey, /* ASCII-Code der Taste */ cKeyExt; /* erweiterter Tastaturcode */ { CHAR *pcWinPtr; /* Zeiger auf Fensterpuffer */ INT i; /* Z„hler */ if(cKey != 0){ switch(cKey){ /* Leertaste - Markieren */ case 32: ClickOnEntries(iDirPtr + iDirCursorPos); break; /* H - Markierten Eintrag zum Hauptprogramm machen */ case 'h': case 'H': MainProgram(); break; /* U - Markierte Eintr„ge zum Hauptprogramm addieren */ case 'u': case 'U': SubProgram(); break; /* š - Markierte Eintr„ge in die Liste der Files bernehmen */ case '': case 'š': case '+': AddEntry(); break; /* E - Namen der markierten Eintr„ge editieren */ case 'e': case 'E': pcWinPtr = OpenWindow(9, 2, 22, 4); gotoxy(11, 4); printf("Neuen Namen eingeben"); gotoxy(11, 5); printf("Name:"); for (i = 4; i <= iDirAnz; i++){ if (Dir[i]->cSelect == 1){ Input(17, 5, 12, (Dir[i]->acName) + 2); Dir[i]->cSelect = 0; } } CloseWindow(pcWinPtr); ShowEntries(); break; /* A - Alle Eintr„ge markieren */ case 'a': case 'A': for (i = 2; i <= iDirAnz; i++) if ((Dir[i]->lBytes > 0) && (i != iHauptPrgPtr)) Dir[i]->cSelect = 1; ShowEntries(); break; /* S - Alle Markierungen rckg„ngig machen */ case 's': case 'S': for (i = 0; i <= iDirAnz; i++) Dir[i]->cSelect = 0; iHauptPrgPtr = -1; lHauptPrgBytes = 0; ShowEntries(); break; /* B - Bearbeitung beenden */ case 'b': case 'B': bEnde1 = 1; /* N - N„chste Magnetkarte einlesen */ case 'n': case 'N': bEnde2 = 1; iHauptPrgPtr = -1; DirHighlightClear(); break; default: break; } } else{ switch(cKeyExt){ /* Cursor nach oben */ case 72: if(iDirCursorPos == 0) DirScroll(UP); else iDirCursorPos--; break; /* Cursor nach unten */ case 80: if(iDirCursorPos == 7) DirScroll(DOWN); else if (iDirPtr + iDirCursorPos < iDirAnz) iDirCursorPos++; break; /* Bild nach oben (PageUp) */ case 73: DirScroll(PAGEUP); break; /* Bild nach unten (PageDn) */ case 81: DirScroll(PAGEDOWN); break; /* Pos1 (Home) */ case 71: DirScroll(HOME); break; /* Ende (End) */ case 79: DirScroll(END); break; default: break; } } return; } /* ----- Magnetkarte einlesen --------------------------------------- */ void DisketteEinlesen() { CHAR cKey, cKeyExt; /* Tastenpuffer */ /* Bildschirm aufbauen */ SetupDiskScreen(); /* Eingabeschleife */ while (bEnde1 == 0){ InitDirVars(); /* Directory des gew„hlten Laufwerkes einlesen */ iDirAnz = DiskIn(); /* Diskettennamen zur Žnderung anzeigen */ if (iDirAnz > 0) TestDiskName(); iDirPtr = 0; ShowEntries(); while (bEnde2 == 0){ /* Cursor positionieren */ gotoxy(1, iDirCursorPos + 1); /* Hat der User sich gerhrt ? */ GetKey(&cKey, &cKeyExt); ActionOnDiskKey(cKey, cKeyExt); } } bEnde1 = 0; return; } /* ----- File-Bildschirm aufbauen ----------------------------------- */ void SetupFileScreen() { clrscr(); printf(" ³ DISVER\n"); printf(" ³ \n"); printf(" ³ Files:\n"); printf(" ³ \n"); printf(" ³ Bytes:\n"); printf(" ³ \n"); printf(" ³ \n"); printf(" ³F1-Men"); gotoxy(0, 0); return; } /* ----- Bytes summieren -------------------------------------------- */ LONG do_sum() { INT i; /* Z„hler */ LONG lSumBytes; /* Summe der Bytes */ lSumBytes = 0; for(i = 0; i <= iFileAnz; i++) lSumBytes += File[i]->lBytes; return(lSumBytes); } /* ----- Alle Selektierungen aufheben ------------------------------- */ void HighLightClear() { INT i; for(i = 0; i <= iFileAnz; i++) File[i]->cSelect = 0; return; } /* ----- Einen Eintrag aus der Liste der Files in der --------------- */ /* ----- angegebenen Zeile ausgeben --------------------------------- */ void ShowOneFileEntry(iNumber, iRow) INT iNumber, /* lfd. Nummer des Eintrages */ iRow; /* Zeile, in der ausgegeben wird */ { CHAR cMarker; /* Markierung */ gotoxy(1, iRow); if (iNumber > iFileAnz){ printf("%31s", " "); return; } switch(File[iNumber]->cSelect){ /* Normale Markierung */ case 1: cMarker = 16; break; /* als Hauptprogramm markiert */ case 2: cMarker = 175; break; /* nicht markiert */ default: cMarker = 32; break; } printf("%c%-12s %6ld %-10s", cMarker, File[iNumber]->acName, File[iNumber]->lBytes, File[iNumber]->acDisk); return; } /* ----- Files ab Position 'iFilePtr' anzeigen ---------------------- */ void ShowFiles() { INT i; /* Z„hler */ if (iFilePtr + 8 > iFileAnz) iFilePtr = iFileAnz - 7; if (iFilePtr < 0) iFilePtr = 0; for (i = 0; i < 8; i++) ShowOneFileEntry(iFilePtr + i, i + 1); return; } /* ----- Liste der Files entsprechend dem Argument scrollen --------- */ void FileScroll(iNum) INT iNum; /* Zeilenanzahl, um die gescrollt wird */ { INT i; switch(iNum){ case END: iFilePtr = iFileAnz - 7; ShowFiles(); break; case HOME: iFilePtr = 0; ShowFiles(); break; case DOWN: if (iFilePtr < iFileAnz - 8){ iFilePtr++; Regs.x.ax = 0x0601; Regs.x.cx = 0; Regs.x.dx = 0x071e; Regs.h.bh = 0; int86(0x10, &Regs, &Regs); ShowOneFileEntry(iFilePtr + 7, 8); } break; case UP: if (iFilePtr > 0){ iFilePtr--; Regs.x.ax = 0x0701; Regs.x.cx = 0; Regs.x.dx = 0x071e; Regs.h.bh = 0; int86(0x10, &Regs, &Regs); ShowOneFileEntry(iFilePtr, 1); } break; case PAGEUP: for (i = 0; i < 8; i++){ if (iFilePtr > 0){ iFilePtr--; Regs.x.ax = 0x0701; Regs.x.cx = 0; Regs.x.dx = 0x071e; Regs.h.bh = 0; int86(0x10, &Regs, &Regs); ShowOneFileEntry(iFilePtr, 1); } } break; case PAGEDOWN: for (i = 0; i < 8; i++){ if (iFilePtr < iFileAnz - 8){ iFilePtr++; Regs.x.ax = 0x0601; Regs.x.cx = 0; Regs.x.dx = 0x071e; Regs.h.bh = 0; int86(0x10, &Regs, &Regs); ShowOneFileEntry(iFilePtr + 7, 8); } } break; default: iFilePtr += iNum; ShowFiles(); break; } return; } /* ----- Men anzeigen und gew„hlten Menpunkt zurckliefern -------- */ CHAR Menu(apcMenuArray) CHAR *apcMenuArray[]; /* Zeiger auf das Array der Menoptionen */ { CHAR cKey, cKeyExt, /* Tasten */ cChar, /* Menauswahl */ *pcWinPtr; /* Zeiger auf Fensterpuffer */ INT iLeft, iTop, /* Dimensionen des zu ”ffnenden Fensters */ iWidth, iLength, iMenuCursorPos, /* Zeile des Auswahlcursors */ i; /* Z„hler */ /* H”he des Fensters berechnen */ iLength = strlen(apcMenuArray[0]); /* breitesten String suchen */ iWidth = 0; for (i = 1; i <= iLength; i++) if(iWidth < strlen(apcMenuArray[i])) iWidth = strlen(apcMenuArray[i]); /* Rahmen in Breite und H”he einbeziehen */ iWidth += 4; iLength += 2; /* Spalte und Zeile der oberen linken Ecke bestimmen */ iLeft = (40 - iWidth) / 2; iTop = (8 - iLength) / 2; /* Fenster aufmachen */ pcWinPtr = OpenWindow(iLeft, iTop, iWidth, iLength); if(pcWinPtr == NULL) return(0); /* Mentitel zentriert ausgeben */ gotoxy(iLeft + 1 + ((iWidth - strlen(apcMenuArray[1])) / 2), iTop + 1); printf("%s", apcMenuArray[1]); /* Menoptionen ausgeben */ for(i = 2; i <= iLength - 1; i++){ gotoxy(iLeft + 3, iTop + i); printf("%s", apcMenuArray[i]); } iMenuCursorPos = 0; cChar = 0; /* Taste holen und auswerten */ do{ gotoxy(iLeft + 3, iTop + 2 + iMenuCursorPos); GetKey(&cKey, &cKeyExt); if (cKey != 0){ if (cKey == 27){ cChar = 27; break; } if (cKey == 13) cChar = *(apcMenuArray[0] + iMenuCursorPos); else cChar = *strchr(apcMenuArray[0], cKey); } else{ switch (cKeyExt){ /* Cursor nach oben */ case 72: iMenuCursorPos--; if (iMenuCursorPos < 0) iMenuCursorPos = 0; break; /* Cursor nach unten */ case 80: iMenuCursorPos++; if (iMenuCursorPos > iLength - 3) iMenuCursorPos = iLength - 3; break; default: break; } } }while(cChar == 0); /* Fenster wieder schlieáen */ CloseWindow(pcWinPtr); ShowFiles(); return(cChar); } /* ----- Daten l”schen ---------------------------------------------- */ void CleanUp() { bModify = 0; iFileAnz = iHauptPrgPtr = -1; iFilePtr = 0; return; } /* ----- Dateinamen mittels File-Requester abfragen ----------------- */ INT FileReq(pcName, iMode) CHAR *pcName; /* Dateiname */ INT iMode; /* Modus (0=Lesen, 1=Schreiben) */ { CHAR *pcWinPtr, /* Zeiger auf Fensterpuffer */ acMode[10], /* Modus-String */ acInput[21], /* Dateiname */ acPath[21]; /* Pfad zur Datei */ INT iEscape; /* Abbruch-Flag */ if(iMode == 0) strcpy(acMode, "lesen"); else strcpy(acMode, "schreiben"); strcpy(acPath, "A:"); strcpy(acInput, "DISVER.DIS"); pcWinPtr = OpenWindow(3, 1, 35, 5); gotoxy(5, 3); printf(" DISVER-Daten %s", acMode); gotoxy(5, 4); printf("Pfad: <%-20s>", acPath); gotoxy(5, 5); printf("Dateiname: <%-20s>", acInput); iEscape = Input(17, 4, 19, acPath); if (iEscape == 1){ CloseWindow(pcWinPtr); return(iEscape); } iEscape = Input(17, 5, 19, acInput); CloseWindow(pcWinPtr); if (iEscape == 1) return(iEscape); ShowFiles(); /* Dateinamen zusammenbasteln */ strcpy(pcName, acPath); strcat(pcName, "\\"); strcat(pcName, acInput); return(0); } /* ----- Disver-Daten laden ----------------------------------------- */ void FileLaden() { INT iEscape, /* Abbruch-Flag */ iAnzahl, /* Anzahl gelesener Bytes */ iInput; /* Filedeskriptor der Datei */ CHAR acInput[42], /* Dateiname */ acIdentify[7]; /* Kennung der Daten */ iInput = 1; do{ /* Dateinamen abfragen */ iEscape = FileReq(acInput, MO_LESEN); if (iEscape == 1) return; /* Datei ”ffnen */ iInput = open(acInput, O_BINARY); if(iInput == -1) Error(4); } while(iInput == -1); /* Kennung prfen, ob es sich auch um DISVER-Daten handelt */ iAnzahl = read(iInput, acIdentify, 7); if(iAnzahl < 7) return; if(strcmp(acIdentify, "DISVER") == 0){ Status(203); /* Žnderungs-Flag setzen, wenn Daten angeh„ngt werden */ if (iFileAnz != -1) bModify = 1; /* Daten einlesen */ while(iAnzahl){ iFileAnz++; if(iFileAnz > MAXFILES){ iFileAnz--; Error(5); break; } /* Speicherplatz fr den File-Eintrag reservieren */ if (AllocEntry(iFileAnz, FILES) == 1){ iFileAnz--; break; } iAnzahl = read(iInput, File[iFileAnz], sizeof(struct FileEntries)); } } else{ Error(6); return; } close(iInput); Status(0); iFileAnz--; iFilePtr = 0; ShowFiles(); return; } /* ----- DISVER-Daten speichern ------------------------------------- */ void FileSpeichern() { CHAR acOutput[42]; /* Dateiname */ INT i, /* Z„hler */ iEscape, /* Abbruch-Flag */ iAnzahl, /* Anzahl geschriebener Bytes */ iOutput; /* Filedeskriptor der Ausgabedatei */ iOutput = 1; do{ /* Dateinamen abfragen */ iEscape = FileReq(acOutput, MO_SCHREIBEN); if (iEscape == 1) return; /* Datei ”ffnen */ iOutput = _creat(acOutput, FA_ARCH); if(iOutput == -1) Error(7); } while(iOutput == -1); /* Kennung schreiben */ iAnzahl = write(iOutput, "DISVER", 7); if (!iAnzahl){ Error(8); return; } Status(204); for(i = 0; i <= iFileAnz; i++){ iAnzahl = write(iOutput, File[i], sizeof(struct FileEntries)); if(!iAnzahl){ Status(0); Error(8); return; } } close(iOutput); Status(0); /* Žnderungsflag zurcksetzen */ bModify = 0; ShowFiles(); return; } /* ----- Programm beenden und vorher allen -------------------------- ----- belegten Speicher freigeben -------------------------------- */ void ThisIsTheEnd() { INT i; /* Z„hler */ if (bModify == 1) FileSpeichern(); for (i = 0; i <= iFileAnz; i++) free(File[i]); clrscr(); printf("Vielen Dank fr den Einsatz \nvon DISVER Portfolio.\n"); exit(0); } /* ----- Sortieren der File-Liste nach dem Filenamen ---------------- ----- im Bereich von 0 bis iEnd ---------------------------------- */ void NameSort(iEnd) INT iEnd; /* Ende des Sortierbereiches */ { INT iUntereSchranke, iObereSchranke, i, j, k; /* Z„hler */ struct FileEntries *W, *X; /* scratch pointer */ iUntereSchranke = (iEnd / 2) + 1; iObereSchranke = iEnd; while (iObereSchranke > 0){ if (iUntereSchranke > 0){ iUntereSchranke--; i = iUntereSchranke; } else{ W = File[0]; File[0] = File[iObereSchranke]; File[iObereSchranke] = W; iObereSchranke--; i = 0; } X = File[i]; k = 0; while ((2 * i <= iObereSchranke) && (k == 0)){ j = 2 * i; if (j < iObereSchranke){ if (strcmp(File[j]->acName, File[j + 1]->acName) < 0) j++; } if (strcmp(X->acName, File[j]->acName) < 0){ File[i] = File[j]; i = j; } else k = 1; } File[i] = X; } return; } /* ----- Sortieren der File-Liste nach dem Kartennamen ---------------- ----- im Bereich von 0 bis iEnd ---------------------------------- */ void CardSort(iEnd) INT iEnd; /* Ende des Sortierbereiches */ { INT iUntereSchranke, iObereSchranke, i, j, k; /* Z„hler */ struct FileEntries *W, *X; /* scratch pointer */ iUntereSchranke = (iEnd / 2) + 1; iObereSchranke = iEnd; while(iObereSchranke > 0){ if(iUntereSchranke > 0){ iUntereSchranke--; i = iUntereSchranke; } else{ W = File[0]; File[0] = File[iObereSchranke]; File[iObereSchranke] = W; iObereSchranke--; i = 0; } X = File[i]; k = 0; while((2 * i <= iObereSchranke) && (k == 0)){ j = 2 * i; if(j < iObereSchranke){ if(strcmp(File[j]->acDisk, File[j + 1]->acDisk) < 0) j++; } if(strcmp(X->acDisk, File[j]->acDisk) < 0){ File[i] = File[j]; i = j; } else k = 1; } File[i] = X; } return; } /* ----- Sortieren der File-Liste nach der Gr”áe -------------------- ----- in Bytes im Bereich von 0 bis iEnd ------------------------- */ void ByteSort(iEnd) INT iEnd; /* Ende des Sortierbereiches */ { INT iUntereSchranke, iObereSchranke, i, j, k; /* Z„hler */ struct FileEntries *W, *X; /* scratch pointer */ iUntereSchranke = (iEnd / 2) + 1; iObereSchranke = iEnd; while(iObereSchranke > 0){ if(iUntereSchranke > 0){ iUntereSchranke--; i = iUntereSchranke; } else{ W = File[0]; File[0] = File[iObereSchranke]; File[iObereSchranke] = W; iObereSchranke--; i = 0; } X = File[i]; k = 0; while((2 * i <= iObereSchranke) && (k == 0)){ j = 2 * i; if(j < iObereSchranke){ if(File[j]->lBytes < File[j + 1]->lBytes) j++; } if(X->lBytes < File[j]->lBytes){ File[i] = File[j]; i = j; } else k = 1; } File[i] = X; } return; } /* ----- File editieren --------------------------------------------- */ void EditAFile() { CHAR *pcWinPtr, /* Zeiger auf den Fensterpuffer */ acEditBytes[7]; /* Puffer fr die Bytes */ INT i; /* Z„hler */ LONG lEditBytes; /* Puffer fr die Bytes */ /* Fenster ”ffnen und beschreiben */ pcWinPtr = OpenWindow(3, 1, 34, 6); gotoxy(13, 3); printf("File editieren"); gotoxy(6, 4); printf(" Name Bytes Karte"); gotoxy(6, 5); printf("------------ ------ ----------"); for(i = 0; i <= iFileAnz; i++){ if(File[i]->cSelect == 1){ /* Werte holen und anzeigen */ gotoxy(6, 6); sprintf(acEditBytes, "%-ld", File[i]->lBytes); printf("%-12s %-6ld %-10s", File[i]->acName, File[i]->lBytes, File[i]->acDisk); /* Werte nacheinander abfragen */ Input(6, 6, 12, File[i]->acName); do{ Input(19, 6, 6, acEditBytes); lEditBytes = atol(acEditBytes); sprintf(acEditBytes, "%-ld", File[i]->lBytes); }while(lEditBytes == 0); File[i]->lBytes = lEditBytes; Input(26, 6, 10, File[i]->acDisk); /* Markierung l”schen und Žnderungs-Flag setzen */ File[i]->cSelect = 0; bModify = 1; } } CloseWindow(pcWinPtr); ShowFiles(); return; } /* ----- Angeklickte Files l”schen ---------------------------------- */ void FileLoeschen() { INT i, j = -1; /* Z„hler */ for(i = 0; i <= iFileAnz; i++){ if(File[i]->cSelect == 0){ /* Žnderungen-Flag setzen */ bModify = 1; j++; File[j] = File[i]; } else File[i]->cSelect = 0; } iFileAnz = j; ShowFiles(); return; } /* ----- Neues File von Hand eingeben ------------------------------- */ void FileNeu() { INT i; /* Z„hler */ /* Prfen, ob noch Platz fr das neue File ist */ if(iFileAnz < MAXFILES){ /* Alle Markierungen l”schen */ for(i = 0; i <= iFileAnz; i++) File[i]->cSelect = 0; /* Leeres File anh„ngen */ iFileAnz++; if (AllocEntry(iFileAnz, FILES) == 1){ iFileAnz--; return; } /* Letztes File selektieren und editieren lassen */ strcpy(File[iFileAnz]->acName, ""); File[iFileAnz]->lBytes = 0; strcpy(File[iFileAnz]->acDisk, ""); File[iFileAnz]->cSelect = 1; EditAFile(); /* Ende der File-Liste zeigen */ if(iFileAnz < 8) iFilePtr = 0; else iFilePtr = iFileAnz - 7; ShowFiles(); } else Error(5); return; } /* ----- Informationen ber das Programm anzeigen ------------------- */ void FileAbout() { CHAR *pcWinPtr; /* Zeiger auf Fensterpuffer */ /* Meldung ausgeben */ pcWinPtr = OpenWindow(1, 0, 37, 7); if(pcWinPtr == NULL) return; gotoxy(10, 2); printf("DISVER Portfolio 1.0"); gotoxy(10, 3); printf("von Michael Schuschk"); gotoxy(7, 4); printf("(C) 1990 Markt & Technik AG"); gotoxy(3, 5); printf("%3d Files mit %d kB gespeichert.", iFileAnz + 1, do_sum() / 1024); gotoxy(5, 6); printf("Es ist noch Platz fr %3d Files.", MAXFILES - iFileAnz - 1); while(!kbhit()); CloseWindow(pcWinPtr); ShowFiles(); return; } /* ----- Markiertes File zum Hauptprogramm machen ------------------- */ void HauptProgramm() { INT i; /* Z„hler */ /* eventuelle vorherige Hauptprogrammmarkierung l”schen */ for (i = 0; i <= iFileAnz; i++) if (File[i]->cSelect == 2) File[i]->cSelect = 0; /* Markiertes File suchen */ for (i = 0; (File[i]->cSelect == 0) && (i <= iFileAnz); i++); if (i != iFileAnz){ /* File markieren und an HauptPrgPtr bergeben */ iHauptPrgPtr = i; File[i]->cSelect = 2; lHauptPrgBytes = File[i]->lBytes; ShowFiles(); } return; } /* ----- Markierte Files zum Hauptprogramm addieren ----------------- */ void UnterProgramm() { INT i, j; /* Z„hler */ j = -1; /* Hauptprogramm markiert ? */ if (iHauptPrgPtr == -1) return; for (i = 0; i <= iFileAnz; i++){ if (File[i]->cSelect == 1){ /* Unterprogramm addieren */ lHauptPrgBytes += File[i]->lBytes; File[iHauptPrgPtr]->lBytes = lHauptPrgBytes; bModify = 1; } else{ /* Hauptprogrammpointer anpassen */ j++; if (i == iHauptPrgPtr) iHauptPrgPtr = j; strcpy(File[j]->acName, File[i]->acName); File[j]->lBytes = File[i]->lBytes; strcpy(File[j]->acDisk, File[i]->acDisk); File[j]->cSelect = 0; } } for (i = j + 1; i <= iFileAnz; i++) File[i]->cSelect = 0; iFileAnz = j; if (iFileAnz < 7) iFilePtr = 0; else iFilePtr = iHauptPrgPtr - 3; File[iHauptPrgPtr]->cSelect = 0; iHauptPrgPtr = -1; ShowFiles(); return; } /* ----- Aktuelle Systemzeit holen und umwandeln -------------------- */ CHAR *Zeit() { struct tm *Tm; /* von localtime() benutzt */ LONG lT; /* von time() benutzt */ static CHAR acZeitBuffer[20], /* Systemzeit als String */ acTage[7][3] = {"So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"}; time(&lT); Tm = localtime(&lT); sprintf(acZeitBuffer, "%s %2d.%2d.%4d %02d:%02d", acTage[Tm->tm_wday], Tm->tm_mday, Tm->tm_mon + 1, Tm->tm_year + 1900, Tm->tm_hour, Tm->tm_min); return(acZeitBuffer); } /* ----- Daten zweispaltig drucken ---------------------------------- */ void DruckenAlles() { INT i, j, k, /* Z„hler */ iSeiten; /* Anzahl zu druckender Seiten */ FILE *out; /* Druckerhandle */ /* Seitenzahl ermitteln */ iSeiten = iFileAnz / 58 / 2; /* Druckerkanal ”ffnen und Drucker auf 80 Zeichen/Zeile stellen */ Status(200); out = fopen("lpt1", "w"); if (out == NULL){ Status(0); Error(9); return; } fprintf(out, "\x1bP"); /* Files drucken */ for(i = 0; i <= iSeiten; i++){ fprintf(out, " DISVER Magnetkartenverwaltung %-s Seite %d von %d\n\n", Zeit(), i + 1, iSeiten + 1); fprintf(out, " Name Bytes Karte Name Bytes Karte\n"); fprintf(out, " ------------ ------ ---------- ------------ ------ ----------\n"); for(j = 0; j <= 57; j++){ k = (2 * i * 58) + j; if(k <= iFileAnz) fprintf(out, " %-12s %6ld %-10s ", File[k]->acName, File[k]->lBytes, File[k]->acDisk); else fprintf(out, "%-45s", " "); k = ((2 * i + 1) * 58) + j; if(k <= iFileAnz) fprintf(out, "%-12s %6ld %-10s\n", File[k]->acName, File[k]->lBytes, File[k]->acDisk); else fprintf(out, "%-30s\n", " "); } /* Fuázeile und Seitenvorschub ausgeben */ fprintf(out, "\n Insgesamt sind %d Files mit %ld Bytes gespeichert\n%c", iFileAnz + 1, do_sum(), 12); } fclose(out); Status(0); return; } /* ----- Projektmen auswerten -------------------------------------- */ void ActionOnProjectMenu() { CHAR cKey; /* Menauswahl */ cKey = Menu(ProjectMenu); switch(cKey){ case 'n': CleanUp(); ShowFiles(); break; case 'l': FileLaden(); ShowFiles(); break; case 's': FileSpeichern(); break; case 'k': DisketteEinlesen(); SetupFileScreen(); iFilePtr = iFileAnz - 7; ShowFiles(); break; case '': FileAbout(); break; case 'e': bEnde = 1; break; default: break; } return; } /* ----- Sortiermen auswerten -------------------------------------- */ void ActionOnSortMenu() { CHAR cKey; /* Menauswahl */ cKey = Menu(SortMenu); switch(cKey){ case 'n': Status(205); NameSort(iFileAnz); Status(0); break; case 'b': Status(205); ByteSort(iFileAnz); Status(0); break; case 'k': Status(205); CardSort(iFileAnz); Status(0); break; default: break; } ShowFiles(); return; } /* ----- Editiermen auswerten -------------------------------------- */ void ActionOnEditMenu() { CHAR cKey; /* Menauswahl */ cKey = Menu(EditMenu); switch(cKey){ case 'h': HauptProgramm(); break; case 'u': UnterProgramm(); break; case 'e': EditAFile(); break; case 'n': FileNeu(); break; case 'l': FileLoeschen(); break; default: break; } return; } /* ----- Optionsmen auswerten -------------------------------------- */ void ActionOnOptionMenu() { CHAR cKey; /* Menauswahl */ cKey = Menu(OptionsMenu); switch(cKey){ case 'a': strcpy(acDrive, "A:\\"); *OptionsMenu[2] = 'û'; *OptionsMenu[3] = ' '; *OptionsMenu[4] = ' '; break; case 'b': strcpy(acDrive, "B:\\"); *OptionsMenu[2] = ' '; *OptionsMenu[3] = 'û'; *OptionsMenu[4] = ' '; break; case 'c': strcpy(acDrive, "C:\\"); *OptionsMenu[2] = ' '; *OptionsMenu[3] = ' '; *OptionsMenu[4] = 'û'; break; default: break; } return; } /* ----- Hauptmen auswerten ---------------------------------------- */ void ActionOnMainMenu() { CHAR cKey; /* Menauswahl */ cKey = Menu(MainMenu); switch(cKey){ case 'p': ActionOnProjectMenu(); break; case 's': ActionOnSortMenu(); break; case 'e': ActionOnEditMenu(); break; case 'd': DruckenAlles(); break; case 'o': ActionOnOptionMenu(); break; default: break; } return; } /* ----- Tastendruck auswerten -------------------------------------- */ void ActionOnKey(cKey, cKeyExt) CHAR cKey, /* ASCII-Code der Taste */ cKeyExt; /* erweiterter Tastaturcode */ { if(cKey != 0){ switch(cKey){ /* Leertaste - Markieren */ case 32: if (File[iFilePtr + iFileCursorPos]->cSelect == 1) File[iFilePtr + iFileCursorPos]->cSelect = 0; else File[iFilePtr + iFileCursorPos]->cSelect = 1; ShowFiles(); break; /* H - Markiertes File zum Hauptprogramm machen */ case 104: case 72: HauptProgramm(); break; /* U - Markierte Files zum Hauptprogramm addieren */ case 117: case 85: UnterProgramm(); break; default: break; } } else{ switch(cKeyExt){ /* F1 - Hauptmen */ case 59: ActionOnMainMenu(); break; /* Cursor nach oben */ case 72: if(iFileCursorPos == 0) FileScroll(UP); else iFileCursorPos--; break; /* Cursor nach unten */ case 80: if(iFileCursorPos == 7) FileScroll(DOWN); else if (iFilePtr + iFileCursorPos < iFileAnz) iFileCursorPos++; break; /* Bild nach oben (PageUp) */ case 73: FileScroll(PAGEUP); break; /* Bild nach unten (PageDn) */ case 81: FileScroll(PAGEDOWN); break; /* Pos1 (Home) */ case 71: FileScroll(HOME); break; /* Ende (End) */ case 79: FileScroll(END); break; default: break; } } return; } /* ----- Das Hauptprogramm ------------------------------------------ ----- (oder was erwarten Sie sonst am Ende des Quelltextes?) ----- */ INT main() { CHAR cKey, cKeyExt; /* ASCII- und erweiterter Tastencode */ #ifdef DEBUG /* Blockcursor einschalten */ Regs.h.ah = 1; Regs.h.ch = 0; Regs.h.cl = 7; int86(0x10, &Regs, &Regs); #endif /* File-Bildschirm aufbauen */ SetupFileScreen(); /* Variable initialisieren */ iFileAnz = -1; iFilePtr = 0; bEnde = 0; /* Erkennung anzeigen */ FileAbout(); /* Taste holen und auswerten */ do{ GetKey(&cKey, &cKeyExt); ActionOnKey(cKey, cKeyExt); /* Anzahl der Files und freien Speicher anzeigen */ gotoxy(35, 4); printf("%3d", iFileAnz + 1); gotoxy(34, 6); printf("%6u", coreleft()); /* Cursor positionieren */ gotoxy(2, iFileCursorPos + 1); }while(bEnde == 0); ThisIsTheEnd(); exit(0); }