home *** CD-ROM | disk | FTP | other *** search
- /* McFree v2.1 by Mack Lifeguard. This program is hereby placed in the
- * public domain. You can use it for whatever purpose you like, just don't
- * hold me responsible for any problems it may cause. */
-
- /* This program is a very simple but interesting example of how you can
- * use the AmigaDOS libraries to cut your executables' size in half. When
- * compiling this program be sure to link with "amiga.lib", since the
- * sprintf() function in amiga.lib uses the internal ROM's printf() function.
- * Thus, you're program is now 3k smaller! Be warned, some features of the
- * regular sprintf() do not work 100% on the amiga.lib sprintf(). Mainly you
- * are limited to only 140 bytes of the final outputting string (anything
- * above that and you get an instant guru), and you can't use the "%.*"
- * qualifier. But for small programs like these, the sprintf() in amiga.lib
- * works great. Again, you must include "amiga.lib" in your LINK list. If you
- * are using SAS C, then just go to scopts and enter "amiga.lib" in the
- * Libraries/Objects section under the Link gadget. */
-
- /* Many more space-saving techniques are used. Primarily they are
- * compiling options. I won't go into detail on how they work, but you can
- * see for yourself the settings in the included SCOPTIONS file. */
-
- /* If you compile this program using standard SAS C options, you will get
- * an executable of size 6619 bytes. Using the included SCOPTIONS file you
- * will get a filesize of 1688. A considerable difference! */
-
- #include <stdio.h>
- #include <dos.h>
- #include <string.h>
- #include <stdlib.h>
- #include <proto/dos.h> /* We use pragmas, so no need for opening libraries.
- * The pragmas in <proto/dos.h> automatically call
- * each dos function directly. */
-
- void errorf(char *text);
- char out[80], *p;
-
- void main(int argc,char *argv[])
- {
-
- /* We use the external argc variable to gauge the number of arguments. */
- /* Argc always returns at least a value of 1 (one). */
-
- __aligned struct InfoData info; /* Just to be safe, use a 4 byte boundary. */
- int x,size=0;
- BPTR lock;
-
- for (p=out; p<&out[80]; p++)
- *p=NULL;
-
- Write(Output(), "\nMcFree v2.1 by Mack Lifeguard\n\n",32);
-
- /* By using the Output() device, in combination with Write(), the program
- * becomes considerably smaller. Instead of using C's printf(), which takes
- * up an additional 3k. */
-
-
- if (argc==1)
- Write(Output(),"USAGE: McFree <Volume1> ... [Volume29]\n\n",40);
-
- /* As mentioned earlier, if there is only one argument (argc==1), then the
- * user did not input any parameters, so we send a message and exit. */
-
-
- for (x=1;x<argc;x++)
- {
-
- /* OK, so the user entered some arguments, lets check to see if they
- * are valid I/O devices, then we calculate their available free
- * storage. NOTE: This is an approximation based on number of blocks
- * used. The exact free storage can only be calculated by going in and
- * adding up each individual file size. By using blocks to calculate,
- * you may be off by a few bytes or so, but you can get the information
- * in a few CPU cycles, without scanning the entire device. */
-
-
- /* Now, lets check to see if we can get a Lock() on the device. */
-
- if ( (lock=Lock (argv[x], ACCESS_READ))==NULL)
- errorf(argv[x]); /* No deal, lets send an error message and continue. */
- else
- {
-
- /* Target is locked! But we're not through yet, lets be extra safe and
- * check to see if we can get a succesful Info() on it. */
-
- if ( !Info(lock,&info) )
- errorf(argv[x]); /* We send an error message but continue loop. */
- else
- {
-
- /* Here is the main calculation part of the program. The Info()
- * function from Amigados has filled our file I/O structure.
- * Remember? The one we aligned on a 4 byte boundary? OK, so now
- * we simply do some multiplication and substraction. The labels
- * should be self-explanatory, we are merely subtracting the used
- * blocks from the available blocks. Then we just multiply the
- * result by the number of bytes in each block. Keep in mind, not
- * all devices have the same number of bytes per block! */
-
- size=(info.id_NumBlocks - info.id_NumBlocksUsed) * info.id_BytesPerBlock;
-
- sprintf(out, "Drive %s has %ld bytes free. \n",argv[x],size);
-
- Write(Output(), out, strlen(out));
- }
- UnLock(lock); /* Always Unlock() what you Lock. If you don't, then
- * you will get an "Object In Use" error the next
- * time you try to access a locked file/device. */
- }
- } /* End of main for loop. */
-
- _exit(0); /* Always exit with 0 on success. */
-
- /* NOTE: I used the special _exit() function (notice the
- * underscore) because the normal exit() function frees memory and
- * closes files for you. However, since we are not using standard C
- * I/O, that is, we are using AmigaDOS functions from libraries,
- * then we really don't need the features of the regular exit().
- * The special _exit() simply returns control to the operating
- * system, without freeing memory or closing files, WE are expected
- * to do that. I use this function because it saves about 2k. */
- }
-
- void errorf(char *text)
- {
- sprintf(out, ">>Error reading volume: \"%.20s\"\n",text);
-
- /* Notice how I used the special sprintf() quailifier "%.20s", this
- * gurantees that a MAXIMUM of 20 characters will be used in the final
- * string. Any characters after 20 are simply ignored in the conversion.
- * This is just a safeguard against breaking the 140 byte limit on the
- * special amiga.lib sprintf() function. If we were using the standard
- * C sprintf() then there wouldn't be any need for this check. */
-
- Write(Output(), out, strlen(out) );
- }
-
-
-
- /*
- CONTACT INFO
- =-=-=-=-=-=-
-
- If you have any questions, bug reports, suggestiongs, you can contact me at
- the following:
-
- Hangar 18: (713) 488-3055
- International Chaos: (713) 999-3640
- Complex Corrosion: (612) 773-0522 [4 nodes]
- Danse Macabre: (713) 324-1165
-
- -Mack Lifeguard/Dual Crew-Shining
-
- */
-
-