home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / c / sortdir.arc / SORTDIR.C
Text File  |  1988-07-28  |  6KB  |  197 lines

  1. /***********************************************************************
  2.     SORTDIR.C
  3.     (c) Rex Conn 12/10/84
  4.  
  5. SORTDIR does a physical sort of your disk directory.  It will perform
  6. either a disk-based sort (for the root directory) or a file sort (for
  7. subdirectories).  It requires DOS 2.0/2.1 to run, and should handle non-
  8. standard media ok.  (I've tested it on a Bernoulli Box and on quad
  9. density diskettes, but if you have strange media, test SORTDIR before
  10. extensive use.)  SORTDIR was created using Computer Innovations C86.
  11.  
  12. SORTDIR will sort system files first, then hidden files, then the volume
  13. name, then any subdirectory names, and finally the normal files, all in
  14. straight ASCII sequence order.
  15.  
  16. To run, just type SORTDIR at the DOS prompt.  There are no options;
  17. SORTDIR will only sort your current directory.
  18.  
  19. Good luck, and use at your own risk!
  20.  
  21. p.s.:  SORTDIR will NOT work with DOS 3.0 and DOS 3.1
  22.  
  23. ************************************************************************/
  24.  
  25. #include "stdio.h"
  26.  
  27. /* structure for directory entries */
  28. struct dnode {
  29.     unsigned char att;
  30.     unsigned char direntry[32];
  31. } *dir[1024];
  32.  
  33. /* FCB structure */
  34. struct filecontrol {
  35.     unsigned char extended[7];
  36.     unsigned char drive[1];
  37.     unsigned char filename[11];
  38.     int blocknum;
  39.     int lrecsize;
  40.     long filesize;
  41.     int fdate;
  42.     unsigned char reserved[10];
  43.     unsigned char lrecnum;
  44.     long recnum;
  45. } fcb;
  46.  
  47. struct regval srv,rrv;
  48. struct segments segregs;
  49.  
  50. unsigned char buf[80],*ptr,buffer[512],bdos(),*strrchr(),*malloc();
  51.  
  52. int    i,j,n,nextfree;
  53. int    dirsector,numsectors,disk;
  54.  
  55. /* comparison routine for QSORT */
  56. comp(a,b)
  57. unsigned char **a,**b;
  58. {
  59.     return strcmp(*a,*b);
  60. }
  61.  
  62. main()
  63. {
  64.     bdos(9,"Sortdir ver. 1.1\r\n$");
  65.     buf[0] = '\\';
  66.     segread(&segregs);
  67.     srv.ds = segregs.sds;
  68.     /* get current directory */
  69.     srv.ah = 0x47;
  70.     srv.dx = 0;
  71.     srv.si = buf+1;
  72.     sysint21(&srv,&rrv);
  73.     /* if in root, sort disk */
  74.     if (buf[1] == '\0') {
  75.         /* determine type of disk to get directory */
  76.         disk = bdos(0x19);
  77.         srv.ah = 0x32;
  78.         srv.dx = 0;
  79.         sysint21(&srv,&rrv);
  80.         dirsector = peek(rrv.bx+16,rrv.ds);
  81.         i = peek(rrv.bx+9,rrv.ds);
  82.         numsectors = (i % 32) ? (i / 32) + 1 : i / 32;
  83.         /* read directory block from disk */
  84.         nextfree = 0;
  85.         for (i=dirsector;i<dirsector + numsectors;i++) {
  86.             getsect(disk,buffer,0,i,1);
  87.             for (n=0;n<512;n+=32) {
  88.                 if (buffer[n] == '\0') {
  89.                     i = dirsector + numsectors;
  90.                     break;
  91.                 }
  92.                 dir[nextfree] = malloc(sizeof(struct dnode));
  93.                 movmem(buffer+n,dir[nextfree]->direntry,32);
  94.                 subsort(nextfree);
  95.                 nextfree++;
  96.             }
  97.         }
  98.         /* sort the block */
  99.         qsort(dir,nextfree,PTRSIZE,comp);
  100.         /* write it back to the disk */
  101.         for (j=0,i=dirsector;i<dirsector + numsectors;i++) {
  102.             for (n=0;n<512;n++)
  103.                 buffer[n] = '\0';
  104.             for (n=0;n<512;n+=32) {
  105.                 movmem(dir[j]->direntry,buffer+n,32);
  106.                 if (++j >= nextfree)
  107.                     break;
  108.             }
  109.             getsect(disk,buffer,1,i,1);
  110.             if (j >= nextfree)
  111.                 break;
  112.         }
  113.         srv.ah = 0x32;            /* force BPB read */
  114.         srv.dx = 0;            /* default disk?? */
  115.         sysint21(&srv,&rrv);
  116.         pokeb(rrv.bx+23,rrv.ds,-1);
  117.         sysint21(&srv,&rrv);
  118.     } else {        /* else sort subdirectory file */
  119.         srv.ah = 0x3B;        /* change directory */
  120.         srv.dx = "..";
  121.         sysint21(&srv,&rrv);
  122.         fcb.extended[0] = 0xFF;
  123.         fcb.extended[6] = 16;
  124.         ptr = strrchr(buf,'\\') + 1;
  125.         for (i=0;i<11;i++) {
  126.             if ((*ptr == '.') && (i == 8))
  127.                 ptr++;
  128.             if ((*ptr) && (*ptr != '.'))
  129.                 fcb.filename[i] = *ptr++;
  130.             else
  131.                 fcb.filename[i] = ' ';
  132.         }
  133.         srv.ah = 0x0F;        /* open the file */
  134.         srv.dx = &fcb;
  135.         sysint21(&srv,&rrv);
  136.         if (rrv.al == 0xFF)
  137.             error("Can't open subdirectory\n$");
  138.         fcb.lrecsize = 32;    /* directory entry size */
  139.         fcb.lrecnum = 0;
  140.  
  141.         fcb.filesize = 32768;
  142.         bdos(0x1A,buffer);
  143.         nextfree = 0;
  144.         srv.ah = 0x14;        /* sequential read */
  145.         do {
  146.             sysint21(&srv,&rrv);
  147.             if (buffer[0] == '\0')    /* end of directory */
  148.                 break;
  149.             dir[nextfree] = malloc(sizeof(struct dnode));
  150.             movmem(buffer,dir[nextfree]->direntry,32);
  151.             subsort(nextfree);
  152.             nextfree++;
  153.         } while (rrv.al == 0);
  154.         qsort(dir,nextfree,PTRSIZE,comp);
  155.         fcb.blocknum = 0;        /* reset block number */
  156.         fcb.lrecnum = 0;
  157.         for (i=0;i<nextfree;i++) {
  158.             srv.ah = 0x15;        /* sequential write */
  159.             bdos(0x1A,dir[i]->direntry);
  160.             sysint21(&srv,&rrv);
  161.         }
  162.         srv.ah = 0x10;            /* close the subdirectory */
  163.         srv.dx = &fcb;
  164.         sysint21(&srv,&rrv);
  165.         srv.ah = 0x3B;            /* change directory */
  166.         srv.dx = buf;
  167.         sysint21(&srv,&rrv);
  168.     }
  169. }
  170.  
  171. /* sort labels first, then hidden files, then subdirs, then everything else */
  172. subsort(a)
  173. int a;
  174. {
  175.     if (dir[a]->direntry[0] == '.')        /* root directory entry? */
  176.         dir[a]->att = 1;
  177.     else if (dir[a]->direntry[11] & 4)    /* system file */
  178.         dir[a]->att = 2;
  179.     else if (dir[a]->direntry[11] & 2)    /* hidden file? */
  180.         dir[a]->att = 3;
  181.     else if (dir[a]->direntry[11] & 8)    /* volume label? */
  182.         dir[a]->att = 4;
  183.     else if (dir[a]->direntry[11] & 16)    /* subdirectory? */
  184.         dir[a]->att = 5;
  185.     else
  186.         dir[a]->att = 6;
  187. }
  188.  
  189. /* print error message and abort */
  190. error(s)
  191. unsigned char *s;
  192. {
  193.     bdos(9,s);
  194.     _exit(1);
  195. }
  196.  
  197.