home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 192_01 / kilarutl.c < prev    next >
Text File  |  1979-12-31  |  16KB  |  681 lines

  1.  
  2. /* -- DECLARE VARIABLES -- */
  3. char fat[1050];
  4. char directry[4096];
  5. unsigned int offset, cluster, nxtclust, direntry, noncontig=0;
  6. unsigned int i,j,cl,numin,tot,sector, bytedata, *pint, nsects, svcluster;
  7. char *cfrom, drive, resp, chgflag;
  8. char file[11], cmpflag, evenflag, col, foundflag;
  9. char ds=0;
  10.  
  11. /* -- GLOBAL VARIABLES FOR SCREEN CONTROL -- */
  12. char scr_cols;
  13. char scr_rows;
  14. char scr_mode;
  15. char scr_page;
  16. char scr_attr;
  17.  
  18. /* ---- EXECUTABLE CODE BEGINS HERE --- */
  19.  
  20. /* -- MAIN ROUTINE -- */
  21. main()
  22. {
  23.  char c, s[10]; 
  24.  int i,j,sectindx;
  25.  
  26. /* SET SCREEN TO WHITE CHARS ON BLUE */
  27.  scr_setup();                   
  28.  scr_setmode(3);
  29.  scr_mode = 3; 
  30.  scr_attr = 0x17;
  31.  scr_clr();
  32.  scr_rowcol(1,1);
  33.  
  34. /* PRINT WELCOME */
  35.  printf("WELCOME to the Kilar Utilities.  These programs give you \n");
  36.  printf("various operations on DS/DD (360K) diskettes with no subdirs.\n");
  37.  
  38. /* GET DRIVE DESIGNATION */
  39.  printf("Enter letter of drive to be accessed/used: ");
  40.  scanf("%c",&drive);
  41.  
  42. /* CONVERT DRIVE FROM ASCII TO BINARY */
  43.  drive = drive - 0x41;          
  44.  if (drive > 26)
  45.    drive = drive - 0x20;
  46.  printf(" \n");
  47.  
  48. /* GET FAT AND DIRECTORY FROM DISKETTE */
  49.  printf("\nGetting FAT and directory from diskette ..... \n");
  50.  getsect(fat,drive,1);
  51.  getsect(&fat[512],drive,2);
  52.  for (i = 0; i < 7; i++)
  53.    getsect(&directry[(i*512)],drive,(i+5));
  54.  
  55. /* DETERMINE AMOUNT OF FRAGMENTATION,
  56.      NON-CONTIGUOUS CLUSTERS IN FILES */ 
  57.  sectindx = sectriz();          
  58.  printf("\n\nFragmentation index for diskette is: %d\n",sectindx);
  59.  printf("\n");
  60.  if (sectindx == 0)
  61.    printf("No file fragmentation on diskette.\n");
  62.  else if (sectindx < 8)
  63.    printf("Only some file fragmentation on diskette.\n");
  64.  else if (sectindx < 15)
  65.    printf("Moderate file fragmentation on diskette.\n");
  66.  else if (sectindx < 22)
  67.    printf("File fragmentation high, COPY *.* to new disk recommended.\n");
  68.  else
  69.    printf("Excessive file fragmentation, COPY *.* to new disk urged.\n");
  70.  
  71.  printf("\nHit any key to continue\n");
  72.  getchar();
  73.  
  74. /* MAIN MENU LOOP */
  75. again:
  76.  scr_clr();
  77.  scr_rowcol(1,1);
  78.  printf("WELCOME to the Kilar Utilities.  These programs give you \n");
  79.  printf("various operations on double sided, double density diskettes.\n");
  80.  scr_rowcol(4,10);
  81.  printf("Please make your selection:\n");
  82.  scr_rowcol(6,13);
  83.  printf("1 - Display/Modify data in specific diskette sector\n");
  84.  scr_rowcol(8,13);
  85.  printf("2 - Display use (file belongs to or free) of sector\n");
  86.  scr_rowcol(10,13);
  87.  printf("3 - Display map showing use of all clusters on disk\n");
  88.  scr_rowcol(12,13);
  89.  printf("4 - Display all sectors used by a specific file\n");
  90.  scr_rowcol(14,13);
  91.  printf("5 - Save a sector (and associated cluster) as a new file\n");
  92.  scr_rowcol(16,13);
  93.  printf("6 - Return to DOS\n");
  94.  scr_rowcol(18,10);
  95.  printf("Strike appropriate digit followed by ENTER key: \n"); 
  96.  gets(s); 
  97.  
  98.  c = s[0]; 
  99.  
  100.  switch(c)
  101.   {
  102.    case '1': sect();        /* DISPLAY/MODIFY SECTOR */
  103.              break;
  104.    case '2': sectuse();     /* USE OF SPECIFIED SECTOR */
  105.              break;
  106.    case '3': clustmap();    /* CLUSTER MAP */
  107.              break;
  108.    case '4': fileallo();    /* SECTORS ALLOCATED TO SPECIFIED FILE */
  109.              break;
  110.    case '5': filesect();    /* SAVE SECTOR AS A FILE */
  111.              break;
  112.    case '6': exit();        /* RETURN TO DOS */
  113.              break;
  114.    default:  printf("Illegal option - try again \n");
  115.   }
  116.  printf("\n Type any key to continue \n");
  117.  c = getchar();
  118.  goto again;                /* WHEN DONE, RETURN TO MAIN MENU */
  119. }
  120.  
  121.  
  122.  
  123. /* --- clustmap routine - displays a cluster map of diskette */
  124. clustmap()
  125. {
  126.  
  127.  nsects = chgflag = 0;
  128.  printf("Cluster map routine. \n");
  129.  printf("Displays use of all data clusters on diskette.\n");
  130.  
  131.  
  132.  printf("Cluster map: \n");
  133.  
  134.  col = 1;
  135.  
  136. /* For each of the data cluster */
  137.  for (cluster = 2; cluster < 356; cluster++) 
  138.   { 
  139.    printf(" %3d=",cluster);
  140.    col += 5;
  141. /* Check if cluster is part of file */
  142.    if (next(cluster) == 0) 
  143.     {
  144.       printf("free         ");
  145.       col += 12;
  146.       checkcol();
  147.       continue;
  148.     }
  149.  
  150. /* Check directory if cluster is beginning of a file */
  151.      foundflag = 0;
  152.      for (i = 0; i < 112; i++)     /* check each directory entry */
  153.      {
  154.       direntry = 32 * i;
  155.       pint = &directry[direntry + 26];   /* check first cluster value */
  156.       if (cluster == *pint)
  157.        {
  158.         directry[direntry+11] = 0;       /* if checks, get file name */
  159.         for (j = 0; j < 8; j++)
  160.          putchar(directry[direntry+j]);
  161.         putchar('.');
  162.         for (j = 8; j < 11; j++)
  163.           putchar(directry[direntry+j]);
  164.         putchar(' ');
  165.         col += 12;                        /* 12 chars displayed */
  166.         checkcol();                       /* check for end of line */
  167.         foundflag = 1;
  168.         break;
  169.        }
  170.       if (foundflag)
  171.         continue; 
  172.   }
  173.  if (foundflag)
  174.    continue;
  175.  
  176.  
  177. /* Check FAT for reference to cluster */
  178.   svcluster = cluster;
  179.   while (cl = prev(svcluster))
  180.     svcluster = cl;
  181.  
  182. /* Check directory for reference to cluster */
  183.   for (i = 0; i < 112; i++)
  184.    {
  185.      direntry = 32 * i;
  186.      pint = &directry[direntry + 26]; 
  187.      if (svcluster == *pint)
  188.       {
  189.        directry[direntry+11] = 0;
  190.        for (j = 0; j < 8; j++)
  191.          putchar(directry[direntry+j]);
  192.        putchar('.');
  193.        for (j = 8; j < 11; j++)
  194.          putchar(directry[direntry+j]);
  195.        putchar(' ');
  196.        col += 12;
  197.        checkcol();
  198.        break;
  199.       }
  200.    }
  201.  }
  202. }
  203.  
  204.  
  205. /* -- checkcol routine - checks for near end of line -- */
  206. checkcol()    
  207. {
  208.  if (col > 66)
  209.   {
  210.    putchar('\n');
  211.    col = 1;
  212.   }
  213.  return;
  214. }
  215.  
  216. /* -- next - use FAT to get no. of the next cluster in file -- */
  217. next(clust) 
  218. unsigned int clust;
  219. {
  220.  unsigned int nxtclust, *pint, offset;
  221.  char evenflag;
  222.  
  223. /* see PC-DOS Technical Reference Manual for explanation */
  224.  if ((clust & 0xfffe) == clust)
  225.    evenflag = 1;
  226.  else
  227.    evenflag = 0;
  228.  nxtclust = clust + clust/2;
  229.  pint = fat + nxtclust;
  230.  offset = *pint;
  231.  if (evenflag)
  232.    offset = offset & 0x0fff;
  233.  else
  234.    offset = offset >> 4;
  235.  return(offset);
  236. }
  237.  
  238. /* -- prev - Check thru FAT to find entry pointing to current
  239.        cluster.  That is the previous cluster. --- */
  240. prev(clust)        
  241. unsigned int clust;
  242. {
  243.  unsigned int nxtclust, *pint, offset;
  244.  char evenflag;
  245.  
  246. for (i = 2; i < 356; i++)      /* check each FAT entry */
  247.  {
  248.   if ((i & 0xfffe) == i)
  249.     evenflag = 1;
  250.   else
  251.     evenflag = 0;              /* determine next cluster */
  252.   nxtclust = i + i/2;
  253.   pint = fat + nxtclust;
  254.   offset = *pint;
  255.   if (evenflag)
  256.     offset = offset & 0x0fff;
  257.   else
  258.     offset = offset >> 4;
  259.   if (offset == clust)         /* if equal to current, have the previous */
  260.     return(i);
  261.   }
  262.  return(0);
  263. }
  264.  
  265.  
  266. /* --- fileallo routine - displays sectors belonging to specified file */
  267.  
  268. fileallo()
  269. {
  270.  
  271.  noncontig = 0;
  272.  nsects = chgflag = 0;
  273.  printf("File allocation routine.\n");
  274.  printf("Displays the logical numbers of sectors the file occupies \n");
  275.  printf("for double sided/double density diskette. \n \n");
  276.  
  277.  printf("Enter 8 letter basename of file in CAPS, spaces after end: ");
  278.  for (i = 0; i < 8; i++)
  279.    file[i] = getchar();
  280.  printf("\nEnter 3 letter suffix of file in CAPS, spaces after end: ");
  281.  for (i = 0; i < 3; i++)
  282.    file[(i+8)] = getchar();
  283.  
  284.  
  285. /* Loop to find file name in directory */
  286.  i = cmpflag = 0;
  287.  while (!cmpflag)
  288.   {
  289.    direntry = i * 32;           /* Find file entry in directory */
  290.    if (!strncmp(&directry[direntry],file,11))
  291.      cmpflag = 1;
  292.    else if (i > 112)           /* If not found, return to DOS */
  293.     {
  294.      printf("File not found, terminating to DOS \n");
  295.      return;
  296.     }
  297.    else
  298.      i++;
  299.   }
  300.  
  301.  pint = &directry[(direntry+26)];     /* Get first no. of first cluster */
  302.  cluster = *pint;
  303.  col = 1;
  304.  printf("\n \nFile is on sectors: \n");
  305.  prtsect(cluster);
  306.  
  307. next1:                                 /* Get next cluster number */
  308.  if ((cluster & 0xfffe) == cluster)
  309.    evenflag = 1;
  310.  else
  311.    evenflag = 0;
  312.  nxtclust = cluster + cluster/2;
  313.  pint = fat + nxtclust;
  314.  offset = *pint;
  315.  if (evenflag)
  316.    offset = offset & 0x0fff;
  317.  else
  318.    offset = offset >> 4;
  319.  if (offset > 0xff7)                /* If last sector, display totals */
  320.   {
  321.    printf("\nTotal of %d sectors. \n",nsects);
  322.    printf("%d noncontiguous cluster breaks. \n",noncontig);
  323.    return;
  324.   }
  325.  else
  326.   {
  327.    if (offset != (cluster+1))
  328.      noncontig++;
  329.    cluster = offset;
  330.    prtsect(cluster);
  331.   }
  332.  goto next1;
  333. }
  334.  
  335.  
  336.  
  337.  
  338.  
  339. /* --- prtsect - prints sectors for current cluster --- */
  340.  
  341. prtsect(clust)        /* Print sector numbers for current cluster */
  342. int clust;
  343. {
  344.  int sect;
  345.  
  346.  sect = (clust - 2)*2 + 12;
  347.  printf("%4d%4d",sect,(sect+1));
  348.  col += 8;
  349.  nsects += 2;
  350.  if (col > 78)
  351.   {
  352.    printf(" \n");
  353.    col = 1;
  354.   }
  355.  return;
  356. }
  357.  
  358. char buffer[4096];
  359. char leadflag;
  360.  
  361.  
  362. /* --- sect - displays contents of specified sector --- */
  363. sect()            
  364. {
  365.  
  366. /* display heading an diskette information */
  367.  chgflag = 0;
  368.  printf("Sector display program. \n");
  369.  printf(" \n");
  370.  printf("For double sided/double density diskette: \n");
  371.  printf("   Sector 0            = boot record. \n");
  372.  printf("   Sectors 1 thru 4    = File Allocation Tables (FAT) \n");
  373.  printf("   Sectors 5 thru 11   = Directory area \n");
  374.  printf("   Sectors 12 thru 719 = File data \n \n");
  375.  printf("Enter number of sector to be displayed: ");
  376.  scanf("%d",§or);
  377.  getsect(buffer,drive,sector);
  378.  
  379. done:
  380.  cfrom=0;
  381.  while (cfrom < 512)
  382.   {
  383.    /* print the offset in hex */
  384.    leadflag = 1;
  385.    dtoh(cfrom);
  386.    putchar(' ');
  387.  
  388.   /* print 16 bytes in hex */
  389.  
  390.    for (i=0; i < 16; i++)
  391.     {
  392.      putchar(' ');
  393.      btoh(buffer[cfrom++]);
  394.     }
  395.    cfrom-=16;
  396.    puts("   ");
  397.  
  398.    /* print the bytes in ascii */
  399.  
  400.    for (i=0; i < 16; i++)
  401.     {
  402.      putchar((buffer[cfrom] >= ' ' && buffer[cfrom] < 0x7f) 
  403.        ? buffer[cfrom]: '.');
  404.      cfrom++;
  405.     }
  406.    puts(" \n");
  407.    if (cfrom == 256)
  408.     {
  409.      printf(" ** Hit any key to continue ** \n");
  410.      getchar();
  411.      printf(" \n");
  412.     }
  413.   }
  414.  
  415.  printf("\n \n Do you wish to change byte(s) of data (Y/N)? ");
  416.  resp = getchar();
  417.  if ((resp == 'Y') || (resp == 'y'))
  418.   {
  419.    chgflag = 1;
  420.    printf("\n \n Enter number of (starting) byte in hex to be modified: ");
  421.    scanf("%x",&cfrom);
  422.    printf("\nEnter a hex number between 100 and FFFF to terminate entries\n"); 
  423. change:
  424.    printf("\n Enter new data in hex: ");
  425.    scanf("%x",&bytedata);
  426.    if (bytedata > 0xff)
  427.      goto done;
  428.    buffer[cfrom++] = bytedata;
  429.    goto change;
  430.   }
  431.  
  432.  if (chgflag)
  433.   {
  434.    printf(" \n Do you wish to update sector on disk with new data (Y/N)? ");
  435.    resp = getchar();
  436.    if ((resp == 'Y') || (resp == 'y'))
  437.     {
  438.      putsect(buffer,drive,sector);
  439.      printf("\n Sector written back to disk. \n");
  440.     }
  441.   }
  442. }    
  443.  
  444. /* display double byte in hex */
  445.  
  446. dtoh(db)
  447. unsigned int db; 
  448. {
  449.  btoh(db>>8);
  450.  btoh(db);
  451. }
  452.  
  453. /* display byte in hex */
  454.  
  455. btoh(b)
  456. char b; 
  457. {
  458.  ntoh(b>>4);
  459.  ntoh(b);
  460. }
  461.  
  462. /* display nibble in hex */
  463.  
  464. ntoh(n)
  465. char n; 
  466. {
  467.  
  468.  n &= 0x0f;
  469.  if (n >= 10)
  470.    putchar(n-10+'A');
  471.  else
  472.    putchar(n+'0');
  473.  return;
  474. }
  475.  
  476.  
  477. /* --- sectuse - display use of specified sector --- */
  478.  
  479. sectuse()
  480. {
  481.  
  482.  nsects = chgflag = 0;
  483.  printf("Sector use routine.\n");
  484.  printf("Displays whether a sector belongs to a file and the name of the\n");
  485.  printf("file if it does. \n \n");
  486.  
  487.  printf("Enter logical number of sector: ");
  488.  scanf("%d",§or);
  489.  cluster = ((sector - 12)/2) + 2;
  490.  
  491.  
  492. /* Check if cluster is part of file */
  493.  if (next(cluster) == 0) 
  494.   {
  495.     printf("Sector is not part of a file, it is free space. \n");
  496.     return;
  497.    }
  498.  
  499. /* Check directory if cluster is beginning of a file */
  500.   for (i = 0; i < 112; i++)
  501.    {
  502.      direntry = 32 * i;
  503.      pint = &directry[direntry + 26]; 
  504.      if (cluster == *pint)
  505.       {
  506.        directry[direntry+11] = 0;
  507.        printf("Sector is part of file ");
  508.        for (j = 0; j < 8; j++)
  509.          putchar(directry[direntry+j]);
  510.        putchar('.');
  511.        for (j = 8; j < 11; j++)
  512.          putchar(directry[direntry+j]);
  513.        putchar('\n');
  514.        return;
  515.       }
  516.    }
  517.  
  518.  
  519. /* Check FAT for reference to cluster */
  520.   while (cl = prev(cluster))
  521.     cluster = cl;
  522.  
  523.   for (i = 0; i < 112; i++)
  524.    {
  525.      direntry = 32 * i;
  526.      pint = &directry[direntry + 26]; 
  527.      if (cluster == *pint)
  528.       {
  529.        directry[direntry+11] = 0;
  530.        printf("Sector is part of file ");
  531.        for (j = 0; j < 8; j++)
  532.          putchar(directry[direntry+j]);
  533.        putchar('.');
  534.        for (j = 8; j < 11; j++)
  535.          putchar(directry[direntry+j]);
  536.        putchar('\n');
  537.        return;
  538.       }
  539.    }
  540.  
  541. }
  542.  
  543.  
  544.  
  545.  
  546. /* ---- filesect - save a sector (and associated cluster) as a file */
  547.  
  548. filesect()
  549. {
  550.  
  551.  nsects = chgflag = 0;
  552.  printf("Sector save routine.\n");
  553.  printf("Saves the cluster associated with sector as a file. \n");
  554.  
  555.  printf("Enter sector number to be saved as file: ");
  556.  scanf("%d",§or);
  557.  printf(" \n");
  558.  
  559. /* determine number of associated cluster */
  560.  cluster = ((sector - 12)/2) + 2;
  561.  
  562. /* file name will be SECTOR.FIL */
  563.  strcpy(file,"SECTOR  FIL");
  564.  
  565. /* find a blank directory entry */
  566.  i = cmpflag = 0;
  567.  while (!cmpflag)
  568.   {
  569.    direntry = i * 32;
  570.    if (directry[direntry] == 0)
  571.      cmpflag = 1;
  572.    else if (i > 112)
  573.     {
  574.      printf("No directory space left, terminating to DOS \n");
  575.      return;
  576.     }
  577.    else
  578.      i++;
  579.   }
  580.  
  581. /* make sure cluster is not first cluster of a file */
  582.  for (i = 0; i < 112; i++)
  583.   {
  584.    if (directry[32*i] != 0xe5)
  585.     {
  586.      pint = directry + 32*i + 26;
  587.      if (cluster == *pint)
  588.        inuse();
  589.     }
  590.   }
  591.  
  592.  strcpy(&directry[direntry],file);
  593.  directry[direntry + 11]= 0x20;
  594.  for (i = 12; i < 26; i++)
  595.    directry[direntry + i] = 0;
  596.  
  597. /* point directory's cluster to this one */
  598.  pint = &directry[(direntry+26)];
  599.  *pint++ = cluster;
  600.  *pint++ = 512;
  601.  *pint = 0;
  602.  
  603. /* make sure cluster is not in use by checking its FAT entry,
  604.     place end of file terminator in it */
  605.  if ((cluster & 0xfffe) == cluster)
  606.    evenflag = 1;
  607.  else
  608.    evenflag = 0;
  609.  nxtclust = cluster + cluster/2;
  610.  pint = fat + nxtclust;
  611.  offset = *pint;
  612.  if (evenflag)
  613.   {
  614.    if (offset & 0x0fff)
  615.      inuse();
  616.    offset &= 0xf000;
  617.    offset |= 0x0fff;
  618.   }
  619.  else
  620.   {
  621.    if (offset & 0xfff0)
  622.      inuse();
  623.    offset &= 0x000f;
  624.    offset |= 0xfff0;
  625.   }
  626.  *pint = offset;
  627.  
  628.  printf("\n \n Writing revised FAT and directory to diskette ..... \n");
  629.  putsect(fat,drive,1);
  630.  putsect(&fat[512],drive,2);
  631.  putsect(fat,drive,3);
  632.  putsect(&fat[512],drive,4);
  633.  
  634.  for (i = 0; i < 7; i++)
  635.    putsect(&directry[(i*512)],drive,(i+5));
  636.  printf("\n Cluster associated with sector %d saved as SECTOR.FIL.\n",sector);
  637. }
  638.  
  639.  
  640. inuse()
  641. {
  642.  printf("\nSector is already in use by a file.  Not made into new file.\n");
  643.  return;
  644. }
  645.  
  646.  
  647. /* sectriz - calculate the fragmentation index of the diskette by
  648.     scanning the FAT */
  649. sectriz()
  650. {
  651.  
  652.  noncontig = nsects = chgflag = 0;
  653.  printf("Calculating fragmentation index.\n");
  654.  
  655.  
  656. /* for each cluster */
  657.  for (cluster = 2; cluster < 355; cluster++)
  658.   {
  659.    if ((cluster & 0xfffe) == cluster)
  660.      evenflag = 1;
  661.    else
  662.      evenflag = 0;
  663.    nxtclust = cluster + cluster/2;   /* get entry */
  664.    pint = fat + nxtclust;
  665.    offset = *pint;
  666.    if (evenflag)
  667.      offset = offset & 0x0fff;
  668.    else
  669.      offset = offset >> 4;
  670.  
  671. /* if entry is not bad cluster, end of file, or next cluster then
  672.       must have non-contiguous segment */
  673.    if ((offset < 0xff7) && (offset != (cluster+1)) && (offset))
  674.      noncontig++;
  675.   }
  676.  return(noncontig);
  677. }
  678.  
  679.  
  680. 
  681.