home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 2 / DATAFILE_PDCD2.iso / utilities3 / discindex / DiscIndex / Source / C / FileUtils next >
Text File  |  1994-08-03  |  6KB  |  226 lines

  1. /* DiscIndex 1.00
  2.  * File and scanning code - FileUtils.c
  3.  * By Neil A Carson 1994 A.D.
  4.  */
  5.  
  6. #include <string.h>
  7.  
  8. #include "dbox.h"
  9. #include "discindex.h"
  10. #include "heap.h"
  11. #include "kernel.h"
  12. #include "visdelay.h"
  13. #include "werr.h"
  14. #include "wimp.h"
  15.  
  16. #define OS_FSControl 0x29
  17. #define OS_GBPB      0x0C
  18.  
  19. extern scan_win_type scan_win_info;
  20. extern dbox scan_dbox;
  21. extern BOOL scan_open;
  22.  
  23. void fname_count(char *, os_gbpb_block *);
  24. void fname_process(char *, os_gbpb_block *);
  25.  
  26. int files_to_process;
  27. disc_type *dest_disc;
  28.  
  29. void do_scan(disc_type *disc)
  30. {
  31.     _kernel_swi_regs r;
  32.     os_error *error;
  33.     BOOL filling = TRUE, all_go = FALSE;
  34.     char *buffer;
  35.  
  36.     if (!scan_open)
  37.     {
  38.         scan_dbox = dbox_new("Scan");
  39.         dbox_show(scan_dbox);
  40.     }
  41.  
  42.     if (scan_win_info.type & directories) dbox_setnumeric(scan_dbox, 5, 1);
  43.         else dbox_setnumeric(scan_dbox, 5, 0);
  44.     if (scan_win_info.type & applications) dbox_setnumeric(scan_dbox, 4, 1);
  45.         else dbox_setnumeric(scan_dbox, 4, 0);
  46.     if (scan_win_info.type & files_apps) dbox_setnumeric(scan_dbox, 3, 1);
  47.         else dbox_setnumeric(scan_dbox, 3, 0);
  48.     if (scan_win_info.type & files) dbox_setnumeric(scan_dbox, 1, 1);
  49.         else dbox_setnumeric(scan_dbox, 1, 0);
  50.     if (scan_win_info.type & root_only) dbox_setnumeric(scan_dbox, 6, 1);
  51.         else dbox_setnumeric(scan_dbox, 6, 0);
  52.     dbox_setnumeric(scan_dbox, 8, scan_win_info.dismount);
  53.     dbox_setfield(scan_dbox, 0, scan_win_info.drive);
  54.  
  55.  
  56.     if (scan_open) return;
  57.     scan_open = TRUE;
  58.  
  59.     while (filling)
  60.     {
  61.         switch(dbox_fillin(scan_dbox))
  62.         {
  63.             case 7:
  64.             if (!dbox_persist())
  65.             {
  66.                 all_go = TRUE;
  67.                 filling = FALSE;
  68.             }
  69.             break;
  70.  
  71.             case dbox_CLOSE:
  72.             filling = FALSE;
  73.             break;
  74.         }
  75.     }
  76.     scan_win_info.type = 0;
  77.     if (dbox_getnumeric(scan_dbox, 5)) scan_win_info.type |= directories;
  78.     if (dbox_getnumeric(scan_dbox, 4)) scan_win_info.type |= applications;
  79.     if (dbox_getnumeric(scan_dbox, 3)) scan_win_info.type |= files_apps;
  80.     if (dbox_getnumeric(scan_dbox, 1)) scan_win_info.type |= files;
  81.     if (dbox_getnumeric(scan_dbox, 6)) scan_win_info.type |= root_only;
  82.     scan_win_info.dismount = dbox_getnumeric(scan_dbox, 8);
  83.     dbox_getfield(scan_dbox, 0, scan_win_info.drive, 32);
  84.     dbox_dispose(&scan_dbox);
  85.     scan_open = FALSE;
  86.  
  87.     if (!all_go) return;
  88.  
  89.     files_to_process = 0;
  90.     dest_disc = disc;
  91.  
  92.     if (dest_disc->files != 0) heap_free(dest_disc->files);
  93.     dest_disc->no = 0;
  94.     dest_disc->used = 0;
  95.  
  96.     if (scan_win_info.type == 0)
  97.     {
  98.         werr(0, "These settings will not find anything!");
  99.         return;
  100.     }
  101.  
  102.    /* Check desired drive/directory is valid */
  103.  
  104.     if (scan_win_info.drive[0] == 0)
  105.     {
  106.         werr(0, "Can't deal with infinitely short paths!");
  107.         return;
  108.     }
  109.     r.r[0] = 0;
  110.     r.r[1] = (int) scan_win_info.drive;
  111.     error = (os_error *) _kernel_swi(OS_FSControl, &r, &r);
  112.     if (error != 0)
  113.     {
  114.         wimp_reporterror(error, wimp_EOK, "Disc Index");
  115.         return;
  116.     }
  117.  
  118.     /* Grab disc name */
  119.  
  120.     if ((buffer = heap_alloc(256)) == 0)
  121.     {
  122.         werr(0, "Not enough RAM for this operation!");
  123.         return;
  124.     }
  125.  
  126.     r.r[0] = 5;
  127.     r.r[2] = (int) buffer;
  128.     error = (os_error *) _kernel_swi(OS_GBPB, &r, &r);
  129.     if (error != 0)
  130.     {
  131.         wimp_reporterror(error, wimp_EOK, "Disc Index");
  132.         return;
  133.     }
  134.     strncpy(dest_disc->disc_name, &buffer[1],buffer[0]);
  135.     dest_disc->disc_name[buffer[0]] = 0;
  136.     heap_free(buffer);
  137.  
  138.     /* Count files needed.... ! */
  139.  
  140.     visdelay_begin();
  141.     recurse(scan_win_info.drive, fname_count);
  142.  
  143.     /* Grab RAM */
  144.  
  145.     if (files_to_process == 0)
  146.     {
  147.         visdelay_end();
  148.         werr(0, "No files match search criteria!");
  149.         return;
  150.     }
  151.     dest_disc->files = heap_alloc((files_to_process + 1) * sizeof(file_type));
  152.     if (dest_disc->files == 0)
  153.     {
  154.         visdelay_end();
  155.         werr(0, "Not enough free memory to store files on this disc!");
  156.         return;
  157.     }
  158.     memset(dest_disc->files, 0, (files_to_process + 1) * sizeof(file_type));
  159.     recurse(scan_win_info.drive, fname_process); /* Now fetch and process ! */
  160.     if (scan_win_info.dismount)
  161.         _kernel_system("DISMOUNT", FALSE);
  162.     visdelay_end();
  163. }
  164.  
  165. BOOL wanted(char *path, os_gbpb_block *file)
  166. {
  167.     char *ptr;
  168.     BOOL is_dir = FALSE, is_app = FALSE, is_file_in_app = FALSE;
  169.     BOOL is_file = FALSE, is_root = FALSE;
  170.  
  171.     if ((file->type == 2) && (file->name[0] != '!')) is_dir = TRUE;
  172.     if ((file->name[0] == '!') && (file->type == 2)) is_app = TRUE;
  173.  
  174.     ptr = strchr(path, '!');
  175.     if ((ptr != 0) && (*(ptr - 1) == '.') && (file->type != 2))
  176.         is_file_in_app = TRUE;
  177.     if ((!is_file_in_app) && (file->type == 1)) is_file = TRUE;
  178.     if (strcmp(path, scan_win_info.drive) == 0) is_root = TRUE;
  179.  
  180.     /* Now see if we actually want this entry or not...
  181.      */
  182.     if ((scan_win_info.type & root_only) && (!is_root)) return FALSE;
  183.  
  184.     if ((scan_win_info.type & directories) && (is_dir)) return TRUE;
  185.     if ((scan_win_info.type & applications) && (is_app)) return TRUE;
  186.  
  187.     if ((scan_win_info.type & files_apps) && (is_file_in_app)) return TRUE;
  188.     if ((scan_win_info.type & files) && (is_file)) return TRUE;
  189.  
  190.     return FALSE;
  191. }
  192.  
  193. void fname_count(char *path, os_gbpb_block *file)
  194. {
  195.     if (wanted(path, file)) files_to_process ++;
  196. }
  197.  
  198. void fname_process(char *path, os_gbpb_block *file)
  199. {
  200.     /* For filetype: >=0 = filetype, -1 = not known, -2 = dir, -3 = app */
  201.  
  202.     dest_disc->used += file->len;
  203.     if (!wanted(path, file)) return;  /* Quick exit clause if needed... */
  204.     strncpy(dest_disc->files[dest_disc->no].name, file->name, 31);
  205.     dest_disc->files[dest_disc->no].name[31] = 0;
  206.     dest_disc->files[dest_disc->no].size = file->len;
  207.  
  208.     if (file->type == 2)
  209.     {
  210.         dest_disc->files[dest_disc->no].type = -2;
  211.         if (file->name[0] == '!') dest_disc->files[dest_disc->no].type = -3;
  212.         dest_disc->no ++;
  213.         return;
  214.     }
  215.  
  216.     if ((file->load & 0xFFF00000) != 0xFFF00000)
  217.     {
  218.         dest_disc->files[dest_disc->no].type = -1;
  219.         dest_disc->no ++;
  220.         return;
  221.     }
  222.  
  223.     dest_disc->files[dest_disc->no].type = (file->load >> 8) & 0xFFF;
  224.     dest_disc->no ++;
  225. }
  226.