home *** CD-ROM | disk | FTP | other *** search
- /* FIT.C : Copyright 1990 Turgut Kalfaoglu, 1378 Sokak 8/10,Izmir, Turkey.
-
- This program will attempt to fit as many files as it can onto a given disk.
- It does this by first copying a large file, and then selecting the file
- that would best fit in the remaining space. The best fit search is not
- 'great' and there is room for improvement. Please send me your version
- so that we can distribute the 'best' version..
-
- I can be reached at <TURGUT@TREARN.BITNET>.
- Compilable under Microsoft C (R) 6.0, for MS-DOS 3.3
- Make sure to link it with SETARGV.OBJ
- Regards, -Turgut Kalfaoglu 10/10/1990
-
- Usage:
- FIT <wildcard specification> destination_drive
-
- Examples:
- FIT *.EXE *.DOC \SOMEDIR\*.TXT A:
- FIT *.* B:\
- */
- #include <io.h>
- #include <fcntl.h>
- #include <sys\types.h>
- #include <sys\stat.h>
- #include <dos.h>
- #include <string.h>
- #include <limits.h>
- #include <errno.h>
- #include <stdio.h>
- #include <malloc.h>
-
- char *filename[1024];
- unsigned long filesize[1024];
-
- char destination; /* drive letter */
- unsigned num_of_files; /* ..left to copy */
- unsigned total_files;
- unsigned long bytesfree;
- unsigned short disk_empty; /* flag to state that it's a blank diskette */
-
- void disp_help();
- unsigned long learn_drive();
- void change_disks();
- int pick_file();
- unsigned load_file_info();
- int copyfile(unsigned int);
- void fatal(char *);
-
- main(int argc, char *argv[]) {
- int i;
- char blurb[255];
-
- if (argc<3) disp_help();
- /* record filenames and sizes */
- total_files = num_of_files = load_file_info(argc,argv);
-
- destination = toupper(argv[argc-1][0]);
- bytesfree = learn_drive();
-
- while (num_of_files > 0) {
- i=pick_file();
- if (i == -1) {
- change_disks();
- continue; }
- if (copyfile(i) != 0) {
- strcpy(blurb,"Error copying");
- strcat(blurb,filename[i]);
- fatal(blurb); }
- filename[i][0] = 0;
- num_of_files--;}
- }
-
- /* we choose a file among those that we have left, and return its number
- */
-
- int pick_file() {
- int i;
- unsigned long leaves=ULONG_MAX;
- long diff; /* can be - */
- int best=-1;
-
- /* we try to find the file that would leave the least amount of space
- on disk */
-
- bytesfree = learn_drive();
-
- for (i=0;i<total_files;i++) {
- if (filename[i][0] == 0) continue;
- if (disk_empty && (filesize[i]>bytesfree)) {
- printf("%s is larger than your diskette size - skipping\n",filename[i]);
- filename[i][0] = 0;
- num_of_files--;
- continue; }
- diff = bytesfree - filesize[i];
- if (diff<0L || diff > leaves) continue;
- best = i;
- leaves = bytesfree - filesize[i]; }
-
- return (best);
- }
-
-
- void change_disks() {
- char c;
- printf("Insert new diskette in drive %c: and hit any key\n",destination);
- c = getch();
- }
-
- /* here we copy a given file to destination */
- int copyfile(unsigned int index) {
- int h1,h2,i;
- char dest[80], fn[80], *buff;
- unsigned count = 0xff00;
- char *buf;
-
- h1 = open(filename[index],O_RDONLY | O_BINARY);
- if (h1 == -1) {
- strcpy(dest,"copyfile: Cannot open ");
- strcat(dest,filename[index]);
- fatal(dest); }
-
- i = strlen(filename[index]);
- while (i>-1) {
- if (filename[index][i] == '\\') break;
- i--; }
-
- if (i>-1)
- strcpy(fn,&filename[index][i+1]);
- else
- strcpy(fn,filename[index]);
-
- dest[0] = destination;
- dest[1] = 0;
- strcat(dest,":");
- strcat(dest,fn);
-
- printf("%s (%lu bytes)\n",filename[index],filesize[index]);
- h2 = open(dest,O_CREAT | O_BINARY | O_WRONLY, S_IREAD | S_IWRITE);
- if (h2 == -1) {
- strcat(dest," - file cannot be opened.");
- fatal(dest); }
-
- if (filesize[index] < count)
- count = (int)filesize[index];
-
- if( (buf = (char *)malloc( (size_t)count )) == NULL ) {
- count = _memmax();
- if( (buf = (char *)malloc( (size_t)count )) == NULL )
- return ENOMEM; }
-
- /* Read-write until there's nothing left. */
- while( !eof( h1 ) ) {
- /* Read and write input. */
- if( (count = read( h1, buf, count )) == -1 )
- return errno;
- if( (count = write( h2, buf, count )) == - 1 )
- return errno; }
-
- /* Close files and release memory. */
- close( h1 );
- close( h2 );
- free( buf );
- return 0;
- }
-
- /* here we load the filenames and sizes into filename and filesize arrayws
- */
- unsigned load_file_info(int num,char *names[]) {
- int handle;
- int file=0;
- unsigned long totbytes=0L;
- unsigned long fsize;
-
- num -= 2; /* we don't want the drive letter */
- for (;num>0;num--) {
- handle = open(names[num],O_BINARY | O_RDONLY);
- fsize = filelength(handle);
- close(handle);
-
- if (fsize<0L) {
- printf("Error learning size of %s - file ignored.\n",names[num]);
- continue; }
-
- if (fsize>3500000L) continue;
-
- totbytes += fsize;
- filename[file] = malloc(sizeof(char) * strlen(names[num])+1);
- filesize[file] = fsize;
-
- if (filename[file] == NULL)
- fatal("Out of memory during load_file_info");
-
- strcpy(filename[file],names[num]);
- file++;
- }
- printf("%lu bytes in %u files.\n",totbytes,file);
- return(file);
- }
-
- unsigned long learn_drive() {
- unsigned int drivenum;
- struct diskfree_t space;
- unsigned long free,total;
-
- drivenum=destination - 'A' +1 ;
- disk_empty = 0;
- _dos_getdiskfree(drivenum,&space);
- free = (long) space.avail_clusters * space.sectors_per_cluster * space.bytes_per_sector;
- total = (long) space.total_clusters * space.sectors_per_cluster * space.bytes_per_sector;
- disk_empty = (total - free) < 1024;
- return (free);
- }
-
- void disp_help() {
- puts("FIT V1.0:(C)1990 Turgut Kalfaoglu,1378 Sok 8/10,Izmir 35210,Turkey\n");
- puts("FIT copies selected files onto diskettes so that they would take up the");
- puts("least number of diskettes.\n");
- puts("Usage: FIT wildcard_file_specs destination_drive");
- puts("Example: FIT *.* \\*.COM A:\n");
- puts("This program is user-supported. If you find it useful, PLEASE");
- puts("send $10 to the above address. Thank you!");
- exit(1); }
-
- void fatal(char *blurb) {
- puts(blurb);
- exit(2); }
-
-