diff --git a/Linux-0.96/INSTALL/autocn/ACONVERT.EXE b/Linux-0.96/INSTALL/autocn/ACONVERT.EXE new file mode 100644 index 00000000..de51a664 Binary files /dev/null and b/Linux-0.96/INSTALL/autocn/ACONVERT.EXE differ diff --git a/Linux-0.96/INSTALL/autocn/AUTOCON.DOC b/Linux-0.96/INSTALL/autocn/AUTOCON.DOC new file mode 100644 index 00000000..6e3bdbe2 --- /dev/null +++ b/Linux-0.96/INSTALL/autocn/AUTOCON.DOC @@ -0,0 +1,1234 @@ + + + + + + + + + + + A U T O C O N + Version 2.0g + March 15, 1992 + + by + Larry Weaver + + + Copyright (c) 1989-92 Larry Weaver + + P.O. Box 2639 + Weaverville CA 96093-2639 + Office : (916) 623-5045 + BBS : (916) 623-4455 + + + + + _______ + ____|__ | (tm) + --| | |------------------- + | ____|__ | Association of + | | |_| Shareware + |__| o | Professionals + -----| | |--------------------- + |___|___| MEMBER + + + AUTOCON + + Introduction + + Definitions: + + In order to describe AutoCon, I need to establish a couple of + definitions. When I use the word "reconfigure", I mean the + process of updating the AUTOEXEC.BAT and CONFIG.SYS files on the + boot drive, followed by an optional reboot of the system. + + When I use the word "configuration", I am referring to an + AUTOEXEC/CONFIG combination held in a record of AutoCon's + database. You will use AutoCon to set up these combinations, and + give each of them a familiar name. + + The ^ symbol denotes the Control key, so ^F3 means hitting the + Control and the F3 key at the same time. Alt denotes the Alt key + (tricky, huh?), so that AltR means hitting the Alt and the R key + at the same time. ENTER (all caps) denotes hitting the Enter key. + + + Description: + + AutoCon is essentially a database manager for your AUTOEXEC.BAT + and CONFIG.SYS files. It enables you to keep up to fifty + different configurations, and to change easily between those + configurations. + + The first time you run AutoCon, it will create a file named + AUTOCON.DAT. That file will contain five configuration records. + Each record will contain a copy of the AUTOEXEC.BAT and + CONFIG.SYS files from the C: drive. The records are initially + named RECORD01 - RECORD05. When you set up a configuration for a + specific purpose, you can change the name to reflect that purpose + (something like Win3 for a Microsoft Windows configuration, and + SDOS for a simple DOS configuration). You can add more records by + hitting the F3 key. + + AutoCon incorporates a full-screen editor to make it easy to + change the AUTOEXEC/CONFIG records. The editor uses Turbo + IDE/Sidekick/WS-compatible keystrokes. If you are not familiar + with these, there is an on-line help file which details all the + keystrokes. If you desire, you can change the editor keystrokes. + The F6 key will pop up a key editor for this purpose. + + If you don't like the built-in editor, you can configure AutoCon + to use a different one. The ^F6 key combination will pop up a + window asking for the name of the editor you wish to run. Since + the configurations will eventually be used as AUTOEXEC.BAT and + CONFIG.SYS files, the editor must be able to produce pure ASCII + files. You can toggle between the internal and external editors + with the ^F6 and the ShiftF6 key combinations. + After you have established your records and names, you can + reconfigure your system by entering the name of the new + configuration on the command line. Typing "AutoCon Win3" would + cause AutoCon to copy the AUTOEXEC and CONFIG fields of the + record named Win3 into the boot drive as AUTOEXEC.BAT and + CONFIG.SYS and optionally reboot the system. + + In the interactive mode, you can page through the records and + reconfigure (using the current on-screen configuration) with a + couple of keystrokes. + + The AutoCon package also includes a device driver which will + allow you to select different configurations during the boot + process. Using this method is optional, and you can switch + between the two methods with a couple of key strokes. + + + Why AutoCon for Configuration Control: + + Three programs were initially responsible for the creation of + AutoCon: my schematic program, my scanner program, and my + programmable logic compiler. Each of these programs require + various device drivers, and almost 600k of memory. When the + computer is configured to run one of the three, neither of the + other two will run; in addition, if the computer is configured the + way I like to work with it, _none_ of the three will run. After + playing with batch files for a while, I decided to write a program + to make it easy to change configurations. + + The above scenario is responsible for the default of five records + in AutoCon. I had a regular configuration, the three special + configurations, and one for experimentation. After I had worked + with AutoCon for a few days, I told a few of my friends about the + program and they wanted to try it. After some very positive + feedback, I decided to try the program out in the Shareware + community. + + An unexpected bonus of using AutoCon became evident when I + received programs with automatic installation modules -- you know, + the ones that like to mess around with your AUTOEXEC and CONFIG + files. Since your configurations are stored in a database, a + change to the AUTOEXEC and CONFIG files doesn't cause a problem. + + I'll use Windows to demonstrate. When I got Windows, and saw + what it was going to do to my system configuration, I used my + "Simple" configuration to reconfigure my system. This + configuration has only the basic stuff in it (path, prompt, + files, and buffers). I then let Windows install itself. After + the installation was finished, I called up AutoCon and created a + new configuration containing the changes Windows had made. After + playing with Windows for a while, I went back to my favorite DOS + configuration in a matter of moments. Now, whenever I want to + run Windows, I just type "AutoCon Win3" on the command line -- + and it's up and running! + INSTALLING AUTOCON + + New Installation: + + To do a new installation of AutoCon, you need to copy four files + (AUTOCON.EXE, AUTOCON.HLP, MENU.CTL, and MENUNUM.COM) to your + hard disk. It doesn't really matter which subdirectory you copy + them into, as long as it's included in the PATH statement. If + you like to have files relating to booting up (such as device + drivers) in your root directory, then MENU.CTL and MENUNUM.COM + should be placed there, otherwise all four files may be placed in + the same subdirectory. When AutoCon is started, it will first + look in the current subdirectory for its Help and data files. If + they are not there, then AutoCon (if you are using DOS 3.3+) will + search the subdirectory it was started from. If they are not + _there_, then AutoCon will search the PATH. As long as the Help + and data files are in the PATH (or in the subdirectory AutoCon + was started from - DOS 3.3+), AutoCon can be installed in any + subdirectory. + + After you have copied the files, change to the subdirectory + AUTOCON.EXE was copied to, and type "AUTOCON" ENTER. You will now + be in the interactive mode, pointing to the name of the first + configuration. This first configuration is a special one to + AutoCon. Several of the default parameters are stored in this + configuration. When you make changes to the first record, you + will be asked whether you want to copy those changes across all + the records. + + IMPORTANT: If you are currently using a disk cache program that + buffers disk writes (PC-KWIK and PCTOOLS are two that I know of), + you need to set up AutoCon to flush the cache before it reboots. + Hit the F4 key, select "Yes", then enter the command (include the + path if necessary) that causes your cache program to flush its + buffers. In the case of PC-KWIK, it is the PC-KWIK program name + followed by /F. AutoCon will execute this program before + reconfiguring. + + AutoCon is now installed, and ready to use. + + + Update: + + If your current AutoCon version is below 2.0 then the new + capabilities of AutoCon require a change to the AUTOCON.DAT file, + so if you are updating to V2.0x of AutoCon from 1.x you have a + little more to do: you need to copy the same four files mentioned + above to the subdirectory where the older version of AutoCon + (which will be overwritten) is installed. There is another new + file in the AutoCon package called ACONVERT.EXE. You need to + change to the subdirectory where AUTOCON.DAT resides, then run the + ACONVERT program. This program will rename AUTOCON.DAT to + AUTOCON.SAV, then convert the file structure to work under AutoCon + V2.0x. After you run ACONVERT.EXE, you no longer need the + ACONVERT.EXE file, so it can be deleted. + + The editor has a few new capabilities which will not be available + until you change the editor keys. Call up AutoCon, then hit the + F6 key. If you have never changed the keys, hit AltR, and + answer "Yes" to restoring the default keystrokes. If you have + changed the keystrokes, page down to the bottom of the key list; + you will see that there are some new keys that need to be + defined. + + In either case, after copying the files, you will need to start + AutoCon and hit the F2 key. Answer yes to update the files to the + new version. + + MENU.CTL & MENUNUM.COM + + The addition of these two files to the AutoCon package changes + its capabilities so much that I decided to skip versions 1.5 - + 1.9 and go directly to version 2.0. MENU.CTL is a device driver + which modifies the way a CONFIG.SYS file is processed by DOS. It + allows AutoCon to set up a menu selection system which can be + activated during the boot process. There are both advantages and + disadvantages to this capability; the major advantage is that you + can pick the configuration you want to use during the boot + process. + + The major disadvantage is that your CONFIG.SYS and AUTOEXEC.BAT + files become quite nonstandard. If you want four choices to be + available to you during the boot, then all four configurations + must be embedded in the AUTOEXEC and CONFIG files. Programs like + Optimize (QEMM utility) will get very confused trying to work + with these files; most automatic installation programs will not + be able to work with them, either. + + I've designed AutoCon to be able to switch between the boot "menu" + mode and the "single" mode with just a couple of keystrokes; this + should provide the best of both worlds. When a program like + Optimize (or perhaps the Windows installation program) needs to + work with your AUTOEXEC and CONFIG files, change to the single + configuration mode. After the program is finished, call up + AutoCon, save the results in one of your configurations, and go + back to the menu mode. + + + MENU.CTL: + AutoCon handles all the nitty-gritty details of interfacing to + MENU.CTL. The only thing you have to do is make sure that + MENU.CTL and MENUNUM.COM are in a subdirectory included in the + PATH statement. To set up MENU.CTL, start AutoCon in the + interactive mode (just type "AUTOCON" ENTER), then hit the AltM + key combination; this will pop up a configuration menu. Select + the configurations you want in the boot-up menu by moving the + highlite bar over the ones you want, and hit the Enter key. The + selected configurations will have a check mark in the first + column. When you've finished selecting configurations, hit the + Escape key. AutoCon will then ask how many seconds you want to + delay (see the following note). Enter a number from 0 to 9. + + You will now be back in the main interactive screen. Hit the F2 + key to reconfigure the system using MENU.CTL (the record on the + screen will be made the boot default record -- if it was not one + of the selected records, it will be added to the default list). + The next time you boot, MENU.CTL will take control of the + CONFIG.SYS file. If you hit a key in the default time, you will + be able to choose from the configurations you selected. + + To go back to a single configuration, start AutoCon in the + interactive mode, and hit the AltS key combination. Change to the + configuration you want to boot with, hit the F2 key, and + you're reconfigured, + + You will always be able to tell which mode AutoCon is in by + looking at the bottom line on the screen in the interactive mode. + If it says MENU.CTL you are in (boot) Menu mode, and if it says + SINGLE you are in Single Mode. + + Time: + When you select Menu mode, you will be asked to select how many + seconds to wait during the boot process; you may enter from 0 + (the default) to 9. If you select 0, when you see the MENU.CTL + box pop up, you will have about a second to hit a key. If you do + hit a key in this time, the menu selection will be placed on the + screen. If not, the boot will continue with the default record. + + If you select any number except 0, you will see the following + messages on the screen during the boot process: + + Press Esc to select -- the default record name will be here -- + + Press any other key to select a different configuration. Time = + + with a decrementing number (starting with the time chosen from + AutoCon) following the = sign. When the time goes to 0, or the + Esc key is hit, the default record will be used to continue + the boot. + + In either case, if a key is hit, the menu choices will be placed + on the screen and you will be able to choose the one you want with + the arrow keys. The one the arrow is pointing to when the ENTER + key is hit will be the configuration used for the boot process. + + Colors: + If you don't like the colors that MENU.CTL uses when it takes + control of the boot process, you can change them using the pull + down menu in AutoCon. Start AutoCon, and hit the AltB + combination. The four colors used by AutoCon can be changed with + this menu. Select the colors you would like MENU.CTL to use, then + write out the new configuration (usually with the F2 key). + + + XMAEM.SYS: + I don't have DOS 4.0, so I don't really have experience with this + device driver. From reading PC Magazine, I know that DOS + processes this device driver out of sequence in the CONFIG.SYS + file. As a consequence, MENU.CTL will not be able to control it. + + + MSDOS 5.0's High and UMB flags: + Microsoft added a couple of capabilities to DOS 5.0 that pose a + special problem for MENU.CTL. These are the DOS=HIGH/LOW and + DOS=UMB/NOUMB flags. DOS processes these flags out of sequence, + so that by the time MENU.CTL has taken over, it has already set + itself up for their use. DOS decides how to set the flags by + parsing the entire CONFIG.SYS file, and using the state of the + last occurrence of the DOS= statement to set the flags. + + AutoCon is still able to control these flags though the method is + a little unorthodox. When you are using Menu mode and MSDOS 5.0, + AutoCon will place the statement DOS=HIGH,NOUMB as the last line + in the CONFIG.SYS file. As a consequence, DOS will attempt to + always load HIGH, and have NOUMB control. When you select a + configuration via MENU.CTL, if that configuration has a DOS=LOW + command in it (and no other program in the configuration has taken + it), MENU.CTL will take the HMA and force DOS Low. The HMA will + be released by MENUNUM runs (as soon as the AUTOEXEC.BAT file + starts executing). If the selected configuration has a DOS=UMB + command, then MENU.CTL will tell DOS to control the UMBs. + + If all of this makes no sense to you, then don't worry about it. + If you are using MSDOS 5.0 and the Menu mode, just place the + appropriate DOS=HIGH/LOW and DOS=UMB/NOUMB commands in each of + your configurations, and AutoCon will do the rest. + + + DRDOS: + As of this release MENU.CTL (Version 1.4 or higher) if fully DRDOS + compatible. + + + CONFIG: + When you switch to the Menu mode, AutoCon will do all of the work + for you. It will take your selected configurations (up to 8) and + create the AUTOEXEC.BAT and CONFIG.SYS files that will allow you + to choose during the boot process. If you look at the CONFIG.SYS + file that has been set up for a boot menu, you will see all the + selected CONFIG fields embedded in the files with DEVICE=MENU.CTL + at the beginning of the file. When MENU.CTL is processed by DOS, + it will take over and allow you to choose the configuration you + want. After you choose, MENU.CTL will leave the chosen + configuration intact and disable the rest. + + If you are using DOS 4.0+, MENU.CTL disables by changing the + CONFIG.SYS commands to remarks. If you are using DOS 3.3 or + below, it will disable the commands by turning them into + BREAK=OFF commands. As a consequence, if you are using a DOS + below 4.0, you will need to make a couple of changes to your + CONFIG commands. In order to have the room to convert the + LASTDRIVE, FILES, and BUFFERS commands, you will need to make the + lines longer. + + I do this by adding an * at the end of the line, as follows: + LASTDRIVE=M: * BUFFERS=10 * FILES=50 * + + If you don't do this, these commands will be disabled by making + them unrecognized. This doesn't cause a problem: you will just + see a lot of "Unrecognized command in CONFIG.SYS" lines coming + out during the boot process. + + Note: AutoCon will also change "Unrecognized" commands to + BREAK=OFF commands if there is room. This will allow you to + freely place REM statements in your CONFIG.SYS file (as long as + you use MENU mode). + + If you want BREAK=ON, you will have to add it to your AUTOEXEC + fields. + + AUTOEXEC: + The AUTOEXEC.BAT file will also contain all the selected + configurations AUTOEXEC fields. At the beginning of the file + will be MENUNUM.COM. This program will interrogate MENU.CTL and + find which configuration was chosen. MENUNUM will set ERRORLEVEL + to match the chosen menu, and an "If" statement will cause the + associated AUTOEXEC to be chosen. + + UNRECOGNIZED COMMANDS - DOS 3.3: + CONFIG.SYS files have a potential problem. If you enter the + following two lines in your CONFIG.SYS file + + REM + DEVICE=ANSI.SYS + + ANSI.SYS will not get loaded. Both lines will be turned into an + "Unrecognized command". This is just something that DOS does, + and there is nothing an outside program can do about it. + + Do not end a CONFIG field with an Unrecognized command. If you + do, the following command will also be Unrecognized, and will + definitely mess up the processing of the CONFIG.SYS file. + + CAUTION: When you start playing around with the Menu mode, be very + careful when updating or creating a configuration. If you read + in an AUTOEXEC.BAT or CONFIG.SYS file which has been set up for + MENU mode, it will contain a lot of commands which will cause + problems if you use it in a reconfiguration. It would be much + better to copy one of the other configurations and not update + from the AUTOEXEC and CONFIG files. + + If you have managed to read and save such a configurations, you + will need to edit and remove the extra statements inserted by + AutoCon. If it is not obvious to you by looking at the AUTOEXEC + and CONFIG fields which statements these are, then do not attempt + to edit the field, simply copy one of the other configurations. + + Magazine Article: + Just as a side note, during the development of MENU.CTL I created + a simpler device driver and decided it would make a good subject + for a magazine article (similar to PC Magazine's CONFIG.CTL + device driver). I wrote it up, and it was published in the Sept. + 1991 issue of Tech Specialist. + + + + NAVIGATING AUTOCON + + + Okay, now you have AutoCon installed; how do you use it? Starting + with version 2.0, the interactive front screen of AutoCon can be + navigated with a pull-down menu. If you need to do something and + can't remember the keystroke combination to get there, use the + menu to find it. On the right of each menu entry is the shortcut + key combination to perform the same operation. I am going to + define the navigation keys in the form of the pull-down menu. + + DataBase Maintenance (Records AltR) + + Previous/Next, browse records: + PgUp/PgDn allows you to page through the records one at a time. + + pIck Record: + F10 pops up a pick-list of all the configurations, and allows + you to choose one and make it current. + + Create Record: + F3 creates a new record, and copies the control structure from + record 1 and the data from the current AUTOEXEC and CONFIG + files. + + Delete Record: + ^F3 deletes the current configuration record. Note that you + cannot delete record number 1, nor can you delete below the + default 5 records. + + Read Files: + F7 will cause the current record to be updated with the + contents of the AUTOEXEC and CONFIG files. + + Read file into AUTOEXEC (rd Auto ^F8): + ^F8 will pop up a window asking for a file name to read into + the AUTOEXEC field. In you enter wildcards, a list of file + names will be popped up to choose from. The AUTOEXEC field of + the current record will be replaced by the contents of the + chosen file. + + Read file into CONFIG (rd confiG ^F9): + ^F9 will pop up a window asking for a file name to read into + the CONFIG field. In you enter wildcards, a list of file names + will be popped up to choose from. The CONFIG field of the + current record will be replaced by the contents of the chosen + file. + + Configure and continue: + ^K^D will cause all current changes to be saved. In other + words, it will rewrite the AUTOCON.DAT file, the AUTOEXEC.BAT + file, and the CONFIG.SYS file. + + Change BAT drive: + F8 will pop up a window to allow you to change the file the + AUTOEXEC field of a configuration is written too. The default + name is C:\AUTOEXEC.BAT. + + Change SYS drive: + F8 will pop up a window to allow you to change the file the + CONFIG field of a configuration is written to. The default + name is C:\CONFIG.SYS. + + cOmpare: + Alt= will compare the current configuration with the contents of + the current AUTOEXEC and CONFIG files. It should be noted that, + if you are using the MENU.CTL device driver option, this + comparison will probably not be applicable. + + boot Type: + F5 will pop up a window to allow you to change the boot type + associated with a configuration. The choices are Warm, Cold, + None, and External. + + Flush: + F4 will pop up a window that will allow you to associate a + cache Flush command with the current configuration record. This + is necessary when the cache used in the configuration does a + write cache operation (PC-KWIK and PCTOOLS both default to this + configuration). + + cLone: + AltC will allow you to clone (or copy) the contents/control + of one of the other configurations to the current + configuration. It will pop up a pick list of all of the + existing configurations, and allow you to pick the one to copy + from. + + If you are using the AutoCon environment variable, you will + need to edit the AUTOEXEC file, and make sure the correct name + is used. + + Update: + ^K^S will save all current record changes to the AUTOCON.DAT + database file. Note that it will not update the AUTOEXEC and + CONFIG Files. You must use ^K^D for that. + + rEstore: + ^K^R will abandon all changes you have made (since the last + AUTOCON.DAT save) and reload the database records from the + AUTOCON.DAT file. + + + Boot Operation (Boot AltB): + + Single: + AltS configures AUTOCON to use only the current record for + reconfiguration purposes. + + Menu: + AltM configures AutoCon to use MENU.CTL in conjunction with + MENUNUM.COM to set up a selection menu to be used during the + boot process. A pick list of the current configurations will + be popped up, and you will be able to choose up to eight + default configurations to be included. After you have chosen + the eight, you will be asked how many seconds to delay during + the boot process. If a number other than 0 is entered, a + message will be placed on the screen during the boot process, + and MENU.CTL will wait that many seconds for a key to be hit. + + Boot Frame: + When booting under menu mode, MENU.CTL pops up some windows + and this selection allows you to change the color of the + window frames of those pop up windows. + + Boot Text: + When booting under menu mode, MENU.CTL pops up some windows + and this selection allows you to change the color of the text + in those pop up windows. + + Boot Attention: + When booting under menu mode, MENU.CTL pops up some windows + and this selection allows you to change the color of the text + used to draw your attention. This is the color of the + decrementing time variable, and the color that will be used + for warning messages. + + Boot Hi_Lite: + When booting under menu mode, MENU.CTL pops up some windows + and this selection allows you to change the color of the + moving selection hi-lite bar used to select a boot + configuration. + + + Editor options (Editor AltE): + + Internal: + ShiftF6 configures the current configuration to use the + internal editor. + + External: + ^F6 configures the current configuration to use an external + editor. A window will pop up asking for the editor's name. You + may include a path in the name, but you must include the + extension (e.g., WORD.EXE or C:\WORD\WORD.EXE). The next time + you edit the AUTOEXEC or CONFIG field for this record, if the + external editor can be found it will be used. If it can't be + found, AutoCon will switch back to the internal editor. + + After the external editor has been installed, it will be used + to edit the AUTOEXEC and CONFIG fields from the main screen. + When you move the cursor to the AUTOEXEC or CONFIG field and + press enter, AutoCon will copy the current record to the + current subdirectory as XYZXYZZ.XYZ (the current subdirectory + must contain at least 4k of disk space). AutoCon then shells + to DOS with the editor name and filename on the command line + (e.g., WS.EXE XYZXYZZ.XYZ). When you exit your editor, AutoCon + should restart. It will copy the XYZXYZZ.XYZ file into the + AUTOEXEC field of the current record and delete the XYZXYZZ.XYZ + file from the subdirectory. + + + CAUTION!! Just to make sure there is no problem with your + editor, create a new record and work with it first, before + taking the chance of harming one of your current records. You + may want to make a copy of your AUTOCON.DAT file and store it + in a safe place until you've verified the operation of the new + release. In fact, you should always keep a backup copy of + AUTOEXEC.DAT. + + + Install Keys: + F6 will pop up a window that will allow you to change the + keystrokes used in the internal editor. F6 may also be used + while in the internal editor to see exactly which key performs + which function. + + Save Keys: + This function is really added for future action (though it is + fully functional in this release). If you have modified the + keystrokes to emulate your favorite work processor, how about + saving them, then upload them to my BBS. + + Get Keys: + This function will allow you to change AutoCon's editor + keystrokes quickly by reading in a keystroke file. + + + coLors AltL: + + Frame: + AltF1 pops up a color pick window which allows you to change + the color of the frames drawn around the windows on the main + interactive screen. + + Frame Text: + AltF2 pops up a color pick window which allows you to change + the color of the text in the windows on the main screen. + + Background: + AltF3 pops up a color pick window which allows you to change + the color of the text and/or background of the main screen. + + Field: + AltF4 pops up a color pick window which allows you to change + the color of the fields that get updated on the screen, the + configuration name, the date and time, the record number, and + the select boxes. + + Prompt: + AltF5 pops up a color pick window which allows you to change + the color of the current select box. This is the color of the + main screen select item that the cursor is positioned to. + + Edit Text: + AltF6 pops up a color pick window which allows you to change + the color of the text used in the editor. + + Marked Text: + AltF7 pops up a color pick window which allows you to change + the color of the text used to show marked blocks in the editor. + + Ctrl Text: + AltF8 pops up a color pick window which allows you to change + the color used to show control characters (value < 20 hex) in + the edit text. + + Menu Frame: + This menu item allows you to change the color of the frame + around the pulldown menus. Note that there is no hotkey. + + Menu Text: + This menu item allows you to change the color of menu items in + the pulldown menus. Note that there is no hotkey. + + Menu Select: + This menu item allows you to change the color of the currently + selected item in the pulldown menus. Note that there is no + hotkey. + + Menu Hi-lite: + This menu item allows you to change the color of the Hi-lited + select character in the pulldown menus. Note that there is no + hotkey. + + Help fRame: + This menu item allows you to change the color of the Frame drawn + around the Help Window (also changes the color of one of the + basic Help Hi-Lite color). + + Help tExt: + This menu item allows you to change the color of the text in the + Help Window. + + Help heAder: + This menu item allows you to change the color of the Header on + the Help window. It will also be the default color of the Help + menu select color. + + Default: + AltF10 pops up a color pick window which allows you to + change all configurable colors back to the defaults. If your + screen goes black, hit AltF10 followed by the Y key, and you + may be able to see the screen again. + + + Quit AltQ : + + Configure: + F2 reconfigures the system. It will save any record changes in + the database file, and create new AUTOEXEC and CONFIG files. It + will then perform the requested reboot. + + Reboot: + This menu item will cause any record changes to be saved in the + database file, and force the default reboot action. Note that + there is no hotkey. + + Exit: + This menu item will save any record changes in the database + file and exit without any reboot action -- a rough equivalent + to hitting the ESC key. + + Abandon/Exit: + ^K^Q will cause any current record changes to be abandoned, and + AutoCon will exit without any reboot action. + + Restore Screen?: + This function can only be reached through the pull down menu. + If you set this to "NO", then AutoCon will not attempt to + restore the original screen on exit. Some video combinations + seem to have a problem with the restoration, so you can turn it + off. + + + Keys not in the Menu: + + AltV : + This key combination will show you the DOS screen as it was + when AutoCon was activated. + + + + + COMMAND LINE OPTIONS + + Environment: + For AutoCon to work correctly with the command-line commands, it + will need to know which configuration was used for the last boot- + up. There is only one sure way for AutoCon to get this + information: if you are using the Menu mode, MENU.CTL will be + able to tell AutoCon which configuration was chosen. + + If you are using the Single mode, to make sure that AutoCon knows + which configuration was used to boot, you need to add a line to + your AUTOEXEC fields. The line is as follows: + + SET AUTOCON= + + in which "configuration name" is the name that shows up on the + front screen in the interactive mode. To make it very easy, a + new key-stroke command was added to the editor. The default key + is AltE. Place your cursor at the position in the AUTOEXEC + field where your other SET commands are located, and press the + AltE combination. AutoCon will insert the proper line in the + file. + + + Reconfigure: + To reconfigure from the command line, type + + AUTOCON ENTER + [e.g., AUTOCON WIN3 ENTER] + + on the command line. As long as AUTOCON.EXE and AUTOCON.DAT are + in the path, the configuration will be updated, and your system + will be rebooted (depending on the current boot choice). + + Alternatively (if you don't want to type the update name), if you + type AUTOCON / ENTER + + AutoCon will pop up a pick list of your configurations, and you + can use the arrow keys to pick a reboot configuration. + + If the update name is the same as the last boot name (see note + above), you will be asked if you really want to do the update. + + + Configuration Inquiry: + Typing AUTOCON /? will cause AutoCon to display the name it + thinks is the current configuration. + + This will be most accurate if Menu mode is active. It should + also be quite accurate if each AUTOEXEC field has the correct + "SET AUTOCON=" command in it. + + If neither of the above applies, it will tell you which command + was last used to configure the AUTOEXEC and CONFIG files, which + may not be the configuration that was used for the last boot. + + + Specific Update: + Typing AUTOCON / ENTER + [e.g., AUTOCON /WIN3 ENTER] + + will cause the named configuration to be updated from the current + C:\AUTOEXEC.BAT and C:\CONFIG.SYS files (or your selected BAT and + SYS filenames). If MENU.CTL is in use, you will be asked if this + is really what you want to do. + + Generic Update: + For those of you who like to live dangerously (all of us from + time to time?), typing "AUTOCON /*" will update the current + configuration (the last one used to reconfigure) from the current + C:\AUTOEXEC.BAT and C:\CONFIG.SYS files (or your selected + filenames). This command will be ignored if the system was + booted with MENU.CTL. + + Equal Check: + Typing "AUTOCON /=" will report on whether or not the current + configuration record is equal to the current record in the + database. + + Batch File Errorlevel Check: + Typing "AUTOCON/@" will set the Errorlevel to + 1 if "" was the one used to boot the system. + This function will set the errorlevel only: there will be nothing + shown on the screen. For full accuracy, see the Environment note + above. + + + + NOTES AND HINTS + + + + Editor Keys: + + I will be enhancing the editor in the next release, so I'm not + going to expend a lot of energy on the Editor Help function in + this one. To find which key does what when you are in the + editor, hit F6 and you will see each action the editor is + capable of and the key assigned to that action. You may also + change the default keys while in this mode. The next release + will add pulldown menus and a much better Help section to the + editor. + + If you are unable to call up the Edit Key function while in the + editor, go back to the main screen, hit F6 to pop up the key + editor, hit END, and you will see a function called Install + Editor Keys. Assign the default F6 key to this function -- or + any other key you like. If you assign another key, the F6 key + will still call up the editor from the main screen, and the + assigned key will work inside the editor. + + + Boot Notes: + + Versions of AutoCon before 2.0 allowed one boot choice for all + configurations. From this version on, you will be able to + select a boot choice for each configuration. + + AutoCon is initially configured with a warm (or soft) reboot. + Some machines have a problem with the warm boot (usually those + with a large hard disk, and a large hard-disk partition + manager) and need a cold boot instead. If you have a reboot + problem, hit F5 and change to a cold boot. This change will be + saved in the AUTOCON.DAT file, and AutoCon will perform a cold + boot (you'll see the memory being checked) in the future. + + Some hardware is so strange (or the software has put the CPU + into such a strange state -- Windows 3 386Enhanced mode) that + even a software cold boot doesn't suffice. If this is the + case, then hit F5 and change to no boot. This last will + require hitting ^AltDel after AutoCon is finished. + + A couple of add-in processor cards (plugging a 286 expansion + card into an XT) come with their own reboot program, and some + people have developed their own reboot utilities to handle + special hardware and/or software needs. For these people, + there is another choice for rebooting. They will need to hit + F5 and change to an External Boot. You will need to enter the + program name that performs your reboot. + + + BAT and SYS Files: + + AutoCon is initially configured to copy the AUTOEXEC and CONFIG + fields to the C drive. For various reasons, some people do + their real boot from a drive other than C. The F8 key will + allow you to change the designated drive (and file name) the + AUTOEXEC field is copied too. The F9 key performs the same + function for the CONFIG field. The new destination files will + be saved to the AUTOCON.DAT file, and used in all future + configurations until you change them again. + + Starting with this version, the BAT and SYS files will be set + with each configuration. Until I make some large changes in + the next version, this will allow you to edit (and keep a + database of) files other than the AUTOEXEC and CONFIG. + + LCD Users: + + If you have a computer with an LCD screen, set your mode to + BW80 (this is mode 2 for you technical people) before starting + AutoCon; that should make the screen show up better. If you + prefer, you can start in color mode, and edit the colors to + something you find suitable. + + Screen Information: + + When you are in the data-entry mode, you have some information + on the screen. The top line has the current date and time, as + well as the name and version of the program. The second line + has the information on the current record, specifically the + record number, and the date and time it was last changed. The + middle of the screen has an area for notes, so that you can + keep track of what this particular record is used for. The + bottom two lines contain help information for the current mode. + + The % on the bottom line of the note frame and of the + edit frame indicates the how full the field is. An empty note + field is 0% full. As you add note characters, the percentage + will increase. (I've had some people ask.) + + The bottom line has some status information about the current + defaults. The first word on the line will be MENU.CTL or + SINGLE. This indicates whether you are using the device driver + to select a configuration during the boot, or whether only a + single configuration is available. + + The second word is either Internal or External; that indicates + whether the internal or the external editor is to be used for + this configuration. The next term is either Flush or No Flush; + that indicates whether or not a Cache Flush command will be + performed for this configuration. The Next word tells what + type of boot will be performed for this configuration; the word + will be either Warm, Cold, None, or External. There may or may + not be a last word. If this record will be one of the default + records used with MENU.CTL, then "Selected" will be written on + the screen. + + + Old Configurations: + If you want to use some configurations you have already + defined, and you are using the internal editor, you may read + them in directly. While in the AUTOEXEC or CONFIG edit mode, + if you hit F5 it will erase the contents of this field, but it + checks with you first. If you then hit ^K ENTER, you will be + given a chance to enter a file name to read into the field. If + you use wildcard notation, AutoCon will pop up a file list for + you to choose from. The selected file name will then be read + into the current field. Do one of the standard exit commands + (AltX, ^K X) and the field now contains the file. + + Do this for each of your current configurations, and you will + now have the convenience of AutoCon with all your standard + configurations. + + Alternately -- especially for those of you using an External + editor -- you may read in a file from the main screen. The ^F8 + key combination will allow you to specify a file name to copy + into the current AUTOEXEC field, and ^F9 performs the same + function for the CONFIG field. + + + LZEXE: + A new program from France has shown up on the scene; it is + called LZEXE. If you use it on AUTOCON.EXE, it will reduce the + size about fifty percent. I am distributing the AUTOCON.EXE + file in the LZEXE format. If you have an XT compatible + machine, then AutoCon may run too slow for you in this format. + If this is the case, you can use the program UNLZEXE to restore + it to its uncompressed format. Both LZEXE and UNLZEXE are + included as a bonus on the registered disk. + + + PKLITE: + Phil Katz has also written a program which will reduce the size + of program files. It is also completely compatible with AutoCon. + + DIET: + There is also a Japanese file compressor called DIET. AutoCon + has also been tested and found compatible with DIET. + CONTACT + + + If you have a problem getting AutoCon set up, or if you find a bug + please let me know immediately. The primary ways to contact me + are to call my office at (916) 623 5045 or (if you have a modem) + my 24 hour BBS at (916) 623 4455. The modem on the BBS is a + 9600 BAUD CompuCom Speedmodem Star. It supports CSP, V32, and V42 + protocols. + + You may also contact me on CompuServe at 72460,3072 or on GEnie + as L.WEAVER1. I check them both at least once a week, and I'm + quite often on CompuServe two or three times a week. + + I'm also open to suggestions for improving AutoCon. A lot of the + current features have been the result of requests made by my + users. + + + + FUTURE + + I think that AutoCon is maturing as a program, and that its + direction is becoming clear. It has changed so much from the + original release that I doubt anyone running version 1.0 would + recognize it as the same program. + + Where is AutoCon going in the future? Well, I have several ideas + in mind for enhancements. You will also have a hand in the + future directions. I have discovered that I can't anticipate all + of your needs. You will have to tell me what changes and + enhancements you would most like to see. + + The biggest set of enhancements I have in mind will concern the + editor. I had a lot of ideas for this release which did not pan + out; you can check the Changes file for the reasons why. I will + add a pulldown menu system to the editor, and give it + split-screen capability. + + I hope to reduce the size as well. Now that AutoCon is approaching + its final form, I can start to optimize a lot of the code in it. + + + LICENSE + + + + This version of AutoCon is NOT public-domain nor free software, + but is being distributed as shareware. + + AUTOCON is copyright (c) 1989-92 by Larry Weaver. + + Non-registered users of this software are granted a limited + license to make an evaluation copy for trial use on a private, + noncommercial basis, for the express purpose of determining + whether AutoCon is suitable for their needs. At the end of this + trial period, you should either register your copy or discontinue + using AutoCon. + + What does all this really mean? If you use this program, then + you should pay for your copy. That way I'll be able to provide + you support and updates, and stay in business. + + An AutoCon registration entitles you to use the program on any + and all computers available to you. + + All users are granted a limited license to copy AutoCon only for + the trial use of others and subject to the above limitations. + This license does NOT include distribution or copying of this + software package + + (a.) in connection with any other product or service, + (b.) for general use within a company or institution, or + (c.) for distribution in modified form, i.e., the file containing + this license information MUST be included, along with the + full AutoCon documentation. + + Operators of electronic bulletin board systems (Sysops) are + encouraged to post AutoCon for downloading by their users, as + long as the above conditions are met. + + If you are the distributor of a public-domain or user-supported + software library, you may be eligible to distribute copies of + AutoCon. You must meet all the above conditions and acquire + written permission from Larry Weaver before doing so, however. + Please telephone or write for details. + + + ASP Requirement + + The program author, Larry Weaver, is an active member of the + Association of Shareware Professionals (ASP). The ASP wants to + make sure that the Shareware principle works for you. If you are + unable to resolve a Shareware-related problem with an ASP member + by contacting that member directly, ASP may be able to help. The + ASP Ombudsman can help you resolve a dispute or problem with an + ASP member, but he does not provide technical support for + members' products. Please write to the ASP Ombudsman at + 545 Grover Road, Muskegon MI 49442, or send a CompuServe message + via EASYPLEX to ASP Ombudsman 70007,3536. + + + DISCLAIMER + + Larry Weaver hereby disclaims all warranties relating to this + product, whether express or implied, including without limitation + any implied warranties of merchantability or fitness for a + particular purpose. Larry Weaver cannot and will not be liable + for any special, incidental, consequential, indirect, or similar + damages due to loss of data or any other reason, even if Larry + Weaver or an authorized Larry Weaver agent has been advised of + the possibility of such damages. In no event shall the liability + for any damages ever exceed the price paid for the license to use + this software, regardless of the form and/or extent of the claim. + The user of this program bears all risk as to the quality and + performance of the software. Use of this program acknowledges + this disclaimer of warranty. + + + + ORDERING INFORMATION + + An AutoCon registration licenses you to use the product on a + regular basis. Users need register only one version of AutoCon; + registration includes licensed use of all upgrades. Registered + users can always get the current version of the program at a + nominal fee ($8.00 as of this writing) by calling or writing + Larry Weaver. Individual registrations for AutoCon cost only + $15. + + CORPORATE SITE LICENSES AND QUANTITY PURCHASES + + All corporate, business, government, or other commercial users of + AutoCon must be registered. A site license is available for a + one-time charge of $120.00 for the first one hundred (or fewer) + users/machines fewer) and $100 for each additional one hundred + (or fewer) users/machines. + + Note: with a site license (if you also purchase the upgrade), + only one copy of the program will be sent. You will be + responsible for distributing additional copies. + + ALL PRICES ARE SUBJECT TO CHANGE WITHOUT NOTICE. + + + Please use the enclosed order form when placing an order, or print + out the file REGISTER.PRN. + + Even if you don't register, how about some feedback? + + You can reach me as + 72460,3072 on CompuServe, or as + L.WEAVER1 on GEnie, + (916) 623-4455 -- Support BBS. + + ------------------- REGISTRATION ---------------------- + + Please support AutoCon! + Thank you for your support. + +Remit To: Larry Weaver + P.O. Box 2639 + Weaverville CA 96093-2639 + + --------------------------- + + You must check one registration option, and one disk option! + + --------------------------- + _ +|_| AutoCon Standard registration ($15.00 -- no disk sent) $______ + _ +|_| AutoCon Site License and Registration (no disk sent) + $120.00 for the first 100 (or fewer) users or machines + 100.00 for each additional 100 (or fewer) users or machines $______ + + --------------------------- + _ +|_| AutoCon Upgrade to the newest version ($8.00; $10.00 foreign) $______ + Registered users only + _ +|_| Subscription plan for REGISTERED users ($21.00; $26.00 foreign) $______ + (Receive the next three updates of AutoCon, as they + become available. This fee is in addition to the + $15.00 or $120.00 registration.) + + --------------------------- + _ +|_| Printed Manual ($8.00) $______ + If you desire, I will print out the AUTOCON.DOC file and + send it to you. You can achieve the same results by printing + it out yourself, but several people seem to want this. + + --------------------------- + +"Foreign" means outside the USA and Canada; the extra charge covers postage. + _ _ +Payment by: |_| Check or |_| Money Order enclosed. + +TOTAL in USA Funds. $______ + Foreign checks are acceptable if they have the US Federal Reserve + Routing Number on them, use the current exchange rate. + _ _ +Disk Type: |_| 5 1/4" (normally sent); |_| 3 1/2" required + +Name ___________________________________________________________________ + +Address ___________________________________________________________________ + + ___________________________________________________________________ + + ___________________________________________________________________ + + + Day Phone: _________________________ Eve: ______________________ + + Compuserve ID: _____________________ + + _ + Invoice Required |_| P. O. Number: ______________________ + + ------------------------ User comments ------------------------- + I acquired AutoCon V2.0g from + [ ] - Friend [ ] - Software product + [ ] - Computer Club [ ] - Computer Store + [ ] - Data Base Service [ ] - Support BBS + [ ] - Electronic BBS - Please give phone no. _____________ + [ ] - Other (please specify) ___________________________ + + I would also appreciate any input you would care to provide + concerning AutoCon. If you have any ideas or comments which would + make AutoCon a better program, please let me know. + + I value your comments! + + Comments and/or suggestions: + ________________________________________________________________ + + ________________________________________________________________ + + ________________________________________________________________ + + ________________________________________________________________ + + ________________________________________________________________ + + ________________________________________________________________ + + ________________________________________________________________ diff --git a/Linux-0.96/INSTALL/autocn/AUTOCON.EXE b/Linux-0.96/INSTALL/autocn/AUTOCON.EXE new file mode 100644 index 00000000..9dfa0b7f Binary files /dev/null and b/Linux-0.96/INSTALL/autocn/AUTOCON.EXE differ diff --git a/Linux-0.96/INSTALL/autocn/AUTOCON.HLP b/Linux-0.96/INSTALL/autocn/AUTOCON.HLP new file mode 100644 index 00000000..705e7e33 Binary files /dev/null and b/Linux-0.96/INSTALL/autocn/AUTOCON.HLP differ diff --git a/Linux-0.96/INSTALL/autocn/CACHE b/Linux-0.96/INSTALL/autocn/CACHE new file mode 100644 index 00000000..925888db --- /dev/null +++ b/Linux-0.96/INSTALL/autocn/CACHE @@ -0,0 +1,34 @@ + +If you are running a Cache program, and do not have it set to write +through, then (if you have Autocon set for a Warm or Cold boot -- and +probably External) you must configure Autocon to "Flush" your cache. +Hit the key, and put in the command string that causes your cache +to flush. The command should be listed in the documentation for your +Cache program. Autocon will then save the information, and perform a +"Flush" before each reboot. + +If you are not sure if your Cache is set to "write through", please +configure Autocon to do the "Flush", just to be on the safe side. + +The symptoms of a cache problem is that the Autoexec and Config files do +not get updated, and/or any edited Autocon configurations do not get +saved. In the worst case, the Autocon.Dat file will get corrupted, and +your screen colors will disappear (screen will be blank when you start +AutoCon). + +Setting Autocon up to do the "Flush" will remove the problems. + +Some Flush commands that I know are: + + PC-KWIK - SUPERPCK /F + PC-CACHE - PC-CACHE /FLUSH + FLASH - FLASH /F? + HYPERDISK - HYPERDK W + SMARTDRV - SMARTDRV /C (new ver with WINDOWS 3.1) + + + +Sorry for any inconvenience, + + + -Larry Weaver diff --git a/Linux-0.96/INSTALL/autocn/CHANGES b/Linux-0.96/INSTALL/autocn/CHANGES new file mode 100644 index 00000000..03775362 --- /dev/null +++ b/Linux-0.96/INSTALL/autocn/CHANGES @@ -0,0 +1,61 @@ + + CHANGES + + I don't know if you read the changes file in the previous version, + so I will summarize it. I sold my home in Santa Barbara, and moved + to a small town in Northern California to concentrate on writing + shareware full time. Well (you may ask), how's it going. + + Since my program was reviewed on page 50 in the Nov. 13, 1990 issue + of PC Magazine, registrations have increased significantly. + Appearantly a lot of people read (and pay attention to) PC + Magazine. Site registrations have really increased, and I now have + some Fortune 50 customers. Banks, however, make up the bulk of + the Site Licensees. + + I ran into a few tax problems (it was either pay Uncle a lot of + money, or put a lot of money into my house), so I've been + consulting pretty heavily the last year and doing major + reconstruction to my house. I think I am finally through with any + big consulting jobs (and with rebuilding my house), so now AutoCon + will be getting a lot more attention. + + This is still not the release I had planned (it will probably show + up some time around July), but one of my competitors was on + Compuserve saying how much better he was than I because his program + could handle DOS 5.0's HIGH and UMB flags. I decided I needed to + add this capability to AutoCon and get out a new release before he + could cause any more problems. So with this release, AutoCon will + handle both MSDOS 5.0's HIGH and UMB flags, and it is compatible + with DRDOS which is one up on my competitor. + + The 2.1 release of AutoCon will have a lot more editor + enhancements. I'm planning pull down menus (similar to the front + screen), and a split screen capability. I also intend to allow + Search/Replace operations to go automatically through all + configurations. I will also be able to use the screen size in + effect when AutoCon is started, instead of switching everything to + the 80X25 mode. + + I have a support BBS online and functional. The number is (916) + 623 4455, and it is in operation 24 hours a day. It has a 9600+ + BAUD modem that is CompuCom CSP, V32, and V42 compatible (of course + it connects just fine at 2400 BAUD). The main function + of the BBS is (of course ) AutoCon support. If it gets busy + enough, it will grow into a full multi-line BBS. As a consequence + there are several megabytes of downloadable files on it, always + including the latest shareware release of AutoCon. I will also set + up a section for a group of Beta testers, so let me know if you are + interested in becomming one. I see several enhancements in + AutoCons future, as well as a few other programs that I have in + mind. + + This is my first BBS and I'm sure there will be will be some + growing pains, so please bear with me. + + I love the place I've moved to and I thank you very much for the + support you have given to AUTOCON, and for giving me the incentive + to change careers. + + + -Larry Weaver diff --git a/Linux-0.96/INSTALL/autocn/FILE_ID.DIZ b/Linux-0.96/INSTALL/autocn/FILE_ID.DIZ new file mode 100644 index 00000000..e8745208 --- /dev/null +++ b/Linux-0.96/INSTALL/autocn/FILE_ID.DIZ @@ -0,0 +1,8 @@ +AutoCon V2.0g is a database manager for +Autoexec and Config Files. Allows up to +50 configurations, and makes switching +between them easy. Run full interactive +(editor, mouse, menus, context sensitive +help, etc.) or command line. MENU.CTL +device driver can setup menu of +configurations during boot. (ASP) diff --git a/Linux-0.96/INSTALL/autocn/KEY.TXT b/Linux-0.96/INSTALL/autocn/KEY.TXT new file mode 100644 index 00000000..6d8bf000 --- /dev/null +++ b/Linux-0.96/INSTALL/autocn/KEY.TXT @@ -0,0 +1,175 @@ +The following is a list of the all of the editor functions, and the +default key assignments. + + CURSOR MOVEMENT: + , + Cursor left one character. + + , + Cursor right one character. + + , + Cursor left one word. A 'word' is a series of non-separator + characters followed by one or more of the following : + ' ', ';', '/', '=' + + , + Cursor right one word. + + , + Cursor to beginning of line. + + , + Cursor to end of line. + + , + Cursor up one line. + + , + Cursor down one line. + + + Scroll display up one line. + + + Scroll display down one line. + + , + Scroll display up one page. + + , + Scroll display down one page. + + , + Move cursor to top of edit window. + + , + Move cursor to bottom of edit window. + + , + Move cursor to beginning of field. + + , + Move cursor to end of field. + + , + Move the cursor to the next tab stop. + + + Move the cursor to the position indicated by the mouse. + + DELETE FUNCTIONS: + , + Delete character at cursor. + + , , + Delete character to left of cursor. + + + Delete current line. + + + Delete from cursor to end of line. + + + Delete word to right of cursor. + + NEW LINE: + , + Start a new line. + + + Split the current line at the cursor. + + DEFAULT CONTROLS: + + Insert control character. For example, to insert a ^G, you + would enter . + + + Toggle insert mode on and off. Fat cursor indicates insert + mode; thin cursor indicates overtype mode. + + + + Toggle auto-indent mode. In auto-indent mode, pressing + in insert mode causes the new line to have the same + indentation as the previous line. Auto-indent also affects + the way that text is formatted when word wrap occurs. + + + Reformat the current paragraph. Use with caution. + + + Reformat the entire field. Use this command with caution. + + + Restore original contents of the line and continue editing. + + SAVE COMMANDS: + , , , , + + Quit editing and abandon changes (With Question). + + , + Save the data, but continue editing. + + , , , + Save the data (if modified), and quit editing. + + BLOCK COMMANDS: + , , + Begin a block mark. End a block mark. + + + Copy a marked block. Move a marked block. + + + Delete a marked block. Delete Contents of Entire field. + +

+ Put marked block in buffer. Copy cUt buffer to Fieeld. + Allows moving data between records. + + + Write the Marked Block to the selected file name. + + + Read the selected file name into the edit field. You can + popup a file list and use a point and shoot select + + + SEARCH COMMANDS: + + Pops up a window for you to enter a string of text to search for. + The string remains valid across all records until it is changed with + another search function. + + + Pops up a window for you to enter a string of text to search for, + then pops up a window for you to enter a string of text to replace + the search string with. You will be asked to confirm the + replacement. The strings remain valid across all records until it + is changed with another search function. + + + Repeats the last Search(/Replace) function without going through the + exercise of entering new strings. + + MISCELLANEOUS COMMANDS: + + , + Help. This command invokes the help routine for this topic + if it exists. Otherwise it does nothing. + + + Pops up a key edit window to allow chaging all of the editor key + assignments. + + + Creates a "SET AUTOCON=" command for the + Autoexec field. If each Autoexec has the correct one, the name of + the boot configuration will be in the environment. + + , , + Changes the keys assigned to change the colors used in the editor. diff --git a/Linux-0.96/INSTALL/autocn/MENU.CTL b/Linux-0.96/INSTALL/autocn/MENU.CTL new file mode 100644 index 00000000..34f26180 Binary files /dev/null and b/Linux-0.96/INSTALL/autocn/MENU.CTL differ diff --git a/Linux-0.96/INSTALL/autocn/MENUNUM.COM b/Linux-0.96/INSTALL/autocn/MENUNUM.COM new file mode 100644 index 00000000..c618398c Binary files /dev/null and b/Linux-0.96/INSTALL/autocn/MENUNUM.COM differ diff --git a/Linux-0.96/INSTALL/autocn/REGISTER.PRN b/Linux-0.96/INSTALL/autocn/REGISTER.PRN new file mode 100644 index 00000000..9cd133cd --- /dev/null +++ b/Linux-0.96/INSTALL/autocn/REGISTER.PRN @@ -0,0 +1,94 @@ + ------------------- REGISTRATION ---------------------- + + Please support AutoCon! + Thank you for your support. + +Remit To: Larry Weaver + P.O. Box 2639 + Weaverville CA 96093-2639 + + --------------------------- + + You must check one registration option, and one disk option! + + --------------------------- + _ +|_| AutoCon Standard registration ($15.00 -- no disk sent) $______ + _ +|_| AutoCon Site License and Registration (no disk sent) + $120.00 for the first 100 (or fewer) users or machines + 100.00 for each additional 100 (or fewer) users or machines $______ + + --------------------------- + _ +|_| AutoCon Upgrade to the newest version ($8.00; $10.00 foreign) $______ + Registered users only + _ +|_| Subscription plan for REGISTERED users ($21.00; $26.00 foreign) $______ + (Receive the next three updates of AutoCon, as they + become available. This fee is in addition to the + $15.00 or $120.00 registration.) + + --------------------------- + _ +|_| Printed Manual ($8.00) $______ + If you desire, I will print out the AUTOCON.DOC file and + send it to you. You can achieve the same results by printing + it out yourself, but several people seem to want this. + + --------------------------- + +"Foreign" means outside the USA and Canada; the extra charge covers postage. + _ _ +Payment by: |_| Check or |_| Money Order enclosed. + +TOTAL in USA Funds. $______ + Foreign checks are acceptable if they have the US Federal Reserve + Routing Number on them, use the current exchange rate. + _ _ +Disk Type: |_| 5 1/4" (normally sent); |_| 3 1/2" required + +Name ___________________________________________________________________ + +Address ___________________________________________________________________ + + ___________________________________________________________________ + + ___________________________________________________________________ + + + Day Phone: _________________________ Eve: ______________________ + + Compuserve ID: _____________________ + + _ + Invoice Required |_| P. O. Number: ______________________ + + ------------------------ User comments ------------------------- + I acquired AutoCon V2.0g from + [ ] - Friend [ ] - Software product + [ ] - Computer Club [ ] - Computer Store + [ ] - Data Base Service [ ] - Support BBS + [ ] - Electronic BBS - Please give phone no. _____________ + [ ] - Other (please specify) ___________________________ + + I would also appreciate any input you would care to provide + concerning AutoCon. If you have any ideas or comments which would + make AutoCon a better program, please let me know. + + I value your comments! + + Comments and/or suggestions: + ________________________________________________________________ + + ________________________________________________________________ + + ________________________________________________________________ + + ________________________________________________________________ + + ________________________________________________________________ + + ________________________________________________________________ + + ________________________________________________________________ diff --git a/Linux-0.96/INSTALL/autocn/WHATSNEW b/Linux-0.96/INSTALL/autocn/WHATSNEW new file mode 100644 index 00000000..38116aa8 --- /dev/null +++ b/Linux-0.96/INSTALL/autocn/WHATSNEW @@ -0,0 +1,441 @@ +Version 2.0g + I still had complaints about people seeing Echo Off in the Autoexec + Bat file, so now if you have a DOS higher than 3.2, it will start + with @Echo off. + + If you are using DOS 5.0, A DOS=HIGH,NOUMB line will be appended to + the bottom of the Autoexec.bat file, and you will have to put a + DOS=LOW (and/ or a DOS=UMB) in the configurations you need them in. + Menu.Ctl will control the flags. + + If you are using DRDOS, Menu.Ctl will now work with it as well as + MSDOS. + + I've changed the way I load configurations, so you will be able to + run AutoCon with less memory, and there is no longer a 6K or 2K + limit on the Autoexec and Config fields. + + Each configuration now has the names of the files that the field is + written to. (I've had several requests for this one.) + + The help screen colors are now installable. + + The MENU.CTL interface has been rewritten to show up more distinctly + when booting. I had several complaints that it was easy to miss. + It will now put up some distinctive boxex, and show up in color if + you have a color monitor. The colors are installable from AutoCon. + + Each configuration now has the names of the files that the field is written + to. (I've had several requests for this one.) + + You can tell AutoCon not to restore the screen on exit (eliminates the + need for AutoConx.exe. + + +Version 2.0e (mainly bug fix) + In Single mode if the Enviornment name wasn't set (AltE in the + editor) AutoCon could get the wrong cache 'Flush' information. This + is fixed, but I highly reccommend setting the Autocon Environment + variable if you are using Single mode. + + If an external editor were being used, and the Autocon or Config + field size got too large, the AutoCon.Dat file could get messed up - + fixed. + + Several people have complained that 4K and 2K is not large enough + for the Autoexec and Config fields, so I'm pushing the size up to 6K + and 4K. Please note that this adds 4K/configuration to AutoCon's + memory requirements. + + There are two extra EXE files on the BBS. AutoCons.exe will still + use 4K and 2K for those needing the smaller memory requirements. + + AutoConx.exe will not restore the screen when it exits. Try this if + you lose the cursor or the screen blanks out when you exit (I've had + two complaints about this). + +Version 2.0d (bug fix) + If AutoCon followed an "ECHO OFF" and a "CLS" statement in a batch + file, the screen could get slightly messed up - fixed. + +Version 2.0c (bug fix) + The user modified colors were getting lost if a reboot was performed + from the command line - fixed. + +Version 2.0b (bug fix) + + MENU.CTL had a problem with the name of the eighth configuration, + which is now fixed. It also had a tendency to leave menu choice 2 + in the hi-lite mode, also fixed. + + Several people complained about seeing the Errorlevel statements in + the AUTOEXEC.BAT during the boot process. AUTOEXEC.BAT files will + now start with ECHO OFF as the first statement if you choose the + MENU.CTL option. + + Version 2.0 would allow you to choose more than the eight default + configurations. This is no longer allowed. + + Version 2.0 had a problem writing the AUTOEXEC.BAT file for the Menu + mode if the Autoexec fields didn't end in a Carriage Return. This + is now fixed. + + +Version 2.0 + + + I'm jumping the version number from 1.4 to 2.0 for this release. + The reason is that AutoCon's capability has changed so much in this + release that I think it warrants a Major revision number change. + + The major change is the inclusion of two new files. These are + MENU.CTL and MENUNUM.COM. Menu.Ctl is a device driver that can + disable commands in the CONFIG.SYS file. MenuNum.Com is a file that + will ask the portion of Menu.Ctl that stays resident which + configuration was chosen, and set the DOS ERRORLEVEL to that number. + This allows setting up menu choices in the AUTOEXEC.BAT file to + match the choice made from the CONFIG.SYS file. Together these two + files allow you to choose a system configuration from a menu of + configurations during the boot process itself. + + AutoCon will handle all of the interface details to these two + commands for you, and allow you to return to a "Normal" system + configuration in just a couple of keystrokes. This will allow you + to run programs like "Optimize" from Quarterdeck. + + + There is a pull-down menu system available on the main screen. Each + item on the menu has a context sensitive help entry. This should + make it very easy to get AutoCon up and running the first time, and + allow you to look up those commands you can't remember the + keystrokes for. + + + There are two new command line options. If you enter + + AutoCon / + + on the command line, a window of your configurations will pop up + asking you to choose which configuration you wish to use to reboot + the system. This is equivalent to the "AutoCon , + except that AutoCon lets you choose the name from a pick list. + + The second new command is + + AutoCon /@ + + where is the name shown on the main screen for + each configuration. If the name matches the configuration that was + used for the boot process, the DOS errorlevel will be set to 1. It + will be set to 0 otherwise. For this function to work correctly, + you need to boot up with Menu.Ctl, or assure that each Autoexec + field has the correct name assigned with a SET command. See the new + "Put Name in Environment" editor function defined below. + + + The internal editor has a few new capabilities. In order to access + most them you will have to edit your keystrokes (using the F6 key). + The block operations are no longer constrained to full lines. The + default keys for reformating were removed. You may reassign them. + + "Search Function" (default assigned to ^Q^F) allows you to search + the text for a specified string of text. The string is active for + the entire AutoCon session, and will be the same across records. + + "Search/Replace Function" (default assigned to ^Q^A) allows you to + search the text for a specified string of text, and relpace it + with another string of text. You will be asked to confirm the + replacement. + + "Repeat Search Function" (default assigned to ^L) This will + repeat the last Search, or Search/Replace that was performed. The + informations is retained during the AutoCon session, and will be + the same across records. + + "Install Editor Keys" (default assigned to F6) allows you to + change the editor keys during an edit session. + + "Put Name in Environment" (default assigned to AltE) will put a + SET command in your edit field. This will guarantee that the + configuration you are editing has its name placed correctly in the + environment. AutoCon will use this name for various command line + functions. + + "Change (Text - AltF6, Block - AltF7, Control Char - AltF8) + Attribute" will allow you to change the keys that call up the + editor color installation windows. + + "View Last Dos Screen" (default assigned to AltV) allows you to + see the DOS screen as it was when AutoCOn was started. Could be + useful if the reason your changing a configuration is shown there. + + + By March 1, 1991 I will have a support BBS in place operating 24 + hours a day. The number will be (916) 623 4455. + + +Version 1.4 + + One of the WhatsNews has to do with me, I am now a member of the ASP + (Association of ShareWare Professionals). The rest of the WhatsNews + all concern changes (and additions) to the program. + + You now have the option to use the built in editor to edit the + Autoexec and Config fields, or to install an external editor to do + the job. will pop up a window for you to enter an external + editor's file name. The Path will be checked for the entered file + name, and if found, it will be used to edit the Autoexec and Config + fields in the future. For more info, see the "Installing External + Editor" section of AUTOCON.DOC. + + From the command line, typing will check the Autoexec + and Config fields of the current configuration record against the + file contents of the current Configuration files (usually + C:\AUTOEXEC.BAT and C:\CONFIG.SYS). The results of the comparison + will be shown on the screen. SPECIAL NOTE! - the configuration will + need to have been saved with the 1.4 version of AUTOCON. + + From the command line, typing will update the Autoexec + and Config fields of the current configuration record from the file + contents of the current Configuration files (usually C:\AUTOEXEC.BAT + and C:\CONFIG.SYS). You might want to be a little careful with this + one. + + The internal editor has a few new capabilities. In order to access + them, you will probably have to edit your keystrokes (using the + key). The new commands are "Split Line", "Cut the marked block", + and "Paste the last Cut block". These commands will be a little + more convenient than the current "Write marked block" and "Read + marked block" file commands. + + "Split Line" (default assigned to key) splits the current + line at the cursor, leaving the cursor where it is, and moving the + rest of the line down to the next line. + + "Cut the marked block" (default assigned to key + combination) will put the current marked block into a text buffer. + "Paste the last Cut block" (default assigned to

key + combination) will paste the contents of the cut buffer to the + current cursor location. This command can be used to move the + data in the same record, or across records. After a cUt, the data + will stay in the buffer until a new cUt is performed, or AUTOCON + is exited. + + Formerly the editor only recognized a ' ' (space) as a word mark + (for , , , etc.). This has been enhanced + to also recognize the following characters as word marks : + '/', ';', and '='. + + Line length was increased to 254 for those long path names (and + any other long lines needed). This necessitated removing the + word-wrap capability while editing the Autoexec and Config + fields (I don't think this will be a hardship, you probably don't + want to word-wrap the lines in your Autoexec and Config files + anyway). Word-wrap is still used in the Notes field, but please + don't enter a line longer than 127 characters in there. + + + A couple of functions were also added to the Interactive Mode. + + will pop-up a pick list of the current configuration + records, and allow you to select one. The contents of the + Autoexec and Config fields of the selected configuration record + will be copied to the current configuration record. Be careful + with this one, there is NO "Undo" command. You can always + use ESC to get out of the pick list without doing a copy. + + will now show the Dos screen as it was when Autocon was + started. + + will check the Autoexec and Config fields of the current + configuration record against the contents of the current + configuration files (C:\AUTOEXEC.BAT and C:\CONFIG.SYS, unless you + have changed them with or keys). SPECIAL NOTE! - the + configuration will need to have been saved with the 1.4 version of + AUTOCON. + + All of the color changes now show up instantly (you previously had + to wait till the next time Autocon was executed to see some of the + color changes). + + ESC is no longer accepted as a "Yes" answer (there were a lot of + complaints on this one). A "Yes" answer now requires a or + key (accept default). + + There are a few cosmetic changes on the screens (all in response to + comments by users). I won't take the space to list each one. + + There are a couple more entrys on the help screen, and (I hope) the + entries are arranged in a little more logical fashion. + + UltraVision : Autocon is now UltraVision "Aware". Autocon will + detect if UltraVision is installed and active. If it is, Autocon + will use UltraVision to switch modes, and restore screens (in other + words, Autocon won't mess up your screen). + + Windows Problems : After spending a very unproductive day on the + phone with Microsoft, I decided to add another boot type option to + Autocon. Several people use Autocon to reconfigure in and out of + Windows. When Windows is running in 386 enhanced mode, a software + boot (usually) doesn't work. Microsoft's recommendation : "Never + reboot while running Windows". They say that this may trash hard + disks and worse (I'm not sure what could be "worse" than trashing a + hard disk). I don't know about you, but I've had to reboot out of + Windows several times. I know it's probably not a good idea, but + there are times it should be quite safe (and times when it is forced + upon us). Anyway, they say that is no way they are aware of to + ensure that a software reboot will work. + Therefore : + + You may now select (N)one as an alternate boot type (using the + key). If you select (N)one, Autocon will now reconfigure the + files, but will not attempt a reboot. Now you may run Autocon + under Windows, and after the system files are reconfigured, you + can hit the dreaded CtrlAltDel key combination. + + By the way, I'm not much of an artist, so if someone (out of the + goodness of their hearts) designs a nice Icon for Autocon, I would + appreciate them sending me a copy. + + + A potentially nasty bug was squashed. Since I never received a + complaint on this one, I assume that I was the only one "bit". If + your current configuration record was the last one, and you deleted + it, Autocon tried to find it again the next time it was started. + This could lead to bizarre behavior (a messed up pointer for those + technical people). If the current record number is larger than the + max record number, it will now be adjusted (with appropriate warning + message). It will still be pointing to the wrong record, but it + will behave in a known fashion. + + ______________________________________________________________________ + +Version 1.3a + + There are a few bug fixes, and a couple of enhancements in this + version. If you used F2 to save changes in the previous versions, + when you hit ESC to exit it would issue a warning that the changes + were about to be lost, this has been corrected. + + AUTOCON will now attempt to detect and restore the EGA/VGA (45/50) + small character mode upon exit. + + After updating the configuration with 1.3a, when AUTOCON is started + in the interactive mode, it will default to the configuration used + in the last update. + + On the command line if you type the name of the current + configuration will be displayed (Note: you must have saved a + configuration with V1.3a first). + + If you are in the full screen entry mode, hitting will update + the Autoexec and Config fields in the current record from the + current AUTOEXEC.BAT and CONFIG.SYS files. This saves going into + each of the two fields and doing a <^KR> . + + From the command line, typing AUTOCON followed by a / and the name + of a configuration (e.g. ) will cause that + configuration to have it's Autoexec and Config fields updated from + the current AUTOEXEC.BAT and CONFIG.SYS files. + + There was a bug in V1.3 that caused AUTOCON to have a problem with + reading files that were not terminated with ^Z. If you got an + "Edit Buffer Full" message when you tried to edit a field that you + know wasn't too big, then you were bitten by this bug. This is + fixed in 1.3a. + + If you were in one of the fields and issued an <^KW> (block save) + and didn't have a marked block, you were not given an error message + in previous versions. This is fixed in 1.3a. + + The help screen displayed in a color change window was the one for + changing the editor keystrokes. This is fixed in 1.3a. + + ______________________________________________________________________ + +Version 1.3 + + There are several changes in this version. If you have added + several extra configurations that you no longer need, the + key will delete the current configuration (you can't delete record + one, nor can you go below five records). + + You can change the keystrokes used by the built in editor. Hitting + the key in the main menu will pop up a key editor which will + allow changing the actions of all of the control keys used in the + editor. + + You can change the colors used by AUTOCON. Hitting the key in + combination with the function keys will allow customization of most + of the colors. The use of each key is detailed in the pop-up help. + + The DAT file format for 1.3 is quite different than the one for 1.2. + The white space has been eliminated, and as a consequence it is + significantly smaller (mine are about 1/4 the previous size). The + first time you run 1.3 it will change the format, and the DAT file + will no longer be compatible with 1.2. You may want to make a copy + of AUTOCON.DAT (just to be on the safe side) before running 1.3. + + + ______________________________________________________________________ + +Version 1.2d keeps current file attributes + + A request was made to update the Autoexec and Config files, but to + not change their current attributes (system, read only, hidden, + etc.). Therefore AUTOCON now reads the current file attributes of + Autoexec.Bat and Config.Sys before updating them, and restores the + attributes after the update. + + + ______________________________________________________________________ + +Version 1.2c adds a boot type select. + + Some computers have trouble with the warm boot that AUTOCON was + originally configured with. These seem to mainly be machines with + large hard disks, and a large hard disk manager. The key now + allows you to change the boot type from warm to cold to get around + this problem. + + + ______________________________________________________________________ + +Version 1.2a is a bug fix. + + AUTOCON didn't recognize more than three configurations from the + command line. + + +Version 1.2 is a bug fix. + + When you attempted to read in your old configuration files to the + AUTOEXEC and CONFIG fields, it always defaulted to C:\AUTOEXEC.BAT + an C:\CONFIG.SYS no matter what files you had selected. The read + file option now works correctly. + + + ______________________________________________________________________ + +Version 1.1 charges are as follows. + + 1. AUTOCON now does a Reboot when a reconfiguration is done from the + command line. + + 2. AUTOCON now handles up to 50 configurations (originally only 5). + + 3. You can now read any file into an AUTOEXEC or CONFIG edit field + (allows you to use your old configurations). + + 4. The On-line Help has been updated/enhanced. + + 5. The Doc file has been enhanced (left out a few things the first + time). + + 6. Allows you the choice of a Reboot when reconfiguring in the data + entry mode. + + 7. Hopefully a better choice of colors on an LCD screen. If you have + an LCD, you need to have your mode set to BW80 (2). + + diff --git a/Linux-0.96/INSTALL/autocn2g.zip b/Linux-0.96/INSTALL/autocn2g.zip new file mode 100644 index 00000000..3b0c1375 Binary files /dev/null and b/Linux-0.96/INSTALL/autocn2g.zip differ diff --git a/Linux-0.96/INSTALL/bootlin4.zip b/Linux-0.96/INSTALL/bootlin4.zip new file mode 100644 index 00000000..4fcd648d Binary files /dev/null and b/Linux-0.96/INSTALL/bootlin4.zip differ diff --git a/Linux-0.96/INSTALL/clock.tar.Z b/Linux-0.96/INSTALL/clock.tar.Z new file mode 100644 index 00000000..36739c6a Binary files /dev/null and b/Linux-0.96/INSTALL/clock.tar.Z differ diff --git a/Linux-0.96/INSTALL/pboot.exe b/Linux-0.96/INSTALL/pboot.exe new file mode 100644 index 00000000..835ebaa1 Binary files /dev/null and b/Linux-0.96/INSTALL/pboot.exe differ diff --git a/Linux-0.96/INSTALL/pboot.zip b/Linux-0.96/INSTALL/pboot.zip new file mode 100644 index 00000000..8584490e Binary files /dev/null and b/Linux-0.96/INSTALL/pboot.zip differ diff --git a/Linux-0.96/INSTALL/pfdisk/MAKE_TCC.BAT b/Linux-0.96/INSTALL/pfdisk/MAKE_TCC.BAT new file mode 100644 index 00000000..8466b230 --- /dev/null +++ b/Linux-0.96/INSTALL/pfdisk/MAKE_TCC.BAT @@ -0,0 +1,3 @@ +@echo This batch file uses Turbo C to build pfdisk.exe +@echo Note that only SMALL model has been tested... +tcc -v- -epfdisk.exe pfdiskaz.c syscodes.c s_msdos.c diff --git a/Linux-0.96/INSTALL/pfdisk/PFDISK.DOC b/Linux-0.96/INSTALL/pfdisk/PFDISK.DOC new file mode 100644 index 00000000..10fc307f --- /dev/null +++ b/Linux-0.96/INSTALL/pfdisk/PFDISK.DOC @@ -0,0 +1,264 @@ + + + + + +PFDISK(8) MAINTENANCE COMMANDS PFDISK(8) + + + + + +NAME + pfdisk - partition fixed disk + +SYNOPSIS + pfdisk device + +DESCRIPTION + pfdisk partitions the fixed disk identified as device into (at + most) four parts, each of which may be independently loaded with + an operating system. The actual name of device depends on the + operating system in use. For ESIX (System V/386) the device + name is either "/dev/rdsk/0s0" or "/dev/rdsk/1s0". For Minix, + it is "/dev/hd0" or "/dev/hd5". For MS-DOS it is a single digit + (zero or one). + + pfdisk reads the hard disk partition table from block zero of + device into memory and allows the user to examine, modify, or + save the partition table. A regular file may be used instead of + a real device for testing purposes, though the device geometry + must be specified manually, and some systems will requrire a + file-name argument with the "R" and "W" commands (DOS, ESIX). + + The partition table on device is NOT modified unless the write + command (W) is used with no argument. + +USAGE + Commands + All pfdisk commands consist of a command word followed by + optional blank-separated command arguments. Note that only the + first letter of a command word is significant (except for "wq" + and "q!"). All command letters are accepted in either upper or + lower case. Numeric arguments are specified using C syntax. + Extra arguments are silently ignored. + + The commands are: + + ? Prints a command summary (help). + + 1 sys_id first last sys_name + Set the partition table entry for part one, using: + sys_id as its system ID code, first as the lowest num- + bered cylinder it uses, last as the highest numbered + cylinder it uses, and sys_name (optional) as the system + name (in the menu name table). + + 2|3|4 sys-id first last sys-name + Similar to 1 but sets partition two, three, or four, + respectively. + + + + + +Release 1.3 Last change: Oct 1990 1 + + + + + + +PFDISK(8) MAINTENANCE COMMANDS PFDISK(8) + + + + + + A number + Mark partition number as active (so it will be used for + booting). If number is zero, no partition will be + active. + + G cylinders heads sectors + Inform pfdisk what the geometry of the device is. + + I Print a summary of the known ID codes. + + L List the partition table. See Output Format below. + + Q Quit without saving. If the memory copy of the parti- + tion table was modified, a warning will be issued and + the command ignored. + + Q! Quit, even if the memory copy of the partition table was + not saved. + + R file-name + Read boot sector from file-name (if given) otherwise + read from device. + + W file-name + Write boot sector to file-name. (if given) otherwise + write to device. + + WQ Same as "write" followed by "quit". + + # This line is a comment (to be ignored). + + Output Format + Here is a sample of the output from the L command: + + # Partition table on device: /dev/rdsk/0s0 + geometry 1222 15 34 (cyls heads sectors) + # ID First(cyl) Last(cyl) Name # start, length (sectors) + 1 4 0 127 MS-LOSS # 34, 65246 + 2 129 128 255 Minix # 65280, 65280 + 3 0 0 0 # 0, 0 + 4 99 256 1220 ESIX # 130560, 492150 + # note: last(4): phys=(1023,14,34) logical=(1220,14,34) + active: 4 + + This output format is carefully constructed so that it may be + saved in a file (by redirecting standard output) and later used + as input (by redirecting standard input). On a UNIX system, one + can save this output using the command: + + + + + +Release 1.3 Last change: Oct 1990 2 + + + + + + +PFDISK(8) MAINTENANCE COMMANDS PFDISK(8) + + + + + + (echo L) | pfdisk device-name > save-file + + save-file is a complete record of the partition table. On a + UNIX system, one could use save-file to re-initialize the parti- + tion table using the command: + + (cat save-file ; echo wq) | pfdisk device-name + + Consistency of each partition table entry is checked while the + table is listed. Any inconsistencies discovered are reported in + a commentary note as shown above. + + Physical vs. Logical + Each partition table entry has both "physical" and a "logical" + fields. The physical fields specify the lowest and highest + cylinder,head,sector combinations to be used in that partition. + The logical start field has the total number of sectors which + precede this partition, and the logical length field has the + total number of sectors contained in this partition. These + fields should be self consistent unless the disk has more than + 1024 cylinders. + + The physical cylinder fields are only ten-bits wide so the con- + tents are limited to 1023. The logical sector fields are 32 bits + wide and always show the true logical beginning and length of + the partition. Generally, the physical start field is used only + to locate the secondary boot sector, and the logical start and + length fields are used to actually delimit the partition used by + a particular system. + + Partition Names + The Name field in the partition table is treated specially if + the bootmenu program is installed in the primary boot sector. + (See the file bootmenu.doc for more information.) pfdisk can + recognize the name table used by bootmenu and will show the + actual names present in that name table. If any other boot pro- + gram is used then the Name field reflects the result of a + table-lookup of the system ID. + + If you provide a name when setting any partition entry, the + boot-sector is marked as using a name table, so that on subse- + quent uses of pfdisk you will see the partition names you have + specified. + + Boot program replacement + You can replace the boot program in your boot sector without + affecting the partition table by using pfdisk as follows. + First, (as always) save a copy of the current boot sector (on a + + + + + +Release 1.3 Last change: Oct 1990 3 + + + + + + +PFDISK(8) MAINTENANCE COMMANDS PFDISK(8) + + + + + + floppy) using the "W file" command. Then, use the "R file" com- + mand to read the new boot program. If the boot program read in + is less than 446 bytes long, the partition table will be + unchanged. + + Unlike the DOS or UNIX fdisk programs, pfdisk has NO boot pro- + gram compiled into its executable image. If you wish to use + pfdisk to partition a newly formatted hard disk, you must have a + boot program image available to read in using the "r file" com- + mand. Two boot programs, "bootmenu.bin" and "bootauto.bin" are + distributed with pfdisk and should be found with its source + files. See the file bootmenu.doc for further information about + these boot programs. + +AUTHOR + Gordon W. Ross + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Release 1.3 Last change: Oct 1990 4 + diff --git a/Linux-0.96/INSTALL/pfdisk/PFDISK.EXE b/Linux-0.96/INSTALL/pfdisk/PFDISK.EXE new file mode 100644 index 00000000..2742a2f4 Binary files /dev/null and b/Linux-0.96/INSTALL/pfdisk/PFDISK.EXE differ diff --git a/Linux-0.96/INSTALL/pfdisk/PFDISKAZ.C b/Linux-0.96/INSTALL/pfdisk/PFDISKAZ.C new file mode 100644 index 00000000..72c47f6d --- /dev/null +++ b/Linux-0.96/INSTALL/pfdisk/PFDISKAZ.C @@ -0,0 +1,605 @@ +/* + * pfdisk - Partition a Fixed DISK + * by Gordon W. Ross, Jan. 1990 + * + * See the file "pfdisk.doc" for user instructions. + * + * This program uses a simple, line-oriented interpreter, + * designed for both interactive and non-interactive use. + * To facilitate non-interactive use, the output from the + * 'L' (list partitions) command is carefully arranged so it + * can be used directly as command input. Neat trick, eh? + */ + +char *versionString = + "# pfdisk version 1.2.1 by Gordon W. Ross Aug. 1990\nModified by S. Lubkin Oct. 1991\n"; + +/* These don't really matter. The user is asked to set them. */ +#define DEFAULT_CYLS 306 +#define DEFAULT_HEADS 4 +#define DEFAULT_SECTORS 17 +#define PROMPT_STRING "pfdisk> " + +#include +#include +#include +#include "sysdep.h" +#include "syscodes.h" + +typedef unsigned char uchar; +typedef unsigned int uint; +typedef unsigned long ulong; + +struct part { /* An entry in the partition table */ + uchar active; /* active flag (0x80 or 0) */ + uchar b_head; /* begin head */ + uchar b_sec; /* sector */ + uchar b_cyl; /* cylinder */ + uchar sysid; /* system id (see sysid.c) */ + uchar e_head; /* end head */ + uchar e_sec; /* end sector */ + uchar e_cyl; /* end cylinder */ + /* These two are just longs, but this way is machine independent. */ + /* uchar lsBeg[4]; /* logical sectors, beginning Saul */ + ulong lsBeg; /* logical sectors, beginning Saul */ + /* uchar lsLen[4]; /* logical sectors, length Saul */ + ulong lsLen; /* logical sectors, length Saul */ +}; + +#define LOC_PT 0x1BE +#define LOC_NT 0x1AA /* Saul */ +/* #define LOC_NT 0x180 Saul */ +/* #define LOC_GWR 0x1A0 Saul */ +#define LOC_GWR 0x1A9 /* Saul */ +#define MAGIC_LOC 0x1FE +#define MAGIC_0 0x55 +#define MAGIC_1 0xAA +#define MAX_LINE 80 +#define NT_ENTRY_SIZE 5 /* Saul */ +/* Note: Entry in "printf" command, should be manually changed, to +"%-NT_ENTRY_SIZE.NT_ENTRY_SIZEs" Saul */ +/* And header printf line should have blanks adjusted Saul */ + +char s[22]; /* For holding error string */ +char buffer[SECSIZE]; /* The boot block buffer */ +int bufmod=0; /* buffer modified... */ + /* (zero means buffer is unmodified) */ +int useNTable; /* boot sector uses name table */ + +/* device parameters (force someone to set them!) */ +unsigned cyls = DEFAULT_CYLS; +unsigned heads = DEFAULT_HEADS; +unsigned sectors = DEFAULT_SECTORS; + +char *devname; /* device name */ +char cmdline[MAX_LINE]; +char filename[80]; /* used by r/w commands */ +char *prompt; /* null if no tty input */ + +/* Some of these strings are used in more than one place. + * For consistency, I put a newline on all of them. + */ +char h_h[] = "? : Help summary\n"; +char h_l[] = "L : List partition table\n"; +char h_1[] = "1 id first last [name]: set partition 1\n"; +char h_2[] = "2,3,4 ... (like 1) : set respective partition\n"; +char h_a[] = "A n [m, ...] : Activate partition(s) n [m, ...]\n"; +char h_g[] = "G cyls heads sectors : set disk Geometry\n"; +char h_i[] = "I : list known ID numbers\n"; +char h_r[] = "R [optional-file] : Read device (or specified file)\n"; +char h_w[] = "W [optional-file] : Write device (or specified file)\n"; +char h_q[] = "Q[!] : Quit (! means force)\n"; + +char * helpTable[] = { +h_h, h_l, h_1, h_2, h_a, h_g, h_i, h_r, h_w, h_q, +"# (All command letters have lower-case equivalents.)\n", +(char *) 0 }; /* This MUST have a zero as the last element */ + +char *BadArg="Error: bad argument: %s\n"; +char *WarnNotSaved = + "Warning, modified partition table not saved.\n"; + +help() +{ + char ** p; + for (p = helpTable; *p; p++) + printf(*p); +} + +/* forward declarations */ +void checkValidity(); +char * setPartition(); +char * makeActive(); +char * setGeometry(); +ulong chs2long(); +char * nameID(); +int printIDs(); + +main(argc,argv) +int argc; +char *argv[]; +{ + char *cmdp; /* points to command word */ + char *argp; /* points to command args */ + + /* check command line args (device name) */ + if (argc != 2) { + usage(argv[0]); /* See s-sysname.c */ + exit(1); + } + devname = argv[1]; + + /* Should we prompt? */ + prompt = (isatty(fileno(stdin))) ? PROMPT_STRING : (char *) 0; + + /* Print version name. */ + fputs(versionString, stderr); + + /* get disk parameters */ + getGeometry(devname,&cyls,&heads,§ors); + + /* Get the boot block. */ + if (getBBlk(devname, buffer) < 0) + fprintf(stderr,"%s: read failed\n", devname); + checkValidity(); + + if (prompt) fprintf(stderr,"For help, enter: '?'\n"); + + + /* Read and process commands a line at a time. */ + while (1) { + if (prompt) fputs(prompt,stdout); + if (! fgets(cmdline, MAX_LINE, stdin)) break; + + /* Find beginning of command word */ + cmdp = cmdline; + while (isspace(*cmdp)) cmdp++; + + /* find beginning of args */ + argp = cmdp; + while (*argp && !isspace(*argp)) argp++; + while (isspace(*argp) || *argp=='=') argp++; + + switch (*cmdp) { + + case '\0': /* blank line */ + case '#': /* line comment */ + break; + + case '?': case 'h': case 'H': + help(); + break; + + case '1': /* set partition entry */ + case '2': case '3': case '4': + argp = setPartition(cmdp, argp); + if (argp) { /* arg list error */ + fprintf(stderr,BadArg,argp); + fprintf(stderr,h_1); + fprintf(stderr,h_2); + break; + } + bufmod = 1; + break; + + case 'a': case 'A': /* activate partition */ + argp = makeActive(argp); + if (argp) { + fprintf(stderr,BadArg,argp); + fprintf(stderr,h_a); + break; + } + bufmod = 1; + break; + + case 'g': case 'G': /* set disk parameters (Geometry) */ + argp = setGeometry(argp); + if (argp) { /* arg list error */ + fprintf(stderr,BadArg,argp); + fprintf(stderr,h_g); + } + break; + + case 'i': case 'I': /* List known ID numbers */ + printIDs(); + break; + + case 'l': case 'L': /* List the partition table */ + listPTable(); + break; + + case 'q': case 'Q': /* Quit */ + if (bufmod && (cmdp[1] != '!')) { + fprintf(stderr,"\007%s%s\n", WarnNotSaved, + "Use 'wq' or 'q!' (enter ? for help)."); + break; + } + exit(0); + /*NOTREACHED*/ + + case 'r': case 'R': /* read from device or file */ + if (sscanf(argp,"%80s",filename) == 1) { + /* Arg specified, read from filename */ + if (getFile(filename, buffer, SECSIZE) < 0) + fprintf(stderr,"%s: read failed\n", filename); + bufmod = 1; + } else { + /* No arg, use device. */ + if (getBBlk(devname, buffer) < 0) + fprintf(stderr,"%s: read failed\n", devname); + bufmod = 0; + } + checkValidity(); + break; + + case 'w': case 'W': /* Write to file or device */ + if (sscanf(argp,"%80s",filename) == 1) { + /* Arg specified, write to filename */ + if (putFile(filename, buffer, SECSIZE) < 0) + fprintf(stderr, "%s: write failed\n", filename); + } else { /* No arg, use device. */ + if (putBBlk(devname, buffer) < 0) + fprintf(stderr, "%s: write failed\n", devname); + bufmod = 0; + } + if (cmdp[1] == 'q' || cmdp[1] == 'Q') exit(0); + break; + + default: + fprintf(stderr,"'%c': unrecognized. Enter '?' for help.\n", *cmdp); + break; + + } /* switch */ + } /* while */ + if (bufmod) fprintf(stderr, WarnNotSaved); + exit(0); +} /* main */ + + +/* Check for valid boot block (magic number in last two bytes). + * Also, check for presence of partition name table. + */ +void checkValidity() +{ + /* Check the magic number. */ + if ((buffer[MAGIC_LOC] & 0xFF) != MAGIC_0 || + (buffer[MAGIC_LOC+1] & 0xFF) != MAGIC_1 ) { + /* The boot sector is not valid -- Fix it. */ + buffer[MAGIC_LOC] = MAGIC_0; + buffer[MAGIC_LOC+1] = MAGIC_1; + bufmod = 1; + fprintf(stderr, +"\n\tWarning: The boot sector has an invalid magic number.\n\ +\tThe magic number has been fixed, but the other contents\n\ +\tare probably garbage. Initialize using the command:\n\ +\t\tR boot-program-file (i.e. bootmenu.bin)\n\ +\tthen set each partition entry if necessary.\n"); + } + + /* Does it use a name table (for a boot menu)? + * My boot program does, and can be identified by + * finding my name in a particular (unused) area. + */ + useNTable = ( buffer[LOC_GWR] == (char)0x3A ); /* Saul */ + /* useNTable = !strcmp(&buffer[LOC_GWR], "Gordon W. Ross"); Saul */ + +} + +char * setPartition(cmdp,argp) /* return string on error */ +char *cmdp,*argp; +{ + struct part *pp; /* partition entry */ + char * np; /* name table pointer */ + char tmpname[20]; + char * newname = tmpname; /* name field */ + int index; /* partition index (0..3) */ + uint id; /* ID code (see syscodes.c) */ + uint first,last; /* user supplied cylinders */ + uint c,h,s; /* working cyl,head,sect, */ + int i; /* returned by sscanf */ + ulong lsbeg, lslen; /* logical begin, length */ + + /* Value check the index */ + index = *cmdp - '1'; + if (index < 0 || index > 3) + return("index"); + pp = (struct part *) &buffer[LOC_PT + index * 16]; + np = &buffer[LOC_NT + index * NT_ENTRY_SIZE]; /* Saul */ + /* np = &buffer[LOC_NT + index * 8]; Saul */ + + /* Read System ID */ + if ((i=sscanf(argp,"%d%d%d%s", &id, &first, &last, newname)) < 1) + return("id"); + + /* If ID==0, just clear out the entry and return. */ + if (id == 0) { + strncpy( (char *) pp, "", 16); + if (useNTable) strncpy( np, "", NT_ENTRY_SIZE); /* Saul */ + /* if (useNTable) strncpy( np, "", 8); Saul */ + return((char *)0); + } + + /* Read first and last cylinder */ + if (i < 3) + return("first last (missing)"); + + /* Reasonable start,end cylinder numbers? */ + if (first > last) return("first > last"); + if (first > 1023) return("first > 1023"); + if (last >= cyls) return("last >= cyls"); + + /* Get (optional) system name. */ + if (i == 3) { /* no name given, use default */ + newname = nameID(id); + } + else useNTable = 1; + + /* Set the ID and name. */ + pp->sysid = id; + if (useNTable) { + strncpy(np, newname, NT_ENTRY_SIZE); /* Saul */ + /* strncpy(np, newname, 8); Saul */ + /* strcpy(&buffer[LOC_GWR], "Gordon W. Ross"); Saul */ + buffer[LOC_GWR] = (char)0x3A; /* Saul */ + } + + /* set beginning c,h,s */ + c = first; + /* if c == 0, head == 1 (reserve track 0) */ + h = (first) ? 0 : 1; + s = 1; + pp->b_cyl = c & 0xFF; + pp->b_head = h; + pp->b_sec = s | ((c >> 2) & 0xC0); + /* Set the logical sector begin field */ + lsbeg = lslen = chs2long(c,h,s); /* using lslen as temp. */ + /* pp->lsBeg[0] = lslen & 0xff; lslen >>= 8; + pp->lsBeg[1] = lslen & 0xff; lslen >>= 8; + pp->lsBeg[2] = lslen & 0xff; lslen >>= 8; + pp->lsBeg[3] = lslen & 0xff; lslen >>= 8; Saul */ + pp->lsBeg = lslen; /* Saul */ + + /* set ending c,h,s (last may be larger than 1023) */ + c = (last>1023) ? 1023 : last; /* limit c to 1023 */ + h = heads - 1; s = sectors; + pp->e_cyl = c & 0xFF; + pp->e_head = h; + pp->e_sec = s | ((c >> 2) & 0xC0); + /* Set the logical sector length field (using REAL end cylinder) */ + lslen = chs2long(last,h,s) + 1 - lsbeg; + /* pp->lsLen[0] = lslen & 0xff; lslen >>= 8; + pp->lsLen[1] = lslen & 0xff; lslen >>= 8; + pp->lsLen[2] = lslen & 0xff; lslen >>= 8; + pp->lsLen[3] = lslen & 0xff; lslen >>= 8; Saul */ + pp->lsLen = lslen; /* Saul */ + + return((char *)0); /* success */ +} /* setPartition() */ + +char * makeActive(argp) /* return error string or zero */ +char *argp; +{ + struct part *pp; /* partition entry */ + int i,act1,act2,act3,act4,act5; /* which one becomes active */ + + act1=0; + act2=0; + act3=0; + act4=0; + if ((i=sscanf(argp,"%d%d%d%d%d", &act1, &act2, &act3, &act4, &act5)) < 1) + return("missing partition number"); + if ( i > 4) + return("at most four partition numbers"); + act1--; /* make it zero-origin */ + act2--; /* make it zero-origin */ + act3--; /* make it zero-origin */ + act4--; /* make it zero-origin */ + + i=0; pp = (struct part *) &buffer[LOC_PT]; + while (i<4) { + if (pp->sysid == 0 && (i == act1|| i == act2 || i == act3 || i == act4)) { + sprintf(s, "partition %d empty", i+1); + return(s); + } + i++; pp++; + } + i=0; pp -= 4; + while (i<4) { + if (i == act1|| i == act2 || i == act3 || i == act4) + pp->active = 0x80; + else + pp->active = 0; + i++; pp++; + } + return((char *)0); +} + +char * setGeometry(argp) /* return string on error */ +char *argp; +{ + int c,h,s; + + if (sscanf(argp,"%d%d%d", &c, &h, &s) < 3) + return("(missing)"); + if (c<1) return("cyls"); + if (h<1) return("heads"); + if (s<1) return("sectors"); + cyls=c; heads=h; sectors=s; + return((char *)0); +} + +listPTable() /* print out partition table */ +{ + struct part * pp; /* partition table entry */ + char *name; + int i; /* partition number */ + /* int numActive=0; /* active partition [1-4], 0==none */ + char Active[20]; /* active partitions [1-4], 0==none */ + uint pbc,pbh,pbs; /* physical beginning c,h,s */ + uint pec,peh,pes; /* physical ending c,h,s */ + uint lbc,lbh,lbs; /* logical beginning c,h,s */ + uint lec,leh,les; /* logical ending c,h,s */ + ulong lsbeg,lslen; /* logical sectors: begin, length */ + + strcpy(Active, "active:"); + printf("# Partition table on device: %s\n", devname); + printf("geometry %d %d %d (cyls heads sectors)\n", + cyls, heads, sectors); + /* printf("# ID First(cyl) Last(cyl) Name "); Saul */ + printf("# ID First(cyl) Last(cyl) Name "); /* Saul */ + printf("# start, length (sectors)\n"); + + for (i=0; i<4; i++) { + pp = (struct part *) &buffer[LOC_PT + i * 16]; + + if (pp->active) { + char s[3]; + sprintf(s, " %d", i+1); + strcat(Active,s); + if (pp->active != 0x80) + fprintf(stderr, "Warning: Partition %d is active, with the illegal activity byte %d.\nCorrect with the \"A\" command.\n", i+1, pp->active); + /* if(numActive) + fprintf(stderr,"Error: multiple active partitions.\n"); + else numActive = i+1; */ + } + + /* physical beginning c,h,s */ + pbc = pp->b_cyl & 0xff | (pp->b_sec << 2) & 0x300; + pbh = pp->b_head; + pbs = pp->b_sec & 0x3F; + + /* physical ending c,h,s */ + pec = pp->e_cyl & 0xff | (pp->e_sec << 2) & 0x300; + peh = pp->e_head; + pes = pp->e_sec & 0x3F; + + /* compute logical beginning (c,h,s) */ + /* lsbeg = ((((((pp->lsBeg[3] ) << 8 ) + | pp->lsBeg[2] ) << 8 ) + | pp->lsBeg[1] ) << 8 ) + | pp->lsBeg[0] ; Saul */ + lsbeg = pp->lsBeg; /* Saul */ + long2chs(lsbeg, &lbc, &lbh, &lbs); + /* compute logical ending (c,h,s) */ + /* lslen = ((((((pp->lsLen[3]) << 8 ) + | pp->lsLen[2]) << 8 ) + | pp->lsLen[1]) << 8 ) + | pp->lsLen[0] ; Saul */ + lslen = pp->lsLen; /* Saul*/ + /* keep beginning <= end ... */ + if (lslen > 0) long2chs(lsbeg+lslen-1, &lec, &leh, &les); + else long2chs(lsbeg, &lec, &leh, &les); + + if (useNTable) + name = &buffer[LOC_NT + i * NT_ENTRY_SIZE ]; /* Saul */ + /* name = &buffer[LOC_NT + i * 8]; Saul */ + else + name = nameID((uint) pp->sysid); + + /* show physical begin, logical end (works for cyl>1023) */ + /* # ID First(cyl) Last(cyl) Name... # ... */ + /* printf("%d %3d %4d %4d %-8.8s # %ld, %ld\n", Saul */ + printf("%d %3d %4d %4d %-5.5s # %ld, %ld\n", /* Saul */ + i+1, pp->sysid, pbc, lec, name, lsbeg, lslen ); + + /* That's all, for an empty partition. */ + if (pp->sysid == 0) continue; + + /* + * Now do some consistency checks... + */ + + /* Same physical / logical beginning? */ + if (pbc != lbc || pbh != lbh || pbs != lbs ) { + printf("# note: first(%d): ", i+1); + printf("phys=(%d,%d,%d) ", pbc, pbh, pbs); + printf("logical=(%d,%d,%d)\n",lbc, lbh, lbs); + } + /* Same physical / logical ending? */ + if (pec != lec || peh != leh || pes != les ) { + printf("# note: last(%d): ", i+1); + printf("phys=(%d,%d,%d) ", pec, peh, pes); + printf("logical=(%d,%d,%d)\n",lec, leh, les); + } + + /* Beginning on cylinder boundary? */ + if (pbc == 0) { /* exception: start on head 1 */ + if (pbh != 1 || pbs != 1) { + printf("# note: first(%i): ", i+1); + printf("phys=(%d,%d,%d) ", pbc, pbh, pbs); + printf("should be (%d,1,1)\n", pbc); + } + } else { /* not on cyl 0 */ + if (pbh != 0 || pbs != 1) { + printf("# note: first(%i): ", i+1); + printf("phys=(%d,%d,%d) ", pbc, pbh, pbs); + printf("should be (%d,0,1)\n", pbc); + } + } + + /* Ending on cylinder boundary? */ + if (peh != (heads-1) || pes != sectors) { + printf("# note: last(%i): ", i+1); + printf("phys=(%d,%d,%d) ", pec, peh, pes); + printf("should be (%d,%d,%d)\n", + pec, heads-1, sectors); + } + + } /* for */ + if ( !Active[7] ) /* No active partitions */ + strcat(Active, " 0 (none)"); + strcat(Active, "\n"); + printf(Active); +/* printf("active: %d %s\n", numActive, + (numActive) ? "" : "(none)"); */ +} /* listPTable() */ + +ulong chs2long(c,h,s) +uint c,h,s; +{ + ulong l; + if (s<1) s=1; + l = c; l *= heads; + l += h; l *= sectors; + l += (s - 1); + return(l); +} + +long2chs(ls, c, h, s) /* convert logical sec-num to c,h,s */ +ulong ls; /* Logical Sector number */ +uint *c,*h,*s; /* cyl, head, sector */ +{ + int spc = heads * sectors; + *c = ls / spc; + ls = ls % spc; + *h = ls / sectors; + *s = ls % sectors + 1; /* sectors count from 1 */ +} + +char * nameID(n) +unsigned int n; +{ + struct intString *is; + + is = sysCodes; + while (is->i) { + if (is->i == n) return(is->s); + is++; + } + if (!n) return(is->s); + return("unknown"); +} + +int printIDs() /* print the known system IDs */ +{ + struct intString * is = sysCodes; + + /* This might need to do more processing eventually, i.e. + * if (prompt) { ... do more processing ... } + */ + printf("_ID_\t__Name__ ____Description____\n"); + while (is->i) { + printf("%3d\t%s\n", is->i, is->s); + is++; + } +} diff --git a/Linux-0.96/INSTALL/pfdisk/SYSCODES.C b/Linux-0.96/INSTALL/pfdisk/SYSCODES.C new file mode 100644 index 00000000..11f5c77e --- /dev/null +++ b/Linux-0.96/INSTALL/pfdisk/SYSCODES.C @@ -0,0 +1,43 @@ +/* This file holds all knowledge of partition ID codes. + * Thanks to leendert@cs.vu.nl (Leendert van Doorn) for + * collecting most of this information. + */ + +#define extern +#include "syscodes.h" +#undef extern + +/* Note that my boot program menu can only use the first 8 characters + * of these names. The colon in the nineth position shows where the + * first truncated char is. (There's not much room in the bootblock!) + * changed sysCodes[] below, adding SIZE tms */ +struct intString sysCodes[SIZE] = { +{ 0x01, "DOS12 :12-bit FAT" }, +{ 0x02, "XENIX :root" }, +{ 0x03, "XENIX :usr" }, +{ 0x04, "DOS16 :16-bit FAT" }, +{ 0x05, "DOSex :DOS 3.3 extended volume" }, +{ 0x06, "DOSbi :DOS 4.0 large volume" }, +{ 0x07, "OS/2 :OS/2 (or QNX or Adv. UNIX...)" }, +{ 0x08, "AIX :file system" }, +{ 0x09, "AIXbt:boot partition" }, + +{ 0x10, "OPUS :?" }, +{ 0x40, "VENIX :Venix 80286" }, +{ 0x51, "NOVEL :?" }, +{ 0x52, "CPM :?" }, +{ 0x63, "UNIX :System V/386" }, +{ 0x64, "NOVEL :?" }, +{ 0x75, "PC/IX :?" }, +{ 0x80, "Minix :Minix (ver. 1.4a and earlier)" }, +{ 0x81, "Minix :Minix (ver. 1.4b and later)" }, +{ 0x93, "Ameba :Amoeba file system" }, +{ 0x94, "Ameba :Amoeba bad block table?" }, +{ 0xDB, "C.DOS :Concurrent DOS" }, + +/* { 0xF2, "DOS-2nd :DOS 3.3+ second partition" }, */ +/* { 0xFF, "BAD-TRK :Bad track table?" }, */ + +/* Make sure this is last! */ +{ 0, "empty" } +}; diff --git a/Linux-0.96/INSTALL/pfdisk/SYSCODES.H b/Linux-0.96/INSTALL/pfdisk/SYSCODES.H new file mode 100644 index 00000000..6fd314da --- /dev/null +++ b/Linux-0.96/INSTALL/pfdisk/SYSCODES.H @@ -0,0 +1,4 @@ +#define SIZE 40 /* added tms */ +struct intString { unsigned int i; char * s; }; +extern struct intString sysCodes[SIZE]; /* was sysCodes[] modified tms */ + diff --git a/Linux-0.96/INSTALL/pfdisk/SYSDEP.H b/Linux-0.96/INSTALL/pfdisk/SYSDEP.H new file mode 100644 index 00000000..1d26b47d --- /dev/null +++ b/Linux-0.96/INSTALL/pfdisk/SYSDEP.H @@ -0,0 +1,22 @@ +/* communicate declarations from the files: s_*.c */ + +#define SECSIZE 0x200 + +extern int usage(); /* print a usage message */ + /* (char *progname) */ + +extern void getGeometry(); /* determine disk parameters */ + /* (char *dev, uint *cyls, uint *heads, uint *sectors) */ + +extern int getFile(); /* open, read, close, return(num-read) */ + /* (char *name, char *buf, int len) */ + +extern int putFile(); /* open, write, close, return(num-writen) */ + /* (char *name, char *buf, int len) */ + +extern int getBBlk(); /* open, read, close, return(num-read) */ + /* (char *dev, char *buf) */ + +extern int putBBlk(); /* open, write, close, return(num-writen) */ + /* (char *dev, char *buf) */ + diff --git a/Linux-0.96/INSTALL/pfdisk/S_MSDOS.C b/Linux-0.96/INSTALL/pfdisk/S_MSDOS.C new file mode 100644 index 00000000..ddeab974 --- /dev/null +++ b/Linux-0.96/INSTALL/pfdisk/S_MSDOS.C @@ -0,0 +1,163 @@ +/* This file contains system-specific functions for MS-DOS. + * The program pfdisk.c calls these routines. + */ +#include +#include +#include +#include +#include + +#define extern +#include "sysdep.h" +#undef extern + +int usage(prog) /* print a usage message */ +char *prog; /* program name */ +{ + fprintf(stderr,"Usage: %s \n", prog); + fprintf(stderr,"\twhere is a digit [0-9]\n"); +} + +void getGeometry(name, c, h, s) +char *name; /* device name */ +unsigned *c,*h,*s; /* cyls, heads, sectors */ +{ + int dev; /* hard disk number */ + union REGS regs; + struct SREGS sregs; + + if (name[0] < '0' || + name[0] > '9' || + name[1] != 0 ) + { + fprintf(stderr,"%s: device name must be a digit\n", name); + return; + } + dev = (name[0] - '0'); + + regs.h.ah = 8; /* get param. */ + regs.h.dl = dev | 0x80; + + int86x(0x13,®s,®s,&sregs); + + /* Are that many drives responding? */ + if (regs.h.dl <= dev ) { + fprintf(stderr,"%s: drive not found\n", name); + return; + } + if (regs.x.cflag) { + fprintf(stderr,"%s: can't get disk parameters\n", name); + return; + } + *c = ((((int) regs.h.cl << 2) & 0x300) | regs.h.ch) + 1; + *h = regs.h.dh + 1; + *s = regs.h.cl & 0x3F; +} + +int getFile(name, buf, len) /* read file into buffer */ +char *name, *buf; +int len; +{ /* (open, read, close) */ + int devfd, retval; + + devfd = open(name, O_RDONLY|O_BINARY, 0); + if (devfd < 0) { + fprintf(stderr,"%s: can't open for reading\n", name); + return(devfd); + } + retval = read(devfd, buf, len); + if (retval < 0) + fprintf(stderr,"%s: read failed\n", name); + close(devfd); + return(retval); +} + +int putFile(name, buf, len) /* write buffer to file */ +char *name, *buf; +int len; +{ /* (open, write, close) */ + int devfd, retval; + + devfd = open(name, + O_WRONLY|O_CREAT|O_BINARY, + S_IREAD|S_IWRITE ); /* stupid DOS... */ + if (devfd < 0) { + fprintf(stderr,"%s: can't open for writing\n", name); + return(devfd); + } + retval = write(devfd, buf, len); + if (retval < 0) + fprintf(stderr,"%s: write failed\n", name); + close(devfd); + return(retval); +} + +int getBBlk(name, buf) /* read boot block into buffer */ +char *name, *buf; +{ /* BIOS absolute disk read */ + int dev; + union REGS regs; + struct SREGS sregs; + + if (name[0] < '0' || + name[0] > '9' || + name[1] != 0 ) + { + fprintf(stderr,"%s: device name must be a digit\n",name); + return(-1); + } + dev = (name[0] - '0'); + + segread(&sregs); /* get ds */ + sregs.es = sregs.ds; /* buffer address */ + regs.x.bx = (int) buf; + + regs.h.ah = 2; /* read */ + regs.h.al = 1; /* sector count */ + regs.h.ch = 0; /* track */ + regs.h.cl = 1; /* start sector */ + regs.h.dh = 0; /* head */ + regs.h.dl = dev|0x80; /* drive */ + + int86x(0x13,®s,®s,&sregs); + if (regs.x.cflag) { + fprintf(stderr,"%s: read failed\n", name); + return(-1); + } + return(SECSIZE); +} + +int putBBlk(name, buf) /* write buffer to boot block */ +char *name, *buf; +{ /* BIOS absolute disk write */ + int dev; + union REGS regs; + struct SREGS sregs; + + if (name[0] < '0' || + name[0] > '9' || + name[1] != 0 ) + { + fprintf(stderr,"%s: device name must be a digit\n", name); + return(-1); + } + dev = (name[0] - '0'); + + segread(&sregs); /* get ds */ + sregs.es = sregs.ds; /* buffer address */ + regs.x.bx = (int) buf; + + regs.h.ah = 3; /* write */ + regs.h.al = 1; /* sector count */ + regs.h.ch = 0; /* track */ + regs.h.cl = 1; /* start sector */ + regs.h.dh = 0; /* head */ + regs.h.dl = dev|0x80; /* drive */ + + int86x(0x13,®s,®s,&sregs); + if (regs.x.cflag) { + fprintf(stderr,"%s: write failed\n",name); + return(-1); + } + return(SECSIZE); +} diff --git a/Linux-0.96/INSTALL/pfdisktc.zip b/Linux-0.96/INSTALL/pfdisktc.zip new file mode 100644 index 00000000..92dddc3e Binary files /dev/null and b/Linux-0.96/INSTALL/pfdisktc.zip differ diff --git a/Linux-0.96/INSTALL/rawrite.c b/Linux-0.96/INSTALL/rawrite.c new file mode 100644 index 00000000..3772b2f7 --- /dev/null +++ b/Linux-0.96/INSTALL/rawrite.c @@ -0,0 +1,182 @@ +/* + rawrite.c Write a binary image to a 360K diskette. + By Mark Becker + + Usage: + MS-DOS prompt> RAWRITE + + And follow the prompts. + +History +------- + + 1.0 - Initial release + 1.1 - Beta test (fixing bugs) 4/5/91 + Some BIOS's don't like full-track writes. + 1.101 - Last beta release. 4/8/91 + Fixed BIOS full-track write by only + writing 3 sectors at a time. + 1.2 - Final code and documentation clean-ups. 4/9/91 +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define FALSE 0 +#define TRUE (!FALSE) + +#define SECTORSIZE 512 + +#define RESET 0 +#define LAST 1 +#define READ 2 +#define WRITE 3 +#define VERIFY 4 +#define FORMAT 5 + +int done; + +/* + Catch ^C and ^Break. +*/ +int handler(void) +{ + done = TRUE; + return(0); +} +void msg(char (*s)) +{ + fprintf(stderr, "%s\n", s); + _exit(1); +} +/* + Identify the error code with a real error message. +*/ +void Error(int (status)) +{ + switch (status) { + case 0x00: msg("Operation Successful"); break; + case 0x01: msg("Bad command"); break; + case 0x02: msg("Address mark not found"); break; + case 0x03: msg("Attempt to write on write-protected disk"); break; + case 0x04: msg("Sector not found"); break; + case 0x05: msg("Reset failed (hard disk)"); break; + case 0x06: msg("Disk changed since last operation"); break; + case 0x07: msg("Drive parameter activity failed"); break; + case 0x08: msg("DMA overrun"); break; + case 0x09: msg("Attempt to DMA across 64K boundary"); break; + case 0x0A: msg("Bad sector detected"); break; + case 0x0B: msg("Bad track detected"); break; + case 0x0C: msg("Unsupported track"); break; + case 0x10: msg("Bad CRC/ECC on disk read"); break; + case 0x11: msg("CRC/ECC corrected data error"); break; + case 0x20: msg("Controller has failed"); break; + case 0x40: msg("Seek operation failed"); break; + case 0x80: msg("Attachment failed to respond"); break; + case 0xAA: msg("Drive not ready (hard disk only"); break; + case 0xBB: msg("Undefined error occurred (hard disk only)"); break; + case 0xCC: msg("Write fault occurred"); break; + case 0xE0: msg("Status error"); break; + case 0xFF: msg("Sense operation failed"); break; + } + _exit(1); +} + +/* + Identify what kind of diskette is installed in the specified drive. + Return the number of sectors per track assumed as follows: + 9 - 360 K and 720 K 5.25". +15 - 1.2 M HD 5.25". +18 - 1.44 M 3.5". +*/ +int nsects(int (drive)) +{ + static int nsect[] = {18, 15, 9}; + + char *buffer; + int i, status; +/* + Read sector 1, head 0, track 0 to get the BIOS running. +*/ + buffer = (char *)malloc(SECTORSIZE); + biosdisk(RESET, drive, 0, 0, 0, 0, buffer); + status = biosdisk(READ, drive, 0, 10, 1, 1, buffer); + if (status == 0x06) /* Door signal change? */ + status = biosdisk(READ, drive, 0, 0, 1, 1, buffer); + + for (i=0; i < sizeof(nsect)/sizeof(int); ++i) { + biosdisk(RESET, drive, 0, 0, 0, 0, buffer); + status = biosdisk(READ, drive, 0, 0, nsect[i], 1, buffer); + if (status == 0x06) + status = biosdisk(READ, drive, 0, 0, nsect[i], 1, buffer); + if (status == 0x00) break; + } + if (i == sizeof(nsect)/sizeof(int)) { + msg("Can't figure out how many sectors/track for this diskette."); + } + free(buffer); + return(nsect[i]); +} + +void main(void) +{ + char fname[MAXPATH]; + char *buffer, *pbuf; + int count, fdin, drive, head, track, status, spt, buflength, ns; + + puts("RaWrite 1.2 - Write disk file to raw floppy diskette\n"); + ctrlbrk(handler); + printf("Enter source file name: "); + scanf("%s", fname); + _fmode = O_BINARY; + if ((fdin = open(fname, O_RDONLY)) <= 0) { + perror(fname); + exit(1); + } + + printf("Enter destination drive: "); + scanf("%s", fname); + drive = fname[0]; + drive = (islower(drive) ? toupper(drive) : drive) - 'A'; + printf("Please insert a formatted diskette into "); + printf("drive %c: and press -ENTER- :", drive + 'A'); + while (bioskey(1) == 0) ; /* Wait... */ + if ((bioskey(0) & 0x7F) == 3) exit(1); /* Check for ^C */ + putchar('\n'); + done = FALSE; +/* + * Determine number of sectors per track and allocate buffers. + */ + spt = nsects(drive); + buflength = spt * SECTORSIZE; + buffer = (char *)malloc(buflength); + printf("Number of sectors per track for this disk is %d\n", spt); + printf("Writing image to drive %c:. Press ^C to abort.\n", drive+'A'); +/* + * Start writing data to diskette until there is no more data to write. + */ + head = track = 0; + while ((count = read(fdin, buffer, buflength)) > 0 && !done) { + pbuf = buffer; + for (ns = 1; count > 0 && !done; ns+=3) { + printf("Track: %02d Head: %2d Sector: %2d\r", track, head, ns); + status = biosdisk(WRITE, drive, head, track, ns, 3, pbuf); + + if (status != 0) Error(status); + + count -= (3*SECTORSIZE); + pbuf += (3*SECTORSIZE); + } + if ((head = (head + 1) & 1) == 0) ++track; + } + if (eof(fdin)) { + printf("\nDone.\n"); + biosdisk(2, drive, 0, 0, 1, 1, buffer); /* Retract head */ + } +} /* end main */ diff --git a/Linux-0.96/INSTALL/rawrite.doc b/Linux-0.96/INSTALL/rawrite.doc new file mode 100644 index 00000000..f4871d1f --- /dev/null +++ b/Linux-0.96/INSTALL/rawrite.doc @@ -0,0 +1,86 @@ +RaWrite 1.2 +----------- + +Purpose +------- + +Write a disk image file to a 360K floppy disk. + + +Equipment/Software Requirements +------------------------------- + +PC/XT/AT with a floppy disk drive capable of reading and writing a 360K +diskette. + +This program uses generic low-level BIOS diskette read/write functions. It +should be portable to nearly every PC in existance. PS/2's should be able +to run RawWrite but this has not been tested. + + +CAVEAT +------ + +This program will write ANY disk file to a floppy, overwriting any previous +information that may have been present. If you wish to re-use a diskette +under MS-DOS thats been written to by RawWrite then the disk will need to be +reformatted; all MS-DOS specific information will have been erased. + + +How to Compile +-------------- + +TCC rawrite.c + +The source code is specific to Borland International's Turbo C 2.01 and has +been tested in all memory models. + + +Usage +----- + +C> RAWRITE + +And follow the prompts. All arguments are case-insensitive. + +A sample run is shown below. The disk file being written, in this example, +is named DEMODISK and the destination - where the image is being written - +is the B: drive. + +This program may be aborted at any time by typing ^C. + + +Sample Run +---------- + +C> RAWRITE +RaWrite 1.2 - Write disk file to raw floppy diskette + +Enter source file name: DEMODISK +Enter destination drive: B +Please insert a formatted 360K diskette into drive B: and press -ENTER- : +Writing image to drive B: + + +Errors +------ + +RaWrite attempts to determine if the diskette is a 360K, 720K, 1.2M, or +1.44M diskette by reading specific sectors. If the inserted diskette is not +one of the mentioned types, then RaWrite will abort with a short error +message. + +Errors such as write protect, door open, bad disk, bad sector, etc. cause a +program abort with a short error message. + + +History +------- + + 1.0 - Initial release + 1.1 - Beta test (fixing bugs) 4/5/91 + Some BIOS's don't like full-track writes. + 1.101 - Last beta release. 4/8/91 + Fixed BIOS full-track write by only only + writing 3 sectors at a time. + 1.2 - Final code and documentation clean-ups. 4/9/91 diff --git a/Linux-0.96/INSTALL/rawrite.exe b/Linux-0.96/INSTALL/rawrite.exe new file mode 100644 index 00000000..a4a464ba Binary files /dev/null and b/Linux-0.96/INSTALL/rawrite.exe differ diff --git a/Linux-0.96/binaries/sbin/rdev b/Linux-0.96/binaries/sbin/rdev new file mode 100644 index 00000000..9a6072be Binary files /dev/null and b/Linux-0.96/binaries/sbin/rdev differ diff --git a/Linux-0.96/binaries/usr.bin/Archivers/Zoo.Fiz.note b/Linux-0.96/binaries/usr.bin/Archivers/Zoo.Fiz.note new file mode 100644 index 00000000..85d27728 --- /dev/null +++ b/Linux-0.96/binaries/usr.bin/Archivers/Zoo.Fiz.note @@ -0,0 +1,6 @@ +This is zoo and fiz from Rahul Dhesi compiled for Linux. It is a very +popular PD archiver in the Ms-Dog world. + +Roger + +cs89rdb@brunel.ac.uk diff --git a/Linux-0.96/binaries/usr.bin/Archivers/fiz b/Linux-0.96/binaries/usr.bin/Archivers/fiz new file mode 100644 index 00000000..a775d82d Binary files /dev/null and b/Linux-0.96/binaries/usr.bin/Archivers/fiz differ diff --git a/Linux-0.96/binaries/usr.bin/Archivers/zip-bin.tar.Z b/Linux-0.96/binaries/usr.bin/Archivers/zip-bin.tar.Z new file mode 100644 index 00000000..14435681 Binary files /dev/null and b/Linux-0.96/binaries/usr.bin/Archivers/zip-bin.tar.Z differ diff --git a/Linux-0.96/binaries/usr.bin/Archivers/zoo b/Linux-0.96/binaries/usr.bin/Archivers/zoo new file mode 100644 index 00000000..df12ed53 Binary files /dev/null and b/Linux-0.96/binaries/usr.bin/Archivers/zoo differ diff --git a/Linux-0.96/binaries/usr.bin/Archivers/zoo-210.bin.tar.Z b/Linux-0.96/binaries/usr.bin/Archivers/zoo-210.bin.tar.Z new file mode 100644 index 00000000..193a9bcc Binary files /dev/null and b/Linux-0.96/binaries/usr.bin/Archivers/zoo-210.bin.tar.Z differ diff --git a/Linux-0.96/binaries/usr.bin/Archivers/zoo.tar.Z b/Linux-0.96/binaries/usr.bin/Archivers/zoo.tar.Z new file mode 100644 index 00000000..4a987723 Binary files /dev/null and b/Linux-0.96/binaries/usr.bin/Archivers/zoo.tar.Z differ diff --git a/Linux-0.96/binaries/usr.bin/Communications/minicom.tar.Z b/Linux-0.96/binaries/usr.bin/Communications/minicom.tar.Z new file mode 100644 index 00000000..c1fbb76f Binary files /dev/null and b/Linux-0.96/binaries/usr.bin/Communications/minicom.tar.Z differ diff --git a/Linux-0.96/binaries/usr.bin/Communications/pcomm96c.tar.Z b/Linux-0.96/binaries/usr.bin/Communications/pcomm96c.tar.Z new file mode 100644 index 00000000..3541b16d Binary files /dev/null and b/Linux-0.96/binaries/usr.bin/Communications/pcomm96c.tar.Z differ diff --git a/Linux-0.96/binaries/usr.bin/Communications/rzsz3.14.tar.Z b/Linux-0.96/binaries/usr.bin/Communications/rzsz3.14.tar.Z new file mode 100644 index 00000000..4e1c4fc9 Binary files /dev/null and b/Linux-0.96/binaries/usr.bin/Communications/rzsz3.14.tar.Z differ diff --git a/Linux-0.96/binaries/usr.bin/bpe.tar.Z b/Linux-0.96/binaries/usr.bin/bpe.tar.Z new file mode 100644 index 00000000..5fb36010 Binary files /dev/null and b/Linux-0.96/binaries/usr.bin/bpe.tar.Z differ diff --git a/Linux-0.96/binaries/usr.bin/cvw.bin.tar.Z b/Linux-0.96/binaries/usr.bin/cvw.bin.tar.Z new file mode 100644 index 00000000..442bfeb8 Binary files /dev/null and b/Linux-0.96/binaries/usr.bin/cvw.bin.tar.Z differ diff --git a/Linux-0.96/binaries/usr.bin/fm.tar.Z b/Linux-0.96/binaries/usr.bin/fm.tar.Z new file mode 100644 index 00000000..7b5f3042 Binary files /dev/null and b/Linux-0.96/binaries/usr.bin/fm.tar.Z differ diff --git a/Linux-0.96/binaries/usr.bin/gdb-4.5.tar.Z b/Linux-0.96/binaries/usr.bin/gdb-4.5.tar.Z new file mode 100644 index 00000000..9f643f48 Binary files /dev/null and b/Linux-0.96/binaries/usr.bin/gdb-4.5.tar.Z differ diff --git a/Linux-0.96/binaries/usr.bin/ka9q.4.bin.tar.Z b/Linux-0.96/binaries/usr.bin/ka9q.4.bin.tar.Z new file mode 100644 index 00000000..fd5c9761 Binary files /dev/null and b/Linux-0.96/binaries/usr.bin/ka9q.4.bin.tar.Z differ diff --git a/Linux-0.96/binaries/usr.bin/lha.Linux b/Linux-0.96/binaries/usr.bin/lha.Linux new file mode 100644 index 00000000..7d7016fd Binary files /dev/null and b/Linux-0.96/binaries/usr.bin/lha.Linux differ diff --git a/Linux-0.96/binaries/usr.bin/nroff.tar.Z b/Linux-0.96/binaries/usr.bin/nroff.tar.Z new file mode 100644 index 00000000..92c3e9ae Binary files /dev/null and b/Linux-0.96/binaries/usr.bin/nroff.tar.Z differ diff --git a/Linux-0.96/binaries/usr.bin/protoize.tar.Z b/Linux-0.96/binaries/usr.bin/protoize.tar.Z new file mode 100644 index 00000000..ee19c176 Binary files /dev/null and b/Linux-0.96/binaries/usr.bin/protoize.tar.Z differ diff --git a/Linux-0.96/binaries/usr.bin/setterm-0.96b.tar.Z b/Linux-0.96/binaries/usr.bin/setterm-0.96b.tar.Z new file mode 100644 index 00000000..f7f8cecc Binary files /dev/null and b/Linux-0.96/binaries/usr.bin/setterm-0.96b.tar.Z differ diff --git a/Linux-0.96/binaries/usr.bin/zoo.bin.tar.gz b/Linux-0.96/binaries/usr.bin/zoo.bin.tar.gz new file mode 100644 index 00000000..2d1fe191 Binary files /dev/null and b/Linux-0.96/binaries/usr.bin/zoo.bin.tar.gz differ diff --git a/Linux-0.96/binaries/usr.games/banner.Z b/Linux-0.96/binaries/usr.games/banner.Z new file mode 100644 index 00000000..be2a95f8 Binary files /dev/null and b/Linux-0.96/binaries/usr.games/banner.Z differ diff --git a/Linux-0.96/binaries/usr.games/dkbtrace.tar.Z b/Linux-0.96/binaries/usr.games/dkbtrace.tar.Z new file mode 100644 index 00000000..4acc0df3 Binary files /dev/null and b/Linux-0.96/binaries/usr.games/dkbtrace.tar.Z differ diff --git a/Linux-0.96/binaries/usr.games/dungeon.tar.Z b/Linux-0.96/binaries/usr.games/dungeon.tar.Z new file mode 100644 index 00000000..f68f1246 Binary files /dev/null and b/Linux-0.96/binaries/usr.games/dungeon.tar.Z differ diff --git a/Linux-0.96/binaries/usr.games/gnuchess-3.1.tar.Z b/Linux-0.96/binaries/usr.games/gnuchess-3.1.tar.Z new file mode 100644 index 00000000..a11846fc Binary files /dev/null and b/Linux-0.96/binaries/usr.games/gnuchess-3.1.tar.Z differ diff --git a/Linux-0.96/binaries/usr.games/mille.tar.Z b/Linux-0.96/binaries/usr.games/mille.tar.Z new file mode 100644 index 00000000..d1f0e1c3 Binary files /dev/null and b/Linux-0.96/binaries/usr.games/mille.tar.Z differ diff --git a/Linux-0.96/binaries/usr.games/neko-bin.tar.Z b/Linux-0.96/binaries/usr.games/neko-bin.tar.Z new file mode 100644 index 00000000..3b79850c Binary files /dev/null and b/Linux-0.96/binaries/usr.games/neko-bin.tar.Z differ diff --git a/Linux-0.96/binaries/usr.games/plumbing.tar.Z b/Linux-0.96/binaries/usr.games/plumbing.tar.Z new file mode 100644 index 00000000..81b91df8 Binary files /dev/null and b/Linux-0.96/binaries/usr.games/plumbing.tar.Z differ diff --git a/Linux-0.96/binaries/usr.games/spider.tar.Z b/Linux-0.96/binaries/usr.games/spider.tar.Z new file mode 100644 index 00000000..bc167370 Binary files /dev/null and b/Linux-0.96/binaries/usr.games/spider.tar.Z differ diff --git a/Linux-0.96/binaries/usr.games/tetris-bin.tar.Z b/Linux-0.96/binaries/usr.games/tetris-bin.tar.Z new file mode 100644 index 00000000..2a33e2ba Binary files /dev/null and b/Linux-0.96/binaries/usr.games/tetris-bin.tar.Z differ diff --git a/Linux-0.96/binaries/usr.games/xgames.tar.Z b/Linux-0.96/binaries/usr.games/xgames.tar.Z new file mode 100644 index 00000000..20b6432f Binary files /dev/null and b/Linux-0.96/binaries/usr.games/xgames.tar.Z differ diff --git a/Linux-0.96/docs/CHANGES-0.96 b/Linux-0.96/docs/CHANGES-0.96 new file mode 100644 index 00000000..6b05b2e3 --- /dev/null +++ b/Linux-0.96/docs/CHANGES-0.96 @@ -0,0 +1,128 @@ +CHANGES IN THE LINUX v0.96 ROOT DISKETTE +Jim Winstead Jr. - 4 July 1992 + +This file mostly contains info about the changes in the root diskette +from Linux v0.95a to Linux v0.96. + +CHANGES + +With the release of Linux v0.95a, the maintenance of the root diskette +has been assumed by Jim Winstead Jr. (jwinstea@jarthur.Claremont.EDU). + +This continues with the release of the Linux 0.96 release diskette. +The changes between the Linux 0.96 and Linux 0.95a root diskettes are +detailed below: + +- bash is back! /bin/sh is now a symlink to /bin/bash. ash was + simple too buggy for general use as /bin/sh. (This was likely + a result of a sloppy port to Linux rather than any flaws with + ash, but it seems silly to worry about ash when bash fits.) + +- GNU tar is not on the root disk. Instead, the POSIX-defined + utility 'pax' is included, which handles tar _and_ cpio + archives. There are symlinks from /bin/cpio and /bin/tar to + /bin/pax to allow using the tar and cpio interfaces to pax. + + (The big change you'll notice is that pax does not support a + 'z' option for compressed tar files. You will have to pipe + them through 'uncompress' first.) + + This was done because pax is roughly 1/3 the size of GNU tar, + and GNU tar offered nothing significant beyond what pax does. + +- the install script has been completely rewritten. Now, it is + much more intelligent, and tries to guide you along the path + of installing Linux on your system. + +- split /etc/rc into /etc/rc and /etc/rc.local. /etc/rc.local + is the only one you should ever have need to change. + +- mount has been improved to accept a -a option. This reads + /etc/fstab and mounts the filesystems specified within, + including swapping partitions. See /etc/fstab to see how it + works. + + Similar changes have been made to swapon to allow the 'swapon' + of a single swap file/partition from /etc/fstab. + + As a result of these two improvements, /bin/mount -a and + /bin/swapon -a have both been added to /etc/rc, and you + shouldn't need to add additional mount commands to rc.local - + use /etc/fstab instead. + + Thanks to Doug Quale for writing the new mount and swapon. + +- uncompress is really a link to compress this time, I screwed + up last time. oops! + +- I recompiled everything with GCC 2.2.2, and they are linked + against shared libraries (located in /lib) - it is important + that /lib be part of your root partition! + +- many of the small utilities are linked as 'impure' + executables. This saves a great deal of disk space, at the + expense that they can't be demand-loaded or shared. Most, if + not all, of the utilities linked this way are very small and + infrequently used, however, so the benefits far outweigh the + small disadvantage there. + +- rootdev really is rdev this time. + +- /dev/MAKEDEV is a fairly generic script for making devices. + It supercedes /INSTALL/mkdev from the 0.95a root disk, and + really should be kept even after installation, because such + things as the scsi tape devices are not made by default - this + script allows you to make them when needed. + +- added the lp devices, scsi devices, and miscellaneous other + devices. + +- included a new termcap file based upon the termcap file + released with the setterm-0.96b utility. Also included are + the termcap entires for X terminals and generic vt100 entries. + +If you have questions, problems, or complaints about the root +diskette, either post to comp.os.linux, or send mail to me at +jwinstea@jarthur.Claremont.EDU. + +If you have questions, problems, or complaints about the boot diskette +or the kernel itself, post to comp.os.linux or send mail to Linus +Torvalds at torvalds@cc.helsinki.fi. + +Remember, the only stupid questions are the ones you don't ask. + +FUTURE CHANGES + +I'm already anticipating some changes for the next release, so here's +a sneak preview: + +- you probably won't notice, but I plan on cleaning up the + source of some of the utilities, most noticeably shutdown, + passwd and mkfs. Those are all pretty ugly. + +- the install script will be improved. The current one was + written rather rapidly, so there are parts of it I'm not + entirely happy with. + +- I'd like to write an update script that will allow people who + have already installed Linux to update their binaries from the + latest root disk. The install script could serve as a base + for this, but is a little destructive at present. (It would + simply copy over old binaries, etc.) + +- the documentation on disk will be cleaned up, and possibly + added to. + +- fill in the gaps in the MAKEDEV script. (SCSI tapes, more pty + devices.) + +- the release after the extended filesystem is added to the + Linux kernel, the root disk will use it. That means v0.98, if + things go according to current plans. This is to allow time + for bugs in the extended filesystem to filter out, and for the + new mkfs and fsck to stabilize. (For those that don't know, + the extended filesystem supports 4 terabyte partitions and long + filenames, and is currently in alpha testing.) + +Again, mail your questions, comments and suggestions about the root +diskette to me at jwinstea@jarthur.Claremont.EDU. diff --git a/Linux-0.96/docs/COPYING-2 b/Linux-0.96/docs/COPYING-2 new file mode 100644 index 00000000..a43ea212 --- /dev/null +++ b/Linux-0.96/docs/COPYING-2 @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/Linux-0.96/docs/INSTALL-0.96 b/Linux-0.96/docs/INSTALL-0.96 new file mode 100644 index 00000000..e44c334c --- /dev/null +++ b/Linux-0.96/docs/INSTALL-0.96 @@ -0,0 +1,119 @@ +INSTALL NOTES FOR LINUX v0.96 +Jim Winstead Jr. - July 4, 1992 + +This file contains basic instructions for installing Linux v0.96. +More detailed instructions have been written by others. Read the +Linux FAQ for some suggestions, and for pointers to other installation +documents. + +COPYRIGHT + +Linux 0.96 is NOT public domain software, but is copyrighted by Linus +Torvalds (torvalds@cc.helsinki.fi). The copyright terms follow the +GNU Copyleft. See the file COPYING from any GNU software package for +the finer points. Note that the unistd library functions and all +library functions written by Linus Torvalds are exempt from this +copyright, and you may use them as you wish. + +WARNING + + The 0.96 root disk requires the 0.96b or later kernel. A bootable + image of this kernel should be available where you got the image + for the 0.96 root disk. + +INSTALLATION + +1) First, and absolutely the most important step, MAKE BACKUPS OF YOUR + SYSTEM! This system won't do anything nearly as nasty as coredump all + over your harddrive (see 386BSD v0.0), but it is quite easy to + accidently screw something up while installing. + +2) Test out the Linux v0.96b boot disk with the Linux v0.96 root + disk. If you are unable to get the boot disk to work properly on + your system, try posting to comp.os.linux, or contacting Linus. + + Notice that Linux (as of v0.95) contains an init/getty/login suite, + and this will start up 'login' on the first four virtual consoles, + accessed by Left-Alt-F[1234]. If you experience problems on one + virtual console, it should be possible to switch to another one. + +3) login as 'install', and the system will walk you through the + process of installing Linux on a hard drive partition. The + process is fairly automated, but the process requires that you go + through the steps of creating a partition for Linux usage. Some + tips follow: + + Read the efdisk file from the intro login, which will explain + the basic concepts of hard disk partitions, and how to use + efdisk. + + You may find it useful to login to one virtual console as + intro, so you can access the on-disk documentation, and + another as install, so you can do the installation and easy + access the documentation. + + The maximum size of a Minix filesystem (the type created by + mkfs) is 64 megabytes. This is not a limitation of mkfs or + Linux, but a limitation of the Minix filesystem that is used. + With the release of Linux v0.97, a new 'extended' filesystem + will be released that will support 4 terabyte (!) partitions, + and extended filenames. + +4) You should now have a complete (but very basic) root filesystem on + your harddrive. To be able to boot from floppy with this as your + root filesystem, you will have to edit the boot diskette. This is + done by modifying the word at offset 508 (decimal) with a program + such as Norton's Disk Editor, or use pboot.exe (available where + you got this file, the boot disk and the root disk, hopefully.) + + This word is in 386-order (that is, least-significant byte first), + which means it should look like one of the following: + + LSB MSB - device + -------------------------- + 01 03 - /dev/hda1 LSB = Least-Significant Byte + 02 03 - /dev/hda2 MSB = Most-Significant Byte + 03 03 - /dev/hda3 + 04 03 - /dev/hda4 + + 41 03 - /dev/hdb1 + 42 03 - /dev/hdb2 + 43 03 - /dev/hdb3 + 44 03 - /dev/hdb4 + + The numbers are in hex, and if you're editing the boot diskette by + hand, these two bytes should initially be 00 00 (and are followed + by two non-zero bytes). + + Note that pboot.exe predates Linux 0.95a, so some of the + information it presents is inaccurate (it refers to the old hd* + naming scheme). The codes to use are as above, but with the most- + significant byte first. (So /dev/hda1 = 0301, /dev/hda2 = 0302, + etc.) + +5) You should now be able to boot from this diskette and it will use + your new Linux partition as the root partition. You'll notice, + however, that you can't do a whole lot with just the programs on + the root diskette. You'll need to get further packages from + whereever you got the root and boot diskettes, and read these from + a floppy using tar and compress. (Simple instructions: Download + the file to DOS, use rawrite to write the tar file to diskette. + Use 'tar zxvf /dev/' to read the file from floppy, where + is the appropriate floppy device. (PS0 is a 1.44 meg + 3.5" as A:, PS1 is a 1.44 meg as B:, at0 is a 1.2 meg as A:, at1 + is a 1.2 meg as B:.) + +6) To reboot your machine when running Linux, you should use the + 'reboot' command. This makes sure to flush all caches to disk, + and notifies other users that the system is going down (well, the + last bit isn't real important). + + FAILURE TO DO THIS COULD RESULT IN BADLY CORRUPT FILESYSTEMS. + +---------------------------------------------------------------------------- + +These instructions are not the best, but should be enough to get you +going. If you have more questions, either post on comp.os.linux, or +send mail to me (jwinstea@jarthur.Claremont.EDU), or to Linus +(torvalds@cc.helsinki.fi). Remember, the only stupid questions are +the ones that you don't ask. diff --git a/Linux-0.96/docs/bash-man.dvi.tar.Z b/Linux-0.96/docs/bash-man.dvi.tar.Z new file mode 100644 index 00000000..dedfaeb4 Binary files /dev/null and b/Linux-0.96/docs/bash-man.dvi.tar.Z differ diff --git a/Linux-0.96/docs/kermit5A.doc.Z b/Linux-0.96/docs/kermit5A.doc.Z new file mode 100644 index 00000000..5d8cc904 Binary files /dev/null and b/Linux-0.96/docs/kermit5A.doc.Z differ diff --git a/Linux-0.96/docs/linux-history b/Linux-0.96/docs/linux-history new file mode 100644 index 00000000..23d23626 --- /dev/null +++ b/Linux-0.96/docs/linux-history @@ -0,0 +1,548 @@ +To: Linux-Activists@BLOOM-PICAYUNE.MIT.EDU +From: torvalds@klaava.Helsinki.FI (Linus Benedict Torvalds) +Subject: Birthday (was Re: Uptime found. Thanks to all) +Date: 31 Jul 92 22:15:20 GMT + +In article <1992Jul30.211132.20101@cc.umontreal.ca> duperval@ERE.UMontreal.CA (Duperval Laurent) writes: +> +>P.S. BTW, noone answered yet: when is Linux's birthday? Let's have a +>party! + +I couldn't for the life of me remember when it all happened, and I don't +keep a diary, so I can't give you any exact dates for when linux "was +born". But I did start to wonder, so I started ftp'ing around for +archives of the comp.os.minix group (where I announced it), and this is +what I came up with (with some editing). + +This is just a sentimental journey into some of the first posts +concerning linux, so you can happily press 'n' now if you actually +thought you'd get anything technical. + +> From: torvalds@klaava.Helsinki.FI (Linus Benedict Torvalds) +> Newsgroups: comp.os.minix +> Subject: Gcc-1.40 and a posix-question +> Message-ID: <1991Jul3.100050.9886@klaava.Helsinki.FI> +> Date: 3 Jul 91 10:00:50 GMT +> +> Hello netlanders, +> +> Due to a project I'm working on (in minix), I'm interested in the posix +> standard definition. Could somebody please point me to a (preferably) +> machine-readable format of the latest posix rules? Ftp-sites would be +> nice. + +The project was obviously linux, so by July 3rd I had started to think +about actual user-level things: some of the device drivers were ready, +and the harddisk actually worked. Not too much else. + +> As an aside for all using gcc on minix - [ deleted ] + +Just a success-report on porting gcc-1.40 to minix using the 1.37 +version made by Alan W Black & co. + +> Linus Torvalds torvalds@kruuna.helsinki.fi +> +> PS. Could someone please try to finger me from overseas, as I've +> installed a "changing .plan" (made by your's truly), and I'm not certain +> it works from outside? It should report a new .plan every time. + +So I was clueless - had just learned about named pipes. Sue me. This +part of the post got a lot more response than the actual POSIX query, +but the query did lure out arl from the woodwork, and we mailed around +for a bit, resulting in the Linux subdirectory on nic.funet.fi. + +Then, almost two months later, I actually had something working: I made +sources for version 0.01 available on nic sometimes around this time. +0.01 sources weren't actually runnable: they were just a token gesture +to arl who had probably started to despair about ever getting anything. +This next post must have been from just a couple of weeks before that +release. + +> From: torvalds@klaava.Helsinki.FI (Linus Benedict Torvalds) +> Newsgroups: comp.os.minix +> Subject: What would you like to see most in minix? +> Summary: small poll for my new operating system +> Message-ID: <1991Aug25.205708.9541@klaava.Helsinki.FI> +> Date: 25 Aug 91 20:57:08 GMT +> Organization: University of Helsinki +> +> +> Hello everybody out there using minix - +> +> I'm doing a (free) operating system (just a hobby, won't be big and +> professional like gnu) for 386(486) AT clones. This has been brewing +> since april, and is starting to get ready. I'd like any feedback on +> things people like/dislike in minix, as my OS resembles it somewhat +> (same physical layout of the file-system (due to practical reasons) +> among other things). +> +> I've currently ported bash(1.08) and gcc(1.40), and things seem to work. +> This implies that I'll get something practical within a few months, and +> I'd like to know what features most people would want. Any suggestions +> are welcome, but I won't promise I'll implement them :-) +> +> Linus (torvalds@kruuna.helsinki.fi) +> +> PS. Yes - it's free of any minix code, and it has a multi-threaded fs. +> It is NOT protable (uses 386 task switching etc), and it probably never +> will support anything other than AT-harddisks, as that's all I have :-(. + +Judging from the post, 0.01 wasn't actually out yet, but it's close. I'd +guess the first version went out in the middle of September -91. I got +some responses to this (most by mail, which I haven't saved), and I even +got a few mails asking to be beta-testers for linux. + +After that just a few general answers to quesions on the net: + +> From: torvalds@klaava.Helsinki.FI (Linus Benedict Torvalds) +> Newsgroups: comp.os.minix +> Subject: Re: What would you like to see most in minix? +> Summary: yes - it's nonportable +> Message-ID: <1991Aug26.110602.19446@klaava.Helsinki.FI> +> Date: 26 Aug 91 11:06:02 GMT +> Organization: University of Helsinki +> +> In article <1991Aug25.234450.22562@nntp.hut.fi> jkp@cs.HUT.FI (Jyrki Kuoppala) writes: +> >> [re: my post about my new OS] +> > +> >Tell us more! Does it need a MMU? +> +> Yes, it needs a MMU (sorry everybody), and it specifically needs a +> 386/486 MMU (see later). +> +> > +> >>PS. Yes - it's free of any minix code, and it has a multi-threaded fs. +> >>It is NOT protable (uses 386 task switching etc) +> > +> >How much of it is in C? What difficulties will there be in porting? +> >Nobody will believe you about non-portability ;-), and I for one would +> >like to port it to my Amiga (Mach needs a MMU and Minix is not free). +> +> Simply, I'd say that porting is impossible. It's mostly in C, but most +> people wouldn't call what I write C. It uses every conceivable feature +> of the 386 I could find, as it was also a project to teach me about the +> 386. As already mentioned, it uses a MMU, for both paging (not to disk +> yet) and segmentation. It's the segmentation that makes it REALLY 386 +> dependent (every task has a 64Mb segment for code & data - max 64 tasks +> in 4Gb. Anybody who needs more than 64Mb/task - tough cookies). +> +> It also uses every feature of gcc I could find, specifically the __asm__ +> directive, so that I wouldn't need so much assembly language objects. +> Some of my "C"-files (specifically mm.c) are almost as much assembler as +> C. It would be "interesting" even to port it to another compiler (though +> why anybody would want to use anything other than gcc is a mystery). + +[ editors note: linux has in fact gotten more portable with newer +versions: there was a lot more assembly in the early versions. Not that +anybody in their right mind would try to port it even now ] + +> Unlike minix, I also happen to LIKE interrupts, so interrupts are +> handled without trying to hide the reason behind them (I especially like +> my hard-disk-driver. Anybody else make interrupts drive a state- +> machine?). All in all it's a porters nightmare. +> +> >As for the features; well, pseudo ttys, BSD sockets, user-mode +> >filesystems (so I can say cat /dev/tcp/kruuna.helsinki.fi/finger), +> >window size in the tty structure, system calls capable of supporting +> >POSIX.1. Oh, and bsd-style long file names. +> +> Most of these seem possible (the tty structure already has stubs for +> window size), except maybe for the user-mode filesystems. As to POSIX, +> I'd be delighted to have it, but posix wants money for their papers, so +> that's not currently an option. In any case these are things that won't +> be supported for some time yet (first I'll make it a simple minix- +> lookalike, keyword SIMPLE). +> +> Linus (torvalds@kruuna.helsinki.fi) +> +> PS. To make things really clear - yes I can run gcc on it, and bash, and +> most of the gnu [bin/file]utilities, but it's not very debugged, and the +> library is really minimal. It doesn't even support floppy-disks yet. It +> won't be ready for distribution for a couple of months. Even then it +> probably won't be able to do much more than minix, and much less in some +> respects. It will be free though (probably under gnu-license or similar). + +Well, obviously something worked on my machine: I doubt I had yet gotten +gcc to compile itself under linux (or I would have been too proud of it +not to mention it). Still before any release-date. + +Then, October 5th, I seem to have released 0.02. As I already +mentioned, 0.01 didn't actually come with any binaries: it was just +source code for people interested in what linux looked like. Note the +lack of announcement for 0.01: I wasn't too proud of it, so I think I +only sent a note to everybody who had shown interest. + +> From: torvalds@klaava.Helsinki.FI (Linus Benedict Torvalds) +> Newsgroups: comp.os.minix +> Subject: Free minix-like kernel sources for 386-AT +> Message-ID: <1991Oct5.054106.4647@klaava.Helsinki.FI> +> Date: 5 Oct 91 05:41:06 GMT +> Organization: University of Helsinki +> +> Do you pine for the nice days of minix-1.1, when men were men and wrote +> their own device drivers? Are you without a nice project and just dying +> to cut your teeth on a OS you can try to modify for your needs? Are you +> finding it frustrating when everything works on minix? No more all- +> nighters to get a nifty program working? Then this post might be just +> for you :-) +> +> As I mentioned a month(?) ago, I'm working on a free version of a +> minix-lookalike for AT-386 computers. It has finally reached the stage +> where it's even usable (though may not be depending on what you want), +> and I am willing to put out the sources for wider distribution. It is +> just version 0.02 (+1 (very small) patch already), but I've successfully +> run bash/gcc/gnu-make/gnu-sed/compress etc under it. +> +> Sources for this pet project of mine can be found at nic.funet.fi +> (128.214.6.100) in the directory /pub/OS/Linux. The directory also +> contains some README-file and a couple of binaries to work under linux +> (bash, update and gcc, what more can you ask for :-). Full kernel +> source is provided, as no minix code has been used. Library sources are +> only partially free, so that cannot be distributed currently. The +> system is able to compile "as-is" and has been known to work. Heh. +> Sources to the binaries (bash and gcc) can be found at the same place in +> /pub/gnu. +> +> ALERT! WARNING! NOTE! These sources still need minix-386 to be compiled +> (and gcc-1.40, possibly 1.37.1, haven't tested), and you need minix to +> set it up if you want to run it, so it is not yet a standalone system +> for those of you without minix. I'm working on it. You also need to be +> something of a hacker to set it up (?), so for those hoping for an +> alternative to minix-386, please ignore me. It is currently meant for +> hackers interested in operating systems and 386's with access to minix. +> +> The system needs an AT-compatible harddisk (IDE is fine) and EGA/VGA. If +> you are still interested, please ftp the README/RELNOTES, and/or mail me +> for additional info. +> +> I can (well, almost) hear you asking yourselves "why?". Hurd will be +> out in a year (or two, or next month, who knows), and I've already got +> minix. This is a program for hackers by a hacker. I've enjouyed doing +> it, and somebody might enjoy looking at it and even modifying it for +> their own needs. It is still small enough to understand, use and +> modify, and I'm looking forward to any comments you might have. +> +> I'm also interested in hearing from anybody who has written any of the +> utilities/library functions for minix. If your efforts are freely +> distributable (under copyright or even public domain), I'd like to hear +> from you, so I can add them to the system. I'm using Earl Chews estdio +> right now (thanks for a nice and working system Earl), and similar works +> will be very wellcome. Your (C)'s will of course be left intact. Drop me +> a line if you are willing to let me use your code. +> +> Linus +> +> PS. to PHIL NELSON! I'm unable to get through to you, and keep getting +> "forward error - strawberry unknown domain" or something. + +Well, it doesn't sound like much of a system, does it? It did work, and +some people even tried it out. There were several bad bugs (and there +was no floppy-driver, no VM, no nothing), and 0.02 wasn't really very +useable. + +0.03 got released shortly thereafter (max 2-3 weeks was the time between +releases even back then), and 0.03 was pretty useable. The next version +was numbered 0.10, as things actually started to work pretty well. The +next post gives some idea of what had happened in two months more... + +> From: torvalds@klaava.Helsinki.FI (Linus Benedict Torvalds) +> Newsgroups: comp.os.minix +> Subject: Re: Status of LINUX? +> Summary: Still in beta +> Message-ID: <1991Dec19.233545.8114@klaava.Helsinki.FI> +> Date: 19 Dec 91 23:35:45 GMT +> Organization: University of Helsinki +> +> In article <469@htsa.htsa.aha.nl> miquels@maestro.htsa.aha.nl (Miquel van Smoorenburg) writes: +> >Hello *, +> > I know some people are working on a FREE O/S for the 386/486, +> >under the name Linux. I checked nic.funet.fi now and then, to see what was +> >happening. However, for the time being I am without FTP access so I don't +> >know what is going on at the moment. Could someone please inform me about it? +> >It's maybe best to follow up to this article, as I think that there are +> >a lot of potential interested people reading this group. Note, that I don't +> >really *have* a >= 386, but I'm sure in time I will. +> +> Linux is still in beta (although available for brave souls by ftp), and +> has reached the version 0.11. It's still not as comprehensive as +> 386-minix, but better in some respects. The "Linux info-sheet" should +> be posted here some day by the person that keeps that up to date. In +> the meantime, I'll give some small pointers. +> +> First the bad news: +> +> - Still no SCSI: people are working on that, but no date yet. +> Thus you need a AT-interface disk (I have one report that it +> works on an EISA 486 with a SCSI disk that emulates the +> AT-interface, but that's more of a fluke than anything else: +> ISA+AT-disk is currently the hardware setup) + +As you can see, 0.11 had already a small following. It wasn't much, but +it did work. + +> - still no init/login: you get into bash as root upon bootup. + +That was still standard in the next release. + +> - although I have a somewhat working VM (paging to disk), it's not +> ready yet. Thus linux needs at least 4M to be able to run the +> GNU binaries (especially gcc). It boots up in 2M, but you +> cannot compile. + +I actually released a 0.11+VM version just before Christmas -91: I +didn't need it myself, but people were trying to compile the kernel in +2MB and failing, so I had to implement it. The 0.11+VM version was +available only to a small number of people that wanted to test it out: +I'm still surprised it worked as well as it did. + +> - minix still has a lot more users: better support. +> +> - it hasn't got years of testing by thousands of people, so there +> are probably quite a few bugs yet. +> +> Then for the good things.. +> +> - It's free (copyright by me, but freely distributable under a +> very lenient copyright) + +The early copyright was in fact much more restrictive than the GNU +copyleft: I didn't allow any money at all to change hands due to linux. +That changed with 0.12. + +> - it's fun to hack on. +> +> - /real/ multithreading filesystem. +> +> - uses the 386-features. Thus locked into the 386/486 family, but +> it makes things clearer when you don't have to cater to other +> chips. +> +> - a lot more... read my .plan. +> +> /I/ think it's better than minix, but I'm a bit prejudiced. It will +> never be the kind of professional OS that Hurd will be (in the next +> century or so :), but it's a nice learning tool (even more so than +> minix, IMHO), and it was/is fun working on it. +> +> Linus (torvalds@kruuna.helsinki.fi) +> +> ---- my .plan -------------------------- +> Free UNIX for the 386 - coming 4QR 91 or 1QR 92. +> +> The current version of linux is 0.11 - it has most things a unix kernel +> needs, and will probably be released as 1.0 as soon as it gets a little +> more testing, and we can get a init/login going. Currently you get +> dumped into a shell as root upon bootup. +> +> Linux can be gotten by anonymous ftp from 'nic.funet.fi' (128.214.6.100) +> in the directory '/pub/OS/Linux'. The same directory also contains some +> binary files to run under Linux. Currently gcc, bash, update, uemacs, +> tar, make and fileutils. Several people have gotten a running system, +> but it's still a hackers kernel. +> +> Linux still requires a AT-compatible disk to be useful: people are +> working on a SCSI-driver, but I don't know when it will be ready. +> +> There are now a couple of other sites containing linux, as people have +> had difficulties with connecting to nic. The sites are: +> Tupac-Amaru.Informatik.RWTH-Aachen.DE (137.226.112.31): +> directory /pub/msdos/replace +> tsx-11.mit.edu (18.172.1.2): +> directory /pub/linux +> +> There is also a mailing list set up 'Linux-activists@niksula.hut.fi'. +> To join, mail a request to 'Linux-activists-request@niksula.hut.fi'. +> It's no use mailing me: I have no actual contact with the mailing-list +> (other than being on it, naturally). +> +> Mail me for more info: +> +> Linus (torvalds@kruuna.Helsinki.FI) +> +> 0.11 has these new things: +> +> - demand loading +> - code/data sharing between unrelated processes +> - much better floppy drivers (they actually work mostly) +> - bug-corrections +> - support for Hercules/MDA/CGA/EGA/VGA +> - the console also beeps (WoW! Wonder-kernel :-) +> - mkfs/fsck/fdisk +> - US/German/French/Finnish keyboards +> - settable line-speeds for com1/2 + +As you can see: 0.11 was actually stand-alone: I wrote the first +mkfs/fsck/fdisk programs for it, so that you didn't need minix any more +to set it up. Also, serial lines had been hard-coded to 2400bps, as that +was all I had. + +> Still lacking: +> - init/login +> - rename system call +> - named pipes +> - symbolic links + +Well, they are all there now: init/login didn't quite make it to 0.12, +and rename() was implemented as a patch somewhere between 0.12 and 0.95. +Symlinks were in 0.95, but named pipes didn't make it until 0.96. + +> 0.12 will probably be out in January (15th or so), and will have: +> - POSIX job control (by tytso) +> - VM (paging to disk) +> - Minor corrections + +Actually, 0.12 was out January 5th, and contained major corrections. It +was in fact a very stable kernel: it worked on a lot of new hardware, +and there was no need for patches for a long time. 0.12 was also the +kernel that "made it": that's when linux started to spread a lot faster. +Earlier kernel releases were very much only for hackers: 0.12 actually +worked quite well. + +That's all I found for 1991 - maybe it answered some questions. + + Linus + +----------------------------------------------------------------------------- + +To: Linux-Activists@BLOOM-PICAYUNE.MIT.EDU +From: torvalds@klaava.Helsinki.FI (Linus Benedict Torvalds) +Subject: Re: Writing an OS - questions !! +Date: 5 May 92 07:58:17 GMT + +In article <10685@inews.intel.com> nani@td2cad.intel.com (V. Narayanan) writes: +> +>Hi folks, +> For quite some time this "novice" has been wondering as to how one goes +>about the task of writing an OS from "scratch". So here are some questions, +>and I would appreciate if you could take time to answer 'em. + +Well, I see someone else already answered, but I thought I'd take on the +linux-specific parts. Just my personal experiences, and I don't know +how normal those are. + +>1) How would you typically debug the kernel during the development phase? + +Depends on both the machine and how far you have gotten on the kernel: +on more simple systems it's generally easier to set up. Here's what I +had to do on a 386 in protected mode. + +The worst part is starting off: after you have even a minimal system you +can use printf etc, but moving to protected mode on a 386 isn't fun, +especially if you at first don't know the architecture very well. It's +distressingly easy to reboot the system at this stage: if the 386 +notices something is wrong, it shuts down and reboots - you don't even +get a chance to see what's wrong. + +Printf() isn't very useful - a reboot also clears the screen, and +anyway, you have to have access to video-mem, which might fail if your +segments are incorrect etc. Don't even think about debuggers: no +debugger I know of can follow a 386 into protected mode. A 386 emulator +might do the job, or some heavy hardware, but that isn't usually +feasible. + +What I used was a simple killing-loop: I put in statements like + +die: + jmp die + +at strategic places. If it locked up, you were ok, if it rebooted, you +knew at least it happened before the die-loop. Alternatively, you might +use the sound io ports for some sound-clues, but as I had no experience +with PC hardware, I didn't even use that. I'm not saying this is the +only way: I didn't start off to write a kernel, I just wanted to explore +the 386 task-switching primitives etc, and that's how I started off (in +about April-91). + +After you have a minimal system up and can use the screen for output, it +gets a bit easier, but that's when you have to enable interrupts. Bang, +instant reboot, and back to the old way. All in all, it took about 2 +months for me to get all the 386 things pretty well sorted out so that I +no longer had to count on avoiding rebooting at once, and having the +basic things set up (paging, timer-interrupt and a simple task-switcher +to test out the segments etc). + +>2) Can you test the kernel functionality by running it as a process on a +> different OS? Wouldn't the OS(the development environment) generate +> exceptions in cases when the kernel (of the new OS) tries to modify +> 'priviledged' registers? + +Yes, it's generally possible for some things, but eg device drivers +usually have to be tested out on the bare machine. I used minix to +develop linux, so I had no access to IO registers, interrupts etc. +Under DOS it would have been possible to get access to all these, but +then you don't have 32-bit mode. Intel isn't that great - it would +probably have been much easier on a 68040 or similar. + +So after getting a simple task-switcher (it switched between two +processes that printed AAAA... and BBBB... respectively by using the +timer-interrupt - Gods I was proud over that), I still had to continue +debugging basically by using printf. The first thing written was the +keyboard driver: that's the reason it's still written completely in +assembler (I didn't dare move to C yet - I was still debugging at +about instruction-level). + +After that I wrote the serial drivers, and voila, I had a simple +terminal program running (well, not that simple actually). It was still +the same two processes (AAA..), but now they read and wrote to the +console/serial lines instead. I had to reboot to get out of it all, but +it was a simple kernel. + +After that is was plain sailing: hairy coding still, but I had some +devices, and debugging was easier. I started using C at this stage, and +it certainly speeds up developement. This is also when I start to get +serious about my megalomaniac ideas to make "a better minix that minix". +I was hoping I'd be able to recompile gcc under linux some day... + +The harddisk driver was more of the same: this time the problems with +bad documentation started to crop up. The PC may be the most used +architecture in the world right now, but that doesn't mean the docs are +any better: in fact I haven't seen /any/ book even mentioning the weird +386-387 coupling in an AT etc (Thanks Bruce). + +After that, a small filesystem, and voila, you have a minimal unix. Two +months for basic setups, but then only slightly longer until I had a +disk-driver (seriously buggy, but it happened to work on my machine) and +a small filesystem. That was about when I made 0.01 available (late +august-91? Something like that): it wasn't pretty, it had no floppy +driver, and it couldn't do much anything. I don't think anybody ever +compiled that version. But by then I was hooked, and didn't want to +stop until I could chuck out minix. + +>3) Would new linkers and loaders have to be written before you get a basic +> kernel running? + +All versions up to about 0.11 were crosscompiled under minix386 - as +were the user programs. I got bash and gcc eventually working under +0.02, and while a race-condition in the buffer-cache code prevented me +from recompiling gcc with itself, I was able to tackle smaller compiles. +0.03 (October?) was able to recompile gcc under itself, and I think +that's the first version that anybody else actually used. Still no +floppies, but most of the basic things worked. + +Afetr 0.03 I decided that the next version was actually useable (it was, +kind of, but boy is X under 0.96 more impressive), and I called the next +version 0.10 (November?). It still had a rather serious bug in the +buffer-cache handling code, but after patching that, it was pretty ok. +0.11 (December) had the first floppy driver, and was the point where I +started doing linux developement under itself. Quite as well, as I +trashed my minix386 partition by mistake when trying to autodial +/dev/hd2. + +By that time others were actually using linux, and running out of +memory. Especially sad was the fact that gcc wouldn't work on a 2MB +machine, and although c386 was ported, it didn't do everything gcc did, +and couldn't recompile the kernel. So I had to implement disk-paging: +0.12 came out in January (?) and had paging by me as well as job control +by tytso (and other patches: pmacdona had started on VC's etc). It was +the first release that started to have "non-essential" features, and +being partly written by others. It was also the first release that +actually did many things better than minix, and by now people started to +really get interested. + +Then it was 0.95 in March, bugfixes in April, and soon 0.96. It's +certainly been fun (and I trust will continue to be so) - reactions have +been mostly very positive, and you do learn a lot doing this type of +thing (on the other hand, your studies suffer in other respects :) + + Linus + diff --git a/Linux-0.96/docs/old.man2.tar.Z b/Linux-0.96/docs/old.man2.tar.Z new file mode 100644 index 00000000..28a053e4 Binary files /dev/null and b/Linux-0.96/docs/old.man2.tar.Z differ diff --git a/Linux-0.96/docs/perl.texinfo.Z b/Linux-0.96/docs/perl.texinfo.Z new file mode 100644 index 00000000..5451fa85 Binary files /dev/null and b/Linux-0.96/docs/perl.texinfo.Z differ diff --git a/Linux-0.96/docs/ue-man.tar.Z b/Linux-0.96/docs/ue-man.tar.Z new file mode 100644 index 00000000..1fd780d5 Binary files /dev/null and b/Linux-0.96/docs/ue-man.tar.Z differ diff --git a/Linux-0.96/images/bootimage-0.96 b/Linux-0.96/images/bootimage-0.96 new file mode 100644 index 00000000..5d2e04c6 Binary files /dev/null and b/Linux-0.96/images/bootimage-0.96 differ diff --git a/Linux-0.96/images/bootimage-0.96a b/Linux-0.96/images/bootimage-0.96a new file mode 100644 index 00000000..ff84b35b Binary files /dev/null and b/Linux-0.96/images/bootimage-0.96a differ diff --git a/Linux-0.96/images/bootimage-0.96b b/Linux-0.96/images/bootimage-0.96b new file mode 100644 index 00000000..e81435b5 Binary files /dev/null and b/Linux-0.96/images/bootimage-0.96b differ diff --git a/Linux-0.96/images/bootimage-0.96c b/Linux-0.96/images/bootimage-0.96c new file mode 100644 index 00000000..2d8009c3 Binary files /dev/null and b/Linux-0.96/images/bootimage-0.96c differ diff --git a/Linux-0.96/patchs/extfs-0.96c-patch b/Linux-0.96/patchs/extfs-0.96c-patch new file mode 100644 index 00000000..e5a12f3a Binary files /dev/null and b/Linux-0.96/patchs/extfs-0.96c-patch differ diff --git a/Linux-0.96/patchs/mouse.tar b/Linux-0.96/patchs/mouse.tar new file mode 100644 index 00000000..af5f435f Binary files /dev/null and b/Linux-0.96/patchs/mouse.tar differ diff --git a/Linux-0.96/patchs/patch-for-extfs-for-inode-bug b/Linux-0.96/patchs/patch-for-extfs-for-inode-bug new file mode 100644 index 00000000..f5414afd Binary files /dev/null and b/Linux-0.96/patchs/patch-for-extfs-for-inode-bug differ diff --git a/Linux-0.96/patchs/patch-for-extfs-for-rename-bug b/Linux-0.96/patchs/patch-for-extfs-for-rename-bug new file mode 100644 index 00000000..a7079b76 Binary files /dev/null and b/Linux-0.96/patchs/patch-for-extfs-for-rename-bug differ diff --git a/Linux-0.96/patchs/patch-for-gnuplot_x11 b/Linux-0.96/patchs/patch-for-gnuplot_x11 new file mode 100644 index 00000000..7304dd63 --- /dev/null +++ b/Linux-0.96/patchs/patch-for-gnuplot_x11 @@ -0,0 +1,80 @@ +Return-Path: +Received: from funet.fi by lazy.qt.IPA.FhG.de with SMTP + (5.61+/IDA-1.2.8/gandalf.2) id AA08341; Wed, 10 Jun 92 07:53:54 +0200 +Received: from santra.hut.fi by funet.fi with SMTP (PP) id <29569-0@funet.fi>; + Wed, 10 Jun 1992 08:44:29 +0300 +Received: from joker.cs.hut.fi by santra.hut.fi (5.65c/8.0/TeKoLa) id AA10220; + Wed, 10 Jun 1992 08:42:21 +0300 +Received: by joker.cs.hut.fi (5.65b/6.8/S-TeKoLa) id AA12590; + Wed, 10 Jun 92 08:41:52 +0259 +Received: from relay2.UU.NET by joker.cs.hut.fi (5.65b/6.8/S-TeKoLa) id AA12557; + Wed, 10 Jun 92 08:38:49 +0259 +Received: from world.std.com by relay2.UU.NET + with SMTP (5.61/UUNET-internet-primary) id AA26986; + Wed, 10 Jun 92 01:38:59 -0400 +Received: by world.std.com (5.61+++/Spike-2.0) id AA13768; + Wed, 10 Jun 92 01:38:59 -0400 +Date: Wed, 10 Jun 92 01:38:59 -0400 +From: jrs@world.std.com (Rick Sladkey) +Message-Id: <9206100538.AA13768@world.std.com> +Sender: owner-linux-activists@niksula.hut.fi +To: linux-activists@niksula.hut.fi +X-Note1: Remember to put 'X-Mn-Key: normal' to your mail body or header +Cc: linux-activists@joker.cs.hut.fi +Subject: gnuplot_x11 +In-Reply-To: <199206091859.AA04063@santra.hut.fi> +References: <199206091859.AA04063@santra.hut.fi> +X-Mn-Key: X11 + +>>>>> On Tue, 09 Jun 92 19:22:16 +0100, mfd1%ukc.ac.uk@FINHUTC.hut.fi said: + +Mitch> has anyone gotten gnuplot to work with X with SPLOTS ?? + +Yes, but it took some work... + +Mitch> Well I tried compiling it with the linux defs in as well (so it +Mitch> works without X11 also i.e. with vgalib) and it compiles ok, +Mitch> even the gnuplot_x11 but when it runs and I try to do a surface +Mitch> plot I get big patches of color all over the plot (usually +Mitch> black). This also happens with hidden line removal! + +I had exactly this problem. + +Mitch> So what am I doing wrong, and is this a gcc or X11 problem ?? + +Well, if I knew much about X, I might be able to figure out what the +source of the problem is. But since I don't, I'll just say what I +did to fix it. gnuplot talks to gnuplot_x11 through a pipe so I wrote +all the output to a debug file and then experimented with sending +variations of the file directly to gnuplot_x11. I discovered that +the line-type command was at fault. gnuplot uses line-types -2 and -1 +to represent borders or axes or something and types 0 through 7 (?) +for different colors. Types -2 and -1 cause gnuplot_x11 to use +a X11 line-width of 2 instead of 0. I suppose this is meant to select +2 pixel-wide lines but they come out more like 2 inches wide... + +Anyway, here is the relevant patch. + +Rick Sladkey +jrs@world.std.com +----- +diff -rc ../gnuplot.orig/gnuplot_x11.c ./gnuplot_x11.c +*** ../gnuplot.orig/gnuplot_x11.c Mon Sep 9 20:13:19 1991 +--- ./gnuplot_x11.c Tue May 26 21:51:59 1992 +*************** +*** 202,209 **** +--- 202,214 ---- + /* X11_linetype(type) - set line type */ + else if (*buf == 'L') { + sscanf(buf, "L%4d", <); ++ #if linux ++ lt = (lt+2)%10; ++ width = 0; ++ #else + lt = (lt%8)+2; + width = (lt == 0) ? 2 : 0; ++ #endif + if (Color) { + if (lt != 1) + type = LineSolid; + diff --git a/Linux-0.96/patchs/patch-for-scsi.c b/Linux-0.96/patchs/patch-for-scsi.c new file mode 100644 index 00000000..ff64fcfd Binary files /dev/null and b/Linux-0.96/patchs/patch-for-scsi.c differ diff --git a/Linux-0.96/patchs/patch0.96a.pl4-0.96b.Z b/Linux-0.96/patchs/patch0.96a.pl4-0.96b.Z new file mode 100644 index 00000000..01044509 Binary files /dev/null and b/Linux-0.96/patchs/patch0.96a.pl4-0.96b.Z differ diff --git a/Linux-0.96/sources/compilers/cvw.src.tar.Z b/Linux-0.96/sources/compilers/cvw.src.tar.Z new file mode 100644 index 00000000..f6bad03e Binary files /dev/null and b/Linux-0.96/sources/compilers/cvw.src.tar.Z differ diff --git a/Linux-0.96/sources/sbin/adduser-0.96.tar.Z b/Linux-0.96/sources/sbin/adduser-0.96.tar.Z new file mode 100644 index 00000000..6ca2cbec Binary files /dev/null and b/Linux-0.96/sources/sbin/adduser-0.96.tar.Z differ diff --git a/Linux-0.96/sources/sbin/adduser.tar.Z b/Linux-0.96/sources/sbin/adduser.tar.Z new file mode 100644 index 00000000..6ca2cbec Binary files /dev/null and b/Linux-0.96/sources/sbin/adduser.tar.Z differ diff --git a/Linux-0.96/sources/sbin/fdformat.c b/Linux-0.96/sources/sbin/fdformat.c new file mode 100644 index 00000000..62c3b6d0 --- /dev/null +++ b/Linux-0.96/sources/sbin/fdformat.c @@ -0,0 +1,100 @@ +/* fdformat.c - Low-level formats a floppy disk. */ + +#include +#include +#include +#include +#include + + +static int ctrl; +struct floppy_struct param; + + +#define SECTOR_SIZE 512 +#define PERROR(msg) { perror(msg); exit(1); } + + +static void format_disk(char *name) +{ + struct format_descr descr; + int track; + char dummy; + + printf("Formatting ... "); + fflush(stdout); + if (ioctl(ctrl,FDFMTBEG,NULL) < 0) PERROR("\nioctl(FDFMTBEG)"); + for (track = 0; track < param.track; track++) { + descr.track = track; + descr.head = 0; + if (ioctl(ctrl,FDFMTTRK,(int) &descr) < 0) PERROR("\nioctl(FDFMTTRK)"); + printf("%3d\b\b\b",track); + fflush(stdout); + if (param.head == 2) { + descr.head = 1; + if (ioctl(ctrl,FDFMTTRK,(int) &descr) < 0) + PERROR("\nioctl(FDFMTTRK)"); + } + } + if (ioctl(ctrl,FDFMTEND,NULL) < 0) PERROR("\nioctl(FDFMTEND)"); + printf("done\n"); +} + + +static void verify_disk(char *name) +{ + unsigned char *data; + int fd,cyl_size,cyl,count; + + cyl_size = param.sect*param.head*512; + if ((data = (unsigned char *) malloc(cyl_size)) == NULL) PERROR("malloc"); + printf("Verifying ... "); + fflush(stdout); + if ((fd = open(name,O_RDONLY)) < 0) PERROR(name); + for (cyl = 0; cyl < param.track; cyl++) { + printf("%3d\b\b\b",cyl); + fflush(stdout); + if (read(fd,data,cyl_size) != cyl_size) PERROR("read"); + for (count = 0; count < cyl_size; count++) + if (data[count] != FD_FILL_BYTE) { + printf("bad data in cyl %d\nContinuing ... ",cyl); + fflush(stdout); + break; + } + } + printf("done\n"); + if (close(fd) < 0) PERROR("close"); +} + + +static void usage(char *name) +{ + char *this; + + if (this = strrchr(name,'/')) name = this+1; + fprintf(stderr,"usage: %s [ -n ] device\n",name); + exit(1); +} + + +main(int argc,char **argv) +{ + int verify; + char *name; + + name = argv[0]; + verify = 1; + if (argc > 1 && argv[1][0] == '-') { + if (argv[1][1] != 'n') usage(name); + verify = 0; + argc--; + argv++; + } + if (argc != 2) usage(name); + if ((ctrl = open(argv[1],3)) < 0) PERROR(argv[1]); + if (ioctl(ctrl,FDGETPRM,(int) ¶m) < 0) PERROR("ioctl(FDGETPRM)"); + printf("%sle-sided, %d tracks, %d sec/track. Total capacity %d kB.\n", + param.head ? "Doub" : "Sing",param.track,param.sect,param.size >> 1); + format_disk(argv[1]); + if (verify) verify_disk(argv[1]); +} diff --git a/Linux-0.96/sources/system/fixkbd.tar.Z b/Linux-0.96/sources/system/fixkbd.tar.Z new file mode 100644 index 00000000..8f64fee8 Binary files /dev/null and b/Linux-0.96/sources/system/fixkbd.tar.Z differ diff --git a/Linux-0.96/sources/system/linux-0.96a.patch2.Z b/Linux-0.96/sources/system/linux-0.96a.patch2.Z new file mode 100644 index 00000000..2cfcda8e Binary files /dev/null and b/Linux-0.96/sources/system/linux-0.96a.patch2.Z differ diff --git a/Linux-0.96/sources/system/linux-0.96a.patch3.Z b/Linux-0.96/sources/system/linux-0.96a.patch3.Z new file mode 100644 index 00000000..c3aa7440 Binary files /dev/null and b/Linux-0.96/sources/system/linux-0.96a.patch3.Z differ diff --git a/Linux-0.96/sources/system/linux-0.96a.patch4.Z b/Linux-0.96/sources/system/linux-0.96a.patch4.Z new file mode 100644 index 00000000..ea93c054 Binary files /dev/null and b/Linux-0.96/sources/system/linux-0.96a.patch4.Z differ diff --git a/Linux-0.96/sources/system/linux-0.96a.tar.Z b/Linux-0.96/sources/system/linux-0.96a.tar.Z new file mode 100644 index 00000000..659f07f1 Binary files /dev/null and b/Linux-0.96/sources/system/linux-0.96a.tar.Z differ diff --git a/Linux-0.96/sources/system/linux-0.96b.1.tar.gz b/Linux-0.96/sources/system/linux-0.96b.1.tar.gz new file mode 100644 index 00000000..924971be Binary files /dev/null and b/Linux-0.96/sources/system/linux-0.96b.1.tar.gz differ diff --git a/Linux-0.96/sources/system/linux-0.96b.patch1.Z b/Linux-0.96/sources/system/linux-0.96b.patch1.Z new file mode 100644 index 00000000..708c2972 Binary files /dev/null and b/Linux-0.96/sources/system/linux-0.96b.patch1.Z differ diff --git a/Linux-0.96/sources/system/linux-0.96b.patch2.Z b/Linux-0.96/sources/system/linux-0.96b.patch2.Z new file mode 100644 index 00000000..cb4ed458 Binary files /dev/null and b/Linux-0.96/sources/system/linux-0.96b.patch2.Z differ diff --git a/Linux-0.96/sources/system/linux-0.96b.tar.Z b/Linux-0.96/sources/system/linux-0.96b.tar.Z new file mode 100644 index 00000000..1f81ae5d Binary files /dev/null and b/Linux-0.96/sources/system/linux-0.96b.tar.Z differ diff --git a/Linux-0.96/sources/system/linux-0.96c.patch1 b/Linux-0.96/sources/system/linux-0.96c.patch1 new file mode 100644 index 00000000..7425d7d7 --- /dev/null +++ b/Linux-0.96/sources/system/linux-0.96c.patch1 @@ -0,0 +1,4265 @@ +*** 0.96c/linux/Makefile Sun Jul 5 03:09:23 1992 +--- linux/Makefile Sat Jul 11 20:11:52 1992 +*************** +*** 89,95 **** + + Version: + @./makever.sh +! @echo \#define UTS_RELEASE \"0.96c-`cat .version`\" > include/linux/config_rel.h + @echo \#define UTS_VERSION \"`date +%D`\" > include/linux/config_ver.h + touch include/linux/config.h + +--- 89,95 ---- + + Version: + @./makever.sh +! @echo \#define UTS_RELEASE \"0.96c.pl1-`cat .version`\" > include/linux/config_rel.h + @echo \#define UTS_VERSION \"`date +%D`\" > include/linux/config_ver.h + touch include/linux/config.h + +*** 0.96c/linux/boot/setup.S Tue May 19 03:36:58 1992 +--- linux/boot/setup.S Thu Jul 9 14:41:55 1992 +*************** +*** 189,197 **** + out #0xA1,al + .word 0x00eb,0x00eb + mov al,#0xFF ! mask off all interrupts for now +- out #0x21,al +- .word 0x00eb,0x00eb + out #0xA1,al + + ! well, that certainly wasn't fun :-(. Hopefully it works, and we don't + ! need no steenking BIOS anyway (except for the initial loading :-). +--- 189,198 ---- + out #0xA1,al + .word 0x00eb,0x00eb + mov al,#0xFF ! mask off all interrupts for now + out #0xA1,al ++ .word 0x00eb,0x00eb ++ mov al,#0xFB ! mask all irq's but irq2 which ++ out #0x21,al ! is cascaded + + ! well, that certainly wasn't fun :-(. Hopefully it works, and we don't + ! need no steenking BIOS anyway (except for the initial loading :-). +*************** +*** 241,250 **** + push ds + push cs + pop ds +! mov ax,#0xc000 + mov es,ax + lea si,msg1 +! call prtstr + flush: in al,#0x60 ! Flush the keyboard buffer + cmp al,#0x82 + jb nokey +--- 242,316 ---- + push ds + push cs + pop ds +! +! ! First try and execute a VESA BIOS call +! +! mov ax,#0x4f00 ! AX = VESA BIOS func RETURN SVGA Info +! push cs +! pop es +! lea di,vib ! ES:[DI] -> VESA Information Block Ptr +! int 0x10 +! +! cmp ax,#0x004f ! Check result status +! jne novesa ! VESA BIOS not supported or failed +! +! ! OK! We got a VESA BIOS, let's figure out what we can do! +! +! ! Print out the VESA information from the VIB +! +! lea si,vib ! This should print out VESA +! lodsb +! call prnt1 +! lodsb +! call prnt1 +! lodsb +! call prnt1 +! lodsb +! call prnt1 +! call space +! +! mov al,vib+5 ! This is the version of VESA supported +! call dprnt +! mov al,#0x2e +! call prnt1 +! mov al,vib+4 +! call dprnt +! call space +! +! push ds +! lds si,vib+6 ! This prints out the OEM string +! call prtstr +! call space +! pop ds +! +! mov al,vib+10 ! This prints out the Vesa Capabilities +! call dprnt +! mov al,vib+11 +! call dprnt +! mov al,vib+12 +! call dprnt +! mov al,vib+13 +! call dprnt +! +! push ds ! Finally, go through the list of modes +! lds si,vib+14 +! model: lodsw ! Get mode number +! cmp ax,#0xFFFF +! je isvesa +! call addmod ! Check to see if this is a TEXT mode +! jmp model +! +! isvesa: call docr +! pop ds +! lea si,dscvesa +! lea di,movesa +! lea cx,selmod +! jmp cx +! +! novesa: mov ax,#0xc000 + mov es,ax + lea si,msg1 +! call prtstr ! Press to see SVGA-modes ... + flush: in al,#0x60 ! Flush the keyboard buffer + cmp al,#0x82 + jb nokey +*************** +*** 463,485 **** + mov al,#0x55 + xor al,#0xea + cmp al,bh +! jne novid7 + lea si,dscvideo7 + lea di,movideo7 + selmod: push si +! lea si,msg2 + call prtstr +! xor cx,cx +! mov cl,(di) + pop si + push si + push cx + tbl: pop bx + push bx +! mov al,bl +! sub al,cl +! call dprnt + call spcing + lodsw + xchg al,ah + call dprnt +--- 529,566 ---- + mov al,#0x55 + xor al,#0xea + cmp al,bh +! je isvideo7 +! lea cx,set8x8 +! jmp cx +! isvideo7: + lea si,dscvideo7 + lea di,movideo7 ++ ++ ! Upon Entry to SELMOD, SI -> list of Modes, DI -> List of Mode Numbers ++ + selmod: push si +! lea si,msg2 ! Numb: Mode: COLSxROWS + call prtstr +! mov cx,(di) ! This gets Number of Modes in list + pop si + push si + push cx + tbl: pop bx + push bx +! mov ax,bx +! sub ax,cx +! call hprntl ! Print out selection number +! push ax + call spcing ++ pop ax ++ push di ++ add ax,ax ++ add ax,#2 ++ add di,ax ++ mov ax,(di) ++ call hprntl ! Print out MODE number ++ call spcing ++ pop di + lodsw + xchg al,ah + call dprnt +*************** +*** 493,499 **** + loop tbl + pop cx + call docr +! lea si,msg3 + call prtstr + pop si + add cl,#0x80 +--- 574,580 ---- + loop tbl + pop cx + call docr +! lea si,msg3 ! Choose Mode Number + call prtstr + pop si + add cl,#0x80 +*************** +*** 509,526 **** + nozero: sub al,#0x80 + dec al + xor ah,ah + add di,ax + inc di +! push ax +! mov al,(di) +! int 0x10 + pop ax +- shl ax,#1 + add si,ax +! lodsw + pop ds + ret +! novid7: + mov ax,#0x1112 + mov bl,#0 + int 0x10 ! use 8x8 font set (50 lines on VGA) +--- 590,627 ---- + nozero: sub al,#0x80 + dec al + xor ah,ah ++ shl ax,#1 ++ push ax + add di,ax + inc di +! inc di +! mov ax,(di) ! AX = Mode +! cmp ah,#0 +! jne setvesa +! int 0x10 ! Set OLD style mode +! +! retmode: + pop ax + add si,ax +! lodsw ! Get COLSxROWS + pop ds + ret +! +! setvesa: +! pop bx +! cmp ah,#0xFF ! Special, mode FF, set 8x8 font +! je set8x8 +! +! push bx +! mov bx,ax ! Mode to set +! mov ax,#0x4f02 ! Set VESA mode +! int 0x10 +! +! jmp retmode +! +! ! If we can't find the adapter in the table, at least set 80x50 +! +! set8x8: + mov ax,#0x1112 + mov bl,#0 + int 0x10 ! use 8x8 font set (50 lines on VGA) +*************** +*** 541,557 **** + mov ax,#0x5032 ! return 80x50 + ret + + ! Routine that 'tabs' to next col. + + spcing: mov al,#0x2e +- call prnt1 +- mov al,#0x20 + call prnt1 +! mov al,#0x20 + call prnt1 +! mov al,#0x20 + call prnt1 +! mov al,#0x20 + call prnt1 + ret + +--- 642,724 ---- + mov ax,#0x5032 ! return 80x50 + ret + ++ ! Routine to add mode in ax to VESA selection table ++ ++ addmod: push cx ++ push ds ++ push es ++ push di ++ push bx ++ push dx ++ push ax ++ ++ mov cx,ax ! CX = VESA mode number ++ push cs ++ pop es ++ lea di,mib ! ES:[DI] -> Mode Information Block ++ mov ax,#0x4f01 ! AX = Get VESA Mode Info ++ int 0x10 ++ ++ cmp ax,#0x004f ! If fails, assume it's not a TEXT mode ++ jne adfail ++ ++ push cs ++ pop ds ! Make DS contain something reasonable ++ ++ mov ax,mib ! Get Mode Attributes field ++ and al,#0x12 ! Mask Text and Extended bits ++ cmp al,#0x02 ! Text and Extended info available? ++ jne adfail ++ ++ call space ++ ++ mov ax,mib+18 ! Horizontal Resolution ++ mov bl,mib+22 ! X Char Size ++ div bl ++ ! HACK: For some reason, my Diamond Stealth card returns 160 cols for its ++ ! 132 coloumn modes, so don't return any sizes > 132? ++ sub al,#132 ++ jbe orgcol ++ sub al,al ++ orgcol: add al,#132 ! MIN(cols, 132) ++ mov dh,al ! Put num cols in DH ++ mov ax,mib+20 ! Vertical Resolution ++ mov bl,mib+23 ! Y Char Size ++ div bl ++ mov dl,al ! Put num rows in DL ++ ++ mov bx,movesa ! Get current number of video modes ++ lea di,movesa ++ inc (di) ! This is a NEW mode ++ add bx,bx ++ add di,bx ++ add di,#2 ++ pop ax ! Get Mode number back ++ push ax ++ mov (di),ax ! Mode number ++ lea di,dscvesa ++ add di,bx ++ mov (di),dx ! Screen resolution ++ ++ adfail: pop ax ++ pop dx ++ pop bx ++ pop di ++ pop es ++ pop ds ++ pop cx ++ ++ ret ++ + ! Routine that 'tabs' to next col. + + spcing: mov al,#0x2e + call prnt1 +! space3: mov al,#0x20 + call prnt1 +! space2: mov al,#0x20 + call prnt1 +! space: mov al,#0x20 + call prnt1 + ret + +*************** +*** 564,569 **** +--- 731,769 ---- + jmp prtstr + fin: ret + ++ ! Routine to print out HEX values on screen. ++ ! The value to be printed is in the AX register. ++ ++ hprntl: xchg ah,al ++ call hprnt ++ xchg ah,al ++ call hprnt ++ ret ++ ++ ! Routine to print out HEX values on the screen ++ ! The valueto be printed is in the AL register. AH is preserved. ++ ++ hprnt: push ax ++ shr al,4 ++ and al,#0xf ++ call hprnt1 ++ pop ax ++ push ax ++ and al,#0xf ++ call hprnt1 ++ pop ax ++ ret ++ ++ ! Routine to print out one HEX digit on the screen. ++ ! The value to be printed is in al (0-F) ++ ++ hprnt1: cmp al,#10 ++ jl hdec ++ add al,#7 ! Convert 10-15 to A-F ++ hdec: add al,#0x30 ! Convert to ASCII ++ call prnt1 ! print it ++ ret ++ + ! Routine to print a decimal value on screen, the value to be + ! printed is put in al (i.e 0-255). + +*************** +*** 635,641 **** + + msg1: .ascii "Press to see SVGA-modes available or any other key to continue." + db 0x0d, 0x0a, 0x0a, 0x00 +! msg2: .ascii "Mode: COLSxROWS:" + db 0x0d, 0x0a, 0x0a, 0x00 + msg3: .ascii "Choose mode by pressing the corresponding number." + db 0x0d, 0x0a, 0x00 +--- 835,841 ---- + + msg1: .ascii "Press to see SVGA-modes available or any other key to continue." + db 0x0d, 0x0a, 0x0a, 0x00 +! msg2: .ascii "Numb: Mode: COLSxROWS:" + db 0x0d, 0x0a, 0x0a, 0x00 + msg3: .ascii "Choose mode by pressing the corresponding number." + db 0x0d, 0x0a, 0x00 +*************** +*** 647,662 **** + + ! Manufacturer: Numofmodes: Mode: + +! moati: .byte 0x02, 0x23, 0x33 +! moahead: .byte 0x05, 0x22, 0x23, 0x24, 0x2f, 0x34 +! mocandt: .byte 0x02, 0x60, 0x61 +! mocirrus: .byte 0x04, 0x1f, 0x20, 0x22, 0x31 +! moeverex: .byte 0x0a, 0x03, 0x04, 0x07, 0x08, 0x0a, 0x0b, 0x16, 0x18, 0x21, 0x40 +! mogenoa: .byte 0x0a, 0x58, 0x5a, 0x60, 0x61, 0x62, 0x63, 0x64, 0x72, 0x74, 0x78 +! moparadise: .byte 0x02, 0x55, 0x54 +! motrident: .byte 0x07, 0x50, 0x51, 0x52, 0x57, 0x58, 0x59, 0x5a +! motseng: .byte 0x05, 0x26, 0x2a, 0x23, 0x24, 0x22 +! movideo7: .byte 0x06, 0x40, 0x43, 0x44, 0x41, 0x42, 0x45 + + ! msb = Cols lsb = Rows: + +--- 847,863 ---- + + ! Manufacturer: Numofmodes: Mode: + +! moati: .word 0x02, 0x23, 0x33 +! moahead: .word 0x05, 0x22, 0x23, 0x24, 0x2f, 0x34 +! mocandt: .word 0x02, 0x60, 0x61 +! mocirrus: .word 0x04, 0x1f, 0x20, 0x22, 0x31 +! moeverex: .word 0x0a, 0x03, 0x04, 0x07, 0x08, 0x0a, 0x0b, 0x16, 0x18, 0x21, 0x40 +! mogenoa: .word 0x0a, 0x58, 0x5a, 0x60, 0x61, 0x62, 0x63, 0x64, 0x72, 0x74, 0x78 +! moparadise: .word 0x02, 0x55, 0x54 +! motrident: .word 0x07, 0x50, 0x51, 0x52, 0x57, 0x58, 0x59, 0x5a +! motseng: .word 0x05, 0x26, 0x2a, 0x23, 0x24, 0x22 +! movideo7: .word 0x06, 0x40, 0x43, 0x44, 0x41, 0x42, 0x45 +! movesa: .word 0x02, 0x03, 0xFFFF, 254*0 + + ! msb = Cols lsb = Rows: + +*************** +*** 670,676 **** +--- 871,881 ---- + dsctrident: .word 0x501e, 0x502b, 0x503c, 0x8419, 0x841e, 0x842b, 0x843c + dsctseng: .word 0x503c, 0x6428, 0x8419, 0x841c, 0x842c + dscvideo7: .word 0x502b, 0x503c, 0x643c, 0x8419, 0x842c, 0x841c ++ dscvesa: .word 0x5019, 0x5032, 254*0 + ++ vib: .word 256*0 ++ mib: .word 256*0 ++ + .text + endtext: + .data +*** 0.96c/linux/fs/inode.c Thu Jul 2 00:42:04 1992 +--- linux/fs/inode.c Sat Jul 11 01:37:05 1992 +*************** +*** 252,257 **** +--- 252,258 ---- + } + inode->i_dev = dev; + inode->i_ino = nr; ++ inode->i_flags = inode->i_sb->s_flags; + read_inode(inode); + return inode; + } +*** 0.96c/linux/fs/open.c Thu Jul 2 00:42:04 1992 +--- linux/fs/open.c Sat Jul 11 03:58:46 1992 +*************** +*** 73,78 **** +--- 73,82 ---- + iput(inode); + return -EACCES; + } ++ if (IS_RDONLY(inode)) { ++ iput(inode); ++ return -EROFS; ++ } + inode->i_size = length; + if (inode->i_op && inode->i_op->truncate) + inode->i_op->truncate(inode); +*************** +*** 91,97 **** + return -EBADF; + if (!(inode = file->f_inode)) + return -ENOENT; +! if (S_ISDIR(inode->i_mode) || !(file->f_flags & 2)) + return -EACCES; + inode->i_size = length; + if (inode->i_op && inode->i_op->truncate) +--- 95,101 ---- + return -EBADF; + if (!(inode = file->f_inode)) + return -ENOENT; +! if (S_ISDIR(inode->i_mode) || !(file->f_mode & 2)) + return -EACCES; + inode->i_size = length; + if (inode->i_op && inode->i_op->truncate) +*************** +*** 112,117 **** +--- 116,125 ---- + + if (!(inode=namei(filename))) + return -ENOENT; ++ if (IS_RDONLY(inode)) { ++ iput(inode); ++ return -EROFS; ++ } + if (times) { + if ((current->euid != inode->i_uid) && !suser()) { + iput(inode); +*************** +*** 215,220 **** +--- 223,230 ---- + return -ENOENT; + if ((current->euid != inode->i_uid) && !suser()) + return -EPERM; ++ if (IS_RDONLY(inode)) ++ return -EROFS; + inode->i_mode = (mode & 07777) | (inode->i_mode & ~07777); + inode->i_dirt = 1; + return 0; +*************** +*** 230,235 **** +--- 240,249 ---- + iput(inode); + return -EPERM; + } ++ if (IS_RDONLY(inode)) { ++ iput(inode); ++ return -EROFS; ++ } + inode->i_mode = (mode & 07777) | (inode->i_mode & ~07777); + inode->i_dirt = 1; + iput(inode); +*************** +*** 245,250 **** +--- 259,266 ---- + return -EBADF; + if (!(inode = file->f_inode)) + return -ENOENT; ++ if (IS_RDONLY(inode)) ++ return -EROFS; + if ((current->euid == inode->i_uid && user == inode->i_uid && + (in_group_p(group) || group == inode->i_gid)) || + suser()) { +*************** +*** 262,267 **** +--- 278,287 ---- + + if (!(inode = lnamei(filename))) + return -ENOENT; ++ if (IS_RDONLY(inode)) { ++ iput(inode); ++ return -EROFS; ++ } + if ((current->euid == inode->i_uid && user == inode->i_uid && + (in_group_p(group) || group == inode->i_gid)) || + suser()) { +*************** +*** 325,330 **** +--- 345,351 ---- + int sys_close(unsigned int fd) + { + struct file * filp; ++ struct inode * inode; + + if (fd >= NR_OPEN) + return -EINVAL; +*************** +*** 340,348 **** + filp->f_count--; + return 0; + } + if (filp->f_op && filp->f_op->release) +! filp->f_op->release(filp->f_inode,filp); +! iput(filp->f_inode); + filp->f_count--; + return 0; + } +--- 361,370 ---- + filp->f_count--; + return 0; + } ++ inode = filp->f_inode; + if (filp->f_op && filp->f_op->release) +! filp->f_op->release(inode,filp); + filp->f_count--; ++ iput(inode); + return 0; + } +*** 0.96c/linux/fs/exec.c Thu Jul 2 01:30:00 1992 +--- linux/fs/exec.c Sat Jul 11 00:49:32 1992 +*************** +*** 183,189 **** + iput(inode); + return -EACCES; + } +! if (!(bh = bread(inode->i_dev,inode->i_data[0]))) { + iput(inode); + return -EACCES; + } +--- 183,189 ---- + iput(inode); + return -EACCES; + } +! if (!(bh = bread(inode->i_dev,bmap(inode,0)))) { + iput(inode); + return -EACCES; + } +*************** +*** 406,412 **** +--- 406,422 ---- + retval = -EACCES; + goto exec_error2; + } ++ if (IS_NOEXEC(inode)) { /* FS mustn't be mounted noexec */ ++ retval = -EPERM; ++ goto exec_error2; ++ } + i = inode->i_mode; ++ if (IS_NOSUID(inode) && (((i & S_ISUID) && inode->i_uid != current-> ++ euid) || ((i & S_ISGID) && inode->i_gid != current->egid)) && ++ !suser()) { ++ retval = -EPERM; ++ goto exec_error2; ++ } + /* make sure we don't let suid, sgid files be ptraced. */ + if (current->flags & PF_PTRACED) { + e_uid = current->euid; +*************** +*** 424,430 **** + retval = -EACCES; + goto exec_error2; + } +! if (!(bh = bread(inode->i_dev,inode->i_data[0]))) { + retval = -EACCES; + goto exec_error2; + } +--- 434,440 ---- + retval = -EACCES; + goto exec_error2; + } +! if (!(bh = bread(inode->i_dev,bmap(inode,0)))) { + retval = -EACCES; + goto exec_error2; + } +*** 0.96c/linux/fs/super.c Fri Jul 3 03:09:37 1992 +--- linux/fs/super.c Sat Jul 11 15:56:17 1992 +*************** +*** 11,16 **** +--- 11,17 ---- + #include + #include + #include ++ /* #include */ + #include + #include + #include +*************** +*** 18,23 **** +--- 19,25 ---- + + #include + ++ + int sync_dev(int dev); + void wait_for_keypress(void); + +*************** +*** 36,41 **** +--- 38,44 ---- + static struct file_system_type file_systems[] = { + {minix_read_super,"minix"}, + {ext_read_super,"ext"}, ++ /* {msdos_read_super,"msdos"}, */ + {NULL,NULL} + }; + +*************** +*** 112,118 **** + sb->s_op->put_super(sb); + } + +! static struct super_block * read_super(int dev,char *name,void *data) + { + struct super_block * s; + struct file_system_type *type; +--- 115,121 ---- + sb->s_op->put_super(sb); + } + +! static struct super_block * read_super(int dev,char *name,int flags,void *data) + { + struct super_block * s; + struct file_system_type *type; +*************** +*** 133,138 **** +--- 136,142 ---- + break; + } + s->s_dev = dev; ++ s->s_flags = flags; + if (!type->read_super(s,data)) + return(NULL); + s->s_dev = dev; +*************** +*** 183,209 **** + return 0; + } + +! int sys_mount(char * dev_name, char * dir_name, char * type, int rw_flag) + { +! struct inode * dev_i, * dir_i; + struct super_block * sb; +- int dev; +- char tmp[100],*t; +- int i; + +! if (!suser()) +! return -EPERM; +! if (!(dev_i = namei(dev_name))) + return -ENOENT; +! dev = dev_i->i_rdev; +! if (!S_ISBLK(dev_i->i_mode)) { +! iput(dev_i); +! return -EPERM; +! } +! iput(dev_i); +! if (!(dir_i=namei(dir_name))) +! return -ENOENT; +! if (dir_i->i_count != 1 || dir_i->i_ino == MINIX_ROOT_INO) { + iput(dir_i); + return -EBUSY; + } +--- 187,209 ---- + return 0; + } + +! /* +! * do_mount() does the actual mounting after sys_mount has done the ugly +! * parameter parsing. When enough time has gone by, and everything uses the +! * new mount() parameters, sys_mount() can then be cleaned up. +! * +! * We cannot mount a filesystem if it has active, used, or dirty inodes. +! * We also have to flush all inode-data for this device, as the new mount +! * might need new info. +! */ +! static int do_mount(int dev, const char * dir, char * type, int flags, void * data) + { +! struct inode * inode, * dir_i; + struct super_block * sb; + +! if (!(dir_i = namei(dir))) + return -ENOENT; +! if (dir_i->i_count != 1 || dir_i->i_mount) { + iput(dir_i); + return -EBUSY; + } +*************** +*** 211,239 **** + iput(dir_i); + return -EPERM; + } +! if (dir_i->i_mount) { + iput(dir_i); + return -EPERM; + } + if (type) { +! i = 0; +! while (i < 100 && (tmp[i] = get_fs_byte(type++))) +! i++; + t = tmp; + } else + t = "minix"; +! if (!(sb = read_super(dev,t,NULL))) { +! iput(dir_i); +! return -EBUSY; +! } +! if (sb->s_covered) { +! iput(dir_i); +! return -EBUSY; +! } +! sb->s_covered = dir_i; +! dir_i->i_mount = 1; +! dir_i->i_dirt = 1; /* NOTE! we don't iput(dir_i) */ +! return 0; /* we do that in umount */ + } + + void mount_root(void) +--- 211,292 ---- + iput(dir_i); + return -EPERM; + } +! for (inode = inode_table+0 ; inode < inode_table+NR_INODE ; inode++) { +! if (inode->i_dev != dev) +! continue; +! if (inode->i_count || inode->i_dirt || inode->i_lock) { +! iput(dir_i); +! return -EBUSY; +! } +! inode->i_dev = 0; +! } +! sb = read_super(dev,type,flags,data); +! if (!sb || sb->s_covered) { + iput(dir_i); ++ return -EBUSY; ++ } ++ sb->s_flags = flags; ++ sb->s_covered = dir_i; ++ dir_i->i_mount = 1; ++ return 0; /* we don't iput(dir_i) - see umount */ ++ } ++ ++ /* ++ * Flags is a 16-bit value that allows up to 16 non-fs dependent flags to ++ * be given to the mount() call (ie: read-only, no-dev, no-suid etc). ++ * ++ * data is a (void *) that can point to any structure up to 4095 bytes, which ++ * can contain arbitrary fs-dependent information (or be NULL). ++ * ++ * NOTE! As old versions of mount() didn't use this setup, the flags has to have ++ * a special 16-bit magic number in the hight word: 0xC0ED. If this magic word ++ * isn't present, the flags and data info isn't used, as the syscall assumes we ++ * are talking to an older version that didn't understand them. ++ */ ++ int sys_mount(char * dev_name, char * dir_name, char * type, ++ unsigned long new_flags, void *data) ++ { ++ struct inode * inode; ++ int dev; ++ int retval = 0; ++ char tmp[100],*t; ++ int i; ++ unsigned long flags = 0; ++ unsigned long page = 0; ++ ++ if (!suser()) + return -EPERM; ++ if (!(inode = namei(dev_name))) ++ return -ENOENT; ++ dev = inode->i_rdev; ++ if (!S_ISBLK(inode->i_mode)) ++ retval = -EPERM; ++ else if (IS_NODEV(inode)) ++ retval = -EACCES; ++ iput(inode); ++ if (retval) ++ return retval; ++ if ((new_flags & 0xffff0000) == 0xC0ED0000) { ++ flags = new_flags & 0xffff; ++ if (data && (unsigned long) data < TASK_SIZE) ++ page = get_free_page(); + } ++ if (page) { ++ i = TASK_SIZE - (unsigned long) data; ++ if (i < 0 || i > 4095) ++ i = 4095; ++ memcpy_fromfs((void *) page,data,i); ++ } + if (type) { +! for (i = 0 ; i < 100 ; i++) +! if (!(tmp[i] = get_fs_byte(type++))) +! break; + t = tmp; + } else + t = "minix"; +! retval = do_mount(dev,dir_name,t,flags,(void *) page); +! free_page(page); +! return retval; + } + + void mount_root(void) +*************** +*** 255,261 **** + p->s_lock = 0; + p->s_wait = NULL; + } +! if (!(p=read_super(ROOT_DEV,"minix",NULL))) + panic("Unable to mount root"); + /*wait_for_keypress(); + if (!(mi=iget(ROOT_DEV,MINIX_ROOT_INO))) +--- 308,314 ---- + p->s_lock = 0; + p->s_wait = NULL; + } +! if (!(p=read_super(ROOT_DEV,"minix",0,NULL))) + panic("Unable to mount root"); + /*wait_for_keypress(); + if (!(mi=iget(ROOT_DEV,MINIX_ROOT_INO))) +*************** +*** 264,269 **** +--- 317,323 ---- + mi=p->s_mounted; + mi->i_count += 3 ; /* NOTE! it is logically used 4 times, not 1 */ + p->s_mounted = p->s_covered = mi; ++ p->s_flags = 0; + current->pwd = mi; + current->root = mi; + free=0; +*** 0.96c/linux/fs/namei.c Thu Jul 2 00:42:04 1992 +--- linux/fs/namei.c Sat Jul 11 03:57:49 1992 +*************** +*** 229,234 **** +--- 229,238 ---- + iput(dir); + return -EACCES; + } ++ if (IS_RDONLY(dir)) { ++ iput(dir); ++ return -EROFS; ++ } + return dir->i_op->create(dir,basename,namelen,mode,res_inode); + } + if (flag & O_EXCL) { +*************** +*** 238,254 **** + } + if (!(inode = follow_link(dir,inode))) + return -ELOOP; + if ((S_ISDIR(inode->i_mode) && (flag & O_ACCMODE)) || + !permission(inode,ACC_MODE(flag))) { + iput(inode); + return -EPERM; + } +- inode->i_atime = CURRENT_TIME; + if (flag & O_TRUNC) + if (inode->i_op && inode->i_op->truncate) { + inode->i_size = 0; + inode->i_op->truncate(inode); + } + *res_inode = inode; + return 0; + } +--- 242,272 ---- + } + if (!(inode = follow_link(dir,inode))) + return -ELOOP; ++ if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) { ++ if (IS_NODEV(inode)) { ++ iput(inode); ++ return -EACCES; ++ } ++ } else { ++ if (IS_RDONLY(inode) && (flag & (O_TRUNC | O_ACCMODE))) { ++ iput(inode); ++ return -EROFS; ++ } ++ } + if ((S_ISDIR(inode->i_mode) && (flag & O_ACCMODE)) || + !permission(inode,ACC_MODE(flag))) { + iput(inode); + return -EPERM; + } + if (flag & O_TRUNC) + if (inode->i_op && inode->i_op->truncate) { + inode->i_size = 0; + inode->i_op->truncate(inode); + } ++ if (!IS_RDONLY(inode)) { ++ inode->i_atime = CURRENT_TIME; ++ inode->i_dirt = 1; ++ } + *res_inode = inode; + return 0; + } +*************** +*** 265,270 **** +--- 283,292 ---- + iput(dir); + return -ENOENT; + } ++ if (IS_RDONLY(dir)) { ++ iput(dir); ++ return -EROFS; ++ } + if (!permission(dir,MAY_WRITE)) { + iput(dir); + return -EACCES; +*************** +*** 295,300 **** +--- 317,326 ---- + iput(dir); + return -ENOENT; + } ++ if (IS_RDONLY(dir)) { ++ iput(dir); ++ return -EROFS; ++ } + if (!permission(dir,MAY_WRITE)) { + iput(dir); + return -EACCES; +*************** +*** 318,323 **** +--- 344,353 ---- + iput(dir); + return -ENOENT; + } ++ if (IS_RDONLY(dir)) { ++ iput(dir); ++ return -EROFS; ++ } + if (!permission(dir,MAY_WRITE)) { + iput(dir); + return -EACCES; +*************** +*** 341,346 **** +--- 371,380 ---- + iput(dir); + return -EPERM; + } ++ if (IS_RDONLY(dir)) { ++ iput(dir); ++ return -EROFS; ++ } + if (!permission(dir,MAY_WRITE)) { + iput(dir); + return -EACCES; +*************** +*** 365,370 **** +--- 399,408 ---- + iput(dir); + return -ENOENT; + } ++ if (IS_RDONLY(dir)) { ++ iput(dir); ++ return -EROFS; ++ } + if (!permission(dir,MAY_WRITE)) { + iput(dir); + return -EACCES; +*************** +*** 395,400 **** +--- 433,443 ---- + iput(dir); + return -EPERM; + } ++ if (IS_RDONLY(dir)) { ++ iput(oldinode); ++ iput(dir); ++ return -EROFS; ++ } + if (dir->i_dev != oldinode->i_dev) { + iput(dir); + iput(oldinode); +*************** +*** 453,458 **** +--- 496,506 ---- + iput(old_dir); + iput(new_dir); + return -EXDEV; ++ } ++ if (IS_RDONLY(new_dir) || IS_RDONLY(old_dir)) { ++ iput(old_dir); ++ iput(new_dir); ++ return -EROFS; + } + if (!old_dir->i_op || !old_dir->i_op->rename) { + iput(old_dir); +*** 0.96c/linux/fs/ioctl.c Thu Jul 2 00:42:04 1992 +--- linux/fs/ioctl.c Sat Jul 11 00:49:32 1992 +*************** +*** 6,11 **** +--- 6,12 ---- + + #include + ++ #include + #include + #include + #include +*************** +*** 13,21 **** +--- 14,30 ---- + int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) + { + struct file * filp; ++ int block; + + if (fd >= NR_OPEN || !(filp = current->filp[fd])) + return -EBADF; ++ if (S_ISREG(filp->f_inode->i_mode) && cmd == BMAP_IOCTL && ++ filp->f_inode->i_op->bmap) { ++ block = get_fs_long((long *) arg); ++ block = filp->f_inode->i_op->bmap(filp->f_inode,block); ++ put_fs_long(block,(long *) arg); ++ return 0; ++ } + if (filp->f_op && filp->f_op->ioctl) + return filp->f_op->ioctl(filp->f_inode, filp, cmd,arg); + return -EINVAL; +*** 0.96c/linux/fs/ext/bitmap.c Fri Jul 3 03:18:53 1992 +--- linux/fs/ext/bitmap.c Sat Jul 11 05:04:14 1992 +*************** +*** 203,208 **** +--- 203,209 ---- + iput(inode); + return NULL; + } ++ inode->i_flags = inode->i_sb->s_flags; + j = 8192; + for (i=0 ; i<8 ; i++) + if (bh=inode->i_sb->s_imap[i]) +*** 0.96c/linux/fs/ext/file.c Fri Jul 3 16:24:07 1992 +--- linux/fs/ext/file.c Sat Jul 11 00:49:32 1992 +*************** +*** 153,160 **** + } while (left > 0); + if (!read) + return -EIO; +! inode->i_atime = CURRENT_TIME; +! inode->i_dirt = 1; + return read; + } + +--- 153,162 ---- + } while (left > 0); + if (!read) + return -EIO; +! if (!IS_RDONLY(inode)) { +! inode->i_atime = CURRENT_TIME; +! inode->i_dirt = 1; +! } + return read; + } + +*** 0.96c/linux/fs/ext/freelists.c Fri Jul 3 03:08:06 1992 +--- linux/fs/ext/freelists.c Sat Jul 11 05:04:14 1992 +*************** +*** 70,81 **** + if (bh->b_count) + brelse(bh); + } +! efb = (struct ext_free_block *) sb->s_zmap[1]->b_data; +! if (efb->count == 254) { + #ifdef EXTFS_DEBUG + printk("ext_free_block: block full, skipping to %d\n", block); + #endif +! brelse (sb->s_zmap[1]); + if (!(sb->s_zmap[1] = bread (dev, block))) + panic ("ext_free_block: unable to read block to free\n"); + efb = (struct ext_free_block *) sb->s_zmap[1]->b_data; +--- 70,83 ---- + if (bh->b_count) + brelse(bh); + } +! if (sb->s_zmap[1]) +! efb = (struct ext_free_block *) sb->s_zmap[1]->b_data; +! if (!sb->s_zmap[1] || efb->count == 254) { + #ifdef EXTFS_DEBUG + printk("ext_free_block: block full, skipping to %d\n", block); + #endif +! if (sb->s_zmap[1]) +! brelse (sb->s_zmap[1]); + if (!(sb->s_zmap[1] = bread (dev, block))) + panic ("ext_free_block: unable to read block to free\n"); + efb = (struct ext_free_block *) sb->s_zmap[1]->b_data; +*************** +*** 209,221 **** + free_super (inode->i_sb); + return; + } +! efi = ((struct ext_free_inode *) inode->i_sb->s_imap[1]->b_data) + +! (((unsigned long) inode->i_sb->s_imap[0])-1)%EXT_INODES_PER_BLOCK; +! if (efi->count == 14) { + #ifdef EXTFS_DEBUG + printk("ext_free_inode: inode full, skipping to %d\n", inode->i_ino); + #endif +! brelse (inode->i_sb->s_imap[1]); + block = 2 + (inode->i_ino - 1) / EXT_INODES_PER_BLOCK; + if (!(bh = bread(inode->i_dev, block))) + panic("ext_free_inode: unable to read inode block\n"); +--- 211,225 ---- + free_super (inode->i_sb); + return; + } +! if (inode->i_sb->s_imap[1]) +! efi = ((struct ext_free_inode *) inode->i_sb->s_imap[1]->b_data) + +! (((unsigned long) inode->i_sb->s_imap[0])-1)%EXT_INODES_PER_BLOCK; +! if (!inode->i_sb->s_imap[1] || efi->count == 14) { + #ifdef EXTFS_DEBUG + printk("ext_free_inode: inode full, skipping to %d\n", inode->i_ino); + #endif +! if (inode->i_sb->s_imap[1]) +! brelse (inode->i_sb->s_imap[1]); + block = 2 + (inode->i_ino - 1) / EXT_INODES_PER_BLOCK; + if (!(bh = bread(inode->i_dev, block))) + panic("ext_free_inode: unable to read inode block\n"); +*************** +*** 249,254 **** +--- 253,259 ---- + iput(inode); + return NULL; + } ++ inode->i_flags = inode->i_sb->s_flags; + if (!inode->i_sb->s_imap[1]) + return 0; + lock_super (inode->i_sb); +*** 0.96c/linux/fs/ext/namei.c Fri Jul 3 16:28:36 1992 +--- linux/fs/ext/namei.c Sat Jul 11 12:35:28 1992 +*************** +*** 808,813 **** +--- 808,817 ---- + retval = 0; + goto end_rename; + } ++ if (S_ISDIR(new_inode->i_mode)) { ++ retval = -EEXIST; ++ goto end_rename; ++ } + if (S_ISDIR(old_inode->i_mode)) { + retval = -EEXIST; + if (new_bh) +*** 0.96c/linux/fs/minix/bitmap.c Thu Jul 2 00:44:28 1992 +--- linux/fs/minix/bitmap.c Sat Jul 11 05:03:11 1992 +*************** +*** 191,196 **** +--- 191,197 ---- + iput(inode); + return NULL; + } ++ inode->i_flags = inode->i_sb->s_flags; + j = 8192; + for (i=0 ; i<8 ; i++) + if (bh=inode->i_sb->s_imap[i]) +*** 0.96c/linux/fs/minix/file.c Thu Jul 2 00:44:28 1992 +--- linux/fs/minix/file.c Sat Jul 11 00:49:33 1992 +*************** +*** 153,160 **** + } while (left > 0); + if (!read) + return -EIO; +! inode->i_atime = CURRENT_TIME; +! inode->i_dirt = 1; + return read; + } + +--- 153,162 ---- + } while (left > 0); + if (!read) + return -EIO; +! if (!IS_RDONLY(inode)) { +! inode->i_atime = CURRENT_TIME; +! inode->i_dirt = 1; +! } + return read; + } + +*** 0.96c/linux/fs/minix/namei.c Fri Jul 3 16:28:36 1992 +--- linux/fs/minix/namei.c Sat Jul 11 12:35:28 1992 +*************** +*** 676,681 **** +--- 676,685 ---- + retval = 0; + goto end_rename; + } ++ if (S_ISDIR(new_inode->i_mode)) { ++ retval = -EEXIST; ++ goto end_rename; ++ } + if (S_ISDIR(old_inode->i_mode)) { + retval = -EEXIST; + if (new_bh) +*** 0.96c/linux/init/main.c Sun Jul 5 00:57:47 1992 +--- linux/init/main.c Tue Jul 7 17:06:59 1992 +*************** +*** 53,58 **** +--- 53,59 ---- + + extern int vsprintf(); + extern void init(void); ++ extern void init_IRQ(void); + extern long blk_dev_init(long,long); + extern long chr_dev_init(long,long); + extern void hd_init(void); +*************** +*** 164,169 **** +--- 165,171 ---- + buffer_memory_end = 1*1024*1024; + main_memory_start = buffer_memory_end; + trap_init(); ++ init_IRQ(); + sched_init(); + main_memory_start = chr_dev_init(main_memory_start,memory_end); + main_memory_start = blk_dev_init(main_memory_start,memory_end); +*************** +*** 183,196 **** + init(); + } + /* +! * NOTE!! For any other task 'pause()' would mean we have to get a +! * signal to awaken, but task0 is the sole exception (see 'schedule()') +! * as task 0 gets activated at every idle moment (when no other tasks +! * can run). For task0 'pause()' just means we go check if some other +! * task can run, and if not we return here. + */ + for(;;) +! __asm__("int $0x80"::"a" (__NR_pause):"ax"); + } + + static int printf(const char *fmt, ...) +--- 185,200 ---- + init(); + } + /* +! * task[0] is meant to be used as an "idle" task: it may not sleep, but +! * it might do some general things like count free pages or it could be +! * used to implement a reasonable LRU algorithm for the paging routines: +! * anything that can be useful, but shouldn't take time from the real +! * processes. +! * +! * Right now task[0] just does a infinite loop in user mode. + */ + for(;;) +! /* nothing */ ; + } + + static int printf(const char *fmt, ...) +*** 0.96c/linux/kernel/Makefile Sun Jul 5 03:09:42 1992 +--- linux/kernel/Makefile Sat Jul 11 20:12:09 1992 +*************** +*** 18,24 **** + + SUBDIRS = chr_drv blk_drv math + +! OBJS = sched.o sys_call.o traps.o asm.o fork.o \ + panic.o printk.o vsprintf.o sys.o exit.o \ + signal.o mktime.o ptrace.o ioport.o itimer.o + +--- 18,24 ---- + + SUBDIRS = chr_drv blk_drv math + +! OBJS = sched.o sys_call.o traps.o irq.o fork.o \ + panic.o printk.o vsprintf.o sys.o exit.o \ + signal.o mktime.o ptrace.o ioport.o itimer.o + +*************** +*** 73,78 **** +--- 73,85 ---- + /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \ + /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ + /usr/src/linux/include/sys/resource.h /usr/src/linux/include/errno.h ++ irq.o : irq.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \ ++ /usr/src/linux/include/stddef.h /usr/src/linux/include/errno.h /usr/src/linux/include/sys/ptrace.h \ ++ /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \ ++ /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ ++ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/sys/param.h \ ++ /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \ ++ /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/io.h /usr/src/linux/include/asm/irq.h + itimer.o : itimer.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \ + /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ + /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ +*** 0.96c/linux/kernel/sched.c Sun Jul 5 01:27:18 1992 +--- linux/kernel/sched.c Tue Jul 7 18:53:54 1992 +*************** +*** 10,15 **** +--- 10,18 ---- + * call functions (type getpid(), which just extracts a field from + * current-task + */ ++ ++ #define TIMER_IRQ 0 ++ + #include + #include + #include +*************** +*** 369,375 **** + unsigned long timer_active = 0; + struct timer_struct timer_table[32]; + +! void do_timer(long cpl) + { + unsigned long mask; + struct timer_struct *tp = timer_table+0; +--- 372,378 ---- + unsigned long timer_active = 0; + struct timer_struct timer_table[32]; + +! static void do_timer(int cpl) + { + unsigned long mask; + struct timer_struct *tp = timer_table+0; +*************** +*** 376,393 **** + struct task_struct ** task_p; + static int avg_cnt = 0; + +! for (mask = 1 ; mask ; tp++,mask += mask) { +! if (mask > timer_active) +! break; +! if (!(mask & timer_active)) +! continue; +! if (tp->expires > jiffies) +! continue; +! timer_active &= ~mask; +! tp->fn(); +! sti(); + } +! + /* Update ITIMER_REAL for every task */ + for (task_p = &LAST_TASK; task_p >= &FIRST_TASK; task_p--) + if (*task_p && (*task_p)->it_real_value +--- 379,397 ---- + struct task_struct ** task_p; + static int avg_cnt = 0; + +! jiffies++; +! if (!cpl) +! current->stime++; +! else +! current->utime++; +! if (--avg_cnt < 0) { +! avg_cnt = 500; +! update_avg(); + } +! if ((--current->counter)<=0) { +! current->counter=0; +! need_resched = 1; +! } + /* Update ITIMER_REAL for every task */ + for (task_p = &LAST_TASK; task_p >= &FIRST_TASK; task_p--) + if (*task_p && (*task_p)->it_real_value +*************** +*** 402,417 **** + send_sig(SIGPROF,current,1); + } + /* Update ITIMER_VIRT for current task if not in a system call */ +! if (cpl && current->it_virt_value && !(--current->it_virt_value)) { + current->it_virt_value = current->it_virt_incr; + send_sig(SIGVTALRM,current,1); + } +! +! if (cpl) +! current->utime++; +! else +! current->stime++; +! + if (next_timer) { + next_timer->jiffies--; + while (next_timer && next_timer->jiffies <= 0) { +--- 406,426 ---- + send_sig(SIGPROF,current,1); + } + /* Update ITIMER_VIRT for current task if not in a system call */ +! if (current->it_virt_value && !(--current->it_virt_value)) { + current->it_virt_value = current->it_virt_incr; + send_sig(SIGVTALRM,current,1); + } +! for (mask = 1 ; mask ; tp++,mask += mask) { +! if (mask > timer_active) +! break; +! if (!(mask & timer_active)) +! continue; +! if (tp->expires > jiffies) +! continue; +! timer_active &= ~mask; +! tp->fn(); +! sti(); +! } + if (next_timer) { + next_timer->jiffies--; + while (next_timer && next_timer->jiffies <= 0) { +*************** +*** 425,438 **** + } + if (current_DOR & 0xf0) + do_floppy_timer(); +- if (--avg_cnt < 0) { +- avg_cnt = 500; +- update_avg(); +- } +- if ((--current->counter)<=0) { +- current->counter=0; +- need_resched = 1; +- } + } + + int sys_alarm(long seconds) +--- 434,439 ---- +*************** +*** 496,501 **** +--- 497,503 ---- + panic("Struct sigaction MUST be 16 bytes"); + set_tss_desc(gdt+FIRST_TSS_ENTRY,&(init_task.task.tss)); + set_ldt_desc(gdt+FIRST_LDT_ENTRY,&(init_task.task.ldt)); ++ set_system_gate(0x80,&system_call); + p = gdt+2+FIRST_TSS_ENTRY; + for(i=1 ; i> 8 , 0x40); /* MSB */ +! set_intr_gate(0x20,&timer_interrupt); +! outb(inb_p(0x21)&~0x01,0x21); +! set_system_gate(0x80,&system_call); + } +--- 513,517 ---- + outb_p(0x36,0x43); /* binary, mode 3, LSB/MSB, ch 0 */ + outb_p(LATCH & 0xff , 0x40); /* LSB */ + outb(LATCH >> 8 , 0x40); /* MSB */ +! request_irq(TIMER_IRQ,do_timer); + } +*** 0.96c/linux/kernel/traps.c Thu May 21 12:53:42 1992 +--- linux/kernel/traps.c Fri Jul 10 16:34:12 1992 +*************** +*** 57,63 **** + void page_fault(void); + void coprocessor_error(void); + void reserved(void); +- void parallel_interrupt(void); + void irq13(void); + void alignment_check(void); + +--- 57,62 ---- +*************** +*** 116,122 **** + + void do_nmi(long esp, long error_code) + { +! die("nmi",esp,error_code); + } + + void do_debug(long esp, long error_code) +--- 115,121 ---- + + void do_nmi(long esp, long error_code) + { +! printk("Uhhuh. NMI received. Dazed and confused, but trying to continue\n"); + } + + void do_debug(long esp, long error_code) +*************** +*** 201,207 **** + for (i=18;i<48;i++) + set_trap_gate(i,&reserved); + set_trap_gate(45,&irq13); +- outb_p(inb_p(0x21)&0xfb,0x21); +- outb(inb_p(0xA1)&0xdf,0xA1); +- set_trap_gate(39,¶llel_interrupt); + } +--- 200,203 ---- +*** 0.96c/linux/kernel/chr_drv/keyboard.c Sun Jul 5 01:20:58 1992 +--- linux/kernel/chr_drv/keyboard.c Tue Jul 7 18:33:38 1992 +*************** +*** 58,64 **** + static void kb_wait(void), kb_ack(void); + static unsigned int handle_diacr(unsigned int); + +! void do_keyboard(void) + { + static unsigned char rep = 0xff, repke0 = 0; + unsigned char scancode, x; +--- 58,64 ---- + static void kb_wait(void), kb_ack(void); + static unsigned int handle_diacr(unsigned int); + +! void keyboard_interrupt(int cpl) + { + static unsigned char rep = 0xff, repke0 = 0; + unsigned char scancode, x; +*************** +*** 874,880 **** + } + + +! #if defined KBD_FR || defined KBD_US + static unsigned char num_table[] = "789-456+1230."; + #else + static unsigned char num_table[] = "789-456+1230,"; +--- 874,880 ---- + } + + +! #if defined KBD_FR || defined KBD_US || defined KBD_UK + static unsigned char num_table[] = "789-456+1230."; + #else + static unsigned char num_table[] = "789-456+1230,"; +*** 0.96c/linux/kernel/chr_drv/console.c Mon Jun 29 05:10:41 1992 +--- linux/kernel/chr_drv/console.c Sat Jul 11 12:41:53 1992 +*************** +*** 30,35 **** +--- 30,37 ---- + * + */ + ++ #define KEYBOARD_IRQ 1 ++ + #include + #include + #include +*************** +*** 68,74 **** + #define NPAR 16 + + extern void vt_init(void); +! extern void keyboard_interrupt(void); + extern void set_leds(void); + extern unsigned char kapplic; + extern unsigned char ckmode; +--- 70,76 ---- + #define NPAR 16 + + extern void vt_init(void); +! extern void keyboard_interrupt(int cpl); + extern void set_leds(void); + extern unsigned char kapplic; + extern unsigned char ckmode; +*************** +*** 241,248 **** + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + " !\"#$%&'()*+,-./0123456789:;<=>?" + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^ " +! "\004\261\007\007\007\007\370\361\007\007\275\267\326\323\327\304" +! "\304\304\304\304\307\266\320\322\272\363\362\343\007\234\007\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\040\255\233\234\376\235\174\025\376\376\246\256\252\055\376\376" +--- 243,250 ---- + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + " !\"#$%&'()*+,-./0123456789:;<=>?" + "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^ " +! "\004\261\007\007\007\007\370\361\040\007\331\277\332\300\305\007" +! "\007\304\007\007\303\264\301\302\263\007\007\007\007\007\234\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\040\255\233\234\376\235\174\025\376\376\246\256\252\055\376\376" +*************** +*** 250,260 **** + "\376\376\376\376\216\217\222\200\376\220\376\376\376\376\376\376" + "\376\245\376\376\376\376\231\376\376\376\376\376\232\376\376\341" + "\205\240\203\376\204\206\221\207\212\202\210\211\215\241\214\213" +! "\376\244\225\242\223\376\224\366\376\227\243\226\201\376\376\230" + }; + + #define NORM_TRANS (translations[0]) + #define GRAF_TRANS (translations[1]) + + static unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7, + 8,12,10,14, 9,13,11,15 }; +--- 252,280 ---- + "\376\376\376\376\216\217\222\200\376\220\376\376\376\376\376\376" + "\376\245\376\376\376\376\231\376\376\376\376\376\232\376\376\341" + "\205\240\203\376\204\206\221\207\212\202\210\211\215\241\214\213" +! "\376\244\225\242\223\376\224\366\376\227\243\226\201\376\376\230", +! /* IBM grapgics: minimal translations (CR, LF, LL and ESC) */ +! "\000\001\002\003\004\005\006\007\010\011\000\013\000\000\016\017" +! "\020\021\022\023\024\025\026\027\030\031\032\000\034\035\036\037" +! "\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057" +! "\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077" +! "\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117" +! "\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137" +! "\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157" +! "\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177" +! "\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217" +! "\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237" +! "\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257" +! "\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277" +! "\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317" +! "\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337" +! "\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357" +! "\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377" + }; + + #define NORM_TRANS (translations[0]) + #define GRAF_TRANS (translations[1]) ++ #define NULL_TRANS (translations[2]) + + static unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7, + 8,12,10,14, 9,13,11,15 }; +*************** +*** 605,611 **** + static void respond_string(char * p, int currcons, struct tty_struct * tty) + { + while (*p) { +! PUTCH(*p,tty->read_q); + p++; + } + TTY_READ_FLUSH(tty); +--- 625,631 ---- + static void respond_string(char * p, int currcons, struct tty_struct * tty) + { + while (*p) { +! put_tty_queue(*p,tty->read_q); + p++; + } + TTY_READ_FLUSH(tty); +*************** +*** 621,627 **** + n /= 10; + } while(n && i < 3); /* We'll take no chances */ + while (i--) { +! PUTCH(buff[i],tty->read_q); + } + /* caller must flush */ + } +--- 641,647 ---- + n /= 10; + } while(n && i < 3); /* We'll take no chances */ + while (i--) { +! put_tty_queue(buff[i],tty->read_q); + } + /* caller must flush */ + } +*************** +*** 628,639 **** + + static void cursor_report(int currcons, struct tty_struct * tty) + { +! PUTCH('\033', tty->read_q); +! PUTCH('[', tty->read_q); + respond_num(y + (decom ? top+1 : 1), currcons, tty); +! PUTCH(';', tty->read_q); + respond_num(x+1, currcons, tty); +! PUTCH('R', tty->read_q); + TTY_READ_FLUSH(tty); + } + +--- 648,659 ---- + + static void cursor_report(int currcons, struct tty_struct * tty) + { +! put_tty_queue('\033', tty->read_q); +! put_tty_queue('[', tty->read_q); + respond_num(y + (decom ? top+1 : 1), currcons, tty); +! put_tty_queue(';', tty->read_q); + respond_num(x+1, currcons, tty); +! put_tty_queue('R', tty->read_q); + TTY_READ_FLUSH(tty); + } + +*************** +*** 905,911 **** + printk("con_write: illegal tty\n\r"); + return; + } +! while (!tty->stopped && (c = GETCH(tty->write_q)) >= 0) { + if (state == ESnormal && translate[c]) { + if (need_wrap) { + cr(currcons); +--- 925,931 ---- + printk("con_write: illegal tty\n\r"); + return; + } +! while (!tty->stopped && (c = get_tty_queue(tty->write_q)) >= 0) { + if (state == ESnormal && translate[c]) { + if (need_wrap) { + cr(currcons); +*************** +*** 1176,1181 **** +--- 1196,1203 ---- + G0_charset = GRAF_TRANS; + else if (c == 'B') + G0_charset = NORM_TRANS; ++ else if (c == 'U') ++ G0_charset = NULL_TRANS; + if (charset == 0) + translate = G0_charset; + state = ESnormal; +*************** +*** 1185,1190 **** +--- 1207,1214 ---- + G1_charset = GRAF_TRANS; + else if (c == 'B') + G1_charset = NORM_TRANS; ++ else if (c == 'U') ++ G1_charset = NULL_TRANS; + if (charset == 1) + translate = G1_charset; + state = ESnormal; +*************** +*** 1338,1345 **** + gotoxy(currcons,orig_x,orig_y); + update_screen(fg_console); + +! set_trap_gate(0x21,&keyboard_interrupt); +! outb_p(inb_p(0x21)&0xfd,0x21); + a=inb_p(0x61); + outb_p(a|0x80,0x61); + outb_p(a,0x61); +--- 1362,1369 ---- + gotoxy(currcons,orig_x,orig_y); + update_screen(fg_console); + +! if (request_irq(KEYBOARD_IRQ,keyboard_interrupt)) +! printk("Unable to get IRQ%d for keyboard driver\n",KEYBOARD_IRQ); + a=inb_p(0x61); + outb_p(a|0x80,0x61); + outb_p(a,0x61); +*** 0.96c/linux/kernel/chr_drv/tty_ioctl.c Fri Jul 3 04:26:08 1992 +--- linux/kernel/chr_drv/tty_ioctl.c Wed Jul 8 17:12:50 1992 +*************** +*** 65,71 **** + } + } + +! static void wait_until_sent(struct tty_struct * tty) + { + while (!(current->signal & ~current->blocked) && !EMPTY(tty->write_q)) { + TTY_WRITE_FLUSH(tty); +--- 65,71 ---- + } + } + +! void wait_until_sent(struct tty_struct * tty) + { + while (!(current->signal & ~current->blocked) && !EMPTY(tty->write_q)) { + TTY_WRITE_FLUSH(tty); +*************** +*** 122,127 **** +--- 122,128 ---- + int channel) + { + int i; ++ unsigned short old_cflag = tty->termios.c_cflag; + + /* If we try to set the state of terminal and we're not in the + foreground, send a SIGTTOU. If the signal is blocked or +*************** +*** 135,141 **** + } + for (i=0 ; i< (sizeof (*termios)) ; i++) + ((char *)&tty->termios)[i]=get_fs_byte(i+(char *)termios); +! if (IS_A_SERIAL(channel)) + change_speed(channel-64); + return 0; + } +--- 136,142 ---- + } + for (i=0 ; i< (sizeof (*termios)) ; i++) + ((char *)&tty->termios)[i]=get_fs_byte(i+(char *)termios); +! if (IS_A_SERIAL(channel) && tty->termios.c_cflag != old_cflag) + change_speed(channel-64); + return 0; + } +*************** +*** 166,171 **** +--- 167,173 ---- + { + int i; + struct termio tmp_termio; ++ unsigned short old_cflag = tty->termios.c_cflag; + + if ((current->tty == channel) && + (tty->pgrp > 0) && +*************** +*** 184,190 **** + tty->termios.c_line = tmp_termio.c_line; + for(i=0 ; i < NCC ; i++) + tty->termios.c_cc[i] = tmp_termio.c_cc[i]; +! if (IS_A_SERIAL(channel)) + change_speed(channel-64); + return 0; + } +--- 186,192 ---- + tty->termios.c_line = tmp_termio.c_line; + for(i=0 ; i < NCC ; i++) + tty->termios.c_cc[i] = tmp_termio.c_cc[i]; +! if (IS_A_SERIAL(channel) && tty->termios.c_cflag != old_cflag) + change_speed(channel-64); + return 0; + } +*************** +*** 232,243 **** + int pgrp; + int dev; + +! if (MAJOR(inode->i_rdev) == 5) { +! dev = current->tty; +! if (dev<0) +! return -EINVAL; +! } else +! dev = MINOR(inode->i_rdev); + tty = tty_table + (dev ? ((dev < 64)? dev-1:dev) : fg_console); + + if (IS_A_PTY(dev)) +--- 234,244 ---- + int pgrp; + int dev; + +! if (MAJOR(file->f_rdev) != 4) { +! printk("tty_ioctl: tty pseudo-major != 4\n"); +! return -EINVAL; +! } +! dev = MINOR(file->f_rdev); + tty = tty_table + (dev ? ((dev < 64)? dev-1:dev) : fg_console); + + if (IS_A_PTY(dev)) +*************** +*** 286,296 **** + return 0; + case TCIOFF: + if (STOP_CHAR(tty)) +! PUTCH(STOP_CHAR(tty),tty->write_q); + return 0; + case TCION: + if (START_CHAR(tty)) +! PUTCH(START_CHAR(tty),tty->write_q); + return 0; + } + return -EINVAL; /* not implemented */ +--- 287,297 ---- + return 0; + case TCIOFF: + if (STOP_CHAR(tty)) +! put_tty_queue(STOP_CHAR(tty),tty->write_q); + return 0; + case TCION: + if (START_CHAR(tty)) +! put_tty_queue(START_CHAR(tty),tty->write_q); + return 0; + } + return -EINVAL; /* not implemented */ +*** 0.96c/linux/kernel/chr_drv/tty_io.c Sat Jul 4 03:21:41 1992 +--- linux/kernel/chr_drv/tty_io.c Wed Jul 8 18:00:50 1992 +*************** +*** 154,160 **** + while (1) { + if (FULL(tty->secondary)) + break; +! c = GETCH(tty->read_q); + if (c < 0) + break; + if (I_STRP(tty)) +--- 154,160 ---- + while (1) { + if (FULL(tty->secondary)) + break; +! c = get_tty_queue(tty->read_q); + if (c < 0) + break; + if (I_STRP(tty)) +*************** +*** 178,190 **** + (c==EOF_CHAR(tty))))) { + if (L_ECHO(tty)) { + if (c<32) { +! PUTCH(8,tty->write_q); +! PUTCH(' ',tty->write_q); +! PUTCH(8,tty->write_q); + } +! PUTCH(8,tty->write_q); +! PUTCH(' ',tty->write_q); +! PUTCH(8,tty->write_q); + TTY_WRITE_FLUSH(tty); + } + DEC(tty->secondary->head); +--- 178,190 ---- + (c==EOF_CHAR(tty))))) { + if (L_ECHO(tty)) { + if (c<32) { +! put_tty_queue(8,tty->write_q); +! put_tty_queue(' ',tty->write_q); +! put_tty_queue(8,tty->write_q); + } +! put_tty_queue(8,tty->write_q); +! put_tty_queue(' ',tty->write_q); +! put_tty_queue(8,tty->write_q); + TTY_WRITE_FLUSH(tty); + } + DEC(tty->secondary->head); +*************** +*** 200,212 **** + continue; + if (L_ECHO(tty)) { + if (c<32) { +! PUTCH(8,tty->write_q); +! PUTCH(' ',tty->write_q); +! PUTCH(8,tty->write_q); + } +! PUTCH(8,tty->write_q); +! PUTCH(32,tty->write_q); +! PUTCH(8,tty->write_q); + TTY_WRITE_FLUSH(tty); + } + DEC(tty->secondary->head); +--- 200,212 ---- + continue; + if (L_ECHO(tty)) { + if (c<32) { +! put_tty_queue(8,tty->write_q); +! put_tty_queue(' ',tty->write_q); +! put_tty_queue(8,tty->write_q); + } +! put_tty_queue(8,tty->write_q); +! put_tty_queue(32,tty->write_q); +! put_tty_queue(8,tty->write_q); + TTY_WRITE_FLUSH(tty); + } + DEC(tty->secondary->head); +*************** +*** 250,265 **** + c==EOF_CHAR(tty))) + tty->secondary->data++; + if ((L_ECHO(tty) || (L_CANON(tty) && L_ECHONL(tty))) && (c==10)) { +! PUTCH(10,tty->write_q); +! PUTCH(13,tty->write_q); + } else if (L_ECHO(tty)) { + if (c<32 && L_ECHOCTL(tty)) { +! PUTCH('^',tty->write_q); +! PUTCH(c+64,tty->write_q); + } else +! PUTCH(c,tty->write_q); + } +! PUTCH(c,tty->secondary); + TTY_WRITE_FLUSH(tty); + } + TTY_WRITE_FLUSH(tty); +--- 250,265 ---- + c==EOF_CHAR(tty))) + tty->secondary->data++; + if ((L_ECHO(tty) || (L_CANON(tty) && L_ECHONL(tty))) && (c==10)) { +! put_tty_queue(10,tty->write_q); +! put_tty_queue(13,tty->write_q); + } else if (L_ECHO(tty)) { + if (c<32 && L_ECHOCTL(tty)) { +! put_tty_queue('^',tty->write_q); +! put_tty_queue(c+64,tty->write_q); + } else +! put_tty_queue(c,tty->write_q); + } +! put_tty_queue(c,tty->secondary); + TTY_WRITE_FLUSH(tty); + } + TTY_WRITE_FLUSH(tty); +*************** +*** 299,305 **** + static int read_chan(unsigned int channel, struct file * file, char * buf, int nr) + { + struct tty_struct * tty; +- struct tty_struct * other_tty = NULL; + int c; + char * b=buf; + int minimum,time; +--- 299,304 ---- +*************** +*** 316,323 **** + return -EIO; + else + return(tty_signal(SIGTTIN, tty)); +- if (channel & 0x80) +- other_tty = tty_table + (channel ^ 0x40); + time = 10L*tty->termios.c_cc[VTIME]; + minimum = tty->termios.c_cc[VMIN]; + if (L_CANON(tty)) { +--- 315,320 ---- +*************** +*** 338,345 **** + minimum = nr; + TTY_READ_FLUSH(tty); + while (nr>0) { +! if (other_tty && other_tty->write) +! TTY_WRITE_FLUSH(other_tty); + cli(); + if (EMPTY(tty->secondary) || (L_CANON(tty) && + !FULL(tty->read_q) && !tty->secondary->data)) { +--- 335,342 ---- + minimum = nr; + TTY_READ_FLUSH(tty); + while (nr>0) { +! if (tty->link && tty->link->write) +! TTY_WRITE_FLUSH(tty->link); + cli(); + if (EMPTY(tty->secondary) || (L_CANON(tty) && + !FULL(tty->read_q) && !tty->secondary->data)) { +*************** +*** 347,356 **** + break; + if (current->signal & ~current->blocked) + break; +! if (IS_A_PTY_SLAVE(channel) && C_HUP(other_tty)) + break; +- if (other_tty && !other_tty->count) +- break; + interruptible_sleep_on(&tty->secondary->proc_list); + sti(); + TTY_READ_FLUSH(tty); +--- 344,351 ---- + break; + if (current->signal & ~current->blocked) + break; +! if (tty->link && !tty->link->count) + break; + interruptible_sleep_on(&tty->secondary->proc_list); + sti(); + TTY_READ_FLUSH(tty); +*************** +*** 358,364 **** + } + sti(); + do { +! c = GETCH(tty->secondary); + if ((EOF_CHAR(tty) != __DISABLED_CHAR && + c==EOF_CHAR(tty)) || c==10) + tty->secondary->data--; +--- 353,359 ---- + } + sti(); + do { +! c = get_tty_queue(tty->secondary); + if ((EOF_CHAR(tty) != __DISABLED_CHAR && + c==EOF_CHAR(tty)) || c==10) + tty->secondary->data--; +*************** +*** 381,388 **** + } + sti(); + TTY_READ_FLUSH(tty); +! if (other_tty && other_tty->write) +! TTY_WRITE_FLUSH(other_tty); + current->timeout = 0; + if (b-buf) + return b-buf; +--- 376,383 ---- + } + sti(); + TTY_READ_FLUSH(tty); +! if (tty->link && tty->link->write) +! TTY_WRITE_FLUSH(tty->link); + current->timeout = 0; + if (b-buf) + return b-buf; +*************** +*** 419,424 **** +--- 414,423 ---- + while (nr>0) { + if (current->signal & ~current->blocked) + break; ++ if (tty->link && !tty->link->count) { ++ send_sig(SIGPIPE,current,0); ++ break; ++ } + if (FULL(tty->write_q)) { + TTY_WRITE_FLUSH(tty); + cli(); +*************** +*** 436,442 **** + c='\r'; + if (c=='\n' && !(tty->flags & TTY_CR_PENDING) && O_NLCR(tty)) { + tty->flags |= TTY_CR_PENDING; +! PUTCH(13,tty->write_q); + continue; + } + if (O_LCUC(tty)) +--- 435,441 ---- + c='\r'; + if (c=='\n' && !(tty->flags & TTY_CR_PENDING) && O_NLCR(tty)) { + tty->flags |= TTY_CR_PENDING; +! put_tty_queue(13,tty->write_q); + continue; + } + if (O_LCUC(tty)) +*************** +*** 444,450 **** + } + b++; nr--; + tty->flags &= ~TTY_CR_PENDING; +! PUTCH(c,tty->write_q); + } + if (nr>0) + schedule(); +--- 443,449 ---- + } + b++; nr--; + tty->flags &= ~TTY_CR_PENDING; +! put_tty_queue(c,tty->write_q); + } + if (nr>0) + schedule(); +*************** +*** 452,457 **** +--- 451,458 ---- + TTY_WRITE_FLUSH(tty); + if (b-buf) + return b-buf; ++ if (tty->link && !tty->link->count) ++ return -EPIPE; + if (current->signal & ~current->blocked) + return -ERESTARTSYS; + return 0; +*************** +*** 460,477 **** + static int tty_read(struct inode * inode, struct file * file, char * buf, int count) + { + int i; +- +- i = read_chan(current->tty,file,buf,count); +- if (i > 0) +- inode->i_atime = CURRENT_TIME; +- return i; +- } + +! static int ttyx_read(struct inode * inode, struct file * file, char * buf, int count) +! { +! int i; +! +! i = read_chan(MINOR(inode->i_rdev),file,buf,count); + if (i > 0) + inode->i_atime = CURRENT_TIME; + return i; +--- 461,472 ---- + static int tty_read(struct inode * inode, struct file * file, char * buf, int count) + { + int i; + +! if (MAJOR(file->f_rdev) != 4) { +! printk("tty_read: pseudo-major != 4\n"); +! return -EINVAL; +! } +! i = read_chan(MINOR(file->f_rdev),file,buf,count); + if (i > 0) + inode->i_atime = CURRENT_TIME; + return i; +*************** +*** 481,502 **** + { + int i; + +! i = write_chan(current->tty,file,buf,count); + if (i > 0) + inode->i_mtime = CURRENT_TIME; + return i; + } + +- static int ttyx_write(struct inode * inode, struct file * file, char * buf, int count) +- { +- int i; +- +- i = write_chan(MINOR(inode->i_rdev),file,buf,count); +- if (i > 0) +- inode->i_mtime = CURRENT_TIME; +- return i; +- } +- + static int tty_lseek(struct inode * inode, struct file * file, off_t offset, int orig) + { + return -EBADF; +--- 476,491 ---- + { + int i; + +! if (MAJOR(file->f_rdev) != 4) { +! printk("tty_write: pseudo-major != 4\n"); +! return -EINVAL; +! } +! i = write_chan(MINOR(file->f_rdev),file,buf,count); + if (i > 0) + inode->i_mtime = CURRENT_TIME; + return i; + } + + static int tty_lseek(struct inode * inode, struct file * file, off_t offset, int orig) + { + return -EBADF; +*************** +*** 522,536 **** + dev = MINOR(dev); + if (dev < 0) + return -ENODEV; + tty = TTY_TABLE(dev); + if (IS_A_PTY_MASTER(dev)) { + if (tty->count) + return -EAGAIN; + } +- if (!tty->count && (!tty->link || !tty->link->count)) { +- flush_input(tty); +- flush_output(tty); +- } + tty->count++; + retval = 0; + if (!(filp->f_flags & O_NOCTTY) && +--- 511,528 ---- + dev = MINOR(dev); + if (dev < 0) + return -ENODEV; ++ filp->f_rdev = 0x0400 | dev; + tty = TTY_TABLE(dev); ++ if (!tty->count && !(tty->link && tty->link->count)) { ++ flush_input(tty); ++ flush_output(tty); ++ } + if (IS_A_PTY_MASTER(dev)) { + if (tty->count) + return -EAGAIN; ++ if (tty->link) ++ tty->link->count++; + } + tty->count++; + retval = 0; + if (!(filp->f_flags & O_NOCTTY) && +*************** +*** 541,576 **** + tty->session = current->session; + tty->pgrp = current->pgrp; + } +! if (IS_A_SERIAL(dev)) + retval = serial_open(dev-64,filp); + else if (IS_A_PTY(dev)) + retval = pty_open(dev,filp); +! if (retval) + tty->count--; + return retval; + } + + static void tty_release(struct inode * inode, struct file * filp) + { + int dev; + struct tty_struct * tty; + +! dev = inode->i_rdev; +! if (MAJOR(dev) == 5) +! dev = current->tty; +! else +! dev = MINOR(dev); +! if (dev < 0) + return; + tty = TTY_TABLE(dev); +! if (--tty->count) + return; +! if (tty == redirect) +! redirect = NULL; +! if (IS_A_SERIAL(dev)) + serial_close(dev-64,filp); +! else if (IS_A_PTY(dev)) + pty_close(dev,filp); + } + + static struct file_operations tty_fops = { +--- 533,582 ---- + tty->session = current->session; + tty->pgrp = current->pgrp; + } +! if (IS_A_SERIAL(dev) && tty->count < 2) + retval = serial_open(dev-64,filp); + else if (IS_A_PTY(dev)) + retval = pty_open(dev,filp); +! if (retval) { + tty->count--; ++ if (IS_A_PTY_MASTER(dev) && tty->link) ++ tty->link->count++; ++ } + return retval; + } + ++ /* ++ * Note that releasing a pty master also releases the child, so ++ * we have to make the redirection checks after that and on both ++ * sides of a pty. ++ */ + static void tty_release(struct inode * inode, struct file * filp) + { + int dev; + struct tty_struct * tty; + +! dev = filp->f_rdev; +! if (MAJOR(dev) != 4) { +! printk("tty_close: tty pseudo-major != 4\n"); + return; ++ } ++ dev = MINOR(filp->f_rdev); + tty = TTY_TABLE(dev); +! if (IS_A_PTY_MASTER(dev) && tty->link) +! tty->link->count--; +! tty->count--; +! if (tty->count) + return; +! if (IS_A_SERIAL(dev)) { +! wait_until_sent(tty); + serial_close(dev-64,filp); +! } else if (IS_A_PTY(dev)) + pty_close(dev,filp); ++ if (!tty->count && (tty == redirect)) ++ redirect = NULL; ++ if (tty = tty->link) ++ if (!tty->count && (tty == redirect)) ++ redirect = NULL; + } + + static struct file_operations tty_fops = { +*************** +*** 584,600 **** + tty_release + }; + +- static struct file_operations ttyx_fops = { +- tty_lseek, +- ttyx_read, +- ttyx_write, +- NULL, /* ttyx_readdir */ +- NULL, /* ttyx_select */ +- tty_ioctl, /* ttyx_ioctl */ +- tty_open, +- tty_release +- }; +- + long tty_init(long kmem_start) + { + int i; +--- 590,595 ---- +*************** +*** 603,609 **** + kmem_start += QUEUES * (sizeof (struct tty_queue)); + table_list[0] = con_queues + 0; + table_list[1] = con_queues + 1; +! chrdev_fops[4] = &ttyx_fops; + chrdev_fops[5] = &tty_fops; + for (i=0 ; i < QUEUES ; i++) + tty_queues[i] = (struct tty_queue) {0,0,0,0,""}; +--- 598,604 ---- + kmem_start += QUEUES * (sizeof (struct tty_queue)); + table_list[0] = con_queues + 0; + table_list[1] = con_queues + 1; +! chrdev_fops[4] = &tty_fops; + chrdev_fops[5] = &tty_fops; + for (i=0 ; i < QUEUES ; i++) + tty_queues[i] = (struct tty_queue) {0,0,0,0,""}; +*** 0.96c/linux/kernel/chr_drv/serial.c Thu Jun 25 18:22:24 1992 +--- linux/kernel/chr_drv/serial.c Tue Jul 7 18:32:46 1992 +*************** +*** 26,41 **** + + #define WAKEUP_CHARS (3*TTY_BUF_SIZE/4) + +- /* +- * note that IRQ9 is what many docs call IRQ2 - on the AT hardware +- * the old IRQ2 line has been changed to IRQ9. The serial_table +- * structure considers IRQ2 to be the same as IRQ9. +- */ +- extern void IRQ9_interrupt(void); +- extern void IRQ3_interrupt(void); +- extern void IRQ4_interrupt(void); +- extern void IRQ5_interrupt(void); +- + struct serial_struct serial_table[NR_SERIALS] = { + { PORT_UNKNOWN, 0, 0x3F8, 4, NULL}, + { PORT_UNKNOWN, 1, 0x2F8, 3, NULL}, +--- 26,31 ---- +*************** +*** 43,62 **** + { PORT_UNKNOWN, 3, 0x2E8, 3, NULL}, + }; + +- static struct serial_struct * irq_info[16] = { NULL, }; +- + static void modem_status_intr(struct serial_struct * info) + { + unsigned char status = inb(info->port+6); + +! if ((status & 0x88) == 0x08 && info->tty->pgrp > 0) +! kill_pg(info->tty->pgrp,SIGHUP,1); + #if 0 +! if ((status & 0x10) == 0x10) +! info->tty->stopped = 0; +! else +! info->tty->stopped = 1; + #endif + } + + void send_break(unsigned int line) +--- 33,52 ---- + { PORT_UNKNOWN, 3, 0x2E8, 3, NULL}, + }; + + static void modem_status_intr(struct serial_struct * info) + { + unsigned char status = inb(info->port+6); + +! if (!(info->tty->termios.c_cflag & CLOCAL)) { +! if ((status & 0x88) == 0x08 && info->tty->pgrp > 0) +! kill_pg(info->tty->pgrp,SIGHUP,1); + #if 0 +! if ((status & 0x10) == 0x10) +! info->tty->stopped = 0; +! else +! info->tty->stopped = 1; + #endif ++ } + } + + void send_break(unsigned int line) +*************** +*** 94,108 **** + int c, i = 0; + + timer_active &= ~(1 << timer); +! do { +! if ((c = GETCH(queue)) < 0) +! return; + outb(c,port); +! i++; +! } while (info->type == PORT_16550A && +! i < 14 && !EMPTY(queue)); + timer_table[timer].expires = jiffies + 10; + timer_active |= 1 << timer; + if (LEFT(queue) > WAKEUP_CHARS) + wake_up(&queue->proc_list); + } +--- 84,102 ---- + int c, i = 0; + + timer_active &= ~(1 << timer); +! while (inb_p(info->port+5) & 0x20) { +! if (queue->tail == queue->head) +! goto end_send; +! c = queue->buf[queue->tail]; +! queue->tail++; +! queue->tail &= TTY_BUF_SIZE-1; + outb(c,port); +! if ((info->type != PORT_16550A) || (++i >= 14)) +! break; +! } + timer_table[timer].expires = jiffies + 10; + timer_active |= 1 << timer; ++ end_send: + if (LEFT(queue) > WAKEUP_CHARS) + wake_up(&queue->proc_list); + } +*************** +*** 111,120 **** + { + unsigned short port = info->port; + struct tty_queue * queue = info->tty->read_q; + + do { +! PUTCH(inb(port),queue); + } while (inb(port+5) & 1); + timer_active |= (1<line; + } + +--- 105,122 ---- + { + unsigned short port = info->port; + struct tty_queue * queue = info->tty->read_q; ++ int head = queue->head; ++ int maxhead = (queue->tail-1) & (TTY_BUF_SIZE-1); + ++ timer_active &= ~((1<line); + do { +! queue->buf[head] = inb(port); +! if (head != maxhead) { +! head++; +! head &= TTY_BUF_SIZE-1; +! } + } while (inb(port+5) & 1); ++ queue->head = head; + timer_active |= (1<line; + } + +*************** +*** 149,159 **** + } + } + +! void do_IRQ(int irq) + { +! check_tty(irq_info[irq]); + } + + static void com1_timer(void) + { + TTY_READ_FLUSH(tty_table+64); +--- 151,197 ---- + } + } + +! /* +! * Again, we disable interrupts to be sure there aren't any races: +! * see send_intr for details. +! */ +! static inline void do_rs_write(struct serial_struct * info) + { +! if (!info->tty || !info->port) +! return; +! if (!info->tty->write_q || EMPTY(info->tty->write_q)) +! return; +! cli(); +! send_intr(info); +! sti(); + } + ++ /* ++ * IRQ routines: one per line ++ */ ++ static void com1_IRQ(int cpl) ++ { ++ check_tty(serial_table+0); ++ } ++ ++ static void com2_IRQ(int cpl) ++ { ++ check_tty(serial_table+1); ++ } ++ ++ static void com3_IRQ(int cpl) ++ { ++ check_tty(serial_table+2); ++ } ++ ++ static void com4_IRQ(int cpl) ++ { ++ check_tty(serial_table+3); ++ } ++ ++ /* ++ * Receive timer routines: one per line ++ */ + static void com1_timer(void) + { + TTY_READ_FLUSH(tty_table+64); +*************** +*** 175,201 **** + } + + /* +! * Again, we disable interrupts to be sure there aren't any races: +! * see send_intr for details. + */ +- static inline void do_rs_write(struct serial_struct * info) +- { +- if (!info->tty || !info->port) +- return; +- if (!info->tty->write_q || EMPTY(info->tty->write_q)) +- return; +- cli(); +- if (inb_p(info->port+5) & 0x20) +- send_intr(info); +- else { +- unsigned int timer = SER1_TIMEOUT+info->line; +- +- timer_table[timer].expires = jiffies + 10; +- timer_active |= 1 << timer; +- } +- sti(); +- } +- + static void com1_timeout(void) + { + do_rs_write(serial_table); +--- 213,220 ---- + } + + /* +! * Send timeout routines: one per line + */ + static void com1_timeout(void) + { + do_rs_write(serial_table); +*************** +*** 276,288 **** + irq = info->irq; + if (irq == 2) + irq = 9; +! if (irq_info[irq] == info) { +! irq_info[irq] = NULL; +! if (irq < 8) +! outb(inb_p(0x21) | (1<irq; + if (irq == 2) + irq = 9; +! free_irq(irq); + } + + static void startup(unsigned short port) +*************** +*** 300,306 **** + { + struct serial_struct * info; + unsigned short port,quot; +! unsigned cflag; + static unsigned short quotient[] = { + 0, 2304, 1536, 1047, 857, + 768, 576, 384, 192, 96, +--- 313,319 ---- + { + struct serial_struct * info; + unsigned short port,quot; +! unsigned cflag,cval; + static unsigned short quotient[] = { + 0, 2304, 1536, 1047, 857, + 768, 576, 384, 192, 96, +*************** +*** 318,339 **** + outb(0x00,port+4); + else if (!inb(port+4)) + startup(port); + cli(); +! outb_p(0x80,port+3); /* set DLAB */ + outb_p(quot & 0xff,port); /* LS of divisor */ + outb_p(quot >> 8,port+1); /* MS of divisor */ +! outb(0x03,port+3); /* reset DLAB */ + sti(); +- /* set byte size and parity */ +- quot = cflag & (CSIZE | CSTOPB); +- quot >>= 4; +- if (cflag & PARENB) +- quot |= 8; +- if (!(cflag & PARODD)) +- quot |= 16; +- outb(quot,port+3); + } + + /* + * this routine enables interrupts on 'line', and disables them for any + * other serial line that shared the same IRQ. Braindamaged AT hardware. +--- 331,355 ---- + outb(0x00,port+4); + else if (!inb(port+4)) + startup(port); ++ /* byte size and parity */ ++ cval = cflag & (CSIZE | CSTOPB); ++ cval >>= 4; ++ if (cflag & PARENB) ++ cval |= 8; ++ if (!(cflag & PARODD)) ++ cval |= 16; + cli(); +! outb_p(cval | 0x80,port+3); /* set DLAB */ + outb_p(quot & 0xff,port); /* LS of divisor */ + outb_p(quot >> 8,port+1); /* MS of divisor */ +! outb(cval,port+3); /* reset DLAB */ + sti(); + } + ++ static void (*serial_handler[NR_SERIALS])(int) = { ++ com1_IRQ,com2_IRQ,com3_IRQ,com4_IRQ ++ }; ++ + /* + * this routine enables interrupts on 'line', and disables them for any + * other serial line that shared the same IRQ. Braindamaged AT hardware. +*************** +*** 341,348 **** + int serial_open(unsigned line, struct file * filp) + { + struct serial_struct * info; +! int irq; + unsigned short port; + + if (line >= NR_SERIALS) + return -ENODEV; +--- 357,365 ---- + int serial_open(unsigned line, struct file * filp) + { + struct serial_struct * info; +! int irq,retval; + unsigned short port; ++ void (*handler)(int) = serial_handler[line]; + + if (line >= NR_SERIALS) + return -ENODEV; +*************** +*** 352,367 **** + irq = info->irq; + if (irq == 2) + irq = 9; +! if (irq_info[irq] && irq_info[irq] != info) +! return -EBUSY; +! cli(); + startup(port); +- irq_info[irq] = info; +- if (irq < 8) +- outb(inb_p(0x21) & ~(1<irq; + if (irq == 2) + irq = 9; +! if (retval = request_irq(irq,handler)) +! return retval; + startup(port); + return 0; + } + +*************** +*** 380,385 **** +--- 390,397 ---- + struct serial_struct tmp; + unsigned new_port; + unsigned irq,new_irq; ++ int retval; ++ void (*handler)(int) = serial_handler[line]; + + if (!suser()) + return -EPERM; +*************** +*** 401,420 **** + if (irq == 2) + irq = 9; + if (irq != new_irq) { +! if (irq_info[new_irq]) +! return -EBUSY; +! cli(); +! irq_info[new_irq] = irq_info[irq]; +! irq_info[irq] = NULL; +! info->irq = new_irq; +! if (irq < 8) +! outb(inb_p(0x21) | (1<port) { +--- 413,422 ---- + if (irq == 2) + irq = 9; + if (irq != new_irq) { +! retval = request_irq(new_irq,handler); +! if (retval) +! return retval; +! free_irq(irq); + } + cli(); + if (new_port != info->port) { +*************** +*** 450,459 **** + timer_table[SER3_TIMEOUT].expires = 0; + timer_table[SER4_TIMEOUT].fn = com4_timeout; + timer_table[SER4_TIMEOUT].expires = 0; +- set_intr_gate(0x23,IRQ3_interrupt); +- set_intr_gate(0x24,IRQ4_interrupt); +- set_intr_gate(0x25,IRQ5_interrupt); +- set_intr_gate(0x29,IRQ9_interrupt); + for (i = 0, info = serial_table; i < NR_SERIALS; i++,info++) { + info->tty = (tty_table+64) + i; + init(info); +--- 452,457 ---- +*** 0.96c/linux/kernel/chr_drv/pty.c Sun Jul 5 03:15:12 1992 +--- linux/kernel/chr_drv/pty.c Wed Jul 8 14:18:16 1992 +*************** +*** 31,40 **** + wake_up(&tty->read_q->proc_list); + if (filp->f_flags & O_NDELAY) + return 0; +- if (IS_A_PTY_MASTER(dev)) { +- tty->link->count++; +- return 0; +- } + while (!tty->link->count && !(current->signal & ~current->blocked)) + interruptible_sleep_on(&tty->link->read_q->proc_list); + if (!tty->link->count) +--- 31,36 ---- +*************** +*** 48,55 **** + + tty = tty_table + dev; + wake_up(&tty->read_q->proc_list); + if (IS_A_PTY_MASTER(dev)) { +- tty->link->count--; + if (tty->link->pgrp > 0) + kill_pg(tty->link->pgrp,SIGHUP,1); + } +--- 44,51 ---- + + tty = tty_table + dev; + wake_up(&tty->read_q->proc_list); ++ wake_up(&tty->link->write_q->proc_list); + if (IS_A_PTY_MASTER(dev)) { + if (tty->link->pgrp > 0) + kill_pg(tty->link->pgrp,SIGHUP,1); + } +*************** +*** 66,73 **** + TTY_READ_FLUSH(to); + continue; + } +! c = GETCH(from->write_q); +! PUTCH(c,to->read_q); + if (current->signal & ~current->blocked) + break; + } +--- 62,69 ---- + TTY_READ_FLUSH(to); + continue; + } +! c = get_tty_queue(from->write_q); +! put_tty_queue(c,to->read_q); + if (current->signal & ~current->blocked) + break; + } +*** 0.96c/linux/kernel/blk_drv/hd.c Wed Jun 3 04:00:19 1992 +--- linux/kernel/blk_drv/hd.c Sat Jul 11 00:49:35 1992 +*************** +*** 16,22 **** +--- 16,25 ---- + * in the early extended-partition checks and added DM partitions + */ + ++ #define HD_IRQ 14 ++ + #include ++ #include + + #include + #include +*************** +*** 82,88 **** + #define port_write(port,buf,nr) \ + __asm__("cld;rep;outsw"::"d" (port),"S" (buf),"c" (nr):"cx","si") + +- extern void hd_interrupt(void); + extern void rd_load(void); + + static unsigned int current_minor; +--- 85,90 ---- +*************** +*** 279,285 **** +--- 281,289 ---- + blk_size[MAJOR_NR] = hd_sizes; + if (NR_HD) + printk("Partition table%s ok.\n\r",(NR_HD>1)?"s":""); ++ #ifdef RAMDISK + rd_load(); ++ #endif + mount_root(); + return (0); + } +*************** +*** 517,523 **** + */ + static void hd_times_out(void) + { +! do_hd = NULL; + reset = 1; + if (!CURRENT) + return; +--- 521,527 ---- + */ + static void hd_times_out(void) + { +! DEVICE_INTR = NULL; + reset = 1; + if (!CURRENT) + return; +*************** +*** 601,607 **** +--- 605,614 ---- + (char *) &loc->sectors); + put_fs_word(hd_info[dev].cyl, + (short *) &loc->cylinders); ++ put_fs_long(hd[MINOR(inode->i_rdev)].start_sect, ++ (long *) &loc->start); + return 0; ++ RO_IOCTLS(inode->i_rdev,arg); + default: + return -EINVAL; + } +*************** +*** 627,638 **** + hd_release /* release */ + }; + + void hd_init(void) + { + blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST; + blkdev_fops[MAJOR_NR] = &hd_fops; +! set_intr_gate(0x2E,&hd_interrupt); +! outb_p(inb_p(0x21)&0xfb,0x21); +! outb(inb_p(0xA1)&0xbf,0xA1); + timer_table[HD_TIMER].fn = hd_times_out; + } +--- 634,668 ---- + hd_release /* release */ + }; + ++ static void hd_interrupt(int cpl) ++ { ++ void (*handler)(void) = DEVICE_INTR; ++ ++ DEVICE_INTR = NULL; ++ timer_active &= ~(1< ++ #include + #include + #include + #include +*************** +*** 70,75 **** +--- 71,101 ---- + wake_up(&bh->b_wait); + } + ++ /* RO fail safe mechanism */ ++ ++ static long ro_bits[NR_BLK_DEV][8]; ++ ++ int is_read_only(int dev) ++ { ++ int minor,major; ++ ++ major = MAJOR(dev); ++ minor = MINOR(dev); ++ if (major < 0 || major >= NR_BLK_DEV) return 0; ++ return ro_bits[major][minor >> 5] & (1 << (minor & 31)); ++ } ++ ++ void set_device_ro(int dev,int flag) ++ { ++ int minor,major; ++ ++ major = MAJOR(dev); ++ minor = MINOR(dev); ++ if (major < 0 || major >= NR_BLK_DEV) return; ++ if (flag) ro_bits[major][minor >> 5] |= 1 << (minor & 31); ++ else ro_bits[major][minor >> 5] &= ~(1 << (minor & 31)); ++ } ++ + /* + * add-request adds a request to the linked list. + * It disables interrupts so that it can muck with the +*************** +*** 203,208 **** +--- 229,238 ---- + } + if (rw!=READ && rw!=WRITE) + panic("Bad block dev command, must be R/W"); ++ if (rw == WRITE && is_read_only(dev)) { ++ printk("Can't page to read-only device 0x%X\n\r",dev); ++ return; ++ } + cli(); + repeat: + req = request+NR_REQUEST; +*************** +*** 238,245 **** +--- 268,281 ---- + if ((major=MAJOR(bh->b_dev)) >= NR_BLK_DEV || + !(blk_dev[major].request_fn)) { + printk("ll_rw_block: Trying to read nonexistent block-device\n\r"); ++ bh->b_dirt = bh->b_uptodate = 0; + return; + } ++ if ((rw == WRITE || rw == WRITEA) && is_read_only(bh->b_dev)) { ++ printk("Can't write to read-only device 0x%X\n\r",bh->b_dev); ++ bh->b_dirt = bh->b_uptodate = 0; ++ return; ++ } + make_request(major,rw,bh); + } + +*************** +*** 251,256 **** +--- 287,293 ---- + request[i].dev = -1; + request[i].next = NULL; + } ++ memset(ro_bits,0,sizeof(ro_bits)); + #ifdef RAMDISK + mem_start += rd_init(mem_start, RAMDISK*1024); + #endif +*************** +*** 270,275 **** +--- 307,316 ---- + + if (rw!=READ && rw!=WRITE) { + printk("ll_rw_swap: bad block dev command, must be R/W"); ++ return; ++ } ++ if (rw == WRITE && is_read_only(dev)) { ++ printk("Can't swap to read-only device 0x%X\n\r",dev); + return; + } + +*** 0.96c/linux/kernel/blk_drv/floppy.c Sat Jul 4 20:44:26 1992 +--- linux/kernel/blk_drv/floppy.c Sat Jul 11 00:49:35 1992 +*************** +*** 38,43 **** +--- 38,45 ---- + * the floppy-change signal detection. + */ + ++ #define FLOPPY_IRQ 6 ++ + #include + #include + #include +*************** +*** 205,211 **** + * and ND is set means no DMA. Hardcoded to 6 (HLD=6ms, use DMA). + */ + +- extern void floppy_interrupt(void); + extern char tmp_floppy_area[1024]; + extern char floppy_track_buffer[512*2*MAX_BUFFER_SECTORS]; + +--- 207,212 ---- +*************** +*** 560,566 **** + else redo_fd_request(); + } + +! void unexpected_floppy_interrupt(void) + { + current_track = NO_TRACK; + output_byte(FD_SENSEI); +--- 561,567 ---- + else redo_fd_request(); + } + +! static void unexpected_floppy_interrupt(void) + { + current_track = NO_TRACK; + output_byte(FD_SENSEI); +*************** +*** 831,836 **** +--- 832,840 ---- + int drive,cnt,okay; + struct floppy_struct *this; + ++ switch (cmd) { ++ RO_IOCTLS(inode->i_rdev,param); ++ } + if (!suser()) return -EPERM; + drive = MINOR(inode->i_rdev); + switch (cmd) { +*************** +*** 975,980 **** +--- 979,1006 ---- + floppy_release /* release */ + }; + ++ static void floppy_interrupt(int cpl) ++ { ++ void (*handler)(void) = DEVICE_INTR; ++ ++ DEVICE_INTR = NULL; ++ if (!handler) ++ handler = unexpected_floppy_interrupt; ++ handler(); ++ } ++ ++ /* ++ * This is the harddisk IRQ descruption. The SA_INTERRUPT in sa_flags ++ * means we run the IRQ-handler with interrupts disabled: this is bad for ++ * interrupt latency, but may be safer... ++ */ ++ static struct sigaction floppy_sigaction = { ++ floppy_interrupt, ++ 0, ++ SA_INTERRUPT, ++ NULL ++ }; ++ + void floppy_init(void) + { + outb(current_DOR,FD_DOR); +*************** +*** 984,989 **** + timer_table[FLOPPY_TIMER].fn = floppy_shutdown; + timer_active &= ~(1 << FLOPPY_TIMER); + config_types(); +! set_intr_gate(0x26,&floppy_interrupt); +! outb(inb_p(0x21)&~0x40,0x21); + } +--- 1010,1015 ---- + timer_table[FLOPPY_TIMER].fn = floppy_shutdown; + timer_active &= ~(1 << FLOPPY_TIMER); + config_types(); +! if (irqaction(FLOPPY_IRQ,&floppy_sigaction)) +! printk("Unable to grab IRQ%d for the floppy driver\n",FLOPPY_IRQ); + } +*** 0.96c/linux/kernel/blk_drv/blk.h Wed Jun 3 04:23:19 1992 +--- linux/kernel/blk_drv/blk.h Sat Jul 11 00:49:34 1992 +*************** +*** 54,59 **** +--- 54,67 ---- + + extern int * blk_size[NR_BLK_DEV]; + ++ extern int is_read_only(int dev); ++ extern void set_device_ro(int dev,int flag); ++ ++ #define RO_IOCTLS(dev,where) \ ++ case BLKROSET: if (!suser()) return -EPERM; \ ++ set_device_ro((dev),get_fs_long((long *) (where))); return 0; \ ++ case BLKROGET: put_fs_long(is_read_only(dev),(long *) (where)); return 0; ++ + #ifdef MAJOR_NR + + /* +*** 0.96c/linux/kernel/blk_drv/ramdisk.c Thu Jun 18 14:16:39 1992 +--- linux/kernel/blk_drv/ramdisk.c Tue Jul 7 16:03:33 1992 +*************** +*** 84,90 **** + void rd_load(void) + { + struct buffer_head *bh; +! struct super_block s; + int block = 256; /* Start at block 256 */ + int i = 1; + int nblocks; +--- 84,90 ---- + void rd_load(void) + { + struct buffer_head *bh; +! struct minix_super_block s; + int block = 256; /* Start at block 256 */ + int i = 1; + int nblocks; +*** 0.96c/linux/kernel/blk_drv/scsi/aha1542.c Thu Jul 2 01:54:30 1992 +--- linux/kernel/blk_drv/scsi/aha1542.c Thu Jul 9 19:44:56 1992 +*************** +*** 8,13 **** +--- 8,14 ---- + #include + #include + #include ++ #include + #include + #include + #include +*************** +*** 34,40 **** + long WAITtimeout, WAITnexttimeout = 3000000; + + void (*do_done)() = NULL; +- extern void aha1542_interrupt(); + + #define aha1542_intr_reset() outb(IRST, CONTROL) + #define aha1542_enable_intr() outb(inb_p(0xA1) & ~8, 0xA1) +--- 35,40 ---- +*************** +*** 192,198 **** + } + + /* A "high" level interrupt handler */ +! void aha1542_intr_handle(void) + { + int flag = inb(INTRFLAGS); + void (*my_done)() = do_done; +--- 192,198 ---- + } + + /* A "high" level interrupt handler */ +! static void aha1542_interrupt(int cpl) + { + int flag = inb(INTRFLAGS); + void (*my_done)() = do_done; +*************** +*** 200,206 **** + + do_done = NULL; + #ifdef DEBUG +! printk("aha1542_intr_handle: "); + if (!(flag&ANYINTR)) printk("no interrupt?"); + if (flag&MBIF) printk("MBIF "); + if (flag&MBOA) printk("MBOF "); +--- 200,206 ---- + + do_done = NULL; + #ifdef DEBUG +! printk("aha1542_interrupt: "); + if (!(flag&ANYINTR)) printk("no interrupt?"); + if (flag&MBIF) printk("MBIF "); + if (flag&MBOA) printk("MBOF "); +*************** +*** 212,218 **** + #endif + aha1542_intr_reset(); + if (!my_done) { +! printk("aha1542_intr_handle: Unexpected interrupt\n"); + return; + } + +--- 212,218 ---- + #endif + aha1542_intr_reset(); + if (!my_done) { +! printk("aha1542_interrupt: Unexpected interrupt\n"); + return; + } + +*************** +*** 219,225 **** + /* is there mail :-) */ + + if (!mb[1].status) { +! DEB(printk("aha1542_intr_handle: strange: mbif but no mail!\n")); + my_done(DID_TIME_OUT << 16); + return; + } +--- 219,225 ---- + /* is there mail :-) */ + + if (!mb[1].status) { +! DEB(printk("aha1542_interrupt: strange: mbif but no mail!\n")); + my_done(DID_TIME_OUT << 16); + return; + } +*************** +*** 235,252 **** + + if (ccb.tarstat == 2) { + int i; +! DEB(printk("aha1542_intr_handle: sense:")); + for (i = 0; i < 12; i++) + printk("%02x ", ccb.cdb[ccb.cdblen+i]); + printk("\n"); + /* +! DEB(printk("aha1542_intr_handle: buf:")); + for (i = 0; i < bufflen; i++) + printk("%02x ", ((unchar *)buff)[i]); + printk("\n"); + */ + } +! DEB(if (errstatus) printk("aha1542_intr_handle: returning %6x\n", errstatus)); + my_done(errstatus); + return; + } +--- 235,252 ---- + + if (ccb.tarstat == 2) { + int i; +! DEB(printk("aha1542_interrupt: sense:")); + for (i = 0; i < 12; i++) + printk("%02x ", ccb.cdb[ccb.cdblen+i]); + printk("\n"); + /* +! DEB(printk("aha1542_interrupt: buf:")); + for (i = 0; i < bufflen; i++) + printk("%02x ", ((unchar *)buff)[i]); + printk("\n"); + */ + } +! DEB(if (errstatus) printk("aha1542_interrupt: returning %6x\n", errstatus)); + my_done(errstatus); + return; + } +*************** +*** 355,361 **** + + void call_buh() + { +! set_intr_gate(0x2b,&aha1542_interrupt); + } + + /* return non-zero on detection */ +--- 355,368 ---- + + void call_buh() + { +! struct sigaction sa; +! +! sa.sa_handler = aha1542_interrupt; +! sa.sa_flags = SA_INTERRUPT; +! sa.sa_mask = 0; +! sa.sa_restorer = NULL; +! if (irqaction(intr_chan,&sa)) +! printk("Unable to allocate IRQ%d for aha controller\n", intr_chan); + } + + /* return non-zero on detection */ +*************** +*** 448,482 **** + DEB(printk("aha1542_reset called\n")); + return 0; + } +- +- __asm__(" +- _aha1542_interrupt: +- cld +- pushl %eax +- pushl %ecx +- pushl %edx +- push %ds +- push %es +- push %fs +- movl $0x10,%eax +- mov %ax,%ds +- mov %ax,%es +- movl $0x17,%eax +- mov %ax,%fs +- movb $0x20,%al +- outb %al,$0xA0 # EOI to interrupt controller #1 +- jmp 1f # give port chance to breathe +- 1: jmp 1f +- 1: outb %al,$0x20 +- # Please, someone, change this to use the timer +- # andl $0xfffeffff,_timer_active +- movl $_aha1542_intr_handle,%edx +- call *%edx # ``interesting'' way of handling intr. +- pop %fs +- pop %es +- pop %ds +- popl %edx +- popl %ecx +- popl %eax +- iret +- "); +--- 455,457 ---- +*** 0.96c/linux/kernel/blk_drv/scsi/sd_ioctl.c Sat May 2 18:37:38 1992 +--- linux/kernel/blk_drv/scsi/sd_ioctl.c Sat Jul 11 00:49:36 1992 +*************** +*** 3,8 **** +--- 3,11 ---- + #include + #include + #include ++ #include ++ #include "../blk.h" ++ #include + #include "scsi.h" + #include "sd.h" + +*************** +*** 13,18 **** +--- 16,22 ---- + int dev = inode->i_rdev; + + switch (cmd) { ++ RO_IOCTLS(dev,arg); + default: + return scsi_ioctl(rscsi_disks[MINOR(dev) >> 4].device,cmd,(void *) arg); + } +*** 0.96c/linux/kernel/blk_drv/scsi/ultrastor.c Fri May 29 00:26:06 1992 +--- linux/kernel/blk_drv/scsi/ultrastor.c Thu Jul 9 19:27:15 1992 +*************** +*** 156,162 **** + }; + #endif + +! void ultrastor_interrupt(void); + + static void (*ultrastor_done)(int, int) = 0; + +--- 156,162 ---- + }; + #endif + +! void ultrastor_interrupt(int cpl); + + static void (*ultrastor_done)(int, int) = 0; + +*************** +*** 293,303 **** + host_number = hostnum; + scsi_hosts[hostnum].this_id = config.ha_scsi_id; + #if USE_QUEUECOMMAND +! set_intr_gate(0x20 + config.interrupt, ultrastor_interrupt); +! /* gate to PIC 2 */ +! outb_p(inb_p(0x21) & ~BIT(2), 0x21); +! /* enable the interrupt */ +! outb(inb_p(0xA1) & ~BIT(config.interrupt - 8), 0xA1); + #endif + return TRUE; + } +--- 293,309 ---- + host_number = hostnum; + scsi_hosts[hostnum].this_id = config.ha_scsi_id; + #if USE_QUEUECOMMAND +! { +! struct sigaction sa; +! sa.sa_handler = ultrastor_interrupt; +! sa.sa_flags = SA_INTERRUPT; +! sa.sa_mask = 0; +! sa.sa_restorer = NULL; +! if (irqaction(config.interrupt,&sa)) { +! printk("unable to get IRQ%d for ultrastor controller\n",config.interrupt); +! return FALSE; +! } +! } + #endif + return TRUE; + } +*************** +*** 421,427 **** + } + + #if USE_QUEUECOMMAND +! void ultrastor_interrupt_service(void) + { + if (ultrastor_done == 0) { + printk("US14F: unexpected ultrastor interrupt\n\r"); +--- 427,433 ---- + } + + #if USE_QUEUECOMMAND +! void ultrastor_interrupt(int cpl) + { + if (ultrastor_done == 0) { + printk("US14F: unexpected ultrastor interrupt\n\r"); +*************** +*** 434,470 **** + (mscp.adapter_status << 16) | mscp.target_status); + ultrastor_done = 0; + } +- +- __asm__(" +- _ultrastor_interrupt: +- cld +- pushl %eax +- pushl %ecx +- pushl %edx +- push %ds +- push %es +- push %fs +- movl $0x10,%eax +- mov %ax,%ds +- mov %ax,%es +- movl $0x17,%eax +- mov %ax,%fs +- movb $0x20,%al +- outb %al,$0xA0 # EOI to interrupt controller #1 +- outb %al,$0x80 # give port chance to breathe +- outb %al,$0x80 +- outb %al,$0x80 +- outb %al,$0x80 +- outb %al,$0x20 +- call _ultrastor_interrupt_service +- pop %fs +- pop %es +- pop %ds +- popl %edx +- popl %ecx +- popl %eax +- iret +- "); + #endif + + #endif +--- 440,445 ---- +*** 0.96c/linux/kernel/sys_call.S Thu Jun 25 16:40:29 1992 +--- linux/kernel/sys_call.S Tue Jul 7 18:39:02 1992 +*************** +*** 81,87 **** + * Ok, I get parallel printer interrupts while using the floppy for some + * strange reason. Urgel. Now I just ignore them. + */ +! .globl _system_call,_timer_interrupt,_sys_execve + .globl _device_not_available, _coprocessor_error + .globl _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_op + .globl _double_fault,_coprocessor_segment_overrun +--- 81,87 ---- + * Ok, I get parallel printer interrupts while using the floppy for some + * strange reason. Urgel. Now I just ignore them. + */ +! .globl _system_call,_sys_execve + .globl _device_not_available, _coprocessor_error + .globl _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_op + .globl _double_fault,_coprocessor_segment_overrun +*************** +*** 88,95 **** + .globl _invalid_TSS,_segment_not_present,_stack_segment + .globl _general_protection,_irq13,_reserved + .globl _alignment_check,_page_fault +! .globl _keyboard_interrupt,_hd_interrupt +! .globl _IRQ3_interrupt,_IRQ4_interrupt,_IRQ5_interrupt,_IRQ9_interrupt + + #define SAVE_ALL \ + cld; \ +--- 88,94 ---- + .globl _invalid_TSS,_segment_not_present,_stack_segment + .globl _general_protection,_irq13,_reserved + .globl _alignment_check,_page_fault +! .globl ret_from_sys_call + + #define SAVE_ALL \ + cld; \ +*************** +*** 170,184 **** + jne 2f + cmpw $0x17,OLDSS(%esp) # was stack segment = 0x17 ? + jne 2f +! 1: movl _current,%eax +! cmpl _task,%eax # task[0] cannot have signals +! je 2f +! cmpl $0,_need_resched + jne reschedule + cmpl $0,state(%eax) # state + jne reschedule + cmpl $0,counter(%eax) # counter + je reschedule + movl signal(%eax),%ebx + movl blocked(%eax),%ecx + notl %ecx +--- 169,185 ---- + jne 2f + cmpw $0x17,OLDSS(%esp) # was stack segment = 0x17 ? + jne 2f +! 1: cmpl $0,_need_resched + jne reschedule ++ movl _current,%eax + cmpl $0,state(%eax) # state + jne reschedule + cmpl $0,counter(%eax) # counter + je reschedule ++ movl $1,_need_resched ++ cmpl _task,%eax # task[0] cannot have signals ++ je 2f ++ movl $0,_need_resched + movl signal(%eax),%ebx + movl blocked(%eax),%ecx + notl %ecx +*************** +*** 240,340 **** + call _math_emulate + addl $4,%esp + ret +- +- .align 2 +- _keyboard_interrupt: +- pushl $-1 +- SAVE_ALL +- ACK_FIRST(0x02) +- sti +- call _do_keyboard +- cli +- UNBLK_FIRST(0x02) +- jmp ret_from_sys_call +- +- .align 2 +- _IRQ3_interrupt: +- pushl $-1 +- SAVE_ALL +- ACK_FIRST(0x08) +- sti +- pushl $3 +- call _do_IRQ +- addl $4,%esp +- cli +- UNBLK_FIRST(0x08) +- jmp ret_from_sys_call +- +- .align 2 +- _IRQ4_interrupt: +- pushl $-1 +- SAVE_ALL +- ACK_FIRST(0x10) +- sti +- pushl $4 +- call _do_IRQ +- addl $4,%esp +- cli +- UNBLK_FIRST(0x10) +- jmp ret_from_sys_call +- +- .align 2 +- _IRQ5_interrupt: +- pushl $-1 +- SAVE_ALL +- ACK_FIRST(0x20) +- sti +- pushl $5 +- call _do_IRQ +- addl $4,%esp +- cli +- UNBLK_FIRST(0x20) +- jmp ret_from_sys_call +- +- .align 2 +- _IRQ9_interrupt: +- pushl $-1 +- SAVE_ALL +- ACK_SECOND(0x02) +- sti +- pushl $9 +- call _do_IRQ +- addl $4,%esp +- cli +- UNBLK_SECOND(0x02) +- jmp ret_from_sys_call +- +- .align 2 +- _timer_interrupt: +- pushl $-1 # mark this as an int +- SAVE_ALL +- ACK_FIRST(0x01) +- sti +- incl _jiffies +- movl CS(%esp),%eax +- andl $3,%eax # %eax is CPL (0 or 3, 0=supervisor) +- pushl %eax +- call _do_timer # 'do_timer(long CPL)' does everything from +- addl $4,%esp # task switching to accounting ... +- cli +- UNBLK_FIRST(0x01) +- jmp ret_from_sys_call +- +- .align 2 +- _hd_interrupt: +- pushl $-1 +- SAVE_ALL +- ACK_SECOND(0x40) +- andl $0xfffeffff,_timer_active +- xorl %edx,%edx +- xchgl _do_hd,%edx +- testl %edx,%edx +- jne 1f +- movl $_unexpected_hd_interrupt,%edx +- 1: call *%edx # "interesting" way of handling intr. +- cli +- UNBLK_SECOND(0x40) +- jmp ret_from_sys_call + + .align 2 + _sys_execve: +--- 241,246 ---- +*** /dev/null Sat Jul 11 22:43:15 1992 +--- linux/kernel/irq.c Thu Jul 9 14:43:34 1992 +*************** +*** 0 **** +--- 1,171 ---- ++ /* ++ * linux/kernel/irq.c ++ * ++ * (C) 1992 Linus Torvalds ++ * ++ * This file contains the code used by various IRQ handling routines: ++ * asking for different IRQ's should be done through these routines ++ * instead of just grabbing them. Thus setups with different IRQ numbers ++ * shouldn't result in any weird surprises, and installing new handlers ++ * should be easier. ++ */ ++ ++ /* ++ * IRQ's are in fact implemented a bit like signal handlers for the kernel. ++ * The same sigaction struct is used, and with similar semantics (ie there ++ * is a SA_INTERRUPT flag etc). Naturally it's not a 1:1 relation, but there ++ * are similarities. ++ * ++ * sa_handler(int irq_NR) is the default function called. ++ * sa_mask is 0 if nothing uses this IRQ ++ * sa_flags contains various info: SA_INTERRUPT etc ++ * sa_restorer is the unused ++ */ ++ ++ #include ++ #include ++ ++ #include ++ ++ #include ++ #include ++ #include ++ #include ++ ++ struct sigaction irq_sigaction[16] = { ++ { NULL, 0, 0, NULL }, ++ }; ++ ++ /* ++ * This builds up the IRQ handler stubs using some ugly macros in irq.h ++ */ ++ BUILD_IRQ(FIRST,0,0x01) ++ BUILD_IRQ(FIRST,1,0x02) ++ BUILD_IRQ(FIRST,2,0x04) ++ BUILD_IRQ(FIRST,3,0x08) ++ BUILD_IRQ(FIRST,4,0x10) ++ BUILD_IRQ(FIRST,5,0x20) ++ BUILD_IRQ(FIRST,6,0x40) ++ BUILD_IRQ(FIRST,7,0x80) ++ BUILD_IRQ(SECOND,8,0x01) ++ BUILD_IRQ(SECOND,9,0x02) ++ BUILD_IRQ(SECOND,10,0x04) ++ BUILD_IRQ(SECOND,11,0x08) ++ BUILD_IRQ(SECOND,12,0x10) ++ BUILD_IRQ(SECOND,13,0x20) ++ BUILD_IRQ(SECOND,14,0x40) ++ BUILD_IRQ(SECOND,15,0x80) ++ ++ /* ++ * This routine gets called at every IRQ request. Interrupts ++ * are enabled, the interrupt has been accnowledged and this ++ * particular interrupt is disabled when this is called. ++ * ++ * The routine has to call the appropriate handler (disabling ++ * interrupts if needed first), and then re-enable this interrupt- ++ * line if the handler was ok. If no handler exists, the IRQ isn't ++ * re-enabled. ++ * ++ * Note similarities on a very low level between this and the ++ * do_signal() function. Naturally this is simplified, but they ++ * get similar arguments, use them similarly etc... Note that ++ * unlike the signal-handlers, the IRQ-handlers don't get the IRQ ++ * (signal) number as argument, but the cpl value at the time of ++ * the interrupt. ++ */ ++ void do_IRQ(int irq, struct pt_regs * regs) ++ { ++ struct sigaction * sa = irq + irq_sigaction; ++ void (*handler)(int); ++ ++ if (!(handler = sa->sa_handler)) ++ return; ++ if (sa->sa_flags & SA_INTERRUPT) ++ cli(); ++ handler(regs->cs & 3); ++ cli(); ++ if (irq < 8) ++ outb(inb_p(0x21) & ~(1< 15) ++ return -EINVAL; ++ if (irq == 2) ++ irq = 9; ++ sa = irq + irq_sigaction; ++ if (sa->sa_mask) ++ return -EBUSY; ++ __asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags)); ++ *sa = *new; ++ sa->sa_mask = 1; ++ if (irq < 8) ++ outb(inb_p(0x21) & ~(1< 15) { ++ printk("Trying to free IRQ%d\n",irq); ++ return; ++ } ++ if (!sa->sa_mask) { ++ printk("Trying to free free IRQ%d\n",irq); ++ return; ++ } ++ __asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags)); ++ if (irq < 8) ++ outb(inb_p(0x21) | (1<sa_handler = NULL; ++ sa->sa_flags = 0; ++ sa->sa_mask = 0; ++ sa->sa_restorer = NULL; ++ __asm__ __volatile__("pushl %0 ; popfl"::"r" (flags)); ++ } ++ ++ void init_IRQ(void) ++ { ++ set_trap_gate(0x20,IRQ0_interrupt); ++ set_trap_gate(0x21,IRQ1_interrupt); ++ set_trap_gate(0x22,IRQ2_interrupt); ++ set_trap_gate(0x23,IRQ3_interrupt); ++ set_trap_gate(0x24,IRQ4_interrupt); ++ set_trap_gate(0x25,IRQ5_interrupt); ++ set_trap_gate(0x26,IRQ6_interrupt); ++ set_trap_gate(0x27,IRQ7_interrupt); ++ set_trap_gate(0x28,IRQ8_interrupt); ++ set_trap_gate(0x29,IRQ10_interrupt); ++ set_trap_gate(0x2a,IRQ10_interrupt); ++ set_trap_gate(0x2b,IRQ11_interrupt); ++ set_trap_gate(0x2c,IRQ12_interrupt); ++ set_trap_gate(0x2d,IRQ13_interrupt); ++ set_trap_gate(0x2e,IRQ14_interrupt); ++ set_trap_gate(0x2f,IRQ15_interrupt); ++ } +*** 0.96c/linux/kernel/ptrace.c Wed Jun 17 13:37:55 1992 +--- linux/kernel/ptrace.c Thu Jul 9 19:18:53 1992 +*************** +*** 39,45 **** + { + int i; + +! for (i = 0; i < NR_TASKS; i++) { + if (task[i] != NULL && (task[i]->pid == pid)) + return task[i]; + } +--- 39,45 ---- + { + int i; + +! for (i = 1; i < NR_TASKS; i++) { + if (task[i] != NULL && (task[i]->pid == pid)) + return task[i]; + } +*************** +*** 238,243 **** +--- 238,245 ---- + if (request == PTRACE_ATTACH) { + long tmp; + ++ if (child == current) ++ return -EPERM; + if ((!current->dumpable || (current->uid != child->euid) || + (current->gid != child->egid)) && !suser()) + return -EPERM; +*** 0.96c/linux/lib/Makefile Sun Jul 5 03:11:58 1992 +--- linux/lib/Makefile Sat Jul 11 20:14:30 1992 +*************** +*** 14,20 **** + $(CC) $(CFLAGS) -c $< + + OBJS = ctype.o _exit.o open.o close.o errno.o write.o dup.o setsid.o \ +! execve.o wait.o string.o malloc.o itimer.o + + lib.a: $(OBJS) + $(AR) rcs lib.a $(OBJS) +--- 14,20 ---- + $(CC) $(CFLAGS) -c $< + + OBJS = ctype.o _exit.o open.o close.o errno.o write.o dup.o setsid.o \ +! execve.o wait.o string.o malloc.o + + lib.a: $(OBJS) + $(AR) rcs lib.a $(OBJS) +*************** +*** 36,43 **** + dup.o : dup.c /usr/src/linux/include/linux/unistd.h + errno.o : errno.c + execve.o : execve.c /usr/src/linux/include/linux/unistd.h +- itimer.o : itimer.c /usr/src/linux/include/linux/unistd.h /usr/src/linux/include/sys/time.h \ +- /usr/src/linux/include/time.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h + malloc.o : malloc.c /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/mm.h \ + /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ + /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ +--- 36,41 ---- +*** 0.96c/linux/include/sys/time.h Mon May 25 22:18:54 1992 +--- linux/include/sys/time.h Wed Jul 8 15:17:52 1992 +*************** +*** 55,61 **** + }; + + int getitimer(int which, struct itimerval *value); +! int setitimer(int which, struct itimerval *value, struct itimerval *ovalue); + + #include + #include +--- 55,61 ---- + }; + + int getitimer(int which, struct itimerval *value); +! int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue); + + #include + #include +*** 0.96c/linux/include/linux/hdreg.h Fri Apr 24 18:26:25 1992 +--- linux/include/linux/hdreg.h Sat Jul 11 00:49:34 1992 +*************** +*** 69,73 **** +--- 69,74 ---- + unsigned char heads; + unsigned char sectors; + unsigned short cylinders; ++ unsigned long start; + }; + #endif +*** 0.96c/linux/include/linux/sched.h Sun Jul 5 01:27:18 1992 +--- linux/include/linux/sched.h Mon Jul 6 00:18:21 1992 +*************** +*** 228,233 **** +--- 228,237 ---- + extern void wake_up(struct task_struct ** p); + extern int in_group_p(gid_t grp); + ++ extern int request_irq(unsigned int irq,void (*handler)(int)); ++ extern void free_irq(unsigned int irq); ++ extern int irqaction(unsigned int irq,struct sigaction * new); ++ + /* + * Entry into gdt where to find first TSS. 0-nul, 1-cs, 2-ds, 3-syscall + * 4-TSS0, 5-LDT0, 6-TSS1 etc ... +*** 0.96c/linux/include/linux/tty.h Sat Jul 4 03:28:16 1992 +--- linux/include/linux/tty.h Tue Jul 7 14:54:51 1992 +*************** +*** 69,76 **** + extern void put_tty_queue(char c, struct tty_queue * queue); + extern int get_tty_queue(struct tty_queue * queue); + +- #define PUTCH(c,queue) put_tty_queue((c),(queue)) +- #define GETCH(queue) get_tty_queue(queue) + #define INTR_CHAR(tty) ((tty)->termios.c_cc[VINTR]) + #define QUIT_CHAR(tty) ((tty)->termios.c_cc[VQUIT]) + #define ERASE_CHAR(tty) ((tty)->termios.c_cc[VERASE]) +--- 69,74 ---- +*************** +*** 166,171 **** +--- 164,170 ---- + + extern void flush_input(struct tty_struct * tty); + extern void flush_output(struct tty_struct * tty); ++ extern void wait_until_sent(struct tty_struct * tty); + extern void copy_to_cooked(struct tty_struct * tty); + + extern int tty_ioctl(struct inode *, struct file *, unsigned int, unsigned int); +*** 0.96c/linux/include/linux/fs.h Fri Jul 3 03:09:37 1992 +--- linux/include/linux/fs.h Sat Jul 11 01:27:13 1992 +*************** +*** 43,49 **** + + #define NR_OPEN 32 + #define NR_INODE 128 +! #define NR_FILE 64 + #define NR_SUPER 8 + #define NR_HASH 307 + #define NR_BUFFERS nr_buffers +--- 43,49 ---- + + #define NR_OPEN 32 + #define NR_INODE 128 +! #define NR_FILE 128 + #define NR_SUPER 8 + #define NR_HASH 307 + #define NR_BUFFERS nr_buffers +*************** +*** 71,76 **** +--- 71,103 ---- + #define SEL_OUT 2 + #define SEL_EX 4 + ++ /* ++ * These are the fs-independent mount-flags: up to 16 flags are supported ++ */ ++ #define MS_RDONLY 1 /* mount read-only */ ++ #define MS_NOSUID 2 /* ignore suid and sgid bits */ ++ #define MS_NODEV 4 /* disallow access to device special files */ ++ #define MS_NOEXEC 8 /* disallow program execution */ ++ ++ /* ++ * Note that read-only etc flags are inode-specific: setting some file-system ++ * flags just means all the inodes inherit those flags by default. It might be ++ * possible to overrride it sevelctively if you really wanted to with some ++ * ioctl() that is not currently implemented. ++ */ ++ #define IS_RDONLY(inode) ((inode)->i_flags & MS_RDONLY) ++ #define IS_NOSUID(inode) ((inode)->i_flags & MS_NOSUID) ++ #define IS_NODEV(inode) ((inode)->i_flags & MS_NODEV) ++ #define IS_NOEXEC(inode) ((inode)->i_flags & MS_NOEXEC) ++ ++ /* the read-only stuff doesn't really belong here, but any other place is ++ probably as bad and I don't want to create yet another include file. */ ++ ++ #define BLKROSET 4701 /* set device read-only (0 = read-write) */ ++ #define BLKROGET 4702 /* get read-only status (0 = read_write) */ ++ ++ #define BMAP_IOCTL 1 ++ + typedef char buffer_block[BLOCK_SIZE]; + + struct buffer_head { +*************** +*** 107,112 **** +--- 134,140 ---- + struct task_struct * i_wait; + struct task_struct * i_wait2; /* for pipes */ + unsigned short i_count; ++ unsigned short i_flags; + unsigned char i_lock; + unsigned char i_dirt; + unsigned char i_pipe; +*************** +*** 120,125 **** +--- 148,154 ---- + unsigned short f_flags; + unsigned short f_count; + unsigned short f_reada; ++ unsigned short f_rdev; /* needed for /dev/tty */ + struct inode * f_inode; + struct file_operations * f_op; + off_t f_pos; +*************** +*** 159,164 **** +--- 188,194 ---- + unsigned char s_dirt; + /* TUBE */ + struct super_operations *s_op; ++ int s_flags; + }; + + struct file_operations { +*** 0.96c/linux/include/linux/config.h Sun Jul 5 01:28:18 1992 +--- linux/include/linux/config.h Sat Jul 11 20:16:04 1992 +*************** +*** 26,32 **** + #define DEF_INITSEG 0x9000 + #define DEF_SYSSEG 0x1000 + #define DEF_SETUPSEG 0x9020 +! #define DEF_SYSSIZE 0x4000 + + /* + * The root-device is no longer hard-coded. You can change the default +--- 26,32 ---- + #define DEF_INITSEG 0x9000 + #define DEF_SYSSEG 0x1000 + #define DEF_SETUPSEG 0x9020 +! #define DEF_SYSSIZE 0x5000 + + /* + * The root-device is no longer hard-coded. You can change the default +*** /dev/null Sat Jul 11 22:43:15 1992 +--- linux/include/asm/irq.h Tue Jul 7 18:45:48 1992 +*************** +*** 0 **** +--- 1,75 ---- ++ #ifndef _ASM_IRQ_H ++ #define _ASM_IRQ_H ++ ++ /* ++ * linux/include/asm/irq.h ++ * ++ * (C) 1992 Linus Torvalds ++ */ ++ ++ #define SAVE_ALL \ ++ "cld\n\t" \ ++ "push %gs\n\t" \ ++ "push %fs\n\t" \ ++ "push %es\n\t" \ ++ "push %ds\n\t" \ ++ "pushl %eax\n\t" \ ++ "pushl %ebp\n\t" \ ++ "pushl %edi\n\t" \ ++ "pushl %esi\n\t" \ ++ "pushl %edx\n\t" \ ++ "pushl %ecx\n\t" \ ++ "pushl %ebx\n\t" \ ++ "movl $0x10,%edx\n\t" \ ++ "mov %dx,%ds\n\t" \ ++ "mov %dx,%es\n\t" \ ++ "movl $0x17,%edx\n\t" \ ++ "mov %dx,%fs\n\t" ++ ++ #define ACK_FIRST(mask) \ ++ "inb $0x21,%al\n\t" \ ++ "jmp 1f\n" \ ++ "1:\tjmp 1f\n" \ ++ "1:\torb $" #mask ",%al\n\t" \ ++ "outb %al,$0x21\n\t" \ ++ "jmp 1f\n" \ ++ "1:\tjmp 1f\n" \ ++ "1:\tmovb $0x20,%al\n\t" \ ++ "outb %al,$0x20\n\t" ++ ++ #define ACK_SECOND(mask) \ ++ "inb $0xA1,%al\n\t" \ ++ "jmp 1f\n" \ ++ "1:\tjmp 1f\n" \ ++ "1:\torb $" #mask ",%al\n\t" \ ++ "outb %al,$0xA1\n\t" \ ++ "jmp 1f\n" \ ++ "1:\tjmp 1f\n" \ ++ "1:\tmovb $0x20,%al\n\t" \ ++ "outb %al,$0xA0" \ ++ "jmp 1f\n" \ ++ "1:\tjmp 1f\n" \ ++ "1:\toutb %al,$0x20\n\t" ++ ++ #define IRQ_NAME2(nr) nr##_interrupt() ++ #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr) ++ ++ #define BUILD_IRQ(chip,nr,mask) \ ++ extern void IRQ_NAME(nr); \ ++ __asm__( \ ++ "\n.align 2\n" \ ++ ".globl _IRQ" #nr "_interrupt\n" \ ++ "_IRQ" #nr "_interrupt:\n\t" \ ++ "pushl $-1\n\t" \ ++ SAVE_ALL \ ++ "cli\n\t" \ ++ ACK_##chip(mask) \ ++ "sti\n\t" \ ++ "movl %esp,%ebx\n\t" \ ++ "pushl %ebx\n\t" \ ++ "pushl $" #nr "\n\t" \ ++ "call _do_IRQ\n\t" \ ++ "addl $8,%esp\n\t" \ ++ "jmp ret_from_sys_call"); ++ ++ #endif diff --git a/Linux-0.96/sources/system/linux-0.96c.patch2 b/Linux-0.96/sources/system/linux-0.96c.patch2 new file mode 100644 index 00000000..02663e0e --- /dev/null +++ b/Linux-0.96/sources/system/linux-0.96c.patch2 @@ -0,0 +1,5509 @@ +*** 0.96c.pl1/linux/Makefile Sat Jul 18 22:27:57 1992 +--- linux/Makefile Thu Jul 16 02:34:48 1992 +*************** +*** 34,39 **** +--- 34,41 ---- + # KEYBOARD = -DKBD_DK -DKBDFLAGS=0 + # KEYBOARD = -DKBD_DK_LATIN1 -DKBDFLAGS=0x9F + # KEYBOARD = -DKBD_DVORAK -DKBDFLAGS=0 ++ # KEYBOARD = -DKBD_SG -DKBDFLAGS=0 ++ # KEYBOARD = -DKBD_SG_LATIN1 -DKBDFLAGS=0x9F + + # + # comment this line if you don't want the emulation-code +*************** +*** 66,72 **** + AR =ar + + ARCHIVES =kernel/kernel.o mm/mm.o fs/fs.o net/net.o +! FILESYSTEMS =fs/minix/minix.o fs/ext/ext.o + DRIVERS =kernel/blk_drv/blk_drv.a kernel/chr_drv/chr_drv.a \ + kernel/blk_drv/scsi/scsi.a + MATH =kernel/math/math.a +--- 68,74 ---- + AR =ar + + ARCHIVES =kernel/kernel.o mm/mm.o fs/fs.o net/net.o +! FILESYSTEMS =fs/minix/minix.o fs/ext/ext.o fs/msdos/msdos.o + DRIVERS =kernel/blk_drv/blk_drv.a kernel/chr_drv/chr_drv.a \ + kernel/blk_drv/scsi/scsi.a + MATH =kernel/math/math.a +*************** +*** 89,95 **** + + Version: + @./makever.sh +! @echo \#define UTS_RELEASE \"0.96c.pl1-`cat .version`\" > include/linux/config_rel.h + @echo \#define UTS_VERSION \"`date +%D`\" > include/linux/config_ver.h + touch include/linux/config.h + +--- 91,97 ---- + + Version: + @./makever.sh +! @echo \#define UTS_RELEASE \"0.96c.pl2-`cat .version`\" > include/linux/config_rel.h + @echo \#define UTS_VERSION \"`date +%D`\" > include/linux/config_ver.h + touch include/linux/config.h + +*** 0.96c.pl1/linux/fs/Makefile Sun Jul 5 03:11:06 1992 +--- linux/fs/Makefile Thu Jul 16 02:36:05 1992 +*************** +*** 7,13 **** + # + # Note 2! The CFLAGS definitions are now in the main makefile... + +! SUBDIRS =minix ext + + .c.s: + $(CC) $(CFLAGS) -S $< +--- 7,13 ---- + # + # Note 2! The CFLAGS definitions are now in the main makefile... + +! SUBDIRS =minix ext msdos + + .c.s: + $(CC) $(CFLAGS) -S $< +*** 0.96c.pl1/linux/fs/buffer.c Fri Jul 3 03:09:37 1992 +--- linux/fs/buffer.c Wed Jul 15 16:07:16 1992 +*************** +*** 30,36 **** + static struct buffer_head * start_buffer = (struct buffer_head *) &end; + static struct buffer_head * hash_table[NR_HASH]; + static struct buffer_head * free_list; +! static struct task_struct * buffer_wait = NULL; + int NR_BUFFERS = 0; + + static inline void wait_on_buffer(struct buffer_head * bh) +--- 30,36 ---- + static struct buffer_head * start_buffer = (struct buffer_head *) &end; + static struct buffer_head * hash_table[NR_HASH]; + static struct buffer_head * free_list; +! static struct wait_queue * buffer_wait = NULL; + int NR_BUFFERS = 0; + + static inline void wait_on_buffer(struct buffer_head * bh) +*** 0.96c.pl1/linux/fs/exec.c Sat Jul 18 22:27:57 1992 +--- linux/fs/exec.c Fri Jul 17 04:30:30 1992 +*************** +*** 101,106 **** +--- 101,107 ---- + has_dumped = 1; + /* write and seek example: from kernel space */ + __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10)); ++ dump.magic = CMAGIC; + dump.u_tsize = current->end_code / PAGE_SIZE; + dump.u_dsize = (current->brk - current->end_code) / PAGE_SIZE; + dump.u_ssize =((current->start_stack +(PAGE_SIZE-1)) / PAGE_SIZE) - +*************** +*** 168,173 **** +--- 169,176 ---- + struct inode * inode; + struct buffer_head * bh; + struct exec ex; ++ int i; ++ struct file * f; + + if (get_limit(0x17) != TASK_SIZE) + return -EINVAL; +*************** +*** 183,188 **** +--- 186,200 ---- + iput(inode); + return -EACCES; + } ++ if (inode->i_count > 1) { /* check for writers */ ++ f=0+file_table; ++ for (i=0 ; if_count && (f->f_mode & 2)) ++ if (inode == f->f_inode) { ++ iput(inode); ++ return -ETXTBSY; ++ } ++ } + if (!(bh = bread(inode->i_dev,bmap(inode,0)))) { + iput(inode); + return -EACCES; +*************** +*** 391,396 **** +--- 403,409 ---- + int sh_bang = 0; + unsigned long p=PAGE_SIZE*MAX_ARG_PAGES-4; + int ch; ++ struct file * f; + + if ((0xffff & eip[1]) != 0x000f) + panic("execve called from supervisor mode"); +*************** +*** 398,403 **** +--- 411,425 ---- + page[i]=0; + if (!(inode=namei(filename))) /* get executables inode */ + return -ENOENT; ++ if (inode->i_count > 1) { /* check for writers */ ++ f=0+file_table; ++ for (i=0 ; if_count && (f->f_mode & 2)) ++ if (inode == f->f_inode) { ++ retval = -ETXTBSY; ++ goto exec_error2; ++ } ++ } + argc = count(argv); + envc = count(envp); + +*** 0.96c.pl1/linux/fs/super.c Sat Jul 18 22:27:57 1992 +--- linux/fs/super.c Wed Jul 15 07:19:47 1992 +*************** +*** 11,17 **** + #include + #include + #include +! /* #include */ + #include + #include + #include +--- 11,17 ---- + #include + #include + #include +! #include + #include + #include + #include +*************** +*** 38,44 **** + static struct file_system_type file_systems[] = { + {minix_read_super,"minix"}, + {ext_read_super,"ext"}, +! /* {msdos_read_super,"msdos"}, */ + {NULL,NULL} + }; + +--- 38,44 ---- + static struct file_system_type file_systems[] = { + {minix_read_super,"minix"}, + {ext_read_super,"ext"}, +! {msdos_read_super,"msdos"}, + {NULL,NULL} + }; + +*************** +*** 65,74 **** + + void free_super(struct super_block * sb) + { +- cli(); + sb->s_lock = 0; + wake_up(&(sb->s_wait)); +- sti(); + } + + void wait_on_super(struct super_block * sb) +--- 65,72 ---- +*** 0.96c.pl1/linux/fs/namei.c Sat Jul 18 22:27:58 1992 +--- linux/fs/namei.c Wed Jul 15 03:05:09 1992 +*************** +*** 197,204 **** + struct inode ** res_inode) + { + const char * basename; +! int namelen,error; + struct inode * dir, *inode; + + if ((flag & O_TRUNC) && !(flag & O_ACCMODE)) + flag |= O_WRONLY; +--- 197,205 ---- + struct inode ** res_inode) + { + const char * basename; +! int namelen,error,i; + struct inode * dir, *inode; ++ struct task_struct ** p; + + if ((flag & O_TRUNC) && !(flag & O_ACCMODE)) + flag |= O_WRONLY; +*************** +*** 258,263 **** +--- 259,278 ---- + iput(inode); + return -EPERM; + } ++ if ((inode->i_count > 1) && (flag & O_ACCMODE)) ++ for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) { ++ if (!*p) ++ continue; ++ if (inode == (*p)->executable) { ++ iput(inode); ++ return -ETXTBSY; ++ } ++ for (i=0; i < (*p)->numlibraries; i++) ++ if (inode == (*p)->libraries[i].library) { ++ iput(inode); ++ return -ETXTBSY; ++ } ++ } + if (flag & O_TRUNC) + if (inode->i_op && inode->i_op->truncate) { + inode->i_size = 0; +*** 0.96c.pl1/linux/fs/pipe.c Thu Jul 2 00:42:04 1992 +--- linux/fs/pipe.c Wed Jul 15 04:24:46 1992 +*************** +*** 117,122 **** +--- 117,144 ---- + } + } + ++ static int pipe_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait) ++ { ++ switch (sel_type) { ++ case SEL_IN: ++ if (!PIPE_EMPTY(*inode) || !PIPE_WRITERS(*inode)) ++ return 1; ++ select_wait(&PIPE_READ_WAIT(*inode), wait); ++ return 0; ++ case SEL_OUT: ++ if (!PIPE_FULL(*inode) || !PIPE_WRITERS(*inode)) ++ return 1; ++ select_wait(&PIPE_WRITE_WAIT(*inode), wait); ++ return 0; ++ case SEL_EX: ++ if (!PIPE_READERS(*inode) || !PIPE_WRITERS(*inode)) ++ return 1; ++ select_wait(&inode->i_wait,wait); ++ return 0; ++ } ++ return 0; ++ } ++ + /* + * Ok, these three routines NOW keep track of readers/writers, + * Linus previously did it with inode->i_count checking. +*************** +*** 150,156 **** + pipe_read, + bad_pipe_rw, + pipe_readdir, +! NULL, /* pipe_select */ + pipe_ioctl, + NULL, /* no special open code */ + pipe_read_release +--- 172,178 ---- + pipe_read, + bad_pipe_rw, + pipe_readdir, +! pipe_select, + pipe_ioctl, + NULL, /* no special open code */ + pipe_read_release +*************** +*** 161,167 **** + bad_pipe_rw, + pipe_write, + pipe_readdir, +! NULL, /* pipe_select */ + pipe_ioctl, + NULL, /* no special open code */ + pipe_write_release +--- 183,189 ---- + bad_pipe_rw, + pipe_write, + pipe_readdir, +! pipe_select, + pipe_ioctl, + NULL, /* no special open code */ + pipe_write_release +*************** +*** 172,178 **** + pipe_read, + pipe_write, + pipe_readdir, +! NULL, /* pipe_select */ + pipe_ioctl, + NULL, /* no special open code */ + pipe_rdwr_release +--- 194,200 ---- + pipe_read, + pipe_write, + pipe_readdir, +! pipe_select, + pipe_ioctl, + NULL, /* no special open code */ + pipe_rdwr_release +*** 0.96c.pl1/linux/fs/select.c Sat Jun 27 16:14:28 1992 +--- linux/fs/select.c Wed Jul 15 16:46:59 1992 +*************** +*** 7,13 **** + + #include + #include +- #include + #include + #include + #include +--- 7,12 ---- +*************** +*** 29,183 **** + * understand what I'm doing here, then you understand how the linux sleep/wakeup + * mechanism works. + * +! * Two very simple procedures, add_wait() and free_wait() make all the work. We +! * have to have interrupts disabled throughout the select, but that's not really +! * such a loss: sleeping automatically frees interrupts when we aren't in this +! * task. + */ + + static select_table * sel_tables = NULL; + +- static void add_wait(struct task_struct ** wait_address, select_table * p) +- { +- int i; +- +- if (!wait_address) +- return; +- for (i = 0 ; i < p->nr ; i++) +- if (p->entry[i].wait_address == wait_address) +- return; +- current->next_wait = NULL; +- p->entry[p->nr].wait_address = wait_address; +- p->entry[p->nr].old_task = *wait_address; +- *wait_address = current; +- p->nr++; +- } +- +- /* +- * free_wait removes the current task from any wait-queues and then +- * wakes up the queues. +- */ +- static void free_one_table(select_table * p) +- { +- int i; +- struct task_struct ** tpp; +- +- for(tpp = &LAST_TASK ; tpp > &FIRST_TASK ; --tpp) +- if (*tpp && ((*tpp)->next_wait == p->current)) +- (*tpp)->next_wait = NULL; +- if (!p->nr) +- return; +- for (i = 0; i < p->nr ; i++) { +- wake_up(p->entry[i].wait_address); +- wake_up(&p->entry[i].old_task); +- } +- p->nr = 0; +- } +- + static void free_wait(select_table * p) + { +! select_table * tmp; + +! if (p->woken) +! return; +! p = sel_tables; +! sel_tables = NULL; +! while (p) { +! wake_up(&p->current); +! p->woken = 1; +! tmp = p->next_table; +! p->next_table = NULL; +! free_one_table(p); +! p = tmp; + } + } + +- static struct tty_struct * get_tty(struct inode * inode) +- { +- int major, minor; +- +- if (!S_ISCHR(inode->i_mode)) +- return NULL; +- if ((major = MAJOR(inode->i_rdev)) != 5 && major != 4) +- return NULL; +- if (major == 5) +- minor = current->tty; +- else +- minor = MINOR(inode->i_rdev); +- if (minor < 0) +- return NULL; +- return TTY_TABLE(minor); +- } +- + /* + * The check_XX functions check out a file. We know it's either +! * a pipe, a character device or a fifo (fifo's not implemented) + */ +! static int check_in(select_table * wait, struct inode * inode) + { +! struct tty_struct * tty; +! +! if (tty = get_tty(inode)) +! if (!EMPTY(tty->secondary)) +! return 1; +! else if (tty->link && !tty->link->count) +! return 1; +! else +! add_wait(&tty->secondary->proc_list, wait); +! else if (inode->i_pipe) +! if (!PIPE_EMPTY(*inode) || !PIPE_WRITERS(*inode)) +! return 1; +! else +! add_wait(&inode->i_wait, wait); +! else if (S_ISSOCK(inode->i_mode)) +! if (sock_select(inode, NULL, SEL_IN, wait)) +! return 1; +! else +! add_wait(&inode->i_wait, wait); + return 0; + } + +! static int check_out(select_table * wait, struct inode * inode) + { +! struct tty_struct * tty; +! +! if (tty = get_tty(inode)) +! if (!FULL(tty->write_q)) +! return 1; +! else +! add_wait(&tty->write_q->proc_list, wait); +! else if (inode->i_pipe) +! if (!PIPE_FULL(*inode)) +! return 1; +! else +! add_wait(&inode->i_wait, wait); +! else if (S_ISSOCK(inode->i_mode)) +! if (sock_select(inode, NULL, SEL_OUT, wait)) +! return 1; +! else +! add_wait(&inode->i_wait, wait); + return 0; + } + +! static int check_ex(select_table * wait, struct inode * inode) + { +! struct tty_struct * tty; +! +! if (tty = get_tty(inode)) +! if (!FULL(tty->write_q)) +! return 0; +! else +! return 0; +! else if (inode->i_pipe) +! if (!PIPE_READERS(*inode) || !PIPE_WRITERS(*inode)) +! return 1; +! else +! add_wait(&inode->i_wait,wait); +! else if (S_ISSOCK(inode->i_mode)) +! if (sock_select(inode, NULL, SEL_EX, wait)) +! return 1; +! else +! add_wait(&inode->i_wait, wait); + return 0; + } + +--- 28,73 ---- + * understand what I'm doing here, then you understand how the linux sleep/wakeup + * mechanism works. + * +! * Two very simple procedures, select_wait() and free_wait() make all the work. +! * select_wait() is a inline-function defined in , as all select +! * functions have to call it to add an entry to the select table. + */ + + static select_table * sel_tables = NULL; + + static void free_wait(select_table * p) + { +! struct select_table_entry * entry = p->entry + p->nr; + +! while (p->nr > 0) { +! p->nr--; +! entry--; +! remove_wait_queue(entry->wait_address,&entry->wait); + } + } + + /* + * The check_XX functions check out a file. We know it's either +! * a pipe, a character device or a fifo + */ +! static int check_in(select_table * wait, struct inode * inode, struct file * file) + { +! if (file->f_op && file->f_op->select) +! return file->f_op->select(inode,file,SEL_IN,wait); + return 0; + } + +! static int check_out(select_table * wait, struct inode * inode, struct file * file) + { +! if (file->f_op && file->f_op->select) +! return file->f_op->select(inode,file,SEL_OUT,wait); + return 0; + } + +! static int check_ex(select_table * wait, struct inode * inode, struct file * file) + { +! if (file->f_op && file->f_op->select) +! return file->f_op->select(inode,file,SEL_EX,wait); + return 0; + } + +*************** +*** 186,191 **** +--- 76,82 ---- + { + int count; + select_table wait_table; ++ struct file * file; + int i; + fd_set mask; + +*************** +*** 209,235 **** + } + repeat: + wait_table.nr = 0; +- wait_table.woken = 0; +- wait_table.current = current; +- wait_table.next_table = sel_tables; +- sel_tables = &wait_table; + *inp = *outp = *exp = 0; + count = 0; + current->state = TASK_INTERRUPTIBLE; + mask = 1; + for (i = 0 ; i < NR_OPEN ; i++, mask += mask) { + if (mask & in) +! if (check_in(&wait_table,current->filp[i]->f_inode)) { + *inp |= mask; + count++; + } + if (mask & out) +! if (check_out(&wait_table,current->filp[i]->f_inode)) { + *outp |= mask; + count++; + } + if (mask & ex) +! if (check_ex(&wait_table,current->filp[i]->f_inode)) { + *exp |= mask; + count++; + } +--- 100,123 ---- + } + repeat: + wait_table.nr = 0; + *inp = *outp = *exp = 0; + count = 0; + current->state = TASK_INTERRUPTIBLE; + mask = 1; + for (i = 0 ; i < NR_OPEN ; i++, mask += mask) { ++ file = current->filp[i]; + if (mask & in) +! if (check_in(&wait_table,file->f_inode,file)) { + *inp |= mask; + count++; + } + if (mask & out) +! if (check_out(&wait_table,file->f_inode,file)) { + *outp |= mask; + count++; + } + if (mask & ex) +! if (check_ex(&wait_table,file->f_inode,file)) { + *exp |= mask; + count++; + } +*** 0.96c.pl1/linux/fs/ext/namei.c Sat Jul 18 22:28:06 1992 +--- linux/fs/ext/namei.c Wed Jul 15 16:11:22 1992 +*************** +*** 885,891 **** + int ext_rename(struct inode * old_dir, const char * old_name, int old_len, + struct inode * new_dir, const char * new_name, int new_len) + { +! static struct task_struct * wait = NULL; + static int lock = 0; + int result; + +--- 885,891 ---- + int ext_rename(struct inode * old_dir, const char * old_name, int old_len, + struct inode * new_dir, const char * new_name, int new_len) + { +! static struct wait_queue * wait = NULL; + static int lock = 0; + int result; + +*** /dev/null Sat Jul 18 22:26:09 1992 +--- linux/fs/msdos/Makefile Thu Jul 16 02:36:33 1992 +*************** +*** 0 **** +--- 1,77 ---- ++ # ++ # Makefile for the linux MS-DOS-filesystem routines. ++ # ++ # Note! Dependencies are done automagically by 'make dep', which also ++ # removes any old dependencies. DON'T put your own dependencies here ++ # unless it's something special (ie not a .c file). ++ # ++ # Note 2! The CFLAGS definitions are now in the main makefile... ++ ++ .c.s: ++ $(CC) $(CFLAGS) \ ++ -S -o $*.s $< ++ .c.o: ++ $(CC) $(CFLAGS) -c -o $*.o $< ++ .s.o: ++ $(AS) -o $*.o $< ++ ++ OBJS= namei.o inode.o file.o dir.o misc.o fat.o ++ ++ msdos.o: $(OBJS) ++ $(LD) -r -o msdos.o $(OBJS) ++ ++ clean: ++ rm -f core *.o *.a tmp_make ++ for i in *.c;do rm -f `basename $$i .c`.s;done ++ ++ dep: ++ sed '/\#\#\# Dependencies/q' < Makefile > tmp_make ++ (for i in *.c;do $(CPP) -M $$i;done) >> tmp_make ++ cp tmp_make Makefile ++ ++ ### Dependencies: ++ dir.o : dir.c /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h \ ++ /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \ ++ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ ++ /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ ++ /usr/src/linux/include/linux/msdos_fs.h /usr/src/linux/include/linux/sched.h \ ++ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ ++ /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ ++ /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h ++ fat.o : fat.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/stat.h \ ++ /usr/src/linux/include/linux/msdos_fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ ++ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \ ++ /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ ++ /usr/src/linux/include/linux/kernel.h ++ file.o : file.c /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h \ ++ /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/sys/types.h \ ++ /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/sched.h \ ++ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \ ++ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ ++ /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ ++ /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ ++ /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/msdos_fs.h ++ inode.o : inode.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/string.h \ ++ /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/stat.h \ ++ /usr/src/linux/include/linux/msdos_fs.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \ ++ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \ ++ /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/sched.h \ ++ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/signal.h \ ++ /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ ++ /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/segment.h ++ misc.o : misc.c /usr/src/linux/include/errno.h /usr/src/linux/include/limits.h \ ++ /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ ++ /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/msdos_fs.h \ ++ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \ ++ /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/sched.h \ ++ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \ ++ /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \ ++ /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h ++ namei.o : namei.c /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h \ ++ /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \ ++ /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \ ++ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \ ++ /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \ ++ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \ ++ /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \ ++ /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/msdos_fs.h +*** /dev/null Sat Jul 18 22:26:09 1992 +--- linux/fs/msdos/dir.c Thu Jul 16 00:35:11 1992 +*************** +*** 0 **** +--- 1,128 ---- ++ /* ++ * linux/fs/msdos/dir.c ++ * ++ * Written 1992 by Werner Almesberger ++ * ++ * MS-DOS directory handling functions ++ */ ++ ++ #include ++ #include ++ #include ++ #include ++ #include ++ ++ /* for compatibility warnings */ ++ #include ++ ++ static int msdos_dummy_read(struct inode *inode,struct file *filp,char *buf, ++ int count); ++ static int msdos_readdir(struct inode *inode,struct file *filp, ++ struct dirent *dirent,int count); ++ ++ ++ static struct file_operations msdos_dir_operations = { ++ NULL, /* lseek - default */ ++ msdos_dummy_read, /* read */ ++ NULL, /* write - bad */ ++ msdos_readdir, /* readdir */ ++ NULL, /* select - default */ ++ NULL, /* ioctl - default */ ++ NULL, /* no special open code */ ++ NULL /* no special release code */ ++ }; ++ ++ struct inode_operations msdos_dir_inode_operations = { ++ &msdos_dir_operations, /* default directory file-ops */ ++ msdos_create, /* create */ ++ msdos_lookup, /* lookup */ ++ NULL, /* link */ ++ msdos_unlink, /* unlink */ ++ NULL, /* symlink */ ++ msdos_mkdir, /* mkdir */ ++ msdos_rmdir, /* rmdir */ ++ NULL, /* mknod */ ++ msdos_rename, /* rename */ ++ NULL, /* readlink */ ++ NULL, /* follow_link */ ++ msdos_bmap, /* bmap */ ++ NULL /* truncate */ ++ }; ++ ++ ++ /* So grep * doesn't complain in the presence of directories. */ ++ ++ static int msdos_dummy_read(struct inode *inode,struct file *filp,char *buf, ++ int count) ++ { ++ static long last_warning = 0; ++ ++ if (CURRENT_TIME-last_warning >= 10) { ++ printk("COMPATIBILITY WARNING: reading a directory\r\n"); ++ last_warning = CURRENT_TIME; ++ } ++ return 0; ++ } ++ ++ ++ static int msdos_readdir(struct inode *inode,struct file *filp, ++ struct dirent *dirent,int count) ++ { ++ int ino,i,i2,last; ++ char c,*walk; ++ struct buffer_head *bh; ++ struct msdos_dir_entry *de; ++ ++ if (!inode || !S_ISDIR(inode->i_mode)) return -EBADF; ++ if (inode->i_ino == MSDOS_ROOT_INO) { ++ /* Fake . and .. for the root directory. */ ++ if (filp->f_pos == 2) filp->f_pos = 0; ++ else if (filp->f_pos < 2) { ++ walk = filp->f_pos++ ? ".." : "."; ++ for (i = 0; *walk; walk++) ++ put_fs_byte(*walk,dirent->d_name+i++); ++ put_fs_long(MSDOS_ROOT_INO,&dirent->d_ino); ++ put_fs_byte(0,dirent->d_name+i); ++ put_fs_word(i,&dirent->d_reclen); ++ return i; ++ } ++ } ++ if (filp->f_pos & (sizeof(struct msdos_dir_entry)-1)) return -ENOENT; ++ bh = NULL; ++ while ((ino = msdos_get_entry(inode,&filp->f_pos,&bh,&de)) > -1) { ++ if (de->name[0] && ((unsigned char *) (de->name))[0] != ++ DELETED_FLAG && !(de->attr & ATTR_VOLUME)) { ++ for (i = last = 0; i < 8; i++) { ++ if (!(c = de->name[i])) break; ++ if (c >= 'A' && c <= 'Z') c += 32; ++ if (c != ' ') last = i+1; ++ put_fs_byte(c,i+dirent->d_name); ++ } ++ i = last; ++ if (de->ext[0] && de->ext[0] != ' ') { ++ put_fs_byte('.',i+dirent->d_name); ++ i++; ++ for (i2 = 0; i2 < 3; i2++) { ++ if (!(c = de->ext[i2])) break; ++ if (c >= 'A' && c <= 'Z') c += 32; ++ put_fs_byte(c,i+dirent->d_name); ++ i++; ++ if (c != ' ') last = i; ++ } ++ } ++ if (i = last) { ++ if (!strcmp(de->name,MSDOS_DOT)) ++ ino = inode->i_ino; ++ else if (!strcmp(de->name,MSDOS_DOTDOT)) ++ ino = msdos_parent_ino(inode,0); ++ put_fs_long(ino,&dirent->d_ino); ++ put_fs_byte(0,i+dirent->d_name); ++ put_fs_word(i,&dirent->d_reclen); ++ brelse(bh); ++ return i; ++ } ++ } ++ } ++ if (bh) brelse(bh); ++ return 0; ++ } +*** /dev/null Sat Jul 18 22:26:09 1992 +--- linux/fs/msdos/file.c Thu Jul 16 00:35:11 1992 +*************** +*** 0 **** +--- 1,210 ---- ++ /* ++ * linux/fs/msdos/file.c ++ * ++ * Written 1992 by Werner Almesberger ++ * ++ * MS-DOS regular file handling primitives ++ */ ++ ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ ++ ++ #define MIN(a,b) (((a) < (b)) ? (a) : (b)) ++ #define MAX(a,b) (((a) > (b)) ? (a) : (b)) ++ ++ ++ static int msdos_file_read(struct inode *inode,struct file *filp,char *buf, ++ int count); ++ static int msdos_file_write(struct inode *inode,struct file *filp,char *buf, ++ int count); ++ ++ ++ static struct file_operations msdos_file_operations = { ++ NULL, /* lseek - default */ ++ msdos_file_read, /* read */ ++ msdos_file_write, /* write */ ++ NULL, /* readdir - bad */ ++ NULL, /* select - default */ ++ NULL, /* ioctl - default */ ++ NULL, /* no special open is needed */ ++ NULL /* release */ ++ }; ++ ++ struct inode_operations msdos_file_inode_operations = { ++ &msdos_file_operations, /* default file operations */ ++ NULL, /* create */ ++ NULL, /* lookup */ ++ NULL, /* link */ ++ NULL, /* unlink */ ++ NULL, /* symlink */ ++ NULL, /* mkdir */ ++ NULL, /* rmdir */ ++ NULL, /* mknod */ ++ NULL, /* rename */ ++ NULL, /* readlink */ ++ NULL, /* follow_link */ ++ msdos_bmap, /* bmap */ ++ msdos_truncate /* truncate */ ++ }; ++ ++ /* No bmap for MS-DOS FS' that don't align data at kByte boundaries. */ ++ ++ struct inode_operations msdos_file_inode_operations_no_bmap = { ++ &msdos_file_operations, /* default file operations */ ++ NULL, /* create */ ++ NULL, /* lookup */ ++ NULL, /* link */ ++ NULL, /* unlink */ ++ NULL, /* symlink */ ++ NULL, /* mkdir */ ++ NULL, /* rmdir */ ++ NULL, /* mknod */ ++ NULL, /* rename */ ++ NULL, /* readlink */ ++ NULL, /* follow_link */ ++ NULL, /* bmap */ ++ msdos_truncate /* truncate */ ++ }; ++ ++ ++ static int msdos_file_read(struct inode *inode,struct file *filp,char *buf, ++ int count) ++ { ++ char *start; ++ int left,offset,size,sector,cnt; ++ char ch; ++ struct buffer_head *bh; ++ void *data; ++ ++ /* printk("msdos_file_read\r\n"); */ ++ if (!inode) { ++ printk("msdos_file_read: inode = NULL\r\n"); ++ return -EINVAL; ++ } ++ if (!S_ISREG(inode->i_mode)) { ++ printk("msdos_file_read: mode = %07o\n",inode->i_mode); ++ return -EINVAL; ++ } ++ if (filp->f_pos >= inode->i_size || count <= 0) return 0; ++ start = buf; ++ while (left = MIN(inode->i_size-filp->f_pos,count-(buf-start))) { ++ if (!(sector = msdos_smap(inode,filp->f_pos >> SECTOR_BITS))) ++ break; ++ offset = filp->f_pos & (SECTOR_SIZE-1); ++ if (!(bh = msdos_sread(inode->i_dev,sector,&data))) break; ++ filp->f_pos += (size = MIN(SECTOR_SIZE-offset,left)); ++ if (inode->i_data[D_BINARY]) { ++ memcpy_tofs(buf,data+offset,size); ++ buf += size; ++ } ++ else for (cnt = size; cnt; cnt--) { ++ if ((ch = *((char *) data+offset++)) == '\r') ++ size--; ++ else { ++ if (ch != 26) put_fs_byte(ch,buf++); ++ else { ++ filp->f_pos = inode->i_size; ++ brelse(bh); ++ return buf-start; ++ } ++ } ++ } ++ brelse(bh); ++ } ++ if (start == buf) return -EIO; ++ return buf-start; ++ } ++ ++ ++ static int msdos_file_write(struct inode *inode,struct file *filp,char *buf, ++ int count) ++ { ++ int sector,offset,size,left,written; ++ int error,carry; ++ char *start,*to,ch; ++ struct buffer_head *bh; ++ void *data; ++ ++ if (!inode) { ++ printk("msdos_file_write: inode = NULL\n"); ++ return -EINVAL; ++ } ++ if (!S_ISREG(inode->i_mode)) { ++ printk("msdos_file_write: mode = %07o\n",inode->i_mode); ++ return -EINVAL; ++ } ++ /* ++ * ok, append may not work when many processes are writing at the same time ++ * but so what. That way leads to madness anyway. ++ */ ++ if (filp->f_flags & O_APPEND) filp->f_pos = inode->i_size; ++ if (count <= 0) return 0; ++ error = carry = 0; ++ for (start = buf; count || carry; count -= size) { ++ while (!(sector = msdos_smap(inode,filp->f_pos >> SECTOR_BITS))) ++ if ((error = msdos_add_cluster(inode)) < 0) break; ++ if (error) break; ++ offset = filp->f_pos & (SECTOR_SIZE-1); ++ size = MIN(SECTOR_SIZE-offset,MAX(carry,count)); ++ if (!(bh = msdos_sread(inode->i_dev,sector,&data))) { ++ error = -EIO; ++ break; ++ } ++ if (inode->i_data[D_BINARY]) { ++ memcpy_fromfs(data+(filp->f_pos & (SECTOR_SIZE-1)), ++ buf,written = size); ++ buf += size; ++ } ++ else { ++ written = left = SECTOR_SIZE-offset; ++ to = data+(filp->f_pos & (SECTOR_SIZE-1)); ++ if (carry) { ++ *to++ = '\n'; ++ left--; ++ carry = 0; ++ } ++ for (size = 0; size < count && left; size++) { ++ if ((ch = get_fs_byte(buf++)) == '\n') { ++ *to++ = '\r'; ++ left--; ++ } ++ if (!left) carry = 1; ++ else { ++ *to++ = ch; ++ left--; ++ } ++ } ++ written -= left; ++ } ++ filp->f_pos += written; ++ if (filp->f_pos > inode->i_size) { ++ inode->i_size = filp->f_pos; ++ inode->i_dirt = 1; ++ } ++ bh->b_dirt = 1; ++ brelse(bh); ++ } ++ inode->i_mtime = inode->i_ctime = CURRENT_TIME; ++ inode->i_data[D_ATTRS] |= ATTR_ARCH; ++ inode->i_dirt = 1; ++ return start == buf ? error : buf-start; ++ } ++ ++ ++ void msdos_truncate(struct inode *inode) ++ { ++ int cluster; ++ ++ if (!S_ISREG(inode->i_mode)) return; ++ cluster = SECTOR_SIZE*MSDOS_SB(inode->i_sb)->cluster_size; ++ (void) fat_free(inode,(inode->i_size+(cluster-1))/cluster); ++ inode->i_data[D_ATTRS] |= ATTR_ARCH; ++ inode->i_dirt = 1; ++ } +*** /dev/null Sat Jul 18 22:26:09 1992 +--- linux/fs/msdos/inode.c Thu Jul 16 00:35:11 1992 +*************** +*** 0 **** +--- 1,275 ---- ++ /* ++ * linux/fs/msdos/inode.c ++ * ++ * Written 1992 by Werner Almesberger ++ */ ++ ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ ++ ++ void msdos_put_inode(struct inode *inode) ++ { ++ struct inode *depend; ++ ++ inode->i_size = 0; ++ msdos_truncate(inode); ++ depend = (struct inode *) inode->i_data[D_DEPEND]; ++ memset(inode,0,sizeof(struct inode)); ++ if (depend) { ++ if ((struct inode *) depend->i_data[D_OLD] != inode) { ++ printk("Invalid link (0x%X): expected 0x%X, got " ++ "0x%X\r\n",(int) depend,(int) inode, ++ depend->i_data[D_OLD]); ++ panic("That's fatal"); ++ } ++ depend->i_data[D_OLD] = 0; ++ iput(depend); ++ } ++ } ++ ++ ++ void msdos_put_super(struct super_block *sb) ++ { ++ cache_inval_dev(sb->s_dev); ++ lock_super(sb); ++ sb->s_dev = 0; ++ free_super(sb); ++ return; ++ } ++ ++ ++ static struct super_operations msdos_sops = { ++ msdos_read_inode, ++ msdos_write_inode, ++ msdos_put_inode, ++ msdos_put_super, ++ NULL, /* added in 0.96c */ ++ msdos_statfs ++ }; ++ ++ ++ static int parse_options(char *options,char *check,char *conversion) ++ { ++ char *this,*value; ++ ++ *check = 'n'; ++ *conversion = 'b'; ++ if (!options) return 1; ++ for (this = strtok(options,","); this; this = strtok(NULL,",")) { ++ if (value = strchr(this,'=')) *value++ = 0; ++ if (!strcmp(this,"check") && value) { ++ if (value[0] && !value[1] && strchr("rns",*value)) ++ *check = *value; ++ else if (!strcmp(value,"releaxed")) *check = 'r'; ++ else if (!strcmp(value,"normal")) *check = 'n'; ++ else if (!strcmp(value,"strict")) *check = 's'; ++ else return 0; ++ } ++ else if (!strcmp(this,"conv") && value) { ++ if (value[0] && !value[1] && strchr("bta",*value)) ++ *conversion = *value; ++ else if (!strcmp(value,"binary")) *conversion = 'b'; ++ else if (!strcmp(value,"text")) *conversion = 't'; ++ else if (!strcmp(value,"auto")) *conversion = 'a'; ++ else return 0; ++ } ++ else return 0; ++ } ++ return 1; ++ } ++ ++ ++ /* Read the super block of an MS-DOS FS. */ ++ ++ struct super_block *msdos_read_super(struct super_block *s,void *data) ++ { ++ struct buffer_head *bh; ++ struct msdos_boot_sector *b; ++ int data_sectors; ++ char check,conversion; ++ ++ if (!parse_options((char *) data,&check,&conversion)) { ++ s->s_dev = 0; ++ return NULL; ++ } ++ cache_init(); ++ lock_super(s); ++ bh = bread(s->s_dev,0); ++ free_super(s); ++ if (bh == NULL) { ++ s->s_dev = 0; ++ printk("MSDOS bread failed\r\n"); ++ return NULL; ++ } ++ b = (struct msdos_boot_sector *) bh->b_data; ++ MSDOS_SB(s)->cluster_size = b->cluster_size; ++ MSDOS_SB(s)->fats = b->fats; ++ MSDOS_SB(s)->fat_start = b->reserved; ++ MSDOS_SB(s)->fat_length = b->fat_length; ++ MSDOS_SB(s)->dir_start = b->reserved+b->fats*b->fat_length; ++ MSDOS_SB(s)->dir_entries = *((unsigned short *) &b->dir_entries); ++ MSDOS_SB(s)->data_start = MSDOS_SB(s)->dir_start+((MSDOS_SB(s)-> ++ dir_entries << 5) >> 9); ++ data_sectors = (*((unsigned short *) &b->sectors) ? *((unsigned short *) ++ &b->sectors) : b->total_sect)-MSDOS_SB(s)->data_start; ++ MSDOS_SB(s)->clusters = b->cluster_size ? data_sectors/b->cluster_size : ++ 0; ++ MSDOS_SB(s)->fat_bits = MSDOS_SB(s)->clusters > MSDOS_FAT12 ? 16 : 12; ++ brelse(bh); ++ printk("[MS-DOS FS Rel. alpha.5, FAT %d, check=%c, conv=%c]\r\n", ++ MSDOS_SB(s)->fat_bits,check,conversion); ++ printk("[me=0x%x,cs=%d,#f=%d,fs=%d,fl=%d,ds=%d,de=%d,data=%d,se=%d,ts=%d]\r\n", ++ b->media,MSDOS_SB(s)->cluster_size,MSDOS_SB(s)->fats,MSDOS_SB(s)->fat_start, ++ MSDOS_SB(s)->fat_length,MSDOS_SB(s)->dir_start,MSDOS_SB(s)->dir_entries, ++ MSDOS_SB(s)->data_start,*(unsigned short *) &b->sectors,b->total_sect); ++ if (!MSDOS_SB(s)->fats || (MSDOS_SB(s)->dir_entries & (MSDOS_DPS-1)) ++ || !b->cluster_size || MSDOS_SB(s)->clusters+2 > MSDOS_SB(s)-> ++ fat_length*SECTOR_SIZE*8/MSDOS_SB(s)->fat_bits) { ++ s->s_dev = 0; ++ printk("Unsupported FS parameters\r\n"); ++ return NULL; ++ } ++ if (!MSDOS_CAN_BMAP(MSDOS_SB(s))) printk("No bmap support\r\n"); ++ s->s_magic = MSDOS_SUPER_MAGIC; ++ MSDOS_SB(s)->name_check = check; ++ MSDOS_SB(s)->conversion = conversion; ++ /* set up enough so that it can read an inode */ ++ s->s_op = &msdos_sops; ++ MSDOS_SB(s)->fs_uid = current->uid; ++ MSDOS_SB(s)->fs_gid = current->gid; ++ MSDOS_SB(s)->fs_umask = current->umask; ++ if (!(s->s_mounted = iget(s->s_dev,MSDOS_ROOT_INO))) { ++ s->s_dev = 0; ++ printk("get root inode failed\n"); ++ return NULL; ++ } ++ return s; ++ } ++ ++ ++ void msdos_statfs(struct super_block *sb,struct statfs *buf) ++ { ++ int cluster_size,free,this; ++ ++ cluster_size = MSDOS_SB(sb)->cluster_size; ++ put_fs_long(sb->s_magic,&buf->f_type); ++ put_fs_long(SECTOR_SIZE,&buf->f_bsize); ++ put_fs_long(MSDOS_SB(sb)->clusters*cluster_size,&buf->f_blocks); ++ free = 0; ++ for (this = 2; this < MSDOS_SB(sb)->clusters+2; this++) ++ if (!fat_access(sb,this,-1)) free++; ++ free *= cluster_size; ++ put_fs_long(free,&buf->f_bfree); ++ put_fs_long(free,&buf->f_bavail); ++ put_fs_long(0,&buf->f_files); ++ put_fs_long(0,&buf->f_ffree); ++ } ++ ++ ++ int msdos_bmap(struct inode *inode,int block) ++ { ++ struct msdos_sb_info *sb; ++ int cluster,offset; ++ ++ sb = MSDOS_SB(inode->i_sb); ++ if ((sb->cluster_size & 1) || (sb->data_start & 1)) return 0; ++ if (inode->i_ino == MSDOS_ROOT_INO) { ++ if (sb->dir_start & 1) return 0; ++ return (sb->dir_start >> 1)+block; ++ } ++ cluster = (block*2)/sb->cluster_size; ++ offset = (block*2) % sb->cluster_size; ++ if (!(cluster = get_cluster(inode,cluster))) return 0; ++ return ((cluster-2)*sb->cluster_size+sb->data_start+offset) >> 1; ++ } ++ ++ ++ void msdos_read_inode(struct inode *inode) ++ { ++ struct buffer_head *bh; ++ struct msdos_dir_entry *raw_entry; ++ int this; ++ ++ /* printk("read inode %d\r\n",inode->i_ino); */ ++ inode->i_data[D_BUSY] = inode->i_data[D_DEPEND] = ++ inode->i_data[D_OLD] = 0; ++ inode->i_data[D_BINARY] = 1; ++ inode->i_uid = MSDOS_SB(inode->i_sb)->fs_uid; ++ inode->i_gid = MSDOS_SB(inode->i_sb)->fs_gid; ++ if (inode->i_ino == MSDOS_ROOT_INO) { ++ inode->i_mode = (0777 & ~MSDOS_SB(inode->i_sb)->fs_umask) | ++ S_IFDIR; ++ inode->i_op = &msdos_dir_inode_operations; ++ inode->i_nlink = 1; ++ inode->i_size = MSDOS_SB(inode->i_sb)->dir_entries* ++ sizeof(struct msdos_dir_entry); ++ inode->i_data[D_START] = 0; ++ inode->i_data[D_ATTRS] = 0; ++ inode->i_mtime = inode->i_atime = inode->i_ctime = 0; ++ return; ++ } ++ if (!(bh = bread(inode->i_dev,inode->i_ino >> MSDOS_DPB_BITS))) ++ panic("unable to read i-node block"); ++ raw_entry = &((struct msdos_dir_entry *) (bh->b_data)) ++ [inode->i_ino & (MSDOS_DPB-1)]; ++ if (raw_entry->attr & ATTR_DIR) { ++ inode->i_mode = MSDOS_MKMODE(raw_entry->attr,0777 & ++ ~MSDOS_SB(inode->i_sb)->fs_umask) | S_IFDIR; ++ inode->i_op = &msdos_dir_inode_operations; ++ inode->i_nlink = 3; ++ inode->i_size = 0; ++ for (this = raw_entry->start; this && this != -1; this = ++ fat_access(inode->i_sb,this,-1)) ++ inode->i_size += SECTOR_SIZE*MSDOS_SB(inode->i_sb)-> ++ cluster_size; ++ } ++ else { ++ inode->i_mode = MSDOS_MKMODE(raw_entry->attr,0666 & ++ ~MSDOS_SB(inode->i_sb)->fs_umask) | S_IFREG; ++ inode->i_op = MSDOS_CAN_BMAP(MSDOS_SB(inode->i_sb)) ? ++ &msdos_file_inode_operations : ++ &msdos_file_inode_operations_no_bmap; ++ inode->i_nlink = 1; ++ inode->i_size = raw_entry->size; ++ } ++ inode->i_data[D_BINARY] = is_binary(MSDOS_SB(inode->i_sb)->conversion, ++ raw_entry->ext); ++ inode->i_data[D_START] = raw_entry->start; ++ inode->i_data[D_ATTRS] = raw_entry->attr & ATTR_UNUSED; ++ inode->i_mtime = inode->i_atime = inode->i_ctime = ++ date_dos2unix(raw_entry->time,raw_entry->date); ++ brelse(bh); ++ } ++ ++ ++ void msdos_write_inode(struct inode *inode) ++ { ++ struct buffer_head *bh; ++ struct msdos_dir_entry *raw_entry; ++ ++ inode->i_dirt = 0; ++ if (inode->i_ino == MSDOS_ROOT_INO || !inode->i_nlink) return; ++ if (!(bh = bread(inode->i_dev,inode->i_ino >> MSDOS_DPB_BITS))) ++ panic("unable to read i-node block"); ++ raw_entry = &((struct msdos_dir_entry *) (bh->b_data)) ++ [inode->i_ino & (MSDOS_DPB-1)]; ++ if (S_ISDIR(inode->i_mode)) { ++ raw_entry->attr = ATTR_DIR; ++ raw_entry->size = 0; ++ } ++ else { ++ raw_entry->attr = ATTR_NONE; ++ raw_entry->size = inode->i_size; ++ } ++ raw_entry->attr |= MSDOS_MKATTR(inode->i_mode) | inode->i_data[D_ATTRS]; ++ raw_entry->start = inode->i_data[D_START]; ++ date_unix2dos(inode->i_mtime,&raw_entry->time,&raw_entry->date); ++ bh->b_dirt = 1; ++ brelse(bh); ++ } +*** /dev/null Sat Jul 18 22:26:09 1992 +--- linux/fs/msdos/misc.c Thu Jul 16 00:38:36 1992 +*************** +*** 0 **** +--- 1,365 ---- ++ /* ++ * linux/fs/msdos/misc.c ++ * ++ * Written 1992 by Werner Almesberger ++ */ ++ ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ ++ ++ static char bin_extensions[] = ++ "EXECOMAPPSYSOVLOBJLIB" /* program code */ ++ "ARCZIPLHALZHZOOTARZ ARJ" /* common archivers */ ++ "GIFBMPTIFGL JPG" /* graphics */ ++ "TFMVF GF PK PXLDVI"; /* TeX */ ++ ++ ++ /* Select binary/text conversion */ ++ ++ int is_binary(char conversion,char *extension) ++ { ++ char *walk; ++ ++ switch (conversion) { ++ case 'b': ++ return 1; ++ case 't': ++ return 0; ++ case 'a': ++ for (walk = bin_extensions; *walk; walk += 3) ++ if (!strncmp(extension,walk,3)) return 1; ++ return 0; ++ default: ++ panic("Invalid conversion mode"); ++ } ++ } ++ ++ ++ static struct wait_queue *creation_wait = NULL; ++ static creation_lock = 0; ++ ++ ++ void lock_creation(void) ++ { ++ while (creation_lock) sleep_on(&creation_wait); ++ creation_lock = 1; ++ } ++ ++ ++ void unlock_creation(void) ++ { ++ creation_lock = 0; ++ wake_up(&creation_wait); ++ } ++ ++ ++ int msdos_add_cluster(struct inode *inode) ++ { ++ static struct wait_queue *wait = NULL; ++ static int lock = 0; ++ static int previous = 0; /* works best if one FS is being used */ ++ int count,this,limit,last,current,sector; ++ void *data; ++ struct buffer_head *bh; ++ ++ if (inode->i_ino == MSDOS_ROOT_INO) return -ENOSPC; ++ while (lock) sleep_on(&wait); ++ lock = 1; ++ limit = MSDOS_SB(inode->i_sb)->clusters; ++ this = limit; /* to keep GCC happy */ ++ for (count = 0; count < limit; count++) { ++ this = ((count+previous) % limit)+2; ++ if (fat_access(inode->i_sb,this,-1) == 0) break; ++ } ++ #ifdef DEBUG ++ printk("free cluster: %d\r\n",this); ++ #endif ++ previous = (count+previous+1) % limit; ++ if (count >= limit) { ++ lock = 0; ++ wake_up(&wait); ++ return -ENOSPC; ++ } ++ fat_access(inode->i_sb,this,MSDOS_SB(inode->i_sb)->fat_bits == 12 ? ++ 0xff8 : 0xfff8); ++ lock = 0; ++ wake_up(&wait); ++ #ifdef DEBUG ++ printk("set to %x\r\n",fat_access(inode->i_sb,this,-1)); ++ #endif ++ if (!S_ISDIR(inode->i_mode)) { ++ last = inode->i_size ? get_cluster(inode,(inode->i_size-1)/ ++ SECTOR_SIZE/MSDOS_SB(inode->i_sb)->cluster_size) : 0; ++ } ++ else { ++ last = 0; ++ if (current = inode->i_data[D_START]) { ++ cache_lookup(inode,INT_MAX,&last,¤t); ++ while (current && current != -1) ++ if (!(current = fat_access(inode->i_sb, ++ last = current,-1))) ++ panic("File without EOF"); ++ } ++ } ++ #ifdef DEBUG ++ printk("last = %d\r\n",last); ++ #endif ++ if (last) fat_access(inode->i_sb,last,this); ++ else { ++ inode->i_data[D_START] = this; ++ inode->i_dirt = 1; ++ } ++ #ifdef DEBUG ++ if (last) printk("next set to %d\r\n",fat_access(inode->i_sb,last,-1)); ++ #endif ++ for (current = 0; current < MSDOS_SB(inode->i_sb)->cluster_size; ++ current++) { ++ sector = MSDOS_SB(inode->i_sb)->data_start+(this-2)* ++ MSDOS_SB(inode->i_sb)->cluster_size+current; ++ #ifdef DEBUG ++ printk("zeroing sector %d\r\n",sector); ++ #endif ++ if (current < MSDOS_SB(inode->i_sb)->cluster_size-1 && ++ !(sector & 1)) { ++ if (!(bh = getblk(inode->i_dev,sector >> 1))) ++ printk("getblk failed\r\n"); ++ else { ++ memset(bh->b_data,0,BLOCK_SIZE); ++ bh->b_uptodate = 1; ++ } ++ current++; ++ } ++ else { ++ if (!(bh = msdos_sread(inode->i_dev,sector,&data))) ++ printk("msdos_sread failed\r\n"); ++ else memset(data,0,SECTOR_SIZE); ++ } ++ if (bh) { ++ bh->b_dirt = 1; ++ brelse(bh); ++ } ++ } ++ if (S_ISDIR(inode->i_mode)) { ++ if (inode->i_size & (SECTOR_SIZE-1)) ++ panic("Odd directory size"); ++ inode->i_size += SECTOR_SIZE*MSDOS_SB(inode->i_sb)-> ++ cluster_size; ++ #ifdef DEBUG ++ printk("size is %d now (%x)\r\n",inode->i_size,inode); ++ #endif ++ inode->i_dirt = 1; ++ } ++ return 0; ++ } ++ ++ ++ /* Linear day numbers of the respective 1sts in non-leap years. */ ++ ++ static int day_n[] = { 0,31,59,90,120,151,181,212,243,273,304,334,0,0,0,0 }; ++ /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */ ++ ++ ++ /* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */ ++ ++ int date_dos2unix(unsigned short time,unsigned short date) ++ { ++ int month,year; ++ ++ month = ((date >> 5) & 4)-1; ++ year = date >> 9; ++ return (time & 31)*2+60*((time >> 5) & 63)+(time >> 11)*3600+86400* ++ ((date & 31)-1+day_n[month]+(year/4)+year*365-((year & 3) == 0 && ++ month < 2 ? 1 : 0)+3653); ++ /* days since 1.1.70 plus 80's leap day */ ++ } ++ ++ ++ /* Convert linear UNIX date to a MS-DOS time/date pair. */ ++ ++ void date_unix2dos(int unix_date,unsigned short *time, ++ unsigned short *date) ++ { ++ int day,year,nl_day,month; ++ ++ *time = (unix_date % 60)/2+(((unix_date/60) % 60) << 5)+ ++ (((unix_date/3600) % 24) << 11); ++ day = unix_date/86400-3652; ++ year = day/365; ++ if ((year+3)/4+365*year > day) year--; ++ day -= (year+3)/4+365*year; ++ if (day == 59 && !(year & 3)) { ++ nl_day = day; ++ month = 2; ++ } ++ else { ++ nl_day = (year & 3) || day <= 59 ? day : day-1; ++ for (month = 0; month < 12; month++) ++ if (day_n[month] > nl_day) break; ++ } ++ *date = nl_day-day_n[month-1]+1+(month << 5)+(year << 9); ++ } ++ ++ ++ /* Returns the inode number of the directory entry at offset pos. If bh is ++ non-NULL, it is brelse'd before. Pos is incremented. The buffer header is ++ returned in bh. */ ++ ++ int msdos_get_entry(struct inode *dir,int *pos,struct buffer_head **bh, ++ struct msdos_dir_entry **de) ++ { ++ int sector,offset; ++ void *data; ++ ++ while (1) { ++ offset = *pos; ++ if ((sector = msdos_smap(dir,*pos >> SECTOR_BITS)) == -1) ++ return -1; ++ if (!sector) return -1; /* FAT error ... */ ++ *pos += sizeof(struct msdos_dir_entry); ++ if (*bh) brelse(*bh); ++ if (!(*bh = msdos_sread(dir->i_dev,sector,&data))) continue; ++ *de = (struct msdos_dir_entry *) (data+(offset & ++ (SECTOR_SIZE-1))); ++ return (sector << MSDOS_DPS_BITS)+((offset & (SECTOR_SIZE-1)) >> ++ MSDOS_DIR_BITS); ++ } ++ } ++ ++ ++ /* Scans a directory for a given file (name points to its formatted name) or ++ for an empty directory slot (name is NULL). Returns the inode number. */ ++ ++ int msdos_scan(struct inode *dir,char *name,struct buffer_head **res_bh, ++ struct msdos_dir_entry **res_de,int *ino) ++ { ++ int pos; ++ struct msdos_dir_entry *de; ++ struct inode *inode; ++ ++ pos = 0; ++ *res_bh = NULL; ++ while ((*ino = msdos_get_entry(dir,&pos,res_bh,&de)) > -1) { ++ if (name) { ++ if (de->name[0] && ((unsigned char *) (de->name))[0] ++ != DELETED_FLAG && !(de->attr & ATTR_VOLUME) && ++ !strncmp(de->name,name,MSDOS_NAME)) break; ++ } ++ else if (!de->name[0] || ((unsigned char *) (de->name))[0] == ++ DELETED_FLAG) { ++ if (!(inode = iget(dir->i_dev,*ino))) break; ++ if (!inode->i_data[D_BUSY]) { ++ iput(inode); ++ break; ++ } ++ /* skip deleted files that haven't been closed yet */ ++ iput(inode); ++ } ++ } ++ if (*ino == -1) { ++ if (*res_bh) brelse(*res_bh); ++ *res_bh = NULL; ++ return name ? -ENOENT : -ENOSPC; ++ } ++ *res_de = de; ++ return 0; ++ } ++ ++ ++ /* Now an ugly part: this set of directory scan routines works on clusters ++ rather than on inodes and sectors. They are necessary to locate the '..' ++ directory "inode". */ ++ ++ ++ static int raw_found(struct super_block *sb,int sector,char *name,int number, ++ int *ino) ++ { ++ struct buffer_head *bh; ++ struct msdos_dir_entry *data; ++ int entry,start; ++ ++ if (!(bh = msdos_sread(sb->s_dev,sector,(void **) &data))) return -EIO; ++ for (entry = 0; entry < MSDOS_DPS; entry++) ++ if (name ? !strncmp(data[entry].name,name,MSDOS_NAME) : ++ *(unsigned char *) data[entry].name != DELETED_FLAG && ++ data[entry].start == number) { ++ if (ino) *ino = sector*MSDOS_DPS+entry; ++ start = data[entry].start; ++ brelse(bh); ++ return start; ++ } ++ brelse(bh); ++ return -1; ++ } ++ ++ ++ static int raw_scan_root(struct super_block *sb,char *name,int number,int *ino) ++ { ++ int count,cluster; ++ ++ for (count = 0; count < MSDOS_SB(sb)->dir_entries/MSDOS_DPS; count++) { ++ if ((cluster = raw_found(sb,MSDOS_SB(sb)->dir_start+count,name, ++ number,ino)) >= 0) return cluster; ++ } ++ return -ENOENT; ++ } ++ ++ ++ static int raw_scan_nonroot(struct super_block *sb,int start,char *name, ++ int number,int *ino) ++ { ++ int count,cluster; ++ ++ do { ++ for (count = 0; count < MSDOS_SB(sb)->cluster_size; count++) { ++ if ((cluster = raw_found(sb,(start-2)*MSDOS_SB(sb)-> ++ cluster_size+MSDOS_SB(sb)->data_start+count,name, ++ number,ino)) >= 0) return cluster; ++ } ++ if (!(start = fat_access(sb,start,-1))) panic("FAT error"); ++ } ++ while (start != -1); ++ return -ENOENT; ++ } ++ ++ ++ static int raw_scan(struct super_block *sb,int start,char *name,int number, ++ int *ino) ++ { ++ if (start) return raw_scan_nonroot(sb,start,name,number,ino); ++ else return raw_scan_root(sb,name,number,ino); ++ } ++ ++ ++ int msdos_parent_ino(struct inode *dir,int locked) ++ { ++ int error,current,prev,this; ++ ++ if (!S_ISDIR(dir->i_mode)) panic("Non-directory fed to m_p_i"); ++ if (dir->i_ino == MSDOS_ROOT_INO) return dir->i_ino; ++ if (!locked) lock_creation(); /* prevent renames */ ++ if ((current = raw_scan(dir->i_sb,dir->i_data[D_START],MSDOS_DOTDOT,0, ++ NULL)) < 0) { ++ if (!locked) unlock_creation(); ++ return current; ++ } ++ if (!current) this = MSDOS_ROOT_INO; ++ else { ++ if ((prev = raw_scan(dir->i_sb,current,MSDOS_DOTDOT,0,NULL)) < ++ 0) { ++ if (!locked) unlock_creation(); ++ return prev; ++ } ++ if ((error = raw_scan(dir->i_sb,prev,NULL,current,&this)) < 0) { ++ if (!locked) unlock_creation(); ++ return error; ++ } ++ } ++ if (!locked) unlock_creation(); ++ return this; ++ } +*** /dev/null Sat Jul 18 22:26:09 1992 +--- linux/fs/msdos/namei.c Thu Jul 16 00:35:11 1992 +*************** +*** 0 **** +--- 1,512 ---- ++ /* ++ * linux/fs/msdos/namei.c ++ * ++ * Written 1992 by Werner Almesberger ++ */ ++ ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ ++ ++ /* MS-DOS "device special files" */ ++ ++ static char *reserved_names[] = { ++ "CON ","PRN ","NUL ","AUX ", ++ "LPT1 ","LPT2 ","LPT3 ","LPT4 ", ++ "COM1 ","COM2 ","COM3 ","COM4 ", ++ NULL }; ++ ++ ++ /* Formats an MS-DOS file name. Rejects invalid names. */ ++ ++ static int msdos_format_name(char conv,const char *name,int len,char *res) ++ { ++ char *walk,**reserved; ++ char c; ++ int space; ++ ++ if (get_fs_byte(name) == DELETED_FLAG) return -EINVAL; ++ if (get_fs_byte(name) == '.' && (len == 1 || (len == 2 && ++ get_fs_byte(name+1) == '.'))) { ++ memset(res+1,' ',10); ++ while (len--) *res++ = '.'; ++ return 0; ++ } ++ space = 0; /* to make GCC happy */ ++ c = 0; ++ for (walk = res; len && walk-res < 8; walk++) { ++ c = get_fs_byte(name++); ++ len--; ++ if (c == ' ' && conv != 'r') return -EINVAL; ++ if (c >= 'A' && c <= 'Z') { ++ if (conv != 'r') return -EINVAL; ++ c += 32; ++ } ++ if (c < ' ' || c == ':' || c == '\\') return -EINVAL; ++ if (c == '.') break; ++ space = c == ' '; ++ *walk = c >= 'a' && c <= 'z' ? c-32 : c; ++ } ++ if (space) return -EINVAL; ++ if (conv == 's' && len && c != '.') { ++ c = get_fs_byte(name++); ++ len--; ++ if (c != '.') return -EINVAL; ++ } ++ while (c != '.' && len--) c = get_fs_byte(name++); ++ if (walk == res) return -EINVAL; ++ if (c == '.') { ++ while (walk-res < 8) *walk++ = ' '; ++ while (len > 0 && walk-res < MSDOS_NAME) { ++ c = get_fs_byte(name++); ++ len--; ++ if (c == ' ' && conv != 'r') return -EINVAL; ++ if (c < ' ' || c == ':' || c == '\\' || c == '.') ++ return -EINVAL; ++ if (c >= 'A' && c <= 'Z') { ++ if (conv != 'r') return -EINVAL; ++ c += 32; ++ } ++ space = c == ' '; ++ *walk++ = c >= 'a' && c <= 'z' ? c-32 : c; ++ } ++ if (space) return -EINVAL; ++ if (conv == 's' && len) return -EINVAL; ++ } ++ while (walk-res < MSDOS_NAME) *walk++ = ' '; ++ for (reserved = reserved_names; *reserved; reserved++) ++ if (!strncmp(res,*reserved,8)) return -EINVAL; ++ return 0; ++ } ++ ++ ++ /* Locates a directory entry. */ ++ ++ static int msdos_find(struct inode *dir,const char *name,int len, ++ struct buffer_head **bh,struct msdos_dir_entry **de,int *ino) ++ { ++ char msdos_name[MSDOS_NAME]; ++ int res; ++ ++ if ((res = msdos_format_name(MSDOS_SB(dir->i_sb)->name_check,name,len, ++ msdos_name)) < 0) return res; ++ return msdos_scan(dir,msdos_name,bh,de,ino); ++ } ++ ++ ++ int msdos_lookup(struct inode *dir,const char *name,int len, ++ struct inode **result) ++ { ++ int ino,res; ++ struct msdos_dir_entry *de; ++ struct buffer_head *bh; ++ struct inode *next; ++ ++ *result = NULL; ++ if (!dir) return -ENOENT; ++ if (!S_ISDIR(dir->i_mode)) { ++ iput(dir); ++ return -ENOENT; ++ } ++ if (len == 1 && get_fs_byte(name) == '.') { ++ *result = dir; ++ return 0; ++ } ++ if (len == 2 && get_fs_byte(name) == '.' && get_fs_byte(name+1) == '.') ++ { ++ ino = msdos_parent_ino(dir,0); ++ iput(dir); ++ if (ino < 0) return ino; ++ if (!(*result = iget(dir->i_dev,ino))) return -EACCES; ++ return 0; ++ } ++ if ((res = msdos_find(dir,name,len,&bh,&de,&ino)) < 0) { ++ iput(dir); ++ return res; ++ } ++ if (bh) brelse(bh); ++ /* printk("lookup: ino=%d\r\n",ino); */ ++ if (!(*result = iget(dir->i_dev,ino))) { ++ iput(dir); ++ return -EACCES; ++ } ++ if ((*result)->i_data[D_BUSY]) { /* mkdir in progress */ ++ iput(*result); ++ iput(dir); ++ return -ENOENT; ++ } ++ while ((*result)->i_data[D_OLD]) { ++ next = (struct inode *) ((*result)->i_data[D_OLD]); ++ iput(*result); ++ if (!(*result = iget(next->i_dev,next->i_ino))) ++ panic("msdos_lookup: Can't happen"); ++ } ++ iput(dir); ++ return 0; ++ } ++ ++ ++ /* Creates a directory entry (name is already formatted). */ ++ ++ static int msdos_create_entry(struct inode *dir,char *name,int is_dir, ++ struct inode **result) ++ { ++ struct buffer_head *bh; ++ struct msdos_dir_entry *de; ++ int res,ino; ++ ++ if ((res = msdos_scan(dir,NULL,&bh,&de,&ino)) < 0) { ++ if (dir->i_ino == MSDOS_ROOT_INO) return -ENOSPC; ++ if ((res = msdos_add_cluster(dir)) < 0) return res; ++ if ((res = msdos_scan(dir,NULL,&bh,&de,&ino)) < 0) return res; ++ } ++ memcpy(de->name,name,MSDOS_NAME); ++ de->attr = is_dir ? ATTR_DIR : ATTR_ARCH; ++ de->start = 0; ++ date_unix2dos(CURRENT_TIME,&de->time,&de->date); ++ de->size = 0; ++ bh->b_dirt = 1; ++ if (*result = iget(dir->i_dev,ino)) msdos_read_inode(*result); ++ brelse(bh); ++ if (!*result) return -EIO; ++ (*result)->i_mtime = (*result)->i_atime = (*result)->i_ctime = ++ CURRENT_TIME; ++ (*result)->i_dirt = 1; ++ return 0; ++ } ++ ++ ++ int msdos_create(struct inode *dir,const char *name,int len,int mode, ++ struct inode **result) ++ { ++ struct buffer_head *bh; ++ struct msdos_dir_entry *de; ++ char msdos_name[MSDOS_NAME]; ++ int ino,res; ++ ++ if (!dir) return -ENOENT; ++ if ((res = msdos_format_name(MSDOS_SB(dir->i_sb)->name_check,name,len, ++ msdos_name)) < 0) { ++ iput(dir); ++ return res; ++ } ++ lock_creation(); ++ if (msdos_scan(dir,msdos_name,&bh,&de,&ino) >= 0) { ++ unlock_creation(); ++ brelse(bh); ++ iput(dir); ++ return -EEXIST; ++ } ++ res = msdos_create_entry(dir,msdos_name,S_ISDIR(mode),result); ++ unlock_creation(); ++ iput(dir); ++ return res; ++ } ++ ++ ++ int msdos_mkdir(struct inode *dir,const char *name,int len,int mode) ++ { ++ struct buffer_head *bh; ++ struct msdos_dir_entry *de; ++ struct inode *inode,*dot; ++ char msdos_name[MSDOS_NAME]; ++ int ino,res; ++ ++ if ((res = msdos_format_name(MSDOS_SB(dir->i_sb)->name_check,name,len, ++ msdos_name)) < 0) { ++ iput(dir); ++ return res; ++ } ++ lock_creation(); ++ if (msdos_scan(dir,msdos_name,&bh,&de,&ino) >= 0) { ++ unlock_creation(); ++ brelse(bh); ++ iput(dir); ++ return -EEXIST; ++ } ++ if ((res = msdos_create_entry(dir,msdos_name,1,&inode)) < 0) { ++ unlock_creation(); ++ iput(dir); ++ return res; ++ } ++ inode->i_data[D_BUSY] = 1; /* prevent lookups */ ++ if ((res = msdos_add_cluster(inode)) < 0) goto mkdir_error; ++ if ((res = msdos_create_entry(inode,MSDOS_DOT,1,&dot)) < 0) ++ goto mkdir_error; ++ dot->i_size = inode->i_size; ++ dot->i_data[D_START] = inode->i_data[D_START]; ++ dot->i_dirt = 1; ++ iput(dot); ++ if ((res = msdos_create_entry(inode,MSDOS_DOTDOT,1,&dot)) < 0) ++ goto mkdir_error; ++ unlock_creation(); ++ dot->i_size = dir->i_size; ++ dot->i_data[D_START] = dir->i_data[D_START]; ++ dot->i_dirt = 1; ++ inode->i_data[D_BUSY] = 0; ++ iput(dot); ++ iput(inode); ++ iput(dir); ++ return 0; ++ mkdir_error: ++ iput(inode); ++ if (msdos_rmdir(dir,name,len) < 0) panic("rmdir in mkdir failed"); ++ unlock_creation(); ++ return res; ++ } ++ ++ ++ int msdos_rmdir(struct inode *dir,const char *name,int len) ++ { ++ int res,ino,pos; ++ struct buffer_head *bh,*dbh; ++ struct msdos_dir_entry *de,*dde; ++ struct inode *inode; ++ ++ bh = NULL; ++ inode = NULL; ++ res = -EINVAL; ++ if (len == 1 && get_fs_byte(name) == '.') goto rmdir_done; ++ if ((res = msdos_find(dir,name,len,&bh,&de,&ino)) < 0) goto rmdir_done; ++ res = -ENOENT; ++ if (!(inode = iget(dir->i_dev,ino))) goto rmdir_done; ++ res = -ENOTDIR; ++ if (!S_ISDIR(inode->i_mode)) goto rmdir_done; ++ res = -EBUSY; ++ if (dir->i_dev != inode->i_dev || dir == inode) goto rmdir_done; ++ if (inode->i_count > 1) goto rmdir_done; ++ res = -ENOTEMPTY; ++ pos = 0; ++ dbh = NULL; ++ while (msdos_get_entry(inode,&pos,&dbh,&dde) > -1) ++ if (dde->name[0] && ((unsigned char *) dde->name)[0] != ++ DELETED_FLAG && strncmp(dde->name,MSDOS_DOT,MSDOS_NAME) && ++ strncmp(dde->name,MSDOS_DOTDOT,MSDOS_NAME)) goto rmdir_done; ++ if (dbh) brelse(dbh); ++ inode->i_nlink = 0; ++ dir->i_mtime = CURRENT_TIME; ++ inode->i_dirt = dir->i_dirt = 1; ++ de->name[0] = DELETED_FLAG; ++ bh->b_dirt = 1; ++ res = 0; ++ rmdir_done: ++ brelse(bh); ++ iput(dir); ++ iput(inode); ++ return res; ++ } ++ ++ ++ int msdos_unlink(struct inode *dir,const char *name,int len) ++ { ++ int res,ino; ++ struct buffer_head *bh; ++ struct msdos_dir_entry *de; ++ struct inode *inode; ++ ++ bh = NULL; ++ inode = NULL; ++ if ((res = msdos_find(dir,name,len,&bh,&de,&ino)) < 0) ++ goto unlink_done; ++ if (!(inode = iget(dir->i_dev,ino))) { ++ res = -ENOENT; ++ goto unlink_done; ++ } ++ if (!S_ISREG(inode->i_mode)) { ++ res = -EPERM; ++ goto unlink_done; ++ } ++ inode->i_nlink = 0; ++ inode->i_data[D_BUSY] = 1; ++ inode->i_dirt = 1; ++ de->name[0] = DELETED_FLAG; ++ bh->b_dirt = 1; ++ unlink_done: ++ brelse(bh); ++ iput(inode); ++ iput(dir); ++ return res; ++ } ++ ++ ++ static int rename_same_dir(struct inode *old_dir,char *old_name, ++ struct inode *new_dir,char *new_name,struct buffer_head *old_bh, ++ struct msdos_dir_entry *old_de,int old_ino) ++ { ++ struct buffer_head *new_bh; ++ struct msdos_dir_entry *new_de; ++ struct inode *new_inode,*old_inode; ++ int new_ino; ++ int exists; ++ ++ if (!strncmp(old_name,new_name,MSDOS_NAME)) return 0; ++ exists = msdos_scan(new_dir,new_name,&new_bh,&new_de,&new_ino) >= 0; ++ if (*(unsigned char *) old_de->name == DELETED_FLAG) { ++ if (exists) brelse(new_bh); ++ return -ENOENT; ++ } ++ if (exists) { ++ if (!(new_inode = iget(new_dir->i_dev,new_ino))) { ++ brelse(new_bh); ++ return -EIO; ++ } ++ if (S_ISDIR(new_inode->i_mode)) { ++ iput(new_inode); ++ brelse(new_bh); ++ return -EPERM; ++ } ++ new_inode->i_nlink = 0; ++ new_inode->i_data[D_BUSY] = 1; ++ new_inode->i_dirt = 1; ++ new_de->name[0] = DELETED_FLAG; ++ new_bh->b_dirt = 1; ++ iput(new_inode); ++ brelse(new_bh); ++ } ++ memcpy(old_de->name,new_name,MSDOS_NAME); ++ old_bh->b_dirt = 1; ++ if (MSDOS_SB(old_dir->i_sb)->conversion == 'a') /* update binary info */ ++ if (old_inode = iget(old_dir->i_dev,old_ino)) { ++ msdos_read_inode(old_inode); ++ iput(old_inode); ++ } ++ return 0; ++ } ++ ++ ++ static int rename_diff_dir(struct inode *old_dir,char *old_name, ++ struct inode *new_dir,char *new_name,struct buffer_head *old_bh, ++ struct msdos_dir_entry *old_de,int old_ino) ++ { ++ struct buffer_head *new_bh,*free_bh,*dotdot_bh; ++ struct msdos_dir_entry *new_de,*free_de,*dotdot_de; ++ struct inode *old_inode,*new_inode,*free_inode,*dotdot_inode,*walk; ++ int new_ino,free_ino,dotdot_ino; ++ int error,exists,ino; ++ ++ if (old_dir->i_dev != new_dir->i_dev) return -EINVAL; ++ if (old_ino == new_dir->i_ino) return -EINVAL; ++ if (!(walk = iget(new_dir->i_dev,new_dir->i_ino))) return -EIO; ++ while (walk->i_ino != MSDOS_ROOT_INO) { ++ ino = msdos_parent_ino(walk,1); ++ iput(walk); ++ if (ino < 0) return ino; ++ if (ino == old_ino) return -EINVAL; ++ if (!(walk = iget(new_dir->i_dev,ino))) return -EIO; ++ } ++ iput(walk); ++ if ((error = msdos_scan(new_dir,NULL,&free_bh,&free_de,&free_ino)) < 0) ++ return error; ++ exists = msdos_scan(new_dir,new_name,&new_bh,&new_de,&new_ino) ++ >= 0; ++ if (!(old_inode = iget(old_dir->i_dev,old_ino))) { ++ brelse(free_bh); ++ if (exists) brelse(new_bh); ++ return -EIO; ++ } ++ if (*(unsigned char *) old_de->name == DELETED_FLAG) { ++ iput(old_inode); ++ brelse(free_bh); ++ if (exists) brelse(new_bh); ++ return -ENOENT; ++ } ++ new_inode = NULL; /* to make GCC happy */ ++ if (exists) { ++ if (!(new_inode = iget(new_dir->i_dev,new_ino))) { ++ iput(old_inode); ++ brelse(new_bh); ++ return -EIO; ++ } ++ if (S_ISDIR(new_inode->i_mode)) { ++ iput(new_inode); ++ iput(old_inode); ++ brelse(new_bh); ++ return -EPERM; ++ } ++ new_inode->i_nlink = 0; ++ new_inode->i_data[D_BUSY] = 1; ++ new_inode->i_dirt = 1; ++ new_de->name[0] = DELETED_FLAG; ++ new_bh->b_dirt = 1; ++ } ++ memcpy(free_de,old_de,sizeof(struct msdos_dir_entry)); ++ memcpy(free_de->name,new_name,MSDOS_NAME); ++ if (!(free_inode = iget(new_dir->i_dev,free_ino))) { ++ free_de->name[0] = DELETED_FLAG; ++ /* Don't mark free_bh as dirty. Both states are supposed to be equivalent. */ ++ brelse(free_bh); ++ if (exists) { ++ iput(new_inode); ++ brelse(new_bh); ++ } ++ return -EIO; ++ } ++ msdos_read_inode(free_inode); ++ old_inode->i_data[D_BUSY] = 1; ++ old_inode->i_dirt = 1; ++ old_de->name[0] = DELETED_FLAG; ++ old_bh->b_dirt = 1; ++ free_bh->b_dirt = 1; ++ if (!exists) iput(free_inode); ++ else { ++ new_inode->i_data[D_DEPEND] = (int) free_inode; ++ free_inode->i_data[D_OLD] = (int) new_inode; ++ /* free_inode is put when putting new_inode */ ++ iput(new_inode); ++ brelse(new_bh); ++ } ++ if (S_ISDIR(old_inode->i_mode)) { ++ if ((error = msdos_scan(old_inode,MSDOS_DOTDOT,&dotdot_bh, ++ &dotdot_de,&dotdot_ino)) < 0) goto rename_done; ++ if (!(dotdot_inode = iget(old_inode->i_dev,dotdot_ino))) { ++ brelse(dotdot_bh); ++ error = -EIO; ++ goto rename_done; ++ } ++ dotdot_de->start = dotdot_inode->i_data[D_START] = ++ new_dir->i_data[D_START]; ++ dotdot_inode->i_dirt = 1; ++ dotdot_bh->b_dirt = 1; ++ iput(dotdot_inode); ++ brelse(dotdot_bh); ++ } ++ error = 0; ++ rename_done: ++ brelse(free_bh); ++ iput(old_inode); ++ return error; ++ } ++ ++ ++ int msdos_rename(struct inode *old_dir,const char *old_name,int old_len, ++ struct inode *new_dir,const char *new_name,int new_len) ++ { ++ char old_msdos_name[MSDOS_NAME],new_msdos_name[MSDOS_NAME]; ++ struct buffer_head *old_bh; ++ struct msdos_dir_entry *old_de; ++ int old_ino,error; ++ ++ if ((error = msdos_format_name(MSDOS_SB(old_dir->i_sb)->name_check, ++ old_name,old_len,old_msdos_name)) < 0) goto rename_done; ++ if ((error = msdos_format_name(MSDOS_SB(new_dir->i_sb)->name_check, ++ new_name,new_len,new_msdos_name)) < 0) goto rename_done; ++ if ((error = msdos_scan(old_dir,old_msdos_name,&old_bh,&old_de, ++ &old_ino)) < 0) goto rename_done; ++ lock_creation(); ++ if (old_dir == new_dir) ++ error = rename_same_dir(old_dir,old_msdos_name,new_dir, ++ new_msdos_name,old_bh,old_de,old_ino); ++ else error = rename_diff_dir(old_dir,old_msdos_name,new_dir, ++ new_msdos_name,old_bh,old_de,old_ino); ++ unlock_creation(); ++ brelse(old_bh); ++ rename_done: ++ iput(old_dir); ++ iput(new_dir); ++ return error; ++ } +*** /dev/null Sat Jul 18 22:26:09 1992 +--- linux/fs/msdos/fat.c Thu Jul 16 00:35:11 1992 +*************** +*** 0 **** +--- 1,277 ---- ++ /* ++ * linux/fs/msdos/fat.c ++ * ++ * Written 1992 by Werner Almesberger ++ */ ++ ++ #include ++ #include ++ #include ++ #include ++ ++ ++ static struct fat_cache *fat_cache,cache[FAT_CACHE]; ++ ++ ++ /* Returns the this'th FAT entry, -1 if it is an end-of-file entry. If ++ new_value is != -1, that FAT entry is replaced by it. */ ++ ++ int fat_access(struct super_block *sb,int this,int new_value) ++ { ++ struct buffer_head *bh,*bh2,*c_bh,*c_bh2; ++ unsigned char *p_first,*p_last; ++ void *data,*data2,*c_data,*c_data2; ++ int first,last,next,copy; ++ ++ if (MSDOS_SB(sb)->fat_bits == 16) first = last = this*2; ++ else { ++ first = this*3/2; ++ last = first+1; ++ } ++ if (!(bh = msdos_sread(sb->s_dev,MSDOS_SB(sb)->fat_start+(first >> ++ SECTOR_BITS),&data))) { ++ printk("bread in fat_access failed\r\n"); ++ return 0; ++ } ++ if ((first >> SECTOR_BITS) == (last >> SECTOR_BITS)) { ++ bh2 = bh; ++ data2 = data; ++ } ++ else { ++ if (!(bh2 = msdos_sread(sb->s_dev,MSDOS_SB(sb)->fat_start+(last ++ >> SECTOR_BITS),&data2))) { ++ brelse(bh); ++ printk("bread in fat_access failed\r\n"); ++ return 0; ++ } ++ } ++ if (MSDOS_SB(sb)->fat_bits == 16) { ++ next = ((unsigned short *) data)[(first & (SECTOR_SIZE-1)) ++ >> 1]; ++ if (next >= 0xfff8) next = -1; ++ } ++ else { ++ p_first = &((unsigned char *) data)[first & (SECTOR_SIZE-1)]; ++ p_last = &((unsigned char *) data2)[(first+1) & ++ (SECTOR_SIZE-1)]; ++ if (this & 1) next = ((*p_first >> 4) | (*p_last << 4)) & 0xfff; ++ else next = (*p_first+(*p_last << 8)) & 0xfff; ++ if (next >= 0xff8) next = -1; ++ } ++ if (new_value != -1) { ++ if (MSDOS_SB(sb)->fat_bits == 16) ++ ((unsigned short *) data)[(first & (SECTOR_SIZE-1)) >> ++ 1] = new_value; ++ else { ++ if (this & 1) { ++ *p_first = (*p_first & 0xf) | (new_value << 4); ++ *p_last = new_value >> 4; ++ } ++ else { ++ *p_first = new_value & 0xff; ++ *p_last = (*p_last & 0xf0) | (new_value >> 8); ++ } ++ bh2->b_dirt = 1; ++ } ++ bh->b_dirt = 1; ++ for (copy = 1; copy < MSDOS_SB(sb)->fats; copy++) { ++ if (!(c_bh = msdos_sread(sb->s_dev,MSDOS_SB(sb)-> ++ fat_start+(first >> SECTOR_BITS)+MSDOS_SB(sb)-> ++ fat_length*copy,&c_data))) break; ++ memcpy(c_data,data,SECTOR_SIZE); ++ c_bh->b_dirt = 1; ++ if (data != data2 || bh != bh2) { ++ if (!(c_bh2 = msdos_sread(sb->s_dev, ++ MSDOS_SB(sb)->fat_start+(first >> ++ SECTOR_BITS)+MSDOS_SB(sb)->fat_length*copy ++ +1,&c_data2))) { ++ brelse(c_bh); ++ break; ++ } ++ memcpy(c_data2,data2,SECTOR_SIZE); ++ brelse(c_bh2); ++ } ++ brelse(c_bh); ++ } ++ } ++ brelse(bh); ++ if (data != data2) brelse(bh2); ++ return next; ++ } ++ ++ ++ void cache_init(void) ++ { ++ static int initialized = 0; ++ int count; ++ ++ if (initialized) return; ++ fat_cache = &cache[0]; ++ for (count = 0; count < FAT_CACHE; count++) { ++ cache[count].device = 0; ++ cache[count].next = count == FAT_CACHE-1 ? NULL : ++ &cache[count+1]; ++ } ++ initialized = 1; ++ } ++ ++ ++ void cache_lookup(struct inode *inode,int cluster,int *f_clu,int *d_clu) ++ { ++ struct fat_cache *walk; ++ ++ #ifdef DEBUG ++ printk("cache lookup: %d\r\n",*f_clu); ++ #endif ++ for (walk = fat_cache; walk; walk = walk->next) ++ if (inode->i_dev == walk->device && walk->ino == inode->i_ino && ++ walk->file_cluster <= cluster && walk->file_cluster > ++ *f_clu) { ++ *d_clu = walk->disk_cluster; ++ #ifdef DEBUG ++ printk("cache hit: %d (%d)\r\n",walk->file_cluster,*d_clu); ++ #endif ++ if ((*f_clu = walk->file_cluster) == cluster) return; ++ } ++ } ++ ++ ++ #ifdef DEBUG ++ static void list_cache(void) ++ { ++ struct fat_cache *walk; ++ ++ for (walk = fat_cache; walk; walk = walk->next) { ++ if (walk->device) printk("(%d,%d) ",walk->file_cluster, ++ walk->disk_cluster); ++ else printk("-- "); ++ } ++ printk("\r\n"); ++ } ++ #endif ++ ++ ++ void cache_add(struct inode *inode,int f_clu,int d_clu) ++ { ++ struct fat_cache *walk,*last; ++ ++ #ifdef DEBUG ++ printk("cache add: %d (%d)\r\n",f_clu,d_clu); ++ #endif ++ last = NULL; ++ for (walk = fat_cache; walk->next; walk = (last = walk)->next) ++ if (inode->i_dev == walk->device && walk->ino == inode->i_ino && ++ walk->file_cluster == f_clu) { ++ if (walk->disk_cluster != d_clu) ++ panic("FAT cache corruption"); ++ /* update LRU */ ++ if (last == NULL) return; ++ last->next = walk->next; ++ walk->next = fat_cache; ++ fat_cache = walk; ++ #ifdef DEBUG ++ list_cache(); ++ #endif ++ return; ++ } ++ walk->device = inode->i_dev; ++ walk->ino = inode->i_ino; ++ walk->file_cluster = f_clu; ++ walk->disk_cluster = d_clu; ++ last->next = NULL; ++ walk->next = fat_cache; ++ fat_cache = walk; ++ #ifdef DEBUG ++ list_cache(); ++ #endif ++ } ++ ++ ++ /* Cache invalidation occurs rarely, thus the LRU chain is not updated. It ++ fixes itself after a while. */ ++ ++ void cache_inval_inode(struct inode *inode) ++ { ++ struct fat_cache *walk; ++ ++ for (walk = fat_cache; walk; walk = walk->next) ++ if (walk->device == inode->i_dev && walk->ino == inode->i_ino) ++ walk->device = 0; ++ } ++ ++ ++ void cache_inval_dev(int device) ++ { ++ struct fat_cache *walk; ++ ++ for (walk = fat_cache; walk; walk = walk->next) ++ if (walk->device == device) walk->device = 0; ++ } ++ ++ ++ int get_cluster(struct inode *inode,int cluster) ++ { ++ int this,count; ++ ++ if (!(this = inode->i_data[D_START])) return 0; ++ if (!cluster) return this; ++ count = 0; ++ for (cache_lookup(inode,cluster,&count,&this); count < cluster; ++ count++) { ++ if ((this = fat_access(inode->i_sb,this,-1)) == -1) return 0; ++ if (!this) return 0; ++ } ++ cache_add(inode,cluster,this); ++ return this; ++ } ++ ++ ++ int msdos_smap(struct inode *inode,int sector) ++ { ++ struct msdos_sb_info *sb; ++ int cluster,offset; ++ ++ sb = MSDOS_SB(inode->i_sb); ++ if (inode->i_ino == MSDOS_ROOT_INO || (S_ISDIR(inode->i_mode) && ++ !inode->i_data[D_START])) { ++ if (sector >= sb->dir_entries >> MSDOS_DPS_BITS) return 0; ++ return sector+sb->dir_start; ++ } ++ cluster = sector/sb->cluster_size; ++ offset = sector % sb->cluster_size; ++ if (!(cluster = get_cluster(inode,cluster))) return 0; ++ return (cluster-2)*sb->cluster_size+sb->data_start+offset; ++ } ++ ++ ++ /* Free all clusters after the skip'th cluster. Doesn't use the cache, ++ because this way we get an additional sanity check. */ ++ ++ int fat_free(struct inode *inode,int skip) ++ { ++ int this,last; ++ ++ if (!(this = inode->i_data[D_START])) return 0; ++ last = 0; ++ while (skip--) { ++ last = this; ++ if ((this = fat_access(inode->i_sb,this,-1)) == -1) ++ return 0; ++ if (!this) { ++ printk("fat_free: skipped EOF\r\n"); ++ return -EIO; ++ } ++ } ++ if (last) ++ fat_access(inode->i_sb,last,MSDOS_SB(inode->i_sb)->fat_bits == ++ 12 ? 0xff8 : 0xfff8); ++ else { ++ inode->i_data[D_START] = 0; ++ inode->i_dirt = 1; ++ } ++ while (this != -1) ++ if (!(this = fat_access(inode->i_sb,this,0))) ++ panic("fat_free: deleting beyond EOF"); ++ cache_inval_inode(inode); ++ return 0; ++ } +*** 0.96c.pl1/linux/fs/minix/namei.c Sat Jul 18 22:28:14 1992 +--- linux/fs/minix/namei.c Wed Jul 15 16:11:22 1992 +*************** +*** 751,757 **** + int minix_rename(struct inode * old_dir, const char * old_name, int old_len, + struct inode * new_dir, const char * new_name, int new_len) + { +! static struct task_struct * wait = NULL; + static int lock = 0; + int result; + +--- 751,757 ---- + int minix_rename(struct inode * old_dir, const char * old_name, int old_len, + struct inode * new_dir, const char * new_name, int new_len) + { +! static struct wait_queue * wait = NULL; + static int lock = 0; + int result; + +*** 0.96c.pl1/linux/kernel/sched.c Sat Jul 18 22:28:23 1992 +--- linux/kernel/sched.c Wed Jul 15 16:28:36 1992 +*************** +*** 35,41 **** + { + int i,j = 4096-sizeof(struct task_struct); + +! printk("%d: pid=%d, state=%d, father=%d, child=%d, ",nr,p->pid, + p->state, p->p_pptr->pid, p->p_cptr ? p->p_cptr->pid : -1); + i=0; + while (ipid, + p->state, p->p_pptr->pid, p->p_cptr ? p->p_cptr->pid : -1); + i=0; + while (itimeout && (*p)->timeout < jiffies) + if ((*p)->state == TASK_INTERRUPTIBLE) { + (*p)->timeout = 0; +! (*p)->state = TASK_RUNNING; + } + if (((*p)->signal & ~(*p)->blocked) && +! (*p)->state==TASK_INTERRUPTIBLE) +! (*p)->state=TASK_RUNNING; + } + + /* this is the scheduler proper: */ +--- 136,146 ---- + if ((*p)->timeout && (*p)->timeout < jiffies) + if ((*p)->state == TASK_INTERRUPTIBLE) { + (*p)->timeout = 0; +! wake_one_task(*p); + } + if (((*p)->signal & ~(*p)->blocked) && +! (*p)->state==TASK_INTERRUPTIBLE) +! wake_one_task(*p); + } + + /* this is the scheduler proper: */ +*************** +*** 181,239 **** + return -EINTR; + } + + /* + * wake_up doesn't wake up stopped processes - they have to be awakened + * with signals or similar. + */ +! void wake_up(struct task_struct **p) + { +! struct task_struct * wakeup_ptr, * tmp; + +! if (p && *p) { +! wakeup_ptr = *p; +! *p = NULL; +! while (wakeup_ptr && wakeup_ptr != task[0]) { +! if (wakeup_ptr->state == TASK_ZOMBIE) + printk("wake_up: TASK_ZOMBIE\n"); +! else if (wakeup_ptr->state != TASK_STOPPED) { +! wakeup_ptr->state = TASK_RUNNING; +! if (wakeup_ptr->counter > current->counter) + need_resched = 1; + } +- tmp = wakeup_ptr->next_wait; +- wakeup_ptr->next_wait = task[0]; +- wakeup_ptr = tmp; + } +! } + } + +! static inline void __sleep_on(struct task_struct **p, int state) + { +! unsigned int flags; + + if (!p) + return; + if (current == task[0]) + panic("task[0] trying to sleep"); +! __asm__("pushfl ; popl %0":"=r" (flags)); +! current->next_wait = *p; +! task[0]->next_wait = NULL; +! *p = current; + current->state = state; + sti(); + schedule(); +! if (current->next_wait != task[0]) +! wake_up(p); +! current->next_wait = NULL; + __asm__("pushl %0 ; popfl"::"r" (flags)); + } + +! void interruptible_sleep_on(struct task_struct **p) + { + __sleep_on(p,TASK_INTERRUPTIBLE); + } + +! void sleep_on(struct task_struct **p) + { + __sleep_on(p,TASK_UNINTERRUPTIBLE); + } +--- 181,248 ---- + return -EINTR; + } + ++ void wake_one_task(struct task_struct * p) ++ { ++ p->state = TASK_RUNNING; ++ if (p->counter > current->counter) ++ need_resched = 1; ++ } ++ + /* + * wake_up doesn't wake up stopped processes - they have to be awakened + * with signals or similar. + */ +! void wake_up(struct wait_queue **q) + { +! struct wait_queue *tmp, *next; +! struct task_struct * p; +! unsigned long flags; + +! if (!q || !(next = *q)) +! return; +! __asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags)); +! do { +! tmp = next; +! next = tmp->next; +! if (p = tmp->task) { +! if (p->state == TASK_ZOMBIE) + printk("wake_up: TASK_ZOMBIE\n"); +! else if (p->state != TASK_STOPPED) { +! p->state = TASK_RUNNING; +! if (p->counter > current->counter) + need_resched = 1; + } + } +! tmp->next = NULL; +! } while (next && next != *q); +! __asm__ __volatile__("pushl %0 ; popfl"::"r" (flags)); + } + +! static inline void __sleep_on(struct wait_queue **p, int state) + { +! unsigned long flags; + + if (!p) + return; + if (current == task[0]) + panic("task[0] trying to sleep"); +! if (current->wait.next) +! printk("__sleep_on: wait->next exists\n"); +! __asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags)); + current->state = state; ++ add_wait_queue(p,¤t->wait); + sti(); + schedule(); +! remove_wait_queue(p,¤t->wait); + __asm__("pushl %0 ; popfl"::"r" (flags)); + } + +! void interruptible_sleep_on(struct wait_queue **p) + { + __sleep_on(p,TASK_INTERRUPTIBLE); + } + +! void sleep_on(struct wait_queue **p) + { + __sleep_on(p,TASK_UNINTERRUPTIBLE); + } +*************** +*** 243,249 **** + * proper. They are here because the floppy needs a timer, and this + * was the easiest way of doing it. + */ +! static struct task_struct * wait_motor[4] = {NULL,NULL,NULL,NULL}; + static int mon_timer[4]={0,0,0,0}; + static int moff_timer[4]={0,0,0,0}; + unsigned char current_DOR = 0x0C; +--- 252,258 ---- + * proper. They are here because the floppy needs a timer, and this + * was the easiest way of doing it. + */ +! static struct wait_queue * wait_motor[4] = {NULL,NULL,NULL,NULL}; + static int mon_timer[4]={0,0,0,0}; + static int moff_timer[4]={0,0,0,0}; + unsigned char current_DOR = 0x0C; +*** 0.96c.pl1/linux/kernel/exit.c Sun Jul 5 01:22:27 1992 +--- linux/kernel/exit.c Tue Jul 14 02:59:22 1992 +*************** +*** 421,426 **** +--- 421,427 ---- + if (stat_addr) + verify_area(stat_addr,4); + repeat: ++ current->signal &= ~(1<<(SIGCHLD-1)); + flag=0; + for (p = current->p_cptr ; p ; p = p->p_osptr) { + if (pid>0) { +*** 0.96c.pl1/linux/kernel/fork.c Sun Jul 5 01:20:58 1992 +--- linux/kernel/fork.c Thu Jul 16 12:54:00 1992 +*************** +*** 66,72 **** + + static int find_empty_process(void) + { +! int i; + + repeat: + if ((++last_pid) & 0xffff0000) +--- 66,72 ---- + + static int find_empty_process(void) + { +! int i, task_nr; + + repeat: + if ((++last_pid) & 0xffff0000) +*************** +*** 75,83 **** + if (task[i] && ((task[i]->pid == last_pid) || + (task[i]->pgrp == last_pid))) + goto repeat; + for(i=1 ; ipid == last_pid) || + (task[i]->pgrp == last_pid))) + goto repeat; ++ /* Only the super-user can fill the last available slot */ ++ task_nr = 0; + for(i=1 ; iwait.task = p; ++ p->wait.next = NULL; + p->state = TASK_UNINTERRUPTIBLE; + p->flags &= ~PF_PTRACED; + p->pid = last_pid; +*************** +*** 125,131 **** + p->tss.esp0 = PAGE_SIZE + (long) p; + p->tss.ss0 = 0x10; + p->tss.eip = eip; +! p->tss.eflags = eflags; + p->tss.eax = 0; + p->tss.ecx = ecx; + p->tss.edx = edx; +--- 134,140 ---- + p->tss.esp0 = PAGE_SIZE + (long) p; + p->tss.ss0 = 0x10; + p->tss.eip = eip; +! p->tss.eflags = eflags & 0xffffcfff; /* iopl is always 0 for a new process */ + p->tss.eax = 0; + p->tss.ecx = ecx; + p->tss.edx = edx; +*** 0.96c.pl1/linux/kernel/traps.c Sat Jul 18 22:28:23 1992 +--- linux/kernel/traps.c Tue Jul 14 15:04:54 1992 +*************** +*** 57,63 **** + void page_fault(void); + void coprocessor_error(void); + void reserved(void); +- void irq13(void); + void alignment_check(void); + + static void die(char * str,long esp_ptr,long nr) +--- 57,62 ---- +*************** +*** 199,203 **** + set_trap_gate(17,&alignment_check); + for (i=18;i<48;i++) + set_trap_gate(i,&reserved); +- set_trap_gate(45,&irq13); + } +--- 198,201 ---- +*** 0.96c.pl1/linux/kernel/printk.c Sun May 17 17:07:00 1992 +--- linux/kernel/printk.c Wed Jul 15 15:49:43 1992 +*************** +*** 22,28 **** + static unsigned long log_page = 0; + static unsigned long log_start = 0; + static unsigned long log_size = 0; +! static struct task_struct * log_wait = NULL; + + int sys_syslog(int type, char * buf, int len) + { +--- 22,28 ---- + static unsigned long log_page = 0; + static unsigned long log_start = 0; + static unsigned long log_size = 0; +! static struct wait_queue * log_wait = NULL; + + int sys_syslog(int type, char * buf, int len) + { +*** 0.96c.pl1/linux/kernel/chr_drv/keyboard.c Sat Jul 18 22:28:23 1992 +--- linux/kernel/chr_drv/keyboard.c Thu Jul 16 02:31:56 1992 +*************** +*** 126,133 **** + qp->buf[qp->head]=ch; + if ((new_head=(qp->head+1)&(TTY_BUF_SIZE-1)) != qp->tail) + qp->head=new_head; +! if (qp->proc_list != NULL) +! qp->proc_list->state=0; + } + + static void puts_queue(char *cp) +--- 126,132 ---- + qp->buf[qp->head]=ch; + if ((new_head=(qp->head+1)&(TTY_BUF_SIZE-1)) != qp->tail) + qp->head=new_head; +! wake_up(&qp->proc_list); + } + + static void puts_queue(char *cp) +*************** +*** 142,149 **** + != qp->tail) + qp->head=new_head; + } +! if (qp->proc_list != NULL) +! qp->proc_list->state=0; + } + + static void ctrl(int sc) +--- 141,147 ---- + != qp->tail) + qp->head=new_head; + } +! wake_up(&qp->proc_list); + } + + static void ctrl(int sc) +*************** +*** 777,782 **** +--- 775,866 ---- + 0, 0, 0, 0, 0, 0, 0, 0, + 0 }; + ++ #elif defined KBD_SG ++ static unsigned char key_map[] = { ++ 0, 27, '1', '2', '3', '4', '5', '6', ++ '7', '8', '9', '0', '\'', '^', 127, 9, ++ 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', ++ 'o', 'p', 0, 0, 13, 0, 'a', 's', ++ 'd', 'f', 'g', 'h', 'j', 'k', 'l', 0, ++ 0, 0, 0, '$', 'y', 'x', 'c', 'v', ++ 'b', 'n', 'm', ',', '.', '-', 0, '*', ++ 0, 32, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, '-', 0, 0, 0, '+', 0, ++ 0, 0, 0, 0, 0, 0, '<', 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0 }; ++ static unsigned char shift_map[] = { ++ 0, 27, '+', '"', '*', 0, '%', '&', ++ '/', '(', ')', '=', '?', '`', 127, 9, ++ 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', ++ 'O', 'P', 0, '!', 13, 0, 'A', 'S', ++ 'D', 'F', 'G', 'H', 'J', 'K', 'L', 0, ++ 0, 0, 0, 0, 'Y', 'X', 'C', 'V', ++ 'B', 'N', 'M', ';', ':', '_', 0, '*', ++ 0, 32, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, '-', 0, 0, 0, '+', 0, ++ 0, 0, 0, 0, 0, 0, '>', 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0 }; ++ static unsigned char alt_map[] = { ++ 0, 0, 0, '@', '#', 0, 0, 0, ++ '|', 0, 0, 0, '\'', '~', 0, 0, ++ '@', 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, '[', ']', 13, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ '{', 0, 0, '}', 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, '\\', 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0 }; ++ #elif defined KBD_SG_LATIN1 ++ static unsigned char key_map[] = { ++ 0, 27, '1', '2', '3', '4', '5', '6', ++ '7', '8', '9', '0', '\'', '^', 127, 9, ++ 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', ++ 'o', 'p', 252, 0, 13, 0, 'a', 's', ++ 'd', 'f', 'g', 'h', 'j', 'k', 'l', 246, ++ 228, 167, 0, '$', 'y', 'x', 'c', 'v', ++ 'b', 'n', 'm', ',', '.', '-', 0, '*', ++ 0, 32, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, '-', 0, 0, 0, '+', 0, ++ 0, 0, 0, 0, 0, 0, '<', 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0 }; ++ static unsigned char shift_map[] = { ++ 0, 27, '+', '"', '*', 231, '%', '&', ++ '/', '(', ')', '=', '?', '`', 127, 9, ++ 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', ++ 'O', 'P', 220, '!', 13, 0, 'A', 'S', ++ 'D', 'F', 'G', 'H', 'J', 'K', 'L', 214, ++ 196, 176, 0, 163, 'Y', 'X', 'C', 'V', ++ 'B', 'N', 'M', ';', ':', '_', 0, '*', ++ 0, 32, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, '-', 0, 0, 0, '+', 0, ++ 0, 0, 0, 0, 0, 0, '>', 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0 }; ++ static unsigned char alt_map[] = { ++ 0, 0, 0, '@', '#', 0, 0, 172, ++ '|', 162, 0, 0, '\'', '~', 0, 0, ++ '@', 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, '[', ']', 13, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 233, ++ '{', 0, 0, '}', 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, '\\', 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0 }; + #else + #error "KBD-type not defined" + #endif +*** 0.96c.pl1/linux/kernel/chr_drv/Makefile Sun Jul 5 03:10:08 1992 +--- linux/kernel/chr_drv/Makefile Thu Jul 16 02:35:31 1992 +*************** +*** 17,23 **** + $(CC) $(CFLAGS) -c $< + + OBJS = tty_io.o console.o keyboard.o serial.o \ +! tty_ioctl.o pty.o lp.o vt.o mem.o + + chr_drv.a: $(OBJS) + $(AR) rcs chr_drv.a $(OBJS) +--- 17,23 ---- + $(CC) $(CFLAGS) -c $< + + OBJS = tty_io.o console.o keyboard.o serial.o \ +! tty_ioctl.o pty.o lp.o vt.o mem.o mouse.o + + chr_drv.a: $(OBJS) + $(AR) rcs chr_drv.a $(OBJS) +*** 0.96c.pl1/linux/kernel/chr_drv/console.c Sat Jul 18 22:28:23 1992 +--- linux/kernel/chr_drv/console.c Wed Jul 15 08:15:19 1992 +*************** +*** 212,218 **** + if (currcons == fg_console) \ + (fg) = (v) + +! int blankinterval = 5*60*HZ; + static int screen_size = 0; + + static void sysbeep(void); +--- 212,218 ---- + if (currcons == fg_console) \ + (fg) = (v) + +! int blankinterval = 10*60*HZ; + static int screen_size = 0; + + static void sysbeep(void); +*************** +*** 315,321 **** + { + if (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_EGAM) + return; +! if (currcons != fg_console || vtmode == KD_GRAPHICS) + return; + cli(); + outb_p(12, video_port_reg); +--- 315,321 ---- + { + if (video_type != VIDEO_TYPE_EGAC && video_type != VIDEO_TYPE_EGAM) + return; +! if (currcons != fg_console || console_blanked || vtmode == KD_GRAPHICS) + return; + cli(); + outb_p(12, video_port_reg); +*************** +*** 609,615 **** + + static inline void set_cursor(int currcons) + { +! if (currcons != fg_console) + return; + cli(); + if (deccm) { +--- 609,615 ---- + + static inline void set_cursor(int currcons) + { +! if (currcons != fg_console || console_blanked) + return; + cli(); + if (deccm) { +*************** +*** 1217,1234 **** + state = ESnormal; + } + } +- timer_active &= ~(1<write_q) && !(TTY_WRITE_BUSY & tty->flags)) { +! tty->flags |= TTY_WRITE_BUSY; +! __asm__ __volatile__("pushl %0 ; popfl"::"r" (flags)); +! tty->write(tty); +! cli(); +! tty->flags &= ~TTY_WRITE_BUSY; +! } +! __asm__ __volatile__("pushl %0 ; popfl"::"r" (flags)); + } + + void tty_read_flush(struct tty_struct * tty) + { +! unsigned long flags; +! +! __asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags)); +! if (!EMPTY(tty->read_q) && !(TTY_READ_BUSY & tty->flags)) { +! tty->flags |= TTY_READ_BUSY; +! __asm__ __volatile__("pushl %0 ; popfl"::"r" (flags)); +! copy_to_cooked(tty); +! cli(); +! tty->flags &= ~TTY_READ_BUSY; +! } +! __asm__ __volatile__("pushl %0 ; popfl"::"r" (flags)); + } + + void change_console(unsigned int new_console) +--- 90,113 ---- + + void tty_write_flush(struct tty_struct * tty) + { +! if (EMPTY(tty->write_q)) +! return; +! if (set_bit(TTY_WRITE_BUSY,&tty->flags)) +! return; +! tty->write(tty); +! if (clear_bit(TTY_WRITE_BUSY,&tty->flags)) +! printk("tty_write_flush: bit already cleared\n"); + } + + void tty_read_flush(struct tty_struct * tty) + { +! if (EMPTY(tty->read_q)) +! return; +! if (set_bit(TTY_READ_BUSY, &tty->flags)) +! return; +! copy_to_cooked(tty); +! if (clear_bit(TTY_READ_BUSY, &tty->flags)) +! printk("tty_read_flush: bit already cleared\n"); + } + + void change_console(unsigned int new_console) +*************** +*** 296,301 **** +--- 288,315 ---- + return -ERESTARTSYS; + } + ++ static void wait_for_canon_input(struct tty_struct * tty) ++ { ++ while (1) { ++ TTY_READ_FLUSH(tty); ++ if (tty->link) ++ if (tty->link->count) ++ TTY_WRITE_FLUSH(tty->link); ++ else ++ return; ++ if (current->signal & ~current->blocked) ++ return; ++ if (FULL(tty->read_q)) ++ return; ++ if (tty->secondary->data) ++ return; ++ cli(); ++ if (!tty->secondary->data) ++ interruptible_sleep_on(&tty->secondary->proc_list); ++ sti(); ++ } ++ } ++ + static int read_chan(unsigned int channel, struct file * file, char * buf, int nr) + { + struct tty_struct * tty; +*************** +*** 315,359 **** + return -EIO; + else + return(tty_signal(SIGTTIN, tty)); +! time = 10L*tty->termios.c_cc[VTIME]; +! minimum = tty->termios.c_cc[VMIN]; +! if (L_CANON(tty)) { +! minimum = nr; +! current->timeout = 0xffffffff; +! time = 0; +! } else if (minimum) +! current->timeout = 0xffffffff; + else { +! minimum = nr; +! if (time) +! current->timeout = time + jiffies; +! time = 0; + } + if (file->f_flags & O_NONBLOCK) + time = current->timeout = 0; + if (minimum>nr) + minimum = nr; +- TTY_READ_FLUSH(tty); + while (nr>0) { +! if (tty->link && tty->link->write) + TTY_WRITE_FLUSH(tty->link); +! cli(); +! if (EMPTY(tty->secondary) || (L_CANON(tty) && +! !FULL(tty->read_q) && !tty->secondary->data)) { +! if (!current->timeout) +! break; +! if (current->signal & ~current->blocked) +! break; +! if (tty->link && !tty->link->count) +! break; +! interruptible_sleep_on(&tty->secondary->proc_list); +! sti(); +! TTY_READ_FLUSH(tty); +! continue; +! } +! sti(); +! do { +! c = get_tty_queue(tty->secondary); + if ((EOF_CHAR(tty) != __DISABLED_CHAR && + c==EOF_CHAR(tty)) || c==10) + tty->secondary->data--; +--- 329,361 ---- + return -EIO; + else + return(tty_signal(SIGTTIN, tty)); +! if (L_CANON(tty)) +! minimum = time = current->timeout = 0; + else { +! time = 10L*tty->termios.c_cc[VTIME]; +! minimum = tty->termios.c_cc[VMIN]; +! if (minimum) +! current->timeout = 0xffffffff; +! else { +! if (time) +! current->timeout = time + jiffies; +! else +! current->timeout = 0; +! time = 0; +! minimum = 1; +! } + } + if (file->f_flags & O_NONBLOCK) + time = current->timeout = 0; ++ else if (L_CANON(tty)) ++ wait_for_canon_input(tty); + if (minimum>nr) + minimum = nr; + while (nr>0) { +! TTY_READ_FLUSH(tty); +! if (tty->link) + TTY_WRITE_FLUSH(tty->link); +! while (nr > 0 && ((c = get_tty_queue(tty->secondary)) >= 0)) { + if ((EOF_CHAR(tty) != __DISABLED_CHAR && + c==EOF_CHAR(tty)) || c==10) + tty->secondary->data--; +*************** +*** 360,380 **** + if ((EOF_CHAR(tty) != __DISABLED_CHAR && + c==EOF_CHAR(tty)) && L_CANON(tty)) + break; +! else { +! put_fs_byte(c,b++); +! if (!--nr) +! break; +! } + if (c==10 && L_CANON(tty)) + break; +! } while (nr>0 && !EMPTY(tty->secondary)); + wake_up(&tty->read_q->proc_list); +! if (L_CANON(tty) || b-buf >= minimum) + break; +! if (time) +! current->timeout = time+jiffies; + } +- sti(); + TTY_READ_FLUSH(tty); + if (tty->link && tty->link->write) + TTY_WRITE_FLUSH(tty->link); +--- 362,389 ---- + if ((EOF_CHAR(tty) != __DISABLED_CHAR && + c==EOF_CHAR(tty)) && L_CANON(tty)) + break; +! put_fs_byte(c,b++); +! nr--; +! if (time) +! current->timeout = time+jiffies; + if (c==10 && L_CANON(tty)) + break; +! }; + wake_up(&tty->read_q->proc_list); +! if (b-buf >= minimum || !current->timeout) + break; +! if (current->signal & ~current->blocked) +! break; +! if (tty->link && !tty->link->count) +! break; +! TTY_READ_FLUSH(tty); +! if (tty->link) +! TTY_WRITE_FLUSH(tty->link); +! cli(); +! if (EMPTY(tty->secondary)) +! interruptible_sleep_on(&tty->secondary->proc_list); +! sti(); + } + TTY_READ_FLUSH(tty); + if (tty->link && tty->link->write) + TTY_WRITE_FLUSH(tty->link); +*************** +*** 433,440 **** + c='\n'; + else if (c=='\n' && O_NLRET(tty)) + c='\r'; +! if (c=='\n' && !(tty->flags & TTY_CR_PENDING) && O_NLCR(tty)) { +! tty->flags |= TTY_CR_PENDING; + put_tty_queue(13,tty->write_q); + continue; + } +--- 442,449 ---- + c='\n'; + else if (c=='\n' && O_NLRET(tty)) + c='\r'; +! if (c=='\n' && O_NLCR(tty) && +! !set_bit(TTY_CR_PENDING,&tty->flags)) { + put_tty_queue(13,tty->write_q); + continue; + } +*************** +*** 442,448 **** + c=toupper(c); + } + b++; nr--; +! tty->flags &= ~TTY_CR_PENDING; + put_tty_queue(c,tty->write_q); + } + if (nr>0) +--- 451,457 ---- + c=toupper(c); + } + b++; nr--; +! clear_bit(TTY_CR_PENDING,&tty->flags); + put_tty_queue(c,tty->write_q); + } + if (nr>0) +*************** +*** 516,521 **** +--- 525,531 ---- + if (!tty->count && !(tty->link && tty->link->count)) { + flush_input(tty); + flush_output(tty); ++ tty->stopped = 0; + } + if (IS_A_PTY_MASTER(dev)) { + if (tty->count) +*************** +*** 540,546 **** + if (retval) { + tty->count--; + if (IS_A_PTY_MASTER(dev) && tty->link) +! tty->link->count++; + } + return retval; + } +--- 550,556 ---- + if (retval) { + tty->count--; + if (IS_A_PTY_MASTER(dev) && tty->link) +! tty->link->count--; + } + return retval; + } +*************** +*** 579,590 **** + redirect = NULL; + } + + static struct file_operations tty_fops = { + tty_lseek, + tty_read, + tty_write, + NULL, /* tty_readdir */ +! NULL, /* tty_select */ + tty_ioctl, + tty_open, + tty_release +--- 589,633 ---- + redirect = NULL; + } + ++ static int tty_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait) ++ { ++ int dev; ++ struct tty_struct * tty; ++ ++ dev = filp->f_rdev; ++ if (MAJOR(dev) != 4) { ++ printk("tty_select: tty pseudo-major != 4\n"); ++ return 0; ++ } ++ dev = MINOR(filp->f_rdev); ++ tty = TTY_TABLE(dev); ++ switch (sel_type) { ++ case SEL_IN: ++ if (!EMPTY(tty->secondary)) ++ return 1; ++ if (tty->link && !tty->link->count) ++ return 1; ++ select_wait(&tty->secondary->proc_list, wait); ++ return 0; ++ case SEL_OUT: ++ if (!FULL(tty->write_q)) ++ return 1; ++ select_wait(&tty->write_q->proc_list, wait); ++ return 0; ++ case SEL_EX: ++ if (tty->link && !tty->link->count) ++ return 1; ++ return 0; ++ } ++ return 0; ++ } ++ + static struct file_operations tty_fops = { + tty_lseek, + tty_read, + tty_write, + NULL, /* tty_readdir */ +! tty_select, + tty_ioctl, + tty_open, + tty_release +*** 0.96c.pl1/linux/kernel/chr_drv/serial.c Sat Jul 18 22:28:31 1992 +--- linux/kernel/chr_drv/serial.c Thu Jul 16 12:39:10 1992 +*************** +*** 33,38 **** +--- 33,40 ---- + { PORT_UNKNOWN, 3, 0x2E8, 3, NULL}, + }; + ++ static void send_intr(struct serial_struct * info); ++ + static void modem_status_intr(struct serial_struct * info) + { + unsigned char status = inb(info->port+6); +*************** +*** 40,51 **** + if (!(info->tty->termios.c_cflag & CLOCAL)) { + if ((status & 0x88) == 0x08 && info->tty->pgrp > 0) + kill_pg(info->tty->pgrp,SIGHUP,1); +! #if 0 +! if ((status & 0x10) == 0x10) +! info->tty->stopped = 0; +! else +! info->tty->stopped = 1; +! #endif + } + } + +--- 42,53 ---- + if (!(info->tty->termios.c_cflag & CLOCAL)) { + if ((status & 0x88) == 0x08 && info->tty->pgrp > 0) + kill_pg(info->tty->pgrp,SIGHUP,1); +! +! if (info->tty->termios.c_cflag & CRTSCTS) +! info->tty->stopped = !(status & 0x10); +! +! if (!info->tty->stopped) +! send_intr(info); + } + } + +*************** +*** 83,88 **** +--- 85,92 ---- + struct tty_queue * queue = info->tty->write_q; + int c, i = 0; + ++ if (info->tty->stopped) return; ++ + timer_active &= ~(1 << timer); + while (inb_p(info->port+5) & 0x20) { + if (queue->tail == queue->head) +*************** +*** 90,97 **** + c = queue->buf[queue->tail]; + queue->tail++; + queue->tail &= TTY_BUF_SIZE-1; +! outb(c,port); +! if ((info->type != PORT_16550A) || (++i >= 14)) + break; + } + timer_table[timer].expires = jiffies + 10; +--- 94,101 ---- + c = queue->buf[queue->tail]; + queue->tail++; + queue->tail &= TTY_BUF_SIZE-1; +! outb(c,port); +! if ((info->type != PORT_16550A) || (++i >= 14) || info->tty->stopped) + break; + } + timer_table[timer].expires = jiffies + 10; +*************** +*** 303,312 **** + outb_p(0x03,port+3); /* reset DLAB */ + outb_p(0x0f,port+4); /* set DTR,RTS, OUT_2 */ + outb_p(0x0f,port+1); /* enable all intrs */ +! inb_p(port+5); +! inb_p(port+0); + inb_p(port+6); +! inb(port+2); + } + + void change_speed(unsigned int line) +--- 307,321 ---- + outb_p(0x03,port+3); /* reset DLAB */ + outb_p(0x0f,port+4); /* set DTR,RTS, OUT_2 */ + outb_p(0x0f,port+1); /* enable all intrs */ +! inb_p(port+2); + inb_p(port+6); +! inb_p(port+2); +! inb_p(port+5); +! do { /* drain all of the stuck characters out of the port */ +! inb_p(port+0); +! } while (inb_p(port+5) & 1 == 1); +! inb_p(port+2); +! inb_p(port+5); + } + + void change_speed(unsigned int line) +*************** +*** 416,421 **** +--- 425,431 ---- + retval = request_irq(new_irq,handler); + if (retval) + return retval; ++ info->irq = new_irq; + free_irq(irq); + } + cli(); +*************** +*** 455,472 **** + for (i = 0, info = serial_table; i < NR_SERIALS; i++,info++) { + info->tty = (tty_table+64) + i; + init(info); + switch (info->type) { + case PORT_8250: +! printk("serial port at 0x%04x is a 8250\n", info->port); + break; + case PORT_16450: +! printk("serial port at 0x%04x is a 16450\n", info->port); + break; + case PORT_16550: +! printk("serial port at 0x%04x is a 16550\n", info->port); + break; + case PORT_16550A: +! printk("serial port at 0x%04x is a 16550A\n", info->port); + break; + } + } +--- 465,488 ---- + for (i = 0, info = serial_table; i < NR_SERIALS; i++,info++) { + info->tty = (tty_table+64) + i; + init(info); ++ if (info->type == PORT_UNKNOWN) ++ continue; ++ printk("serial port at 0x%04x (irq = %d)",info->port,info->irq); + switch (info->type) { + case PORT_8250: +! printk(" is a 8250\n"); + break; + case PORT_16450: +! printk(" is a 16450\n"); + break; + case PORT_16550: +! printk(" is a 16550\n"); + break; + case PORT_16550A: +! printk(" is a 16550A\n"); +! break; +! default: +! printk("\n"); + break; + } + } +*** /dev/null Sat Jul 18 22:26:09 1992 +--- linux/kernel/chr_drv/mouse.c Wed Jul 15 04:46:19 1992 +*************** +*** 0 **** +--- 1,177 ---- ++ /* ++ * Logitech Bus Mouse Driver for Linux ++ * by James Banks ++ * ++ * Heavily modified by David Giller ++ * changed from queue- to counter- driven ++ * hacked out a (probably incorrect) mouse_select ++ * ++ * Modified again by Nathan Laredo to interface with ++ * 0.96c-pl1 IRQ handling changes (13JUL92) ++ * didn't bother touching select code. ++ * ++ * Modified the select() code blindly to conform to the VFS ++ * requirements. 92.07.14 - Linus. Somebody should test it out. ++ * ++ * version 0.1 ++ */ ++ ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ #include ++ ++ static struct mouse_status mouse; ++ ++ static void mouse_interrupt(int cpl) ++ { ++ char dx, dy, buttons; ++ ++ MSE_INT_OFF(); ++ ++ outb(MSE_READ_X_LOW, MSE_CONTROL_PORT); ++ dx = (inb(MSE_DATA_PORT) & 0xf); ++ ++ outb(MSE_READ_X_HIGH, MSE_CONTROL_PORT); ++ dx |= (inb(MSE_DATA_PORT) & 0xf) << 4; ++ ++ outb(MSE_READ_Y_LOW, MSE_CONTROL_PORT ); ++ dy = (inb(MSE_DATA_PORT) & 0xf); ++ ++ outb(MSE_READ_Y_HIGH, MSE_CONTROL_PORT); ++ buttons = inb(MSE_DATA_PORT); ++ ++ dy |= (buttons & 0xf) << 4; ++ buttons = ((buttons >> 5) & 0x07); ++ ++ mouse.buttons = buttons; ++ mouse.latch_buttons |= buttons; ++ mouse.dx += dx; ++ mouse.dy += dy; ++ mouse.ready = 1; ++ if (mouse.inode && mouse.inode->i_wait) ++ wake_up(&mouse.inode->i_wait); ++ ++ MSE_INT_ON(); ++ } ++ ++ static void release_mouse(struct inode * inode, struct file * file) ++ { ++ MSE_INT_OFF(); ++ mouse.active = 0; ++ mouse.ready = 0; ++ mouse.inode = NULL; ++ free_irq(MOUSE_IRQ); ++ } ++ ++ static int open_mouse(struct inode * inode, struct file * file) ++ { ++ if (mouse.active) ++ return -EBUSY; ++ if (!mouse.present) ++ return -EINVAL; ++ if (request_irq(MOUSE_IRQ, mouse_interrupt)) ++ return -EBUSY; ++ mouse.active = 1; ++ mouse.ready = 0; ++ mouse.inode = inode; ++ mouse.dx = 0; ++ mouse.dy = 0; ++ mouse.buttons = mouse.latch_buttons = 0x80; ++ MSE_INT_ON(); ++ return 0; ++ } ++ ++ static int write_mouse(struct inode * inode, struct file * file, char * buffer, int count) ++ { ++ return -EINVAL; ++ } ++ ++ static int read_mouse(struct inode * inode, struct file * file, char * buffer, int count) ++ { ++ int i; ++ ++ if (count < 3) return -EINVAL; ++ if (!mouse.ready) return -EAGAIN; ++ ++ MSE_INT_OFF(); ++ ++ put_fs_byte(mouse.latch_buttons | 0x80, buffer); ++ ++ if (mouse.dx < -127) mouse.dx = -127; ++ if (mouse.dx > 127) mouse.dx = 127; ++ ++ put_fs_byte((char)mouse.dx, buffer + 1); ++ ++ if (mouse.dy < -127) mouse.dy = -127; ++ if (mouse.dy > 127) mouse.dy = 127; ++ ++ put_fs_byte((char) -mouse.dy, buffer + 2); ++ ++ for (i = 3; i < count; i++) ++ put_fs_byte(0x00, buffer + i); ++ ++ mouse.dx = 0; ++ mouse.dy = 0; ++ mouse.latch_buttons = mouse.buttons; ++ mouse.ready = 0; ++ ++ MSE_INT_ON(); ++ return i; ++ } ++ ++ static int mouse_select(struct inode *inode, struct file *file, int sel_type, select_table * wait) ++ { ++ if (sel_type != SEL_IN) ++ return 0; ++ if (mouse.ready) ++ return 1; ++ select_wait(&inode->i_wait,wait); ++ return 0; ++ } ++ ++ static struct file_operations mouse_fops = { ++ NULL, /* mouse_seek */ ++ read_mouse, ++ write_mouse, ++ NULL, /* mouse_readdir */ ++ mouse_select, /* mouse_select */ ++ NULL, /* mouse_ioctl */ ++ open_mouse, ++ release_mouse, ++ }; ++ ++ long mouse_init(long kmem_start) ++ { ++ int i; ++ ++ outb(MSE_CONFIG_BYTE, MSE_CONFIG_PORT); ++ outb(MSE_SIGNATURE_BYTE, MSE_SIGNATURE_PORT); ++ ++ for (i = 0; i < 100000; i++); /* busy loop */ ++ if (inb(MSE_SIGNATURE_PORT) != MSE_SIGNATURE_BYTE) { ++ printk("No bus mouse detected.\n"); ++ mouse.present = 0; ++ return kmem_start; ++ } ++ chrdev_fops[10] = &mouse_fops; ++ outb(MSE_DEFAULT_MODE, MSE_CONFIG_PORT); ++ ++ MSE_INT_OFF(); ++ ++ mouse.present = 1; ++ mouse.active = 0; ++ mouse.ready = 0; ++ mouse.buttons = mouse.latch_buttons = 0x80; ++ mouse.dx = 0; ++ mouse.dy = 0; ++ printk("Bus mouse detected and installed.\n"); ++ return kmem_start; ++ } +*** 0.96c.pl1/linux/kernel/chr_drv/mem.c Sun Jul 5 00:47:51 1992 +--- linux/kernel/chr_drv/mem.c Wed Jul 15 00:35:55 1992 +*************** +*** 246,250 **** +--- 246,251 ---- + chrdev_fops[1] = &mem_fops; + mem_start = tty_init(mem_start); + mem_start = lp_init(mem_start); ++ mem_start = mouse_init(mem_start); + return mem_start; + } +*** 0.96c.pl1/linux/kernel/blk_drv/ll_rw_blk.c Sat Jul 18 22:28:40 1992 +--- linux/kernel/blk_drv/ll_rw_blk.c Wed Jul 15 16:02:43 1992 +*************** +*** 26,32 **** + /* + * used to wait on when there are no free requests + */ +! struct task_struct * wait_for_request = NULL; + + /* blk_dev_struct is: + * do_request-address +--- 26,32 ---- + /* + * used to wait on when there are no free requests + */ +! struct wait_queue * wait_for_request = NULL; + + /* blk_dev_struct is: + * do_request-address +*************** +*** 207,213 **** + /* fill up the request-info, and add it to the queue */ + req->dev = bh->b_dev; + req->cmd = rw; +! req->errors=0; + req->sector = bh->b_blocknr<<1; + req->nr_sectors = 2; + req->buffer = bh->b_data; +--- 207,213 ---- + /* fill up the request-info, and add it to the queue */ + req->dev = bh->b_dev; + req->cmd = rw; +! req->errors = 0; + req->sector = bh->b_blocknr<<1; + req->nr_sectors = 2; + req->buffer = bh->b_data; +*************** +*** 251,257 **** + req->sector = page<<3; + req->nr_sectors = 8; + req->buffer = buffer; +! req->waiting = current; + req->bh = NULL; + req->next = NULL; + current->state = TASK_UNINTERRUPTIBLE; +--- 251,257 ---- + req->sector = page<<3; + req->nr_sectors = 8; + req->buffer = buffer; +! req->waiting = ¤t->wait; + req->bh = NULL; + req->next = NULL; + current->state = TASK_UNINTERRUPTIBLE; +*************** +*** 332,338 **** + req->sector = b[i] << 1; + req->nr_sectors = 2; + req->buffer = buf; +! req->waiting = current; + req->bh = NULL; + req->next = NULL; + current->state = TASK_UNINTERRUPTIBLE; +--- 332,338 ---- + req->sector = b[i] << 1; + req->nr_sectors = 2; + req->buffer = buf; +! req->waiting = ¤t->wait; + req->bh = NULL; + req->next = NULL; + current->state = TASK_UNINTERRUPTIBLE; +*** 0.96c.pl1/linux/kernel/blk_drv/floppy.c Sat Jul 18 22:28:40 1992 +--- linux/kernel/blk_drv/floppy.c Wed Jul 15 16:00:15 1992 +*************** +*** 177,183 **** + /* Synchronization of FDC access. */ + + static volatile int format_status = FORMAT_NONE, fdc_busy = 0; +! static struct task_struct *fdc_wait = NULL, *format_done = NULL; + + /* Errors during formatting are counted here. */ + +--- 177,183 ---- + /* Synchronization of FDC access. */ + + static volatile int format_status = FORMAT_NONE, fdc_busy = 0; +! static struct wait_queue *fdc_wait = NULL, *format_done = NULL; + + /* Errors during formatting are counted here. */ + +*************** +*** 233,239 **** + static unsigned char current_track = NO_TRACK; + static unsigned char command = 0; + unsigned char selected = 0; +! struct task_struct * wait_on_floppy_select = NULL; + + void floppy_deselect(unsigned int nr) + { +--- 233,239 ---- + static unsigned char current_track = NO_TRACK; + static unsigned char command = 0; + unsigned char selected = 0; +! struct wait_queue * wait_on_floppy_select = NULL; + + void floppy_deselect(unsigned int nr) + { +*** 0.96c.pl1/linux/kernel/blk_drv/blk.h Sat Jul 18 22:28:48 1992 +--- linux/kernel/blk_drv/blk.h Wed Jul 15 15:59:24 1992 +*************** +*** 27,33 **** + unsigned long sector; + unsigned long nr_sectors; + char * buffer; +! struct task_struct * waiting; + struct buffer_head * bh; + struct buffer_head * bhtail; + struct request * next; +--- 27,33 ---- + unsigned long sector; + unsigned long nr_sectors; + char * buffer; +! struct wait_queue * waiting; + struct buffer_head * bh; + struct buffer_head * bhtail; + struct request * next; +*************** +*** 50,56 **** + + extern struct blk_dev_struct blk_dev[NR_BLK_DEV]; + extern struct request request[NR_REQUEST]; +! extern struct task_struct * wait_for_request; + + extern int * blk_size[NR_BLK_DEV]; + +--- 50,56 ---- + + extern struct blk_dev_struct blk_dev[NR_BLK_DEV]; + extern struct request request[NR_REQUEST]; +! extern struct wait_queue * wait_for_request; + + extern int * blk_size[NR_BLK_DEV]; + +*** 0.96c.pl1/linux/kernel/sys_call.S Sat Jul 18 22:28:57 1992 +--- linux/kernel/sys_call.S Tue Jul 14 15:11:03 1992 +*************** +*** 37,44 **** + * 40(%esp) - %oldss + */ + +- SIG_CHLD = 17 +- + EBX = 0x00 + ECX = 0x04 + EDX = 0x08 +--- 37,42 ---- +*************** +*** 86,92 **** + .globl _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_op + .globl _double_fault,_coprocessor_segment_overrun + .globl _invalid_TSS,_segment_not_present,_stack_segment +! .globl _general_protection,_irq13,_reserved + .globl _alignment_check,_page_fault + .globl ret_from_sys_call + +--- 84,90 ---- + .globl _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_op + .globl _double_fault,_coprocessor_segment_overrun + .globl _invalid_TSS,_segment_not_present,_stack_segment +! .globl _general_protection,_reserved + .globl _alignment_check,_page_fault + .globl ret_from_sys_call + +*************** +*** 109,167 **** + movl $0x17,%edx; \ + mov %dx,%fs + +- #define ACK_FIRST(mask) \ +- inb $0x21,%al; \ +- jmp 1f; \ +- 1: jmp 1f; \ +- 1: orb $(mask),%al; \ +- outb %al,$0x21; \ +- jmp 1f; \ +- 1: jmp 1f; \ +- 1: movb $0x20,%al; \ +- outb %al,$0x20 +- +- #define ACK_SECOND(mask) \ +- inb $0xA1,%al; \ +- jmp 1f; \ +- 1: jmp 1f; \ +- 1: orb $(mask),%al; \ +- outb %al,$0xA1; \ +- jmp 1f; \ +- 1: jmp 1f; \ +- 1: movb $0x20,%al; \ +- outb %al,$0xA0 \ +- jmp 1f; \ +- 1: jmp 1f; \ +- 1: outb %al,$0x20 +- +- #define UNBLK_FIRST(mask) \ +- inb $0x21,%al; \ +- jmp 1f; \ +- 1: jmp 1f; \ +- 1: andb $~(mask),%al; \ +- outb %al,$0x21 +- +- #define UNBLK_SECOND(mask) \ +- inb $0xA1,%al; \ +- jmp 1f; \ +- 1: jmp 1f; \ +- 1: andb $~(mask),%al; \ +- outb %al,$0xA1 +- + .align 2 +- bad_sys_call: +- movl $-ENOSYS,EAX(%esp) +- jmp ret_from_sys_call +- .align 2 + reschedule: + pushl $ret_from_sys_call + jmp _schedule + .align 2 + _system_call: +! pushl %eax # save orig_eax + SAVE_ALL + cmpl _NR_syscalls,%eax +! jae bad_sys_call + call _sys_call_table(,%eax,4) + movl %eax,EAX(%esp) # save the return value + ret_from_sys_call: +--- 107,123 ---- + movl $0x17,%edx; \ + mov %dx,%fs + + .align 2 + reschedule: + pushl $ret_from_sys_call + jmp _schedule + .align 2 + _system_call: +! pushl %eax # save orig_eax + SAVE_ALL ++ movl $-ENOSYS,EAX(%esp) + cmpl _NR_syscalls,%eax +! jae ret_from_sys_call + call _sys_call_table(,%eax,4) + movl %eax,EAX(%esp) # save the return value + ret_from_sys_call: +*************** +*** 212,227 **** + iret + + .align 2 +- _irq13: +- pushl %eax +- xorb %al,%al +- outb %al,$0xF0 +- movb $0x20,%al +- outb %al,$0x20 +- jmp 1f +- 1: jmp 1f +- 1: outb %al,$0xA0 +- popl %eax + _coprocessor_error: + pushl $-1 # mark this as an int. + SAVE_ALL +--- 168,173 ---- +*** 0.96c.pl1/linux/kernel/ioport.c Tue Apr 21 19:24:55 1992 +--- linux/kernel/ioport.c Wed Jul 15 21:13:36 1992 +*************** +*** 92,94 **** +--- 92,121 ---- + } + return 0; + } ++ ++ unsigned int *stack; ++ ++ /* ++ * sys_iopl has to be used when you want to access the IO ports ++ * beyond the 0x3ff range: to get the full 65536 ports bitmapped ++ * you'd need 8kB of bitmaps/process, which is a bit excessive. ++ * ++ * Here we just change the eflags value on the stack: we allow ++ * only the super-user to do it. This depends on the stack-layout ++ * on system-call entry - see also fork() and the signal handling ++ * code. ++ */ ++ int sys_iopl(long ebx,long ecx,long edx, ++ long esi, long edi, long ebp, long eax, long ds, ++ long es, long fs, long gs, long orig_eax, ++ long eip,long cs,long eflags,long esp,long ss) ++ { ++ unsigned int level = ebx; ++ ++ if (level > 3) ++ return -EINVAL; ++ if (!suser()) ++ return -EPERM; ++ *(&eflags) = (eflags & 0xffffcfff) | (level << 12); ++ return 0; ++ } +*** 0.96c.pl1/linux/kernel/irq.c Sat Jul 18 22:28:57 1992 +--- linux/kernel/irq.c Thu Jul 16 12:32:26 1992 +*************** +*** 36,43 **** +--- 36,50 ---- + { NULL, 0, 0, NULL }, + }; + ++ void irq13(void); ++ + /* + * This builds up the IRQ handler stubs using some ugly macros in irq.h ++ * ++ * These macros create the low-level assembly IRQ routines that do all ++ * the operations that are needed to keep the AT interrupt-controller ++ * happy. They are also written to be fast - and to disable interrupts ++ * as little as humanly possible. + */ + BUILD_IRQ(FIRST,0,0x01) + BUILD_IRQ(FIRST,1,0x02) +*************** +*** 62,70 **** + * particular interrupt is disabled when this is called. + * + * The routine has to call the appropriate handler (disabling +! * interrupts if needed first), and then re-enable this interrupt- +! * line if the handler was ok. If no handler exists, the IRQ isn't +! * re-enabled. + * + * Note similarities on a very low level between this and the + * do_signal() function. Naturally this is simplified, but they +--- 69,77 ---- + * particular interrupt is disabled when this is called. + * + * The routine has to call the appropriate handler (disabling +! * interrupts if needed first). If no handler exists, we return +! * an error value, telling the low-level IRQ routines not to +! * re-enable this IRQ line. + * + * Note similarities on a very low level between this and the + * do_signal() function. Naturally this is simplified, but they +*************** +*** 73,94 **** + * (signal) number as argument, but the cpl value at the time of + * the interrupt. + */ +! void do_IRQ(int irq, struct pt_regs * regs) + { + struct sigaction * sa = irq + irq_sigaction; + void (*handler)(int); + + if (!(handler = sa->sa_handler)) +! return; + if (sa->sa_flags & SA_INTERRUPT) + cli(); + handler(regs->cs & 3); +- cli(); +- if (irq < 8) +- outb(inb_p(0x21) & ~(1<sa_handler)) +! return -1; /* the irq isn't re-enabled */ +! __asm__ __volatile__("movl %%esp,%0":"=r" (esp)); +! if (esp < 200+(unsigned long)(current+1)) { +! printk("Stack overflow on IRQ%d: shutting down\n",irq); +! return -1; +! } + if (sa->sa_flags & SA_INTERRUPT) + cli(); + handler(regs->cs & 3); + sti(); ++ return 0; /* re-enable the irq when returning */ + } + + int irqaction(unsigned int irq, struct sigaction * new) +*************** +*** 150,155 **** +--- 159,172 ---- + __asm__ __volatile__("pushl %0 ; popfl"::"r" (flags)); + } + ++ extern void math_error(void); ++ ++ static void math_error_irq(int cpl) ++ { ++ outb(0,0xF0); ++ math_error(); ++ } ++ + void init_IRQ(void) + { + set_trap_gate(0x20,IRQ0_interrupt); +*************** +*** 161,167 **** + set_trap_gate(0x26,IRQ6_interrupt); + set_trap_gate(0x27,IRQ7_interrupt); + set_trap_gate(0x28,IRQ8_interrupt); +! set_trap_gate(0x29,IRQ10_interrupt); + set_trap_gate(0x2a,IRQ10_interrupt); + set_trap_gate(0x2b,IRQ11_interrupt); + set_trap_gate(0x2c,IRQ12_interrupt); +--- 178,184 ---- + set_trap_gate(0x26,IRQ6_interrupt); + set_trap_gate(0x27,IRQ7_interrupt); + set_trap_gate(0x28,IRQ8_interrupt); +! set_trap_gate(0x29,IRQ9_interrupt); + set_trap_gate(0x2a,IRQ10_interrupt); + set_trap_gate(0x2b,IRQ11_interrupt); + set_trap_gate(0x2c,IRQ12_interrupt); +*************** +*** 168,171 **** +--- 185,190 ---- + set_trap_gate(0x2d,IRQ13_interrupt); + set_trap_gate(0x2e,IRQ14_interrupt); + set_trap_gate(0x2f,IRQ15_interrupt); ++ if (request_irq(13,math_error_irq)) ++ printk("Unable to get IRQ13 for math-error handler\n"); + } +*** 0.96c.pl1/linux/kernel/ptrace.c Sat Jul 18 22:28:57 1992 +--- linux/kernel/ptrace.c Fri Jul 17 03:39:50 1992 +*************** +*** 240,246 **** + + if (child == current) + return -EPERM; +! if ((!current->dumpable || (current->uid != child->euid) || + (current->gid != child->egid)) && !suser()) + return -EPERM; + /* the same process cannot be attached many times */ +--- 240,246 ---- + + if (child == current) + return -EPERM; +! if ((!child->dumpable || (current->uid != child->euid) || + (current->gid != child->egid)) && !suser()) + return -EPERM; + /* the same process cannot be attached many times */ +*** 0.96c.pl1/linux/tools/build.c Tue May 26 19:40:55 1992 +--- linux/tools/build.c Thu Jul 16 00:40:25 1992 +*************** +*** 32,38 **** + #define MINIX_HEADER 32 + #define GCC_HEADER 1024 + +! #define SYS_SIZE 0x4000 + + #define DEFAULT_MAJOR_ROOT 0 + #define DEFAULT_MINOR_ROOT 0 +--- 32,38 ---- + #define MINIX_HEADER 32 + #define GCC_HEADER 1024 + +! #define SYS_SIZE 0x5000 + + #define DEFAULT_MAJOR_ROOT 0 + #define DEFAULT_MINOR_ROOT 0 +*** 0.96c.pl1/linux/include/sys/user.h Wed Jun 10 15:24:39 1992 +--- linux/include/sys/user.h Fri Jul 17 04:30:30 1992 +*************** +*** 62,67 **** +--- 62,68 ---- + struct pt_regs * u_ar0; /* Used by gdb to help find the values for */ + /* the registers. */ + struct user_i387_struct* u_fpstate; /* Math Co-processor pointer. */ ++ unsigned long magic; /* To uniquely identify a core file */ + }; + #define NBPG 4096 + #define UPAGES 1 +*** 0.96c.pl1/linux/include/a.out.h Fri Apr 24 18:26:25 1992 +--- linux/include/a.out.h Fri Jul 17 04:30:30 1992 +*************** +*** 72,77 **** +--- 72,79 ---- + /* Code indicating demand-paged executable. */ + #define ZMAGIC 0413 + ++ /* Code indicating core file. */ ++ #define CMAGIC 0421 + #if !defined (N_BADMAG) + #define N_BADMAG(x) \ + (N_MAGIC(x) != OMAGIC && N_MAGIC(x) != NMAGIC \ +*** 0.96c.pl1/linux/include/linux/sched.h Sat Jul 18 22:29:05 1992 +--- linux/include/linux/sched.h Wed Jul 15 16:46:48 1992 +*************** +*** 128,136 **** + */ + struct task_struct *p_opptr,*p_pptr, *p_cptr, *p_ysptr, *p_osptr; + /* +! * sleep makes a singly linked list with this. + */ +! struct task_struct *next_wait; + unsigned short uid,euid,suid; + unsigned short gid,egid,sgid; + unsigned long timeout; +--- 128,137 ---- + */ + struct task_struct *p_opptr,*p_pptr, *p_cptr, *p_ysptr, *p_osptr; + /* +! * For ease of programming... Normal sleeps don't need to +! * keep track of a wait-queue: every task has an entry of it's own + */ +! struct wait_queue wait; + unsigned short uid,euid,suid; + unsigned short gid,egid,sgid; + unsigned long timeout; +*************** +*** 185,191 **** + /* ec,brk... */ 0,0,0,0,0,0,0, \ + /* pid etc.. */ 0,0,0,0, \ + /* suppl grps*/ {NOGROUP,}, \ +! /* proc links*/ &init_task.task,&init_task.task,NULL,NULL,NULL,NULL, \ + /* uid etc */ 0,0,0,0,0,0, \ + /* timeout */ 0,0,0,0,0,0,0,0,0,0,0,0, \ + /* min_flt */ 0,0,0,0, \ +--- 186,193 ---- + /* ec,brk... */ 0,0,0,0,0,0,0, \ + /* pid etc.. */ 0,0,0,0, \ + /* suppl grps*/ {NOGROUP,}, \ +! /* proc links*/ &init_task.task,&init_task.task,NULL,NULL,NULL, \ +! /* wait queue*/ {&init_task.task,NULL}, \ + /* uid etc */ 0,0,0,0,0,0, \ + /* timeout */ 0,0,0,0,0,0,0,0,0,0,0,0, \ + /* min_flt */ 0,0,0,0, \ +*************** +*** 222,231 **** + #define CURRENT_TIME (startup_time+(jiffies+jiffies_offset)/HZ) + + extern void add_timer(long jiffies, void (*fn)(void)); +! extern void sleep_on(struct task_struct ** p); + extern int send_sig(long sig,struct task_struct * p,int priv); +- extern void interruptible_sleep_on(struct task_struct ** p); +- extern void wake_up(struct task_struct ** p); + extern int in_group_p(gid_t grp); + + extern int request_irq(unsigned int irq,void (*handler)(int)); +--- 224,236 ---- + #define CURRENT_TIME (startup_time+(jiffies+jiffies_offset)/HZ) + + extern void add_timer(long jiffies, void (*fn)(void)); +! +! extern void sleep_on(struct wait_queue ** p); +! extern void interruptible_sleep_on(struct wait_queue ** p); +! extern void wake_up(struct wait_queue ** p); +! extern void wake_one_task(struct task_struct * p); +! + extern int send_sig(long sig,struct task_struct * p,int priv); + extern int in_group_p(gid_t grp); + + extern int request_irq(unsigned int irq,void (*handler)(int)); +*************** +*** 259,266 **** +--- 264,273 ---- + __asm__("cmpl %%ecx,_current\n\t" \ + "je 1f\n\t" \ + "movw %%dx,%1\n\t" \ ++ "cli\n\t" \ + "xchgl %%ecx,_current\n\t" \ + "ljmp %0\n\t" \ ++ "sti\n\t" \ + "cmpl %%ecx,_last_task_used_math\n\t" \ + "jne 1f\n\t" \ + "clts\n" \ +*************** +*** 297,302 **** +--- 304,354 ---- + + #define set_base(ldt,base) _set_base( ((char *)&(ldt)) , base ) + #define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , (limit-1)>>12 ) ++ ++ extern inline void add_wait_queue(struct wait_queue ** p, struct wait_queue * wait) ++ { ++ unsigned long flags; ++ struct wait_queue * tmp; ++ ++ __asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags)); ++ wait->next = *p; ++ tmp = wait; ++ while (tmp->next) ++ if ((tmp = tmp->next)->next == *p) ++ break; ++ *p = tmp->next = wait; ++ __asm__ __volatile__("pushl %0 ; popfl"::"r" (flags)); ++ } ++ ++ extern inline void remove_wait_queue(struct wait_queue ** p, struct wait_queue * wait) ++ { ++ unsigned long flags; ++ struct wait_queue * tmp; ++ ++ __asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags)); ++ if (*p == wait) ++ if ((*p = wait->next) == wait) ++ *p = NULL; ++ tmp = wait; ++ while (tmp && tmp->next != wait) ++ tmp = tmp->next; ++ if (tmp) ++ tmp->next = wait->next; ++ wait->next = NULL; ++ __asm__ __volatile__("pushl %0 ; popfl"::"r" (flags)); ++ } ++ ++ extern inline void select_wait(struct wait_queue ** wait_address, select_table * p) ++ { ++ struct select_table_entry * entry = p->entry + p->nr; ++ ++ if (!wait_address) ++ return; ++ entry->wait_address = wait_address; ++ entry->wait.task = current; ++ add_wait_queue(wait_address,&entry->wait); ++ p->nr++; ++ } + + static unsigned long inline _get_base(char * addr) + { +*** 0.96c.pl1/linux/include/linux/sys.h Wed Jun 17 05:25:11 1992 +--- linux/include/linux/sys.h Wed Jul 15 21:01:13 1992 +*************** +*** 112,117 **** +--- 112,118 ---- + extern int sys_newlstat(); + extern int sys_newfstat(); + extern int sys_newuname(); ++ extern int sys_iopl(); + + fn_ptr sys_call_table[] = { sys_setup, sys_exit, sys_fork, sys_read, + sys_write, sys_open, sys_close, sys_waitpid, sys_creat, sys_link, +*************** +*** 133,139 **** + sys_truncate, sys_ftruncate, sys_fchmod, sys_fchown, sys_getpriority, + sys_setpriority, sys_profil, sys_statfs, sys_fstatfs, sys_ioperm, + sys_socketcall, sys_syslog, sys_setitimer, sys_getitimer, sys_newstat, +! sys_newlstat, sys_newfstat, sys_newuname }; + + /* So we don't have to do any more manual updating.... */ + int NR_syscalls = sizeof(sys_call_table)/sizeof(fn_ptr); +--- 134,140 ---- + sys_truncate, sys_ftruncate, sys_fchmod, sys_fchown, sys_getpriority, + sys_setpriority, sys_profil, sys_statfs, sys_fstatfs, sys_ioperm, + sys_socketcall, sys_syslog, sys_setitimer, sys_getitimer, sys_newstat, +! sys_newlstat, sys_newfstat, sys_newuname, sys_iopl }; + + /* So we don't have to do any more manual updating.... */ + int NR_syscalls = sizeof(sys_call_table)/sizeof(fn_ptr); +*** 0.96c.pl1/linux/include/linux/tty.h Sat Jul 18 22:29:05 1992 +--- linux/include/linux/tty.h Wed Jul 15 15:51:40 1992 +*************** +*** 30,36 **** + unsigned long data; + unsigned long head; + unsigned long tail; +! struct task_struct * proc_list; + unsigned char buf[TTY_BUF_SIZE]; + }; + +--- 30,36 ---- + unsigned long data; + unsigned long head; + unsigned long tail; +! struct wait_queue * proc_list; + unsigned char buf[TTY_BUF_SIZE]; + }; + +*************** +*** 126,136 **** + /* + * so that interrupts won't be able to mess up the + * queues, copy_to_cooked must be atomic with repect +! * to itself, as must tty->write. These are the flag bits. + */ +! #define TTY_WRITE_BUSY 1 +! #define TTY_READ_BUSY 2 +! #define TTY_CR_PENDING 4 + + #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) + #define TTY_READ_FLUSH(tty) tty_read_flush((tty)) +--- 126,161 ---- + /* + * so that interrupts won't be able to mess up the + * queues, copy_to_cooked must be atomic with repect +! * to itself, as must tty->write. These are the flag +! * bit-numbers. Use the set_bit() and clear_bit() +! * macros to make it all atomic. + */ +! #define TTY_WRITE_BUSY 0 +! #define TTY_READ_BUSY 1 +! #define TTY_CR_PENDING 2 +! +! /* +! * These have to be done with inline assembly: that way the bit-setting +! * is guaranteed to be atomic. Both set_bit and clear_bit return 0 +! * if the bit-setting went ok, != 0 if the bit already was set/cleared. +! */ +! extern inline int set_bit(int nr,int * addr) +! { +! char ok; +! +! __asm__ __volatile__("btsl %1,%2\n\tsetb %0": +! "=q" (ok):"r" (nr),"m" (*(addr))); +! return ok; +! } +! +! extern inline int clear_bit(int nr, int * addr) +! { +! char ok; +! +! __asm__ __volatile__("btrl %1,%2\n\tsetnb %0": +! "=q" (ok):"r" (nr),"m" (*(addr))); +! return ok; +! } + + #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) + #define TTY_READ_FLUSH(tty) tty_read_flush((tty)) +*** 0.96c.pl1/linux/include/linux/fs.h Sat Jul 18 22:29:05 1992 +--- linux/include/linux/fs.h Wed Jul 15 15:19:53 1992 +*************** +*** 6,11 **** +--- 6,14 ---- + #ifndef _FS_H + #define _FS_H + ++ #include ++ #include ++ + #include + #include + #include +*************** +*** 41,57 **** + #define MAJOR(a) (((unsigned)(a))>>8) + #define MINOR(a) ((a)&0xff) + +- #define NR_OPEN 32 +- #define NR_INODE 128 +- #define NR_FILE 128 +- #define NR_SUPER 8 +- #define NR_HASH 307 +- #define NR_BUFFERS nr_buffers +- #define BLOCK_SIZE 1024 +- #define BLOCK_SIZE_BITS 10 +- #define MAX_CHRDEV 16 +- #define MAX_BLKDEV 16 +- + #ifndef NULL + #define NULL ((void *) 0) + #endif +--- 44,49 ---- +*************** +*** 78,83 **** +--- 70,76 ---- + #define MS_NOSUID 2 /* ignore suid and sgid bits */ + #define MS_NODEV 4 /* disallow access to device special files */ + #define MS_NOEXEC 8 /* disallow program execution */ ++ #define MS_SYNC 16 /* writes are synced at once */ + + /* + * Note that read-only etc flags are inode-specific: setting some file-system +*************** +*** 89,94 **** +--- 82,88 ---- + #define IS_NOSUID(inode) ((inode)->i_flags & MS_NOSUID) + #define IS_NODEV(inode) ((inode)->i_flags & MS_NODEV) + #define IS_NOEXEC(inode) ((inode)->i_flags & MS_NOEXEC) ++ #define IS_SYNC(inode) ((inode)->i_flags & MS_SYNC) + + /* the read-only stuff doesn't really belong here, but any other place is + probably as bad and I don't want to create yet another include file. */ +*************** +*** 108,114 **** + unsigned char b_dirt; /* 0-clean,1-dirty */ + unsigned char b_count; /* users using this block */ + unsigned char b_lock; /* 0 - ok, 1 -locked */ +! struct task_struct * b_wait; + struct buffer_head * b_prev; + struct buffer_head * b_next; + struct buffer_head * b_prev_free; +--- 102,108 ---- + unsigned char b_dirt; /* 0-clean,1-dirty */ + unsigned char b_count; /* users using this block */ + unsigned char b_lock; /* 0 - ok, 1 -locked */ +! struct wait_queue * b_wait; + struct buffer_head * b_prev; + struct buffer_head * b_next; + struct buffer_head * b_prev_free; +*************** +*** 131,138 **** + unsigned long i_data[16]; + struct inode_operations * i_op; + struct super_block * i_sb; +! struct task_struct * i_wait; +! struct task_struct * i_wait2; /* for pipes */ + unsigned short i_count; + unsigned short i_flags; + unsigned char i_lock; +--- 125,132 ---- + unsigned long i_data[16]; + struct inode_operations * i_op; + struct super_block * i_sb; +! struct wait_queue * i_wait; +! struct wait_queue * i_wait2; /* for pipes */ + unsigned short i_count; + unsigned short i_flags; + unsigned char i_lock; +*************** +*** 154,171 **** + off_t f_pos; + }; + +- typedef struct { +- struct task_struct * old_task; +- struct task_struct ** wait_address; +- } wait_entry; +- +- typedef struct select_table_struct { +- int nr, woken; +- struct task_struct * current; +- struct select_table_struct * next_table; +- wait_entry entry[NR_OPEN*3]; +- } select_table; +- + struct super_block { + unsigned long s_ninodes; + unsigned long s_nzones; +--- 148,153 ---- +*************** +*** 182,188 **** + struct inode * s_covered; + struct inode * s_mounted; + unsigned long s_time; +! struct task_struct * s_wait; + unsigned char s_lock; + unsigned char s_rd_only; + unsigned char s_dirt; +--- 164,170 ---- + struct inode * s_covered; + struct inode * s_mounted; + unsigned long s_time; +! struct wait_queue * s_wait; + unsigned char s_lock; + unsigned char s_rd_only; + unsigned char s_dirt; +*** 0.96c.pl1/linux/include/linux/string.h Thu Jul 2 01:06:49 1992 +--- linux/include/linux/string.h Wed Jul 15 06:58:53 1992 +*************** +*** 273,279 **** + + extern inline char * strtok(char * s,const char * ct) + { +! register char * __res __asm__("si"); + __asm__("testl %1,%1\n\t" + "jne 1f\n\t" + "testl %0,%0\n\t" +--- 273,279 ---- + + extern inline char * strtok(char * s,const char * ct) + { +! register char * __res; + __asm__("testl %1,%1\n\t" + "jne 1f\n\t" + "testl %0,%0\n\t" +*************** +*** 324,335 **** + "jne 8f\n\t" + "movl %0,%1\n" + "8:" +! #if __GNUC__ == 2 +! :"=r" (__res) +! #else +! :"=b" (__res) +! #endif +! ,"=S" (___strtok) + :"0" (___strtok),"1" (s),"g" (ct) + :"ax","cx","dx","di"); + return __res; +--- 324,330 ---- + "jne 8f\n\t" + "movl %0,%1\n" + "8:" +! :"=b" (__res),"=S" (___strtok) + :"0" (___strtok),"1" (s),"g" (ct) + :"ax","cx","dx","di"); + return __res; +*** 0.96c.pl1/linux/include/linux/unistd.h Wed Jun 17 14:41:25 1992 +--- linux/include/linux/unistd.h Wed Jul 15 20:58:31 1992 +*************** +*** 116,121 **** +--- 116,122 ---- + #define __NR_lstat 107 + #define __NR_fstat 108 + #define __NR_uname 109 ++ #define __NR_iopl 110 + + extern int errno; + +*** 0.96c.pl1/linux/include/linux/fcntl.h Thu Jul 2 00:56:39 1992 +--- linux/include/linux/fcntl.h Tue Jul 14 16:04:33 1992 +*************** +*** 3,20 **** + + #include + +! /* open/fcntl - NOCTTY, NDELAY isn't implemented yet */ +! #define O_ACCMODE 00003 +! #define O_RDONLY 00 +! #define O_WRONLY 01 +! #define O_RDWR 02 +! #define O_CREAT 00100 /* not fcntl */ +! #define O_EXCL 00200 /* not fcntl */ +! #define O_NOCTTY 00400 /* not fcntl */ +! #define O_TRUNC 01000 /* not fcntl */ +! #define O_APPEND 02000 +! #define O_NONBLOCK 04000 + #define O_NDELAY O_NONBLOCK + + /* Defines for fcntl-commands. Note that currently + * locking isn't supported, and other things aren't really +--- 3,21 ---- + + #include + +! /* open/fcntl - O_SYNC isn't implemented yet */ +! #define O_ACCMODE 0003 +! #define O_RDONLY 00 +! #define O_WRONLY 01 +! #define O_RDWR 02 +! #define O_CREAT 0100 /* not fcntl */ +! #define O_EXCL 0200 /* not fcntl */ +! #define O_NOCTTY 0400 /* not fcntl */ +! #define O_TRUNC 01000 /* not fcntl */ +! #define O_APPEND 02000 +! #define O_NONBLOCK 04000 + #define O_NDELAY O_NONBLOCK ++ #define O_SYNC 010000 + + /* Defines for fcntl-commands. Note that currently + * locking isn't supported, and other things aren't really +*** /dev/null Sat Jul 18 22:26:09 1992 +--- linux/include/linux/mouse.h Wed Jul 15 04:15:55 1992 +*************** +*** 0 **** +--- 1,61 ---- ++ /* ++ * linux/include/linux/mouse.h: header file for Logitech Bus Mouse driver ++ * by James Banks ++ * ++ * based on information gleamed from various mouse drivers on the net ++ * ++ * Heavily modified by David giller (rafetmad@oxy.edu) ++ * ++ * Minor modifications for Linux 0.96c-pl1 by Nathan Laredo ++ * gt7080a@prism.gatech.edu (13JUL92) ++ * ++ */ ++ ++ #ifndef _MOUSE_H ++ #define _MOUSE_H ++ ++ #define MOUSE_IRQ 5 ++ ++ #define MSE_DATA_PORT 0x23c ++ #define MSE_SIGNATURE_PORT 0x23d ++ #define MSE_CONTROL_PORT 0x23e ++ #define MSE_INTERRUPT_PORT 0x23e ++ #define MSE_CONFIG_PORT 0x23f ++ ++ #define MSE_ENABLE_INTERRUPTS 0x00 ++ #define MSE_DISABLE_INTERRUPTS 0x10 ++ ++ #define MSE_READ_X_LOW 0x80 ++ #define MSE_READ_X_HIGH 0xa0 ++ #define MSE_READ_Y_LOW 0xc0 ++ #define MSE_READ_Y_HIGH 0xe0 ++ ++ /* Magic number used to check if the mouse exists */ ++ #define MSE_CONFIG_BYTE 0x91 ++ #define MSE_DEFAULT_MODE 0x90 ++ #define MSE_SIGNATURE_BYTE 0xa5 ++ ++ /* useful macros */ ++ ++ #define MSE_INT_OFF() outb(MSE_DISABLE_INTERRUPTS, MSE_CONTROL_PORT) ++ #define MSE_INT_ON() outb(MSE_ENABLE_INTERRUPTS, MSE_CONTROL_PORT) ++ ++ struct mouse_status ++ { ++ char buttons; ++ char latch_buttons; ++ int dx; ++ int dy; ++ ++ int present; ++ int ready; ++ int active; ++ ++ struct inode *inode; ++ }; ++ ++ /* Function Prototypes */ ++ extern long mouse_init(long); ++ ++ #endif ++ +*** /dev/null Sat Jul 18 22:26:09 1992 +--- linux/include/linux/msdos_fs.h Thu Jul 16 00:35:11 1992 +*************** +*** 0 **** +--- 1,190 ---- ++ /* ++ * The MS-DOS filesystem constants/structures ++ */ ++ ++ #ifndef _MSDOS_FS_H ++ #define _MSDOS_FS_H ++ ++ #include ++ #include ++ ++ #define MSDOS_ROOT_INO 1 ++ #define SECTOR_SIZE 512 /* sector size (bytes) */ ++ #define SECTOR_BITS 9 /* log2(SECTOR_SIZE) */ ++ #define MSDOS_DPB (MSDOS_DPS*2) /* dir entries per block */ ++ #define MSDOS_DPB_BITS 5 /* log2(MSDOS_DPB) */ ++ #define MSDOS_DPS (SECTOR_SIZE/sizeof(struct msdos_dir_entry)) ++ #define MSDOS_DPS_BITS 4 /* log2(MSDOS_DPS) */ ++ #define MSDOS_DIR_BITS 5 /* log2(sizeof(struct msdos_dir_entry)) */ ++ ++ #define MSDOS_SUPER_MAGIC 0x4d44 /* MD */ ++ ++ #define FAT_CACHE 8 /* FAT cache size */ ++ ++ #define ATTR_RO 1 /* read-only */ ++ #define ATTR_HIDDEN 2 /* hidden */ ++ #define ATTR_SYS 4 /* system */ ++ #define ATTR_VOLUME 8 /* volume label */ ++ #define ATTR_DIR 16 /* directory */ ++ #define ATTR_ARCH 32 /* archived */ ++ ++ #define ATTR_NONE 0 /* no attribute bits */ ++ #define ATTR_UNUSED (ATTR_VOLUME | ATTR_ARCH | ATTR_SYS) ++ /* attribute bits that are copied "as is" */ ++ ++ #define DELETED_FLAG 0xe5 /* marks file as deleted when in name[0] */ ++ ++ #define D_START 0 /* i_data[0]: first cluster or 0 */ ++ #define D_ATTRS 1 /* i_data[1]: unused attribute bits */ ++ #define D_BUSY 2 /* i_data[2]: file is either deleted but still open, or ++ inconsistent (mkdir) */ ++ #define D_DEPEND 3 /* i_data[3]: pointer to inode that depends on the current ++ inode */ ++ #define D_OLD 4 /* i_data[4]: pointer to the old inode this inode depends ++ on */ ++ #define D_BINARY 5 /* i_data[5]: file contains non-text data */ ++ ++ #define SET_DIRTY(i) (i)->i_dirt = (i)->i_data[D_DIRT] = 1 ++ ++ #define MSDOS_SB(s) ((struct msdos_sb_info *) s) ++ ++ #define MSDOS_NAME 11 /* maximum name length */ ++ #define MSDOS_DOT ". " /* ".", padded to MSDOS_NAME chars */ ++ #define MSDOS_DOTDOT ".. " /* "..", padded to MSDOS_NAME chars */ ++ ++ #define MSDOS_FAT12 4086 /* maximum number of clusters in a 12 bit FAT */ ++ ++ struct msdos_boot_sector { ++ char ignored[13]; ++ unsigned char cluster_size; /* sectors/cluster */ ++ unsigned short reserved; /* reserved sectors */ ++ unsigned char fats; /* number of FATs */ ++ unsigned char dir_entries[2];/* root directory entries */ ++ unsigned char sectors[2]; /* number of sectors */ ++ unsigned char media; /* media code (unused) */ ++ unsigned short fat_length; /* sectors/FAT */ ++ unsigned short secs_track; /* sectors per track (unused) */ ++ unsigned short heads; /* number of heads (unused) */ ++ unsigned long hidden; /* hidden sectors (unused) */ ++ unsigned long total_sect; /* number of sectors (if sectors == 0) */ ++ }; ++ ++ struct msdos_sb_info { /* space in struct super_block is 28 bytes */ ++ unsigned short cluster_size; /* sectors/cluster */ ++ unsigned char fats,fat_bits; /* number of FATs, FAT bits (12 or 16) */ ++ unsigned short fat_start,fat_length; /* FAT start & length (sec.) */ ++ unsigned short dir_start,dir_entries; /* root dir start & entries */ ++ unsigned short data_start; /* first data sector */ ++ unsigned long clusters; /* number of clusters */ ++ uid_t fs_uid; ++ gid_t fs_gid; ++ unsigned short fs_umask; ++ unsigned char name_check; /* r = releaxed, n = normal, s = strict */ ++ unsigned char conversion; /* b = binary, t = text, a = auto */ ++ }; /* 28 bytes */ ++ ++ struct msdos_dir_entry { ++ char name[8],ext[3]; /* name and extension */ ++ unsigned char attr; /* attribute bits */ ++ char unused[10]; ++ unsigned short time,date,start; /* time, date and first cluster */ ++ unsigned long size; /* file size (in bytes) */ ++ }; ++ ++ struct fat_cache { ++ int device; /* device number. 0 means unused. */ ++ int ino; /* inode number. */ ++ int file_cluster; /* cluster number in the file. */ ++ int disk_cluster; /* cluster number on disk. */ ++ struct fat_cache *next; /* next cache entry */ ++ }; ++ ++ /* Determine whether this FS has kB-aligned data. */ ++ ++ #define MSDOS_CAN_BMAP(mib) (!(((mib)->cluster_size & 1) || \ ++ ((mib)->data_start & 1))) ++ ++ /* Convert attribute bits and a mask to the UNIX mode. */ ++ ++ #define MSDOS_MKMODE(a,m) (m & (a & ATTR_RO ? 0444 : (a & ATTR_HIDDEN ? 0 : \ ++ 0777))) ++ ++ /* Convert the UNIX mode to MS-DOS attribute bits. */ ++ ++ #define MSDOS_MKATTR(m) (!(m & 0600) ? ATTR_HIDDEN : ((m & 0600) == 0400 ? \ ++ ATTR_RO : ATTR_NONE)) ++ ++ ++ static inline struct buffer_head *msdos_sread(int dev,int sector,void **start) ++ { ++ struct buffer_head *bh; ++ ++ if (!(bh = bread(dev,sector >> 1))) return NULL; ++ *start = bh->b_data+((sector & 1) << SECTOR_BITS); ++ return bh; ++ } ++ ++ ++ /* misc.c */ ++ ++ extern int is_binary(char conversion,char *extension); ++ extern void lock_creation(void); ++ extern void unlock_creation(void); ++ extern int msdos_add_cluster(struct inode *inode); ++ extern int date_dos2unix(unsigned short time,unsigned short date); ++ extern void date_unix2dos(int unix_date,unsigned short *time, ++ unsigned short *date); ++ extern int msdos_get_entry(struct inode *dir,int *pos,struct buffer_head **bh, ++ struct msdos_dir_entry **de); ++ extern int msdos_scan(struct inode *dir,char *name,struct buffer_head **res_bh, ++ struct msdos_dir_entry **res_de,int *ino); ++ extern int msdos_parent_ino(struct inode *dir,int locked); ++ ++ /* fat.c */ ++ ++ extern int fat_access(struct super_block *sb,int this,int new_value); ++ extern int msdos_smap(struct inode *inode,int sector); ++ extern int fat_free(struct inode *inode,int skip); ++ extern void cache_init(void); ++ void cache_lookup(struct inode *inode,int cluster,int *f_clu,int *d_clu); ++ void cache_add(struct inode *inode,int f_clu,int d_clu); ++ void cache_inval_inode(struct inode *inode); ++ void cache_inval_dev(int device); ++ int get_cluster(struct inode *inode,int cluster); ++ ++ /* namei.c */ ++ ++ extern int msdos_lookup(struct inode *dir,const char *name,int len, ++ struct inode **result); ++ extern int msdos_create(struct inode *dir,const char *name,int len,int mode, ++ struct inode **result); ++ extern int msdos_mkdir(struct inode *dir,const char *name,int len,int mode); ++ extern int msdos_rmdir(struct inode *dir,const char *name,int len); ++ extern int msdos_unlink(struct inode *dir,const char *name,int len); ++ extern int msdos_rename(struct inode *old_dir,const char *old_name,int old_len, ++ struct inode *new_dir,const char *new_name,int new_len); ++ ++ /* inode.c */ ++ ++ extern void msdos_put_inode(struct inode *inode); ++ extern void msdos_put_super(struct super_block *sb); ++ extern struct super_block *msdos_read_super(struct super_block *s,void *data); ++ extern void msdos_statfs(struct super_block *sb,struct statfs *buf); ++ extern int msdos_bmap(struct inode *inode,int block); ++ extern void msdos_read_inode(struct inode *inode); ++ extern void msdos_write_inode(struct inode *inode); ++ ++ /* dir.c */ ++ ++ extern struct file_operations msdos_dir_operations; ++ extern struct inode_operations msdos_dir_inode_operations; ++ ++ /* file.c */ ++ ++ extern struct file_operations msdos_file_operations; ++ extern struct inode_operations msdos_file_inode_operations; ++ extern struct inode_operations msdos_file_inode_operations_no_bmap; ++ ++ extern void msdos_truncate(struct inode *inode); ++ ++ #endif +*** /dev/null Sat Jul 18 22:26:09 1992 +--- linux/include/linux/wait.h Wed Jul 15 16:46:10 1992 +*************** +*** 0 **** +--- 1,19 ---- ++ #ifndef _LINUX_WAIT_H ++ #define _LINUX_WAIT_H ++ ++ #include ++ ++ struct wait_queue { ++ struct task_struct * task; ++ struct wait_queue * next; ++ }; ++ ++ typedef struct select_table_struct { ++ int nr; ++ struct select_table_entry { ++ struct wait_queue wait; ++ struct wait_queue ** wait_address; ++ } entry[NR_OPEN*3]; ++ } select_table; ++ ++ #endif +*** /dev/null Sat Jul 18 22:26:09 1992 +--- linux/include/linux/limits.h Wed Jul 15 15:19:24 1992 +*************** +*** 0 **** +--- 1,16 ---- ++ #ifndef _LINUX_LIMITS_H ++ #define _LINUX_LIMITS_H ++ ++ #define NR_OPEN 32 ++ #define NR_INODE 128 ++ #define NR_FILE 128 ++ #define NR_SUPER 8 ++ #define NR_HASH 307 ++ #define NR_BUFFERS nr_buffers ++ #define BLOCK_SIZE 1024 ++ #define BLOCK_SIZE_BITS 10 ++ #define MAX_CHRDEV 16 ++ #define MAX_BLKDEV 16 ++ ++ ++ #endif +*** 0.96c.pl1/linux/include/asm/io.h Tue Jun 2 12:25:20 1992 +--- linux/include/asm/io.h Tue Jul 14 05:15:21 1992 +*************** +*** 11,23 **** + + extern void inline outb(char value, unsigned short port) + { +! __asm__ volatile ("outb %0,%1" + ::"a" ((char) value),"d" ((unsigned short) port)); + } + + extern void inline outb_p(char value, unsigned short port) + { +! __asm__ volatile ("outb %0,%1\n\t" + #ifdef REALLY_SLOW_IO + "outb %0,$0x80\n\t" + "outb %0,$0x80\n\t" +--- 11,23 ---- + + extern void inline outb(char value, unsigned short port) + { +! __asm__ __volatile__ ("outb %0,%1" + ::"a" ((char) value),"d" ((unsigned short) port)); + } + + extern void inline outb_p(char value, unsigned short port) + { +! __asm__ __volatile__ ("outb %0,%1\n\t" + #ifdef REALLY_SLOW_IO + "outb %0,$0x80\n\t" + "outb %0,$0x80\n\t" +*************** +*** 30,36 **** + extern unsigned char inline inb(unsigned short port) + { + unsigned char _v; +! __asm__ volatile ("inb %1,%0" + :"=a" (_v):"d" ((unsigned short) port)); + return _v; + } +--- 30,36 ---- + extern unsigned char inline inb(unsigned short port) + { + unsigned char _v; +! __asm__ __volatile__ ("inb %1,%0" + :"=a" (_v):"d" ((unsigned short) port)); + return _v; + } +*************** +*** 38,44 **** + extern unsigned char inline inb_p(unsigned short port) + { + unsigned char _v; +! __asm__ volatile ("inb %1,%0\n\t" + #ifdef REALLY_SLOW_IO + "outb %0,$0x80\n\t" + "outb %0,$0x80\n\t" +--- 38,44 ---- + extern unsigned char inline inb_p(unsigned short port) + { + unsigned char _v; +! __asm__ __volatile__ ("inb %1,%0\n\t" + #ifdef REALLY_SLOW_IO + "outb %0,$0x80\n\t" + "outb %0,$0x80\n\t" +*** 0.96c.pl1/linux/include/asm/memory.h Fri Apr 24 18:26:25 1992 +--- linux/include/asm/memory.h Tue Jul 14 05:15:21 1992 +*************** +*** 7,13 **** + */ + #define memcpy(dest,src,n) ({ \ + void * _res = dest; \ +! __asm__ ("cld;rep;movsb" \ + ::"D" ((long)(_res)),"S" ((long)(src)),"c" ((long) (n)) \ + :"di","si","cx"); \ + _res; \ +--- 7,13 ---- + */ + #define memcpy(dest,src,n) ({ \ + void * _res = dest; \ +! __asm__ __volatile__ ("cld;rep;movsb" \ + ::"D" ((long)(_res)),"S" ((long)(src)),"c" ((long) (n)) \ + :"di","si","cx"); \ + _res; \ +*** 0.96c.pl1/linux/include/asm/system.h Fri Apr 24 18:26:25 1992 +--- linux/include/asm/system.h Tue Jul 14 05:13:01 1992 +*************** +*** 1,5 **** + #define move_to_user_mode() \ +! __asm__ ("movl %%esp,%%eax\n\t" \ + "pushl $0x17\n\t" \ + "pushl %%eax\n\t" \ + "pushfl\n\t" \ +--- 1,5 ---- + #define move_to_user_mode() \ +! __asm__ __volatile__ ("movl %%esp,%%eax\n\t" \ + "pushl $0x17\n\t" \ + "pushl %%eax\n\t" \ + "pushfl\n\t" \ +*************** +*** 13,26 **** + "mov %%ax,%%gs" \ + :::"ax") + +! #define sti() __asm__ ("sti"::) +! #define cli() __asm__ ("cli"::) +! #define nop() __asm__ ("nop"::) + +! #define iret() __asm__ ("iret"::) + + #define _set_gate(gate_addr,type,dpl,addr) \ +! __asm__ ("movw %%dx,%%ax\n\t" \ + "movw %0,%%dx\n\t" \ + "movl %%eax,%1\n\t" \ + "movl %%edx,%2" \ +--- 13,26 ---- + "mov %%ax,%%gs" \ + :::"ax") + +! #define sti() __asm__ __volatile__ ("sti"::) +! #define cli() __asm__ __volatile__ ("cli"::) +! #define nop() __asm__ __volatile__ ("nop"::) + +! #define iret() __asm__ __volatile__ ("iret"::) + + #define _set_gate(gate_addr,type,dpl,addr) \ +! __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \ + "movw %0,%%dx\n\t" \ + "movl %%eax,%1\n\t" \ + "movl %%edx,%2" \ +*************** +*** 50,56 **** + ((limit) & 0x0ffff); } + + #define _set_tssldt_desc(n,addr,type) \ +! __asm__ ("movw $232,%1\n\t" \ + "movw %%ax,%2\n\t" \ + "rorl $16,%%eax\n\t" \ + "movb %%al,%3\n\t" \ +--- 50,56 ---- + ((limit) & 0x0ffff); } + + #define _set_tssldt_desc(n,addr,type) \ +! __asm__ __volatile__ ("movw $232,%1\n\t" \ + "movw %%ax,%2\n\t" \ + "rorl $16,%%eax\n\t" \ + "movb %%al,%3\n\t" \ +*** 0.96c.pl1/linux/include/asm/segment.h Fri Apr 24 18:26:25 1992 +--- linux/include/asm/segment.h Tue Jul 14 05:15:21 1992 +*************** +*** 94,99 **** + + extern inline void set_fs(unsigned long val) + { +! __asm__("mov %0,%%fs"::"r" ((unsigned short) val)); + } + +--- 94,99 ---- + + extern inline void set_fs(unsigned long val) + { +! __asm__ __volatile__("mov %0,%%fs"::"r" ((unsigned short) val)); + } + +*** 0.96c.pl1/linux/include/asm/irq.h Sat Jul 18 22:29:14 1992 +--- linux/include/asm/irq.h Tue Jul 14 15:22:18 1992 +*************** +*** 46,56 **** + "jmp 1f\n" \ + "1:\tjmp 1f\n" \ + "1:\tmovb $0x20,%al\n\t" \ +! "outb %al,$0xA0" \ + "jmp 1f\n" \ + "1:\tjmp 1f\n" \ + "1:\toutb %al,$0x20\n\t" + + #define IRQ_NAME2(nr) nr##_interrupt() + #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr) + +--- 46,70 ---- + "jmp 1f\n" \ + "1:\tjmp 1f\n" \ + "1:\tmovb $0x20,%al\n\t" \ +! "outb %al,$0xA0\n\t" \ + "jmp 1f\n" \ + "1:\tjmp 1f\n" \ + "1:\toutb %al,$0x20\n\t" + ++ #define UNBLK_FIRST(mask) \ ++ "inb $0x21,%al\n\t" \ ++ "jmp 1f\n" \ ++ "1:\tjmp 1f\n" \ ++ "1:\tandb $~(" #mask "),%al\n\t" \ ++ "outb %al,$0x21\n\t" ++ ++ #define UNBLK_SECOND(mask) \ ++ "inb $0xA1,%al\n\t" \ ++ "jmp 1f\n" \ ++ "1:\tjmp 1f\n" \ ++ "1:\tandb $~(" #mask "),%al\n\t" \ ++ "outb %al,$0xA1\n\t" ++ + #define IRQ_NAME2(nr) nr##_interrupt() + #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr) + +*************** +*** 70,75 **** +--- 84,94 ---- + "pushl $" #nr "\n\t" \ + "call _do_IRQ\n\t" \ + "addl $8,%esp\n\t" \ ++ "testl %eax,%eax\n\t" \ ++ "jne ret_from_sys_call\n\t" \ ++ "cli\n\t" \ ++ UNBLK_##chip(mask) \ ++ "sti\n\t" \ + "jmp ret_from_sys_call"); + + #endif +*** 0.96c.pl1/linux/net/kern_sock.h Sat May 2 22:25:46 1992 +--- linux/net/kern_sock.h Wed Jul 15 16:09:48 1992 +*************** +*** 33,39 **** + struct socket *conn; /* server socket connected to */ + struct socket *iconn; /* incomplete client connections */ + struct socket *next; +! struct task_struct **wait; /* ptr to place to wait on */ + void *dummy; + }; + +--- 33,39 ---- + struct socket *conn; /* server socket connected to */ + struct socket *iconn; /* incomplete client connections */ + struct socket *next; +! struct wait_queue **wait; /* ptr to place to wait on */ + void *dummy; + }; + +*************** +*** 52,58 **** + int *usockaddr_len, int peer); + int (*read)(struct socket *sock, char *ubuf, int size, int nonblock); + int (*write)(struct socket *sock, char *ubuf, int size, int nonblock); +! int (*select)(struct socket *sock, int which); + int (*ioctl)(struct socket *sock, unsigned int cmd, unsigned long arg); + }; + +--- 52,58 ---- + int *usockaddr_len, int peer); + int (*read)(struct socket *sock, char *ubuf, int size, int nonblock); + int (*write)(struct socket *sock, char *ubuf, int size, int nonblock); +! int (*select)(struct socket *sock, int sel_type, select_table * wait); + int (*ioctl)(struct socket *sock, unsigned int cmd, unsigned long arg); + }; + +*** 0.96c.pl1/linux/net/socket.c Thu Jul 2 00:48:29 1992 +--- linux/net/socket.c Wed Jul 15 16:09:14 1992 +*************** +*** 44,51 **** + static int sock_readdir(struct inode *inode, struct file *file, + struct dirent *dirent, int count); + static void sock_close(struct inode *inode, struct file *file); +! /*static*/ int sock_select(struct inode *inode, struct file *file, int which, +! select_table *seltable); + static int sock_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned int arg); + +--- 44,50 ---- + static int sock_readdir(struct inode *inode, struct file *file, + struct dirent *dirent, int count); + static void sock_close(struct inode *inode, struct file *file); +! static int sock_select(struct inode *inode, struct file *file, int which, select_table *seltable); + static int sock_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned int arg); + +*************** +*** 64,70 **** + + static struct socket sockets[NSOCKETS]; + #define last_socket (sockets + NSOCKETS - 1) +! static struct task_struct *socket_wait_free = NULL; + + /* + * obtains the first available file descriptor and sets it up for use +--- 63,69 ---- + + static struct socket sockets[NSOCKETS]; + #define last_socket (sockets + NSOCKETS - 1) +! static struct wait_queue *socket_wait_free = NULL; + + /* + * obtains the first available file descriptor and sets it up for use +*************** +*** 289,306 **** + return sock->ops->ioctl(sock, cmd, arg); + } + +! /*static*/ int +! sock_select(struct inode *inode, struct file *file, int which, +! select_table *seltable) + { + struct socket *sock; + + PRINTK("sock_select: inode = 0x%x, kind = %s\n", inode, +! (which == SEL_IN) ? "in" : +! (which == SEL_OUT) ? "out" : "ex"); + if (!(sock = socki_lookup(inode))) { +! printk("sock_write: can't find socket for inode!\n"); +! return -EBADF; + } + + /* +--- 288,304 ---- + return sock->ops->ioctl(sock, cmd, arg); + } + +! static int +! sock_select(struct inode *inode, struct file *file, int sel_type, select_table * wait) + { + struct socket *sock; + + PRINTK("sock_select: inode = 0x%x, kind = %s\n", inode, +! (sel_type == SEL_IN) ? "in" : +! (sel_type == SEL_OUT) ? "out" : "ex"); + if (!(sock = socki_lookup(inode))) { +! printk("sock_select: can't find socket for inode!\n"); +! return 0; + } + + /* +*************** +*** 307,325 **** + * handle server sockets specially + */ + if (sock->flags & SO_ACCEPTCON) { +! if (which == SEL_IN) { + PRINTK("sock_select: %sconnections pending\n", + sock->iconn ? "" : "no "); + return sock->iconn ? 1 : 0; + } + PRINTK("sock_select: nothing else for server socket\n"); + return 0; + } +- + /* + * we can't return errors to select, so its either yes or no. + */ +! return sock->ops->select(sock, which) ? 1 : 0; + } + + void +--- 305,328 ---- + * handle server sockets specially + */ + if (sock->flags & SO_ACCEPTCON) { +! if (sel_type == SEL_IN) { + PRINTK("sock_select: %sconnections pending\n", + sock->iconn ? "" : "no "); ++ if (sock->iconn) ++ return 1; ++ select_wait(&inode->i_wait, wait); + return sock->iconn ? 1 : 0; + } + PRINTK("sock_select: nothing else for server socket\n"); ++ select_wait(&inode->i_wait, wait); + return 0; + } + /* + * we can't return errors to select, so its either yes or no. + */ +! if (sock->ops && sock->ops->select) +! return sock->ops->select(sock, sel_type, wait); +! return 0; + } + + void +*** 0.96c.pl1/linux/net/unix.c Thu Jul 2 00:48:29 1992 +--- linux/net/unix.c Wed Jul 15 04:37:51 1992 +*************** +*** 53,59 **** + int nonblock); + static int unix_proto_write(struct socket *sock, char *ubuf, int size, + int nonblock); +! static int unix_proto_select(struct socket *sock, int which); + static int unix_proto_ioctl(struct socket *sock, unsigned int cmd, + unsigned long arg); + +--- 53,59 ---- + int nonblock); + static int unix_proto_write(struct socket *sock, char *ubuf, int size, + int nonblock); +! static int unix_proto_select(struct socket *sock, int sel_type, select_table * wait); + static int unix_proto_ioctl(struct socket *sock, unsigned int cmd, + unsigned long arg); + +*************** +*** 519,529 **** + } + + static int +! unix_proto_select(struct socket *sock, int which) + { + struct unix_proto_data *upd, *peerupd; + +! if (which == SEL_IN) { + upd = UN_DATA(sock); + PRINTK("unix_proto_select: there is%s data available\n", + UN_BUF_AVAIL(upd) ? "" : " no"); +--- 519,529 ---- + } + + static int +! unix_proto_select(struct socket *sock, int sel_type, select_table * wait) + { + struct unix_proto_data *upd, *peerupd; + +! if (sel_type == SEL_IN) { + upd = UN_DATA(sock); + PRINTK("unix_proto_select: there is%s data available\n", + UN_BUF_AVAIL(upd) ? "" : " no"); +*************** +*** 533,542 **** + PRINTK("unix_proto_select: socket not connected (read EOF)\n"); + return 1; + } +! else +! return 0; + } +! if (which == SEL_OUT) { + if (sock->state != SS_CONNECTED) { + PRINTK("unix_proto_select: socket not connected (write EOF)\n"); + return 1; +--- 533,542 ---- + PRINTK("unix_proto_select: socket not connected (read EOF)\n"); + return 1; + } +! select_wait(sock->wait,wait); +! return 0; + } +! if (sel_type == SEL_OUT) { + if (sock->state != SS_CONNECTED) { + PRINTK("unix_proto_select: socket not connected (write EOF)\n"); + return 1; +*************** +*** 544,550 **** + peerupd = UN_DATA(sock->conn); + PRINTK("unix_proto_select: there is%s space available\n", + UN_BUF_SPACE(peerupd) ? "" : " no"); +! return (UN_BUF_SPACE(peerupd) > 0); + } + /* SEL_EX */ + PRINTK("unix_proto_select: there are no exceptions here?!\n"); +--- 544,553 ---- + peerupd = UN_DATA(sock->conn); + PRINTK("unix_proto_select: there is%s space available\n", + UN_BUF_SPACE(peerupd) ? "" : " no"); +! if (UN_BUF_SPACE(peerupd) > 0) +! return 1; +! select_wait(sock->wait,wait); +! return 0; + } + /* SEL_EX */ + PRINTK("unix_proto_select: there are no exceptions here?!\n"); diff --git a/Linux-0.96/sources/system/linux-0.96c.tar.Z b/Linux-0.96/sources/system/linux-0.96c.tar.Z new file mode 100644 index 00000000..9bb606af Binary files /dev/null and b/Linux-0.96/sources/system/linux-0.96c.tar.Z differ diff --git a/Linux-0.96/sources/system/scsi.0.96a+.tar.Z b/Linux-0.96/sources/system/scsi.0.96a+.tar.Z new file mode 100644 index 00000000..529d8010 Binary files /dev/null and b/Linux-0.96/sources/system/scsi.0.96a+.tar.Z differ diff --git a/Linux-0.96/sources/system/scsi.diffs.0.96a.3.Z b/Linux-0.96/sources/system/scsi.diffs.0.96a.3.Z new file mode 100644 index 00000000..0207c8d1 Binary files /dev/null and b/Linux-0.96/sources/system/scsi.diffs.0.96a.3.Z differ diff --git a/Linux-0.96/sources/usr.bin.X11/olgx-src.tar.Z b/Linux-0.96/sources/usr.bin.X11/olgx-src.tar.Z new file mode 100644 index 00000000..bb83f43b Binary files /dev/null and b/Linux-0.96/sources/usr.bin.X11/olgx-src.tar.Z differ diff --git a/Linux-0.96/sources/usr.bin.X11/olvwm-src.tar.Z b/Linux-0.96/sources/usr.bin.X11/olvwm-src.tar.Z new file mode 100644 index 00000000..4560ed32 Binary files /dev/null and b/Linux-0.96/sources/usr.bin.X11/olvwm-src.tar.Z differ diff --git a/Linux-0.96/sources/usr.bin.X11/x11emacs.patches b/Linux-0.96/sources/usr.bin.X11/x11emacs.patches new file mode 100644 index 00000000..da834eab --- /dev/null +++ b/Linux-0.96/sources/usr.bin.X11/x11emacs.patches @@ -0,0 +1,292 @@ +*** ORIG/process.c Tue Feb 25 17:07:16 1992 +--- process.c Tue May 19 00:03:54 1992 +*************** +*** 2174,2179 **** +--- 2174,2197 ---- + return Qnil; + } + #endif /* IRIS and HAVE_SETSID */ ++ #if defined (USG) && defined (HAVE_TCATTR) ++ struct termios t; ++ switch (signo) ++ { ++ case SIGINT: ++ ioctl (XFASTINT (p->infd), TCGETS, &t); ++ send_process (proc, &t.c_cc[VINTR], 1); ++ return Qnil; ++ case SIGQUIT: ++ ioctl (XFASTINT (p->infd), TCGETS, &t); ++ send_process (proc, &t.c_cc[VQUIT], 1); ++ return Qnil; ++ case SIGTSTP: ++ ioctl (XFASTINT (p->infd), TCGETS, &t); ++ send_process (proc, &t.c_cc[VSUSP], 1); ++ return Qnil; ++ } ++ #endif /* USG and HAVE_TCATTR */ + + /* Get the pgrp using the tty itself, if we have that. + Otherwise, use the pty to get the pgrp. */ +*** ORIG/sysdep.c Tue Feb 25 17:07:30 1992 +--- sysdep.c Sun May 3 21:46:06 1992 +*************** +*** 1116,1121 **** +--- 1116,1122 ---- + #ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */ + #undef _IOFBF + #endif ++ #ifndef LINUX + #ifdef _IOFBF + /* This symbol is defined on recent USG systems. + Someone says without this call USG won't really buffer the file +*************** +*** 1124,1129 **** +--- 1125,1131 ---- + #else + setbuf (stdout, _sobuf); + #endif ++ #endif /* LINUX */ + set_terminal_modes (); + if (term_initted && no_redraw_on_reenter) + { +*** ORIG/unexec.c Tue Feb 25 17:07:00 1992 +--- unexec.c Fri May 1 00:50:16 1992 +*************** +*** 236,242 **** + + #else /* not HPUX */ + +! #if defined (USG) && !defined (IBMRTAIX) && !defined (IRIS) + static struct bhdr hdr, ohdr; + #define a_magic fmagic + #define a_text tsize +--- 236,242 ---- + + #else /* not HPUX */ + +! #if defined (USG) && !defined (IBMRTAIX) && !defined (IRIS) && !defined(LINUX) + static struct bhdr hdr, ohdr; + #define a_magic fmagic + #define a_text tsize +*** /dev/null Fri Apr 17 21:27:15 1992 +--- config.h Sun May 17 16:02:18 1992 +*************** +*** 0 **** +--- 1,217 ---- ++ /* GNU Emacs site configuration template file. ++ Copyright (C) 1988 Free Software Foundation, Inc. ++ ++ This file is part of GNU Emacs. ++ ++ GNU Emacs is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 1, or (at your option) ++ any later version. ++ ++ GNU Emacs is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with GNU Emacs; see the file COPYING. If not, write to ++ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ++ ++ /* this config.h tuned for linux 0.96 and gcc 2.11a ++ by Rick Sladkey , your mileage may vary */ ++ ++ /* Include here a s- file that describes the system type you are using. ++ See the file ../etc/MACHINES for a list of systems and ++ the names of the s- files to use for them. ++ See s-template.h for documentation on writing s- files. */ ++ #include "s-usg5-2.h" /* as close as anything */ ++ ++ /* overrides for linux versus s-usg5-2.h */ ++ ++ #undef TERMINFO /* not really SYSV */ ++ #undef COFF /* not really SYSV */ ++ #undef NOMULTIPLEJOBS /* not even used ... */ ++ #undef NONSYSTEM_DIR_LIBRARY /* use our dirent library for VFS */ ++ #undef static /* static is OK for with gcc */ ++ ++ /* just a few small changes for linux ... */ ++ ++ #define LINUX /* for differentiation */ ++ ++ /* let's see, what have we got here */ ++ ++ #define HAVE_TCATTR /* fixes ^z problems */ ++ #define HAVE_SETSID /* fixes shell problems */ ++ #define HAVE_DUP2 /* is builtin */ ++ #define HAVE_TIMEVAL /* is builtin */ ++ #define HAVE_GETTIMEOFDAY /* is builtin */ ++ #define HAVE_RENAME /* is builtin */ ++ #define HAVE_RANDOM /* is builtin */ ++ #define HAVE_SELECT /* seems to work */ ++ #define HAVE_PTYS /* mostly works */ ++ #define HAVE_CLOSEDIR /* we have a closedir */ ++ #define HAVE_GETPAGESIZE /* we now have getpagesize (0.96) */ ++ #define HAVE_VFORK /* we now have vfork (0.96) */ ++ ++ #define BSTRING /* we now have bcopy, etc. (0.96) */ ++ #define USE_UTIME /* don't have utimes */ ++ #define NO_SIOCTL_H /* don't have sioctl.h */ ++ #define SYSV_SYSTEM_DIR /* use dirent.h */ ++ #define USG_SYS_TIME /* use sys/time.h, not time.h */ ++ /* #define NBPC 4096 /* see getpagesize.h */ ++ ++ #define INTERRUPTABLE_CLOSE /* no harm if not true */ ++ #define close sys_close ++ ++ #define C_DEBUG_SWITCH -g -Dconst= ++ #define C_OPTIMIZE_SWITCH -O2 -g -Dconst= /* gcc groks -Ox */ ++ #define OLDXMENU_OPTIONS CFLAGS=-O2 EXTRA=insque.o /* doesn't work anyway */ ++ ++ #if 0 /* choose for yourself */ ++ #define SYSTEM_MALLOC /* produces smaller binary */ ++ #else ++ #define ULIMIT_BREAK_VALUE (16*1024*1024) /* ulimit not implemented */ ++ #endif ++ ++ /* misc. kludges for linux */ ++ ++ #define const /* avoids type mismatch errors */ ++ ++ #define MAXNAMLEN NAME_MAX /* missing SYSV-ism */ ++ ++ #define SIGBUS SIGSEGV /* rename to harmless work-alike */ ++ #define SIGSYS SIGSEGV /* rename to harmless work-alike */ ++ ++ #define _STDDEF_H /* defeat NULL problems */ ++ ++ #ifdef _ANSIDECL_H /* defeat DEFUN problems, arghh */ ++ #undef DEFUN ++ #else ++ #define _ANSIDECL_H ++ #endif ++ ++ #define VSWTCH VSWTC /* mis-spelling in termios.h? */ ++ #define CDEL '\0' /* missing termio-ism */ ++ ++ /* we have non-standard standard I/O (iostream) ... */ ++ ++ #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_pptr - (FILE)->_pbase) ++ ++ /* defines for linux in preparation for m-intel386.h */ ++ ++ #define DONT_DEFINE_SIGNAL /* live with the warnings */ ++ ++ /* Include here a m- file that describes the machine and system you use. ++ See the file ../etc/MACHINES for a list of machines and ++ the names of the m- files to use for them. ++ See m-template.h for info on what m- files should define. ++ */ ++ #include "m-intel386.h" ++ ++ /* overrides for linux versus m-intel386.h */ ++ ++ /* #undef NO_REMAP /* would require hacking crt0.c */ ++ ++ #define LINK_STATICALLY /* can't get shared libs to work with 0.96 */ ++ ++ #ifdef NO_REMAP ++ #ifndef emacs /* defeat some ymakefile problems */ ++ #undef i386 ++ #undef linux ++ #undef static ++ #endif ++ #define START_FILES pre-crt0.o /usr/lib/gcc-lib/i386-linux/2.1/crt0.o ++ #ifdef LINK_STATICALLY ++ #define LIBS_SYSTEM -L/usr/lib/static -lc ++ #else ++ #define LIBS_SYSTEM -L/usr/lib/shared -lc ++ #endif ++ #else ++ #undef CRT0_DUMMIES ++ #endif ++ ++ /* also note other necessary changes in the source: ++ 1) setvbuf/setbuf is (still) broken and must be commented out of sysdep.c ++ 2) process.c has a hack to get shell-mode job control working ++ (problem is related to process groups) ++ 3) unexec.c needs treatment like IRIS for a.out header ++ */ ++ ++ /* and now we return you to your standard config.h ... */ ++ ++ /* Load in the conversion definitions if this system ++ needs them and the source file being compiled has not ++ said to inhibit this. There should be no need for you ++ to alter these lines. */ ++ ++ #ifdef SHORTNAMES ++ #ifndef NO_SHORTNAMES ++ #include "../shortnames/remap.h" ++ #endif /* not NO_SHORTNAMES */ ++ #endif /* SHORTNAMES */ ++ ++ /* Define HAVE_X_WINDOWS if you want to use the X window system. */ ++ ++ #define HAVE_X_WINDOWS /* now available with 0.96 */ ++ ++ /* Define X11 if you want to use version 11 of X windows. ++ Otherwise, Emacs expects to use version 10. */ ++ ++ #ifdef HAVE_X_WINDOWS ++ #define X11 ++ #endif ++ ++ /* Define HAVE_X_MENU if you want to use the X window menu system. ++ This appears to work on some machines that support X ++ and not on others. */ ++ ++ /* #define HAVE_X_MENU */ ++ ++ /* Define `subprocesses' should be defined if you want to ++ have code for asynchronous subprocesses ++ (as used in M-x compile and M-x shell). ++ These do not work for some USG systems yet; ++ for the ones where they work, the s-*.h file defines this flag. */ ++ ++ #ifndef VMS ++ #ifndef USG ++ #define subprocesses ++ #endif ++ #endif ++ ++ /* Define USER_FULL_NAME to return a string ++ that is the user's full name. ++ It can assume that the variable `pw' ++ points to the password file entry for this user. ++ ++ At some sites, the pw_gecos field contains ++ the user's full name. If neither this nor any other ++ field contains the right thing, use pw_name, ++ giving the user's login name, since that is better than nothing. */ ++ ++ #define USER_FULL_NAME pw->pw_gecos ++ ++ /* Define AMPERSAND_FULL_NAME if you use the convention ++ that & in the full name stands for the login id. */ ++ ++ /* #define AMPERSAND_FULL_NAME */ ++ ++ /* # bytes of pure Lisp code to leave space for. ++ Note that s-vms.h and m-sun2.h may override this default. */ ++ ++ #ifndef PURESIZE ++ #ifdef HAVE_X_WINDOWS ++ #define PURESIZE 122000 ++ #else ++ #define PURESIZE 120000 ++ #endif ++ #endif ++ ++ /* Define HIGHPRI as a negative number ++ if you want Emacs to run at a higher than normal priority. ++ For this to take effect, you must install Emacs with setuid root. ++ Emacs will change back to the users's own uid after setting ++ its priority. */ ++ ++ /* #define HIGHPRI */ ++ diff --git a/Linux-0.96/sources/usr.bin.X11/xclk.tar.Z b/Linux-0.96/sources/usr.bin.X11/xclk.tar.Z new file mode 100644 index 00000000..729ce4cd Binary files /dev/null and b/Linux-0.96/sources/usr.bin.X11/xclk.tar.Z differ diff --git a/Linux-0.96/sources/usr.bin.X11/xdvi-src.tar.Z b/Linux-0.96/sources/usr.bin.X11/xdvi-src.tar.Z new file mode 100644 index 00000000..713099f2 Binary files /dev/null and b/Linux-0.96/sources/usr.bin.X11/xdvi-src.tar.Z differ diff --git a/Linux-0.96/sources/usr.bin.X11/xload.tar.Z b/Linux-0.96/sources/usr.bin.X11/xload.tar.Z new file mode 100644 index 00000000..2c52c25a Binary files /dev/null and b/Linux-0.96/sources/usr.bin.X11/xload.tar.Z differ diff --git a/Linux-0.96/sources/usr.bin.X11/xlock2-src.tar.Z b/Linux-0.96/sources/usr.bin.X11/xlock2-src.tar.Z new file mode 100644 index 00000000..e659b15c Binary files /dev/null and b/Linux-0.96/sources/usr.bin.X11/xlock2-src.tar.Z differ diff --git a/Linux-0.96/sources/usr.bin/Zoo.Fiz.note b/Linux-0.96/sources/usr.bin/Zoo.Fiz.note new file mode 100644 index 00000000..85d27728 --- /dev/null +++ b/Linux-0.96/sources/usr.bin/Zoo.Fiz.note @@ -0,0 +1,6 @@ +This is zoo and fiz from Rahul Dhesi compiled for Linux. It is a very +popular PD archiver in the Ms-Dog world. + +Roger + +cs89rdb@brunel.ac.uk diff --git a/Linux-0.96/sources/usr.bin/binsrc.Tar.Z b/Linux-0.96/sources/usr.bin/binsrc.Tar.Z new file mode 100644 index 00000000..18900314 Binary files /dev/null and b/Linux-0.96/sources/usr.bin/binsrc.Tar.Z differ diff --git a/Linux-0.96/sources/usr.bin/binutils.tar.Z b/Linux-0.96/sources/usr.bin/binutils.tar.Z new file mode 100644 index 00000000..0247d812 Binary files /dev/null and b/Linux-0.96/sources/usr.bin/binutils.tar.Z differ diff --git a/Linux-0.96/sources/usr.bin/block.tar.Z b/Linux-0.96/sources/usr.bin/block.tar.Z new file mode 100644 index 00000000..e4d805f1 Binary files /dev/null and b/Linux-0.96/sources/usr.bin/block.tar.Z differ diff --git a/Linux-0.96/sources/usr.bin/hemacs.tar.Z b/Linux-0.96/sources/usr.bin/hemacs.tar.Z new file mode 100644 index 00000000..40614b27 Binary files /dev/null and b/Linux-0.96/sources/usr.bin/hemacs.tar.Z differ diff --git a/Linux-0.96/sources/usr.bin/lha-1.00.tar.gz b/Linux-0.96/sources/usr.bin/lha-1.00.tar.gz new file mode 100644 index 00000000..6a308379 Binary files /dev/null and b/Linux-0.96/sources/usr.bin/lha-1.00.tar.gz differ diff --git a/Linux-0.96/sources/usr.bin/mtools.tar.Z b/Linux-0.96/sources/usr.bin/mtools.tar.Z new file mode 100644 index 00000000..249be077 Binary files /dev/null and b/Linux-0.96/sources/usr.bin/mtools.tar.Z differ diff --git a/Linux-0.96/sources/usr.bin/rzsz.README b/Linux-0.96/sources/usr.bin/rzsz.README new file mode 100644 index 00000000..9642169e --- /dev/null +++ b/Linux-0.96/sources/usr.bin/rzsz.README @@ -0,0 +1,24 @@ +WED Jul 29 20:02:06 MET 1992 + + Zmodem v3.18 for Linux + ~~~~~~~~~~~~~~~~~~~~~~ + Package info: 'rzsz9202.tar-z' patched with ''rzsz9202.dff.Z' + + * * * +Enter 'make' for a list of available targets ('make linux!' for a complete +installation). Please login as 'root' and ensure that the the directories +/usr/local/bin , /usr/local/lib and /usr/man/man1 exist. +The patched sources are ready to compile with GCC 2.2.2. All executables have +been successfully tested under Linux v0.96c-pl2 . + +Note: I've added an environment variable called 'RZSZLINE' that points to your +serial port device. It's a good idea to define it when you login, so put the +following statements in your ~/.profile : + RZSZLINE=/dev/ttys0 # or whatever + export RZSZLINE + +I'd like to thank Nathan Laredo and Werner Almesberger for their hints and +suggestions. + +Have fun with it. +--Fabian Mueller, fabi@imp.ch diff --git a/Linux-0.96/sources/usr.bin/rzsz9202.dff.Z b/Linux-0.96/sources/usr.bin/rzsz9202.dff.Z new file mode 100644 index 00000000..ff670028 Binary files /dev/null and b/Linux-0.96/sources/usr.bin/rzsz9202.dff.Z differ diff --git a/Linux-0.96/sources/usr.bin/rzsz9202.tar.z b/Linux-0.96/sources/usr.bin/rzsz9202.tar.z new file mode 100644 index 00000000..23cc43c9 Binary files /dev/null and b/Linux-0.96/sources/usr.bin/rzsz9202.tar.z differ diff --git a/Linux-0.96/sources/usr.bin/selection-1.3.tar.Z b/Linux-0.96/sources/usr.bin/selection-1.3.tar.Z new file mode 100644 index 00000000..bbb0ec44 Binary files /dev/null and b/Linux-0.96/sources/usr.bin/selection-1.3.tar.Z differ diff --git a/Linux-0.96/sources/usr.bin/setserial.c b/Linux-0.96/sources/usr.bin/setserial.c new file mode 100644 index 00000000..1bfa00d1 --- /dev/null +++ b/Linux-0.96/sources/usr.bin/setserial.c @@ -0,0 +1,207 @@ +From owner-linux-activists@joker.cs.hut.fi Tue Jul 14 05:42:55 1992 +Received: from funet.fi by lazy.qt.IPA.FhG.de with SMTP + (5.61+/IDA-1.2.8/gandalf.2) id AA09550; Tue, 14 Jul 92 05:42:52 +0200 +Received: from santra.hut.fi by funet.fi with SMTP (PP) id <24104-0@funet.fi>; + Tue, 14 Jul 1992 06:41:04 +0300 +Received: from joker.cs.hut.fi by santra.hut.fi (5.65c/8.0/TeKoLa) id AA24830; + Tue, 14 Jul 1992 06:39:57 +0300 +Received: by joker.cs.hut.fi (5.65b/6.8/S-TeKoLa) id AA08793; + Tue, 14 Jul 92 06:39:34 +0300 +Received: from relay2.UU.NET by joker.cs.hut.fi (5.65b/6.8/S-TeKoLa) id AA08245; + Tue, 14 Jul 92 06:33:44 +0300 +Received: from world.std.com by relay2.UU.NET + with SMTP (5.61/UUNET-internet-primary) id AA00942; + Mon, 13 Jul 92 23:34:03 -0400 +Received: by world.std.com (5.61+++/Spike-2.0) id AA12321; + Mon, 13 Jul 92 23:33:37 -0400 +Date: Mon, 13 Jul 92 23:33:37 -0400 +From: jrs@world.std.com (Rick Sladkey) +Message-Id: <9207140333.AA12321@world.std.com> +Sender: owner-linux-activists@niksula.hut.fi +To: linux-activists@niksula.hut.fi +X-Note1: Remember to put 'X-Mn-Key: normal' to your mail body or header +Subject: setserial.c +X-Mn-Key: NORMAL + +Here is a program that uses the recent serial ioctl calls to change +the port or IRQ of a serial device. I use it to change /dev/ttys3 to +IRQ 5. You must be root to run it or make it setuid to root. Please +be careful when specifying port numbers! + +If you get the message "Device busy" it means that you have another +serial port currently using that IRQ or that you have specified an IRQ +that is used by another hardware device such as the keyboard or a hard +disk controller. + +IRQs 2, 3, 4, and 5 are typically available and can often be set by +DIP switches or jumpers on your serial card. With 0.96c patchlevel 1 +or higher you can use any IRQ that your card lets you configure and +that is unused by Linux. If you are not sure, go ahead and try. +Linux will let you know. + +Some examples: + +# setserial +usage: setserial serial-device [ port irq ] +for example: setserial /dev/ttys3 0x03e8 5 +Use a leading '0x' for hex numbers. +CAUTION: Using an invalid port can lock up your machine! +# setserial /dev/ttys3 +/dev/ttys3, Type: 16450, Line: 2, Port: 0x03e8, IRQ: 4 +# setserial /dev/ttys3 0 5 +/dev/ttys3, Type: 16450, Line: 2, Port: 0x03e8 (was 0x03e8), IRQ: 5 (was 4) +# + +There is a minor bug that prevents this from working with 0.96c +patchlevel 1. Use unpatched 0.96c, wait for 0.96c patchlevel 2, or +apply this patch. + +*** linux/kernel/chr_drv/serial.c.orig Sun Jul 12 23:48:13 1992 +--- linux/kernel/chr_drv/serial.c Mon Jul 13 19:28:37 1992 +*************** +*** 416,421 **** +--- 416,422 ---- + retval = request_irq(new_irq,handler); + if (retval) + return retval; ++ info->irq = new_irq; + free_irq(irq); + } + cli(); + +I have uploaded setserial.tar.Z to banjo and tsx-11. + +Rick Sladkey +jrs@world.std.com +----- +/* setserial.c - get/set Linux serial port info - rick sladkey */ + +/* compile with something like: + + CC = gcc + CFLAGS = -nostdinc -I/usr/src/linux/include -I/usr/include + + setserial: setserial.c + $(CC) $(CFLAGS) setserial.c -o setserial + +*/ + +#include +#include +#include +#include + +#include +#include + +char *progname; + +struct serial_type_struct { + int id; + char *name; +} serial_type_tbl[] = { + PORT_UNKNOWN, "unknown", + PORT_8250, "8250", + PORT_16450, "16450", + PORT_16550, "16550", + PORT_16550A, "16550A", + -1, NULL +}; + +char *serial_type(int id) +{ + int i; + + for (i = 0; serial_type_tbl[i].id != -1; i++) + if (id == serial_type_tbl[i].id) + return serial_type_tbl[i].name; + return "undefined"; +} + +int atonum(char *s) +{ + int n; + + while (*s == ' ') + s++; + if (strncmp(s, "0x", 2) == 0 || strncmp(s, "0X", 2) == 0) + sscanf(s + 2, "%x", &n); + else if (s[0] == '0' && s[1]) + sscanf(s + 1, "%o", &n); + else + sscanf(s, "%d", &n); + return n; +} + +void getserial(char *device, int fd) +{ + struct serial_struct serinfo; + + if (ioctl(fd, TIOCGSERIAL, &serinfo) < 0) { + perror("Cannot get serial info"); + exit(1); + } + printf("%s, Type: %s, Line: %d, Port: 0x%.4x, IRQ: %d\n", + device, serial_type(serinfo.type), + serinfo.line, serinfo.port, serinfo.irq); +} + +void setserial(char *device, int fd, int port, int irq) +{ + struct serial_struct old_serinfo, new_serinfo; + + if (ioctl(fd, TIOCGSERIAL, &old_serinfo) < 0) { + perror("Cannot get serial info"); + exit(1); + } + new_serinfo = old_serinfo; + new_serinfo.port = port; + new_serinfo.irq = irq; + if (ioctl(fd, TIOCSSERIAL, &new_serinfo) < 0) { + perror("Cannot set serial info"); + exit(1); + } + if (ioctl(fd, TIOCGSERIAL, &new_serinfo) < 0) { + perror("Cannot get serial info"); + exit(1); + } + printf("%s, Type: %s, Line: %d, " + "Port: 0x%.4x (was 0x%.4x), IRQ: %d (was %d)\n", + device, serial_type(new_serinfo.type), + new_serinfo.line, new_serinfo.port, old_serinfo.port, + new_serinfo.irq, old_serinfo.irq); +} + +main(int argc, char **argv) +{ + char *device; + int fd; + + progname = argv[0]; + if (argc == 1) { + fprintf(stderr, "usage: %s serial-device [ port irq ]\n", + progname); + fprintf(stderr, "for example: %s /dev/ttys3 0x03e8 5\n", + progname); + fprintf(stderr, "Use a leading '0x' for hex numbers.\n"); + fprintf(stderr, "CAUTION: " + "Using an invalid port can lock up your machine!\n"); + exit(1); + } + device = argv[1]; + if ((fd = open(device, O_RDWR)) < 0) { + perror("Cannot open serial device"); + exit(1); + } + if (argc == 2) + getserial(device, fd); + else if (argc == 4) + setserial(device, fd, atonum(argv[2]), atonum(argv[3])); + else { + fprintf(stderr, "%s: wrong number of arguments\n", progname); + exit(1); + } + exit(0); +} + + diff --git a/Linux-0.96/sources/usr.bin/shutl-1.6Bsrc.tar.Z b/Linux-0.96/sources/usr.bin/shutl-1.6Bsrc.tar.Z new file mode 100644 index 00000000..90ccef2d Binary files /dev/null and b/Linux-0.96/sources/usr.bin/shutl-1.6Bsrc.tar.Z differ diff --git a/Linux-0.96/sources/usr.bin/txtutl-1.3src.tar.Z b/Linux-0.96/sources/usr.bin/txtutl-1.3src.tar.Z new file mode 100644 index 00000000..495a0dc7 Binary files /dev/null and b/Linux-0.96/sources/usr.bin/txtutl-1.3src.tar.Z differ diff --git a/Linux-0.96/sources/usr.bin/ue-man.tar.Z b/Linux-0.96/sources/usr.bin/ue-man.tar.Z new file mode 100644 index 00000000..1fd780d5 Binary files /dev/null and b/Linux-0.96/sources/usr.bin/ue-man.tar.Z differ diff --git a/Linux-0.96/sources/usr.bin/ue311c-src.tar.Z b/Linux-0.96/sources/usr.bin/ue311c-src.tar.Z new file mode 100644 index 00000000..05ba93b0 Binary files /dev/null and b/Linux-0.96/sources/usr.bin/ue311c-src.tar.Z differ diff --git a/Linux-0.96/sources/usr.bin/unzip.README b/Linux-0.96/sources/usr.bin/unzip.README new file mode 100644 index 00000000..7a8c1515 --- /dev/null +++ b/Linux-0.96/sources/usr.bin/unzip.README @@ -0,0 +1,14 @@ +Sun Jul 26 18:02:06 1992 + + UNZIP (v4.2) / ZIPINFO (v0.96k BETA) / SHIP (1.1) for Linux + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Package info: 'unzipsrc.tar.Z' patched with 'unzipsrc.dff.Z' + (available on banjo.concert.net /pub/Linux/Incoming) + * * * +Enter 'sh Make_linux' for a complete installation. Please login as 'root' and +ensure the the directories /usr/local/bin and /usr/man/man1 exist. The sources +are ready to compile with GCC 2.2.2; all executables have been successfully +tested under Linux v0.96c-pl2. + +Regards, +--Fabian Mueller, fabi@imp.ch diff --git a/Linux-0.96/sources/usr.bin/unzip.tar.Z b/Linux-0.96/sources/usr.bin/unzip.tar.Z new file mode 100644 index 00000000..157c337d Binary files /dev/null and b/Linux-0.96/sources/usr.bin/unzip.tar.Z differ diff --git a/Linux-0.96/sources/usr.bin/zip10c.README b/Linux-0.96/sources/usr.bin/zip10c.README new file mode 100644 index 00000000..9734085f --- /dev/null +++ b/Linux-0.96/sources/usr.bin/zip10c.README @@ -0,0 +1,24 @@ +Sat Jul 25 20:47:04 MET 1992 + + Zip 1.0 w/ encryption code + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + Package info: 'zip10c_src.tar.Z.' + (available on banjo.concert.net /pub/Linux/Incoming) + + + o Revised for GCC 2.2.2 (tested under Linux 0.96c-pl2) + o Added code for non-export version (now zip supports password + encryption/decryption, please read 'README.crypt'!) + NOTE: To unzip an encrypted Zipfile you have to use 'zipcloak' first + (enter 'zipcloak -h' for a short help) + o Installation: + (1) Unpack the sources + (2) Enter 'make linux' in the 'Zip10c.src' directory + (3) Move the executables and the man page to the + appropriate directories: + for i in zip zipnote zipcloak zipsplit ship ; \ + do mv $i /usr/local/bin ; done ; \ + mv zip.1 /usr/man/man1 + +Regarts, +--Fabian Mueller, fabi@imp.ch diff --git a/Linux-0.96/sources/usr.bin/zip10c.tar.gz b/Linux-0.96/sources/usr.bin/zip10c.tar.gz new file mode 100644 index 00000000..85db0a29 Binary files /dev/null and b/Linux-0.96/sources/usr.bin/zip10c.tar.gz differ diff --git a/Linux-0.96/sources/usr.bin/zoo.tar.gz b/Linux-0.96/sources/usr.bin/zoo.tar.gz new file mode 100644 index 00000000..bfeaba6b Binary files /dev/null and b/Linux-0.96/sources/usr.bin/zoo.tar.gz differ diff --git a/Linux-0.96/sources/usr.games/calendar.tar.Z b/Linux-0.96/sources/usr.games/calendar.tar.Z new file mode 100644 index 00000000..1424e7f3 Binary files /dev/null and b/Linux-0.96/sources/usr.games/calendar.tar.Z differ diff --git a/Linux-0.96/sources/usr.games/dungeon.tar.Z b/Linux-0.96/sources/usr.games/dungeon.tar.Z new file mode 100644 index 00000000..a59c520e Binary files /dev/null and b/Linux-0.96/sources/usr.games/dungeon.tar.Z differ diff --git a/Linux-0.96/sources/usr.games/gnuchess-3.1.tar.Z b/Linux-0.96/sources/usr.games/gnuchess-3.1.tar.Z new file mode 100644 index 00000000..ce85d747 Binary files /dev/null and b/Linux-0.96/sources/usr.games/gnuchess-3.1.tar.Z differ diff --git a/Linux-0.96/sources/usr.games/hangman.tar.Z b/Linux-0.96/sources/usr.games/hangman.tar.Z new file mode 100644 index 00000000..fb590161 Binary files /dev/null and b/Linux-0.96/sources/usr.games/hangman.tar.Z differ diff --git a/Linux-0.96/sources/usr.games/lander-src.tar.Z b/Linux-0.96/sources/usr.games/lander-src.tar.Z new file mode 100644 index 00000000..ef072bbc Binary files /dev/null and b/Linux-0.96/sources/usr.games/lander-src.tar.Z differ diff --git a/Linux-0.96/sources/usr.games/life.tar.Z b/Linux-0.96/sources/usr.games/life.tar.Z new file mode 100644 index 00000000..4ab4eeec Binary files /dev/null and b/Linux-0.96/sources/usr.games/life.tar.Z differ diff --git a/Linux-0.96/sources/usr.games/moria.tar.Z b/Linux-0.96/sources/usr.games/moria.tar.Z new file mode 100644 index 00000000..d7ea5ea7 Binary files /dev/null and b/Linux-0.96/sources/usr.games/moria.tar.Z differ diff --git a/Linux-0.96/sources/usr.games/rain.tar.Z b/Linux-0.96/sources/usr.games/rain.tar.Z new file mode 100644 index 00000000..49da97e0 Binary files /dev/null and b/Linux-0.96/sources/usr.games/rain.tar.Z differ diff --git a/Linux-0.96/sources/usr.games/rogue.tar.Z b/Linux-0.96/sources/usr.games/rogue.tar.Z new file mode 100644 index 00000000..752af2c6 Binary files /dev/null and b/Linux-0.96/sources/usr.games/rogue.tar.Z differ diff --git a/Linux-0.96/sources/usr.games/sokoban-src.tar.Z b/Linux-0.96/sources/usr.games/sokoban-src.tar.Z new file mode 100644 index 00000000..2654ef96 Binary files /dev/null and b/Linux-0.96/sources/usr.games/sokoban-src.tar.Z differ diff --git a/Linux-0.96/sources/usr.games/tetris-src.tar.Z b/Linux-0.96/sources/usr.games/tetris-src.tar.Z new file mode 100644 index 00000000..c378fc75 Binary files /dev/null and b/Linux-0.96/sources/usr.games/tetris-src.tar.Z differ diff --git a/Linux-0.96/sources/usr.games/tetris.tar.Z b/Linux-0.96/sources/usr.games/tetris.tar.Z new file mode 100644 index 00000000..9f849a0f Binary files /dev/null and b/Linux-0.96/sources/usr.games/tetris.tar.Z differ diff --git a/Linux-0.96/sources/usr.games/torus.tar.Z b/Linux-0.96/sources/usr.games/torus.tar.Z new file mode 100644 index 00000000..56e57dcb Binary files /dev/null and b/Linux-0.96/sources/usr.games/torus.tar.Z differ diff --git a/Linux-0.96/sources/usr.games/worms.tar.Z b/Linux-0.96/sources/usr.games/worms.tar.Z new file mode 100644 index 00000000..3d0bf729 Binary files /dev/null and b/Linux-0.96/sources/usr.games/worms.tar.Z differ diff --git a/Linux-0.96/sources/usr.games/yahtzee.tar.Z b/Linux-0.96/sources/usr.games/yahtzee.tar.Z new file mode 100644 index 00000000..0945134a Binary files /dev/null and b/Linux-0.96/sources/usr.games/yahtzee.tar.Z differ