home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d0xx / d035 / dirutil.lha / DirUtil / dirutil.c next >
Encoding:
C/C++ Source or Header  |  1986-09-09  |  27.2 KB  |  1,097 lines

  1. /* DIRectory UTILity II -
  2.     Original Version (Directory Utilitity 1.0) by Chris Nicotra
  3.     Revisions/Enhancements/Fixes by David L. Jobusch
  4.                    ...umn-cs!isucs1!jobusch
  5.  
  6.     This program is in the public domain. Nicotra source downloaded
  7.     from local BBS and modified by Jobusch. Word is Nicotra recently
  8.     released an improved version (1.3). Hope his code is better than
  9.     it was in 1.0. NO guarentees...if you blow up a disk with this
  10.     program, it's your own damn fault.                */
  11.  
  12. #include <exec/types.h>
  13. #include <exec/memory.h>
  14. #include <intuition/intuition.h>
  15. #include <intuition/intuitionbase.h>
  16. #include <graphics/gfxbase.h>
  17. #include <stdio.h>
  18. #include <libraries/dos.h>
  19.  
  20. #define INTUITION          0x00000001
  21. #define GRAPHICS           0x00000002
  22. #define WINDOW             0x00000004
  23. #define INITDIRLOCKOK         0x00000008
  24.  
  25. #ifdef SHOW
  26. #define SHOWDIR    "sys:c"        /* What directory its in    */
  27. #define SHOWCMD    "show"        /* Name of the actual program    */
  28. #define SHOWNAMELENGTH 10       /* Make changes? Set this!    */
  29. #define RAMSHOW    "ram:DIRUTIL.SHOW" /* Where it will end up    */
  30. #define RAMSHOWLEN  16        /* CHANGE THIS IF YOU CHANGE NAME!*/
  31. #endif
  32.  
  33. #define FBSIZE  (long)(sizeof (struct FileInfoBlock))
  34. #define MAXFILE 100        /* Maximum files to look at in directory */
  35. #define MAXFNAME 10        /* Maximum files to show at once     */
  36. #define MAXCHAR     30         /* Max file name length             */
  37. #define MAXCD      255        /* Max current dir name length         */
  38.  
  39. #define SLIDE_GADGET     0
  40. #define ERR_GADGET     3
  41. #define CURDIR_GADGET    4    /* Gadget labels             */
  42. #define CPDIR_GADGET    5
  43. #define DF0_GADGET    6
  44. #define DF1_GADGET    7
  45. #define HD0_GADGET    8
  46. #define RAM_GADGET    9
  47. #define ALL_GADGET    10
  48. #define CLEAR_GADGET    11
  49. #define COPY_GADGET    12
  50. #define DELETE_GADGET    13
  51. #define RENAME_GADGET    14
  52. #define GETDIR_GADGET    15
  53. #define MAKEDIR_GADGET    16
  54. #define DELETEDIR_GADGET 17
  55. #define PARENT_GADGET    18
  56. #define ROOT_GADGET    19
  57. #define LIST_GADGET    20
  58. #define BUT_FIRST DF0_GADGET
  59.  
  60. #ifdef SHOW
  61. #define SHOW_GADGET    21
  62. #define FIRST_GADGET    But_gad[15]
  63. #define KILL_SHOW    But_gad[15]
  64. #define BUT_LAST    SHOW_GADGET
  65. #endif
  66. #ifndef SHOW
  67. #define FIRST_GADGET    But_gad[14]
  68. #define BUT_LAST    LIST_GADGET
  69. #endif
  70.  
  71. #define WinIDCMP  CLOSEWINDOW | REFRESHWINDOW | GADGETUP | MOUSEBUTTONS
  72.  
  73. extern APTR AllocMem();
  74. struct IntuitionBase *IntuitionBase;
  75. struct GfxBase *GfxBase;
  76. struct IntuiMessage *message;
  77. struct RastPort *rp;
  78. struct Window *w;
  79.  
  80. /************************************************************************/
  81. /*         Source/Destination string gadgets            */
  82. /************************************************************************/
  83. USHORT str_pairs [] = { 0,0,  590,0,  590,9,  0,9,  0,0,};
  84. struct Border str_border =
  85. {
  86.     -1,-1,              /* Leftedge, Topedge */
  87.      1, 1, JAM1,        /* FrontPen, BackPen, Drawmode */
  88.      5,                 /* Number of Pairs */
  89.     (APTR) &str_pairs,  /* XY, Pointer to XY pairs */
  90.     NULL,               /* More borders */
  91. };
  92.  
  93. /* Error display */
  94. char err_buf[MAXCD+1];
  95. struct StringInfo err_str = 
  96. { &err_buf, NULL, 0, MAXCD+1,   0, 0, 0, 0, 2,0, NULL, 0, NULL, };
  97.  
  98. struct Gadget Err_gad =
  99. {
  100.     NULL, /* last in the list of gadgets */
  101.     21,122,
  102.     588, 9,
  103.     GADGHCOMP, GADGIMMEDIATE | RELVERIFY | STRINGCENTER,
  104.     STRGADGET,
  105.         (APTR) &str_border,
  106.     NULL,
  107.     NULL,    /* Intuitext pointer */
  108.     0,
  109.     &err_str,
  110.     ERR_GADGET,
  111.     NULL,
  112. };
  113.  
  114. struct IntuiText Curdir_text = {1,0,JAM1, -10,0,NULL,"S",NULL,};
  115. char cd_buf[MAXCD+1];
  116. struct StringInfo Curdir_str = 
  117. { &cd_buf, NULL, 0, MAXCD+1,   0, 0, 0, 0, 2,0, NULL, 0, NULL, };
  118. struct Gadget Curdir_gad =
  119. {
  120.     &Err_gad,
  121.     21,100,
  122.     588, 9,
  123.         GADGHCOMP, GADGIMMEDIATE | RELVERIFY,
  124.     STRGADGET,
  125.         (APTR) &str_border,
  126.     NULL,
  127.     &Curdir_text,
  128.     0,
  129.     &Curdir_str,
  130.     CURDIR_GADGET,
  131.     NULL,
  132. };
  133.  
  134. /* Destination definitions */
  135. char cp_buf[MAXCD+1];
  136. struct IntuiText Cpdir_text = {1,0,JAM1,-10,0,NULL,"D",NULL,};
  137. struct StringInfo Cpdir_str = 
  138. { &cp_buf, NULL, 0, MAXCD+1,   0, 0, 0, 0, 2,0, NULL, 0, NULL, };
  139.  
  140. struct Gadget Cpdir_gad =
  141. {
  142.         &Curdir_gad,
  143.     21,111,
  144.     588, 9,
  145.         GADGHCOMP, GADGIMMEDIATE | RELVERIFY,
  146.     STRGADGET,
  147.         (APTR) &str_border,
  148.     NULL,
  149.     &Cpdir_text,
  150.     0,
  151.     &Cpdir_str,
  152.     CPDIR_GADGET,
  153.     NULL,
  154. };
  155.  
  156. /************************************************************************/
  157. /*        File Select Gadget Declarations                */
  158. /************************************************************************/
  159. struct Image slide_img;
  160. struct PropInfo slide_prop;
  161. struct Gadget Slide_gad =
  162. {
  163.     &Cpdir_gad,         /* Next gadget */
  164.     20, 14,             /* Left, Top edge */
  165.     20, 84,         /* Width Hieght */
  166.     GADGHNONE,          /* Flags */
  167.     GADGIMMEDIATE       /* More flags */
  168.     | RELVERIFY,
  169.     PROPGADGET,         /* Gadget type */
  170.     (APTR)&slide_img,   /* Border definition */
  171.     NULL,               /* Select render */
  172.     NULL,               /* Gadget text */
  173.     0,                  /* MutualExclude */
  174.     (APTR) &slide_prop, /* Special Info - proportional specification */
  175.     SLIDE_GADGET,
  176.     NULL,
  177. };
  178.  
  179. /* Button Gadget IDs */
  180.  
  181. struct IntuiText But_text[] =
  182. {
  183.     3,2,JAM2,0,0,NULL,"  df0:   ",NULL,
  184.     3,2,JAM2,0,0,NULL,"  df1:   ",NULL,
  185.     3,2,JAM2,0,0,NULL,"  hd0:   ",NULL,
  186.     3,2,JAM2,0,0,NULL,"  ram:   ",NULL,
  187.     3,2,JAM2,0,0,NULL,"   ALL   ",NULL,
  188.     3,2,JAM2,0,0,NULL,"  CLEAR  ",NULL,
  189.     3,2,JAM2,0,0,NULL,"  COPY   ",NULL,
  190.     3,2,JAM2,0,0,NULL," DELETE  ",NULL,
  191.     3,2,JAM2,0,0,NULL," RENAME  ",NULL,
  192.     3,2,JAM2,0,0,NULL," GETDIR  ",NULL,
  193.     3,2,JAM2,0,0,NULL," MAKEDIR ",NULL,
  194.     3,2,JAM2,0,0,NULL,"DELETEDIR",NULL,
  195.         3,2,JAM2,0,0,NULL," PARENT  ",NULL,
  196.     3,2,JAM2,0,0,NULL,"  ROOT   ",NULL,
  197.     3,2,JAM2,0,0,NULL,"  LIST   ",NULL,
  198. #ifdef SHOW
  199.     3,2,JAM2,0,0,NULL,"SHOW ILBM",NULL,
  200. #endif
  201. };
  202.  
  203. struct Gadget But_gad[] =
  204. {
  205.     NULL,5,174,72,8,GADGHCOMP,GADGIMMEDIATE | RELVERIFY,BOOLGADGET,
  206.         NULL,NULL,NULL,NULL,NULL,DF0_GADGET,NULL,
  207.     NULL,5,174,72,8,GADGHCOMP,GADGIMMEDIATE | RELVERIFY,BOOLGADGET,
  208.         NULL,NULL,NULL,NULL,NULL,DF1_GADGET,NULL,
  209.     NULL,5,174,72,8,GADGHCOMP,GADGIMMEDIATE | RELVERIFY,BOOLGADGET,
  210.         NULL,NULL,NULL,NULL,NULL,HD0_GADGET,NULL,
  211.     NULL,5,174,72,8,GADGHCOMP,GADGIMMEDIATE | RELVERIFY,BOOLGADGET,
  212.         NULL,NULL,NULL,NULL,NULL,RAM_GADGET,NULL,
  213.     NULL,5,174,72,8,GADGHCOMP,GADGIMMEDIATE | RELVERIFY,BOOLGADGET,
  214.         NULL,NULL,NULL,NULL,NULL,ALL_GADGET,NULL,
  215.     NULL,5,174,72,8,GADGHCOMP,GADGIMMEDIATE | RELVERIFY,BOOLGADGET,
  216.         NULL,NULL,NULL,NULL,NULL,CLEAR_GADGET,NULL,
  217.     NULL,5,174,72,8,GADGHCOMP,GADGIMMEDIATE | RELVERIFY,BOOLGADGET,
  218.         NULL,NULL,NULL,NULL,NULL,COPY_GADGET,NULL,
  219.     NULL,5,174,72,8,GADGHCOMP,GADGIMMEDIATE | RELVERIFY,BOOLGADGET,
  220.         NULL,NULL,NULL,NULL,NULL,DELETE_GADGET,NULL,
  221.     NULL,5,174,72,8,GADGHCOMP,GADGIMMEDIATE | RELVERIFY,BOOLGADGET,
  222.         NULL,NULL,NULL,NULL,NULL,RENAME_GADGET,NULL,
  223.     NULL,5,174,72,8,GADGHCOMP,GADGIMMEDIATE | RELVERIFY,BOOLGADGET,
  224.         NULL,NULL,NULL,NULL,NULL, GETDIR_GADGET,NULL,
  225.     NULL,5,174,72,8,GADGHCOMP,GADGIMMEDIATE | RELVERIFY,BOOLGADGET,
  226.         NULL,NULL,NULL,NULL,NULL,MAKEDIR_GADGET,NULL,
  227.     NULL,5,174,72,8,GADGHCOMP,GADGIMMEDIATE | RELVERIFY,BOOLGADGET,
  228.         NULL,NULL,NULL,NULL,NULL,DELETEDIR_GADGET,NULL,
  229.     NULL,5,174,72,8,GADGHCOMP,GADGIMMEDIATE | RELVERIFY,BOOLGADGET,
  230.         NULL,NULL,NULL,NULL,NULL,PARENT_GADGET,NULL,
  231.     NULL,5,174,72,8,GADGHCOMP,GADGIMMEDIATE | RELVERIFY,BOOLGADGET,
  232.         NULL,NULL,NULL,NULL,NULL,ROOT_GADGET,NULL,
  233.     NULL,5,174,72,8,GADGHCOMP,GADGIMMEDIATE | RELVERIFY,BOOLGADGET,
  234.         NULL,NULL,NULL,NULL,NULL,LIST_GADGET,NULL,
  235. #ifdef SHOW
  236.     NULL,5,174,72,8,GADGHCOMP,GADGIMMEDIATE | RELVERIFY,BOOLGADGET,
  237.         NULL,NULL,NULL,NULL,NULL,SHOW_GADGET,NULL,
  238. #endif
  239. };
  240.  
  241. /* BORDER DEFINITION FOR FILE SELECT AREA */
  242. USHORT Fil_pairs [] = { 40,15,  356,15,  356,98, 40,98, 40,15, };
  243. struct Border Fil_border =
  244. {
  245.     -1,-1,              /* Leftedge, Topedge */
  246.     1, 0, JAM1,        /* FrontPen, BackPen, Drawmode */
  247.     5,                 /* Number of Pairs */
  248.     (APTR) Fil_pairs,   /* XY, Pointer to XY pairs */
  249.     NULL,               /* More borders */
  250. };
  251.  
  252.  
  253. struct NewWindow nw =
  254. {
  255.     0,0,                /* Start position */
  256.     640,134,            /* Width, height */
  257.     0,1,                 /* Detail, block pens */
  258.     WinIDCMP,        /* IDCMP flags */
  259.     WINDOWSIZING
  260.     | WINDOWDEPTH
  261.     | WINDOWDRAG
  262.     | REPORTMOUSE
  263.     | WINDOWCLOSE
  264.     | ACTIVATE
  265.     | RMBTRAP
  266.     | SMART_REFRESH,
  267.     &FIRST_GADGET,      /* First gadget in the list */
  268.     NULL,               /* User checkmark */
  269.     "D I R U T I L    I I: Chris Nicotra / Dave Jobusch",
  270.     NULL,   
  271.     NULL,               /* Pointer to superbitmap */
  272.     100, 40, 640, 125,     /* Now sizeable */
  273.     WBENCHSCREEN,       /* Using the Workbench screen */
  274. };
  275.  
  276. /* The following structure is used to hold the directory entries */
  277. struct DirTable
  278. {
  279.     char  dt_fname[MAXCHAR];    /* File name */
  280.     short dt_select;        /* Select flag */
  281.     short dt_dir;            /* Directory flag */
  282.     long  dt_size;            /* File size */
  283. };
  284.  
  285. struct DirTable dirtable[MAXFILE+1];
  286. struct FileLock *InitialCurrentDirLock;
  287. struct FileLock *CurrentDirLock;
  288. struct FileLock *RAMSHOWLOCK;
  289. int cmp_dt();
  290. int numdir;
  291. int cur_index;
  292. int NILFD = 0;
  293. unsigned int mask = 0;
  294. char curdir[MAXCD+1],requestedcd[MAXCD+1];
  295.  
  296. main(argc,argv)
  297. char *argv[];
  298. {
  299.     struct Gadget *gad_ptr;
  300.     struct IntuiText *text_ptr;
  301.     ULONG MessageClass;
  302.     USHORT code;
  303.     int i;
  304. #ifdef SHOW
  305.     char SHOWNAME[SHOWNAMELENGTH];
  306. #endif
  307.  
  308.     if(argc>2) {
  309.         printf("usage: %s [SHOW]\n",*argv);
  310.         exit(1);
  311.     }
  312.  
  313. #ifdef SHOW
  314.     if((argc==0)||((argc==2)&&(!strcmp(argv[1],"SHOW")))) {
  315.     /*  WBENCH      CLI AND SHOW OPTION                                    */
  316.         if(!(NILFD = Open("nil:",MODE_OLDFILE))) {
  317.             puts("DirUtil FATAL: Can't open NIL: in main\n");
  318.             exit(2);
  319.         }
  320.     /* If SHOW option was given, the default show command is loaded */
  321.     /* into the RAMdisk. It will will show up in DIRUTIL directory    */
  322.     /* listings of RAM: but it cant be deleted while you are    */
  323.     /* still in DIRUTIL. Create the path name for your show cmd,    */
  324.     /* and put a copy of it into RAMDisk. Then rename it to RAMSHOW */
  325.     /* Sure its a kludge, but this way I didn't have to change copy */
  326.     /* or do an Execute. If for some reason you are running two    */
  327.     /* DirUtil's, the Rename will fail, but there will still be    */
  328.     /* a RAM:DIRUTIL.SHOW file...I hope.                */
  329.         sprintf(SHOWNAME,"%s/%s",SHOWDIR,SHOWCMD);
  330.         copy(SHOWNAME,"ram:");
  331.         sprintf(SHOWNAME,"%s%s","ram:",SHOWCMD);
  332.         Rename(SHOWNAME,RAMSHOW);
  333.         if(!(RAMSHOWLOCK = Lock(RAMSHOW,ACCESS_READ))) {
  334.             printf("DirUtil FATAL: Can't get Lock on %s\n",RAMSHOW);
  335.             Close(NILFD);
  336.             exit(3);
  337.         }
  338.     } 
  339. #endif
  340.  
  341.     *cp_buf = 0;
  342.     strcpy(curdir,"ram:");
  343.     strcpy(requestedcd,curdir);
  344.     if(!(CurrentDirLock = Lock(curdir,ACCESS_READ))) {
  345.         printf("DirUtil FATAL: Could not lock RAMdisk!\n");
  346.         close_things();
  347.         exit(4);
  348.     }
  349.     mask |= INITDIRLOCKOK;
  350.     InitialCurrentDirLock = CurrentDir(CurrentDirLock);
  351.  
  352.     /* Gadget initialization */
  353.     slide_prop.Flags = FREEVERT | AUTOKNOB;
  354.     slide_prop.VertBody = 0;
  355.     slide_prop.VertPot = 0x8000;
  356.  
  357.     /* Setup the button gadgets */
  358.     for (i=0;i<(BUT_LAST-BUT_FIRST)+1;i++) {
  359.         gad_ptr = &But_gad[i];
  360.         text_ptr = &But_text[i];
  361.  
  362.         gad_ptr->LeftEdge = ((i%3) * 90) + 360;
  363.         gad_ptr->TopEdge = ((i/3) * 15) + 14;
  364.  
  365.         if (i)
  366.             gad_ptr->NextGadget = &But_gad[i-1];
  367.         else
  368.             gad_ptr->NextGadget = &Slide_gad;
  369.  
  370.         gad_ptr->GadgetText = text_ptr;
  371.  
  372.         text_ptr->LeftEdge = 0;
  373.         text_ptr->TopEdge = 0;
  374.     }
  375.  
  376.     if (!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",0))) {
  377.         puts("DirUtil FATAL : no graphics library!!!\n");
  378.         close_things();
  379.         exit(5);
  380.     }
  381.     mask |= GRAPHICS;
  382.  
  383.     if (!(IntuitionBase = (struct IntuitionBase *)
  384.         OpenLibrary("intuition.library",0))) {
  385.         puts("DirUtil FATAL : no intuition here!!\n");
  386.         close_things();
  387.         exit(6);
  388.     }
  389.     mask |= INTUITION;
  390.  
  391.     if (!(w = (struct Window *) OpenWindow(&nw) )) {
  392.         puts("DirUtil FATAL : Could not open the window\n");
  393.         close_things();
  394.         exit(7);
  395.     }
  396.     mask |= WINDOW;
  397.  
  398.     /************ INITIALIZATION BEFORE main() loop *****************/
  399.     rp = w->RPort;
  400.     DrawBorder(rp,&Fil_border,0,0);
  401.  
  402.     getdir(curdir);
  403.     new_dir();
  404.  
  405.     display_error("O.K.",0);
  406.     RefreshGadgets(&FIRST_GADGET,w,NULL);
  407. #ifdef SHOW
  408.     if(!NILFD) OffGadget(&KILL_SHOW,w,NULL);
  409. #endif
  410.  
  411.     for (;;) {
  412.         WaitPort(w->UserPort); 
  413.             message = (struct IntuiMessage *) GetMsg(w->UserPort);
  414.         MessageClass = message->Class;
  415.         code = message->Code;
  416.         ReplyMsg(message);
  417.         switch (MessageClass) {
  418.             case GADGETUP:
  419.             case GADGETDOWN:
  420.                 display_error("O.K.",0);
  421.                         do_gadgets(message,w);
  422.                         break;
  423.  
  424.             case REFRESHWINDOW:
  425.                 BeginRefresh(w); EndRefresh(w);
  426.                 dis_files(cur_index);
  427.                 DrawBorder(rp,&Fil_border,0,0);
  428.                 break;
  429.  
  430.             case CLOSEWINDOW:
  431.                 close_things();
  432.                 exit(0);
  433.                         break;
  434.  
  435.             case MOUSEBUTTONS:
  436.                 if (code == SELECTDOWN)
  437.                     sel_file();
  438.                         break;
  439.  
  440.             default:
  441.                 break;
  442.         } /*end switch*/
  443.         } /*end for*/
  444. }
  445.  
  446. do_gadgets(mes,win)
  447. struct IntuiMessage *mes;
  448. struct Window *win;
  449. {
  450.     struct FileLock *MakeDirLock;
  451.     struct Gadget *igad;
  452.     int gadgid;                 /* ID Code identifying which gadget */
  453.     int i;
  454.  
  455.     igad = (struct Gadget *) mes->IAddress;
  456.     gadgid = igad->GadgetID;
  457.     switch (gadgid) {
  458.         case CURDIR_GADGET:
  459.                 ModifyIDCMP(w,0);
  460.             nullterm(cd_buf,MAXCD);
  461.             Curdir_str.NumChars = strlen(cd_buf);
  462.             Curdir_str.BufferPos = strlen(cd_buf);
  463.             getdir(cd_buf);
  464.             new_dir();
  465.             ModifyIDCMP(w,WinIDCMP);
  466.             break;
  467.  
  468.         case ERR_GADGET:
  469.             nullterm(err_buf,MAXCD);
  470.             err_str.NumChars = strlen(err_buf);
  471.             err_str.BufferPos = strlen(err_buf);
  472.             break;
  473.  
  474.         case CPDIR_GADGET:    
  475.             nullterm(cp_buf,MAXCD);
  476.             Cpdir_str.NumChars = strlen(cp_buf);
  477.             Cpdir_str.BufferPos = strlen(cp_buf);
  478.             break;
  479.  
  480.         case SLIDE_GADGET:
  481.             rdis_files();
  482.             break;
  483.  
  484.         case ROOT_GADGET:
  485.         case PARENT_GADGET:
  486.             par_dir(gadgid);
  487.             break;
  488.  
  489. #ifdef SHOW
  490.         case SHOW_GADGET:
  491.             display_error("SHOW : Now showing selected pictures.",0);
  492. #endif
  493.         case DELETE_GADGET:
  494.         case COPY_GADGET:
  495.         case LIST_GADGET:
  496.         case RENAME_GADGET:
  497.         case DELETEDIR_GADGET:
  498.             action_on_selected(gadgid);
  499.             break;
  500.  
  501.         case MAKEDIR_GADGET:
  502.         /* Attempt to create the named directory. Note that since
  503.            the CurrentDir is whatever is in the CurrentDir gadget,
  504.            if you don't give a complete path name, it will assume
  505.            to create the directory in the current directory.
  506.            Also, 1.1 CreateDir does not care if you try to create
  507.            a directory entry on top of a file of the same name.
  508.            Code around this...                       */
  509.             if(MakeDirLock = Lock(cp_buf,ACCESS_READ)) {
  510.                 UnLock(MakeDirLock);
  511.                 display_error("MAKEDIR ERROR : DIRECTORY / FILE ALREADY EXISTS. " ,IoErr());
  512.                 break;
  513.             } 
  514.             if (!(MakeDirLock = CreateDir(cp_buf))) {
  515.                 display_error("MAKEDIR ERROR : CreateDir FAILED. ", IoErr());
  516.                 break;
  517.             }
  518.             UnLock(MakeDirLock);
  519.             getdir(curdir);
  520.             new_dir();
  521.             break;
  522.  
  523.         case DF0_GADGET:
  524.             getdir("df0:"); new_dir(); break;
  525.         case DF1_GADGET:
  526.             getdir("df1:"); new_dir(); break;
  527.         case RAM_GADGET:
  528.             getdir("ram:"); new_dir(); break;
  529.         case HD0_GADGET:
  530.             getdir("hd0:"); new_dir(); break;
  531.  
  532.         case GETDIR_GADGET: 
  533.             getdir(requestedcd);
  534.             new_dir();
  535.             break;
  536.  
  537.         case CLEAR_GADGET:
  538.             for (i=0;i<numdir;i++)
  539.                 dirtable[i].dt_select = 0;
  540.             dis_files(cur_index);
  541.             break;
  542.  
  543.         case ALL_GADGET:
  544.             for (i=0;i<numdir;i++)
  545.                 if (!dirtable[i].dt_dir)
  546.                     dirtable[i].dt_select = 1;
  547.             dis_files(cur_index);
  548.             break;
  549.  
  550.         default:
  551.                 break;
  552.     }
  553. }
  554.  
  555.  
  556. getdir(DirToGet) 
  557. char *DirToGet;
  558. {
  559.     struct FileLock *filelock;
  560.     struct FileInfoBlock *fb;
  561.     char EffectiveDir[MAXCD+1];
  562.  
  563.     if (!(*DirToGet))
  564.         strcpy(EffectiveDir,":");
  565.     else
  566.         strcpy(EffectiveDir,DirToGet);
  567.  
  568.     /* If we cant open requested dir, don't change */
  569. TRYAGAIN:
  570.     if (!(filelock = Lock(EffectiveDir,ACCESS_READ))) {
  571.         strcpy(EffectiveDir,curdir);
  572.         display_error("ERROR : CAN'T LOCK REQUESTED DIRECTORY. ", IoErr());
  573.         if(!(filelock = Lock(EffectiveDir,ACCESS_READ))) {
  574.             display_error("FATAL : CAN'T LOCK CURRENT DIR. SWITCHING TO RAM: ", IoErr());
  575.             strcpy(EffectiveDir,"RAM:");
  576.             goto TRYAGAIN;
  577.         }
  578.     }
  579.     /* Allocate the file info block */
  580.     fb = AllocMem(FBSIZE,MEMF_CLEAR | MEMF_PUBLIC);
  581.     if (!Examine(filelock,fb)) {
  582.         FreeMem(fb,FBSIZE);
  583.         UnLock(filelock);
  584.         display_error("FATAL : CAN'T READ INFO BLOCK. SWITCHING TO RAM: ",IoErr());
  585.         strcpy(EffectiveDir,"RAM:");
  586.         goto TRYAGAIN;
  587.     }
  588.     if(fb->fib_DirEntryType < 0) {     /* ITS A FILE- NOT A DIRECTORY    */
  589.         strcpy(EffectiveDir,curdir);/* Forget request, use current*/
  590.         FreeMem(fb,FBSIZE);
  591.         UnLock(filelock);
  592.         display_error("WARNING : DIRECTORY REQUESTED WAS REGULAR FILE - NO CHANGES. ", IoErr());
  593.         goto TRYAGAIN;
  594.     }
  595.  
  596.     /* Copy directory string into gadget structure */
  597.     strcpy(cd_buf,EffectiveDir);
  598.     Curdir_str.NumChars = strlen(EffectiveDir);
  599.     Curdir_str.BufferPos = strlen(EffectiveDir);
  600.     strcpy(curdir,EffectiveDir);
  601.     strcpy(requestedcd,EffectiveDir);
  602.     RefreshGadgets(&Cpdir_gad,w,NULL);
  603.  
  604.     numdir = 0;
  605.     cur_index = 0;
  606.  
  607.     /* Loop through each of the files in this directory */
  608.     while (ExNext(filelock,fb)) {
  609.             if (fb->fib_DirEntryType < 0)
  610.             dirtable[numdir].dt_dir = 0;
  611.         else
  612.             dirtable[numdir].dt_dir = -1;
  613.         dirtable[numdir].dt_select = 0;
  614.         dirtable[numdir].dt_size = fb->fib_Size;
  615.         strncpy(dirtable[numdir].dt_fname,fb->fib_FileName,MAXCHAR);
  616.         nullterm(dirtable[numdir].dt_fname,MAXCHAR);
  617.  
  618.         if (++numdir == MAXFILE)
  619.             break;
  620.     }
  621.  
  622.     /* Sort the table */
  623.     qsort(dirtable,numdir,(sizeof (struct DirTable)),cmp_dt); 
  624.     FreeMem(fb,FBSIZE);
  625.     UnLock(CurrentDirLock);        /* Release old CD lock        */
  626.     UnLock(filelock);        /* Release new request lock */
  627.     CurrentDirLock = Lock(EffectiveDir);
  628.     CurrentDir(CurrentDirLock);    /* MAKE IT THE CURRENT DIRECTORY */
  629. }
  630.  
  631.  
  632.  
  633. rdis_files()
  634. {
  635.     USHORT Vpot;
  636.     int numd;
  637.     int pos;
  638.  
  639.     if (numdir > MAXFNAME) {
  640.         Vpot = slide_prop.VertPot;
  641.         Vpot >>= 1;
  642.         Vpot &= 0x7fff;
  643.         numd = numdir - MAXFNAME;
  644.         pos = ((float) Vpot / (float) 0x7fff) * numd;
  645.         cur_index = pos;
  646.         dis_files(pos);
  647.     }
  648. }
  649.  
  650. /**********************************************************************
  651. *    new_dir - New directory
  652. *    Purpose: To display a new directory and initialize the slide gadget.
  653. **********************************************************************/
  654. new_dir()
  655. {
  656.     USHORT Vbody;
  657.  
  658.     if (numdir <= MAXFNAME) 
  659.         Vbody = 0xffff;
  660.     else {
  661.         Vbody = ((float) 0x7fff) / (((float) numdir) / ((float) MAXFNAME));
  662.         Vbody <<= 1;
  663.     }
  664.     cur_index = 0;
  665.     ModifyProp(&Slide_gad,w,NULL,slide_prop.Flags,0,0,0,Vbody);
  666.     dis_files(0);
  667. }
  668.  
  669. /**********************************************************************
  670. *    dis_files - Display files
  671. *    Purpose:      To display a page of file names
  672. *    Parameters: pos - The position in the file list
  673. **********************************************************************/
  674. dis_files(pos)
  675. int pos;
  676. {
  677.     int i;
  678.  
  679.     for (i=0;i<MAXFNAME;i++)
  680.         dis_name(i+pos,i);
  681. }
  682.  
  683. /***********************************************************************
  684. *    dis_name - Display a file name
  685. *    Purpose: To display a file name
  686. *    Parameters:
  687. *        file - File index (into dirtable) or -1 for blank entry
  688. *        pos - The position in the file list
  689. **********************************************************************/
  690. dis_name(file,pos)
  691. int file;
  692. int pos;
  693. {
  694.     static char file_name[MAXCHAR+8];
  695.     static struct IntuiText file_text = {
  696.         2,0,JAM2,45,15,NULL,(UBYTE *)file_name, NULL };
  697.  
  698.     /* Set the top position */
  699.     file_text.TopEdge = (pos*8)+16;
  700.  
  701.     if (file == -1 || file >= numdir) {
  702.         sprintf(file_name,"%-38.38s","");
  703.         file_text.FrontPen = 2;
  704.         file_text.BackPen = 2;    /* black */
  705.     } else {
  706.         if (dirtable[file].dt_dir) {
  707.             sprintf(file_name,"%-30.30s%-8.8s",dirtable[file].dt_fname,"");
  708.             if (dirtable[file].dt_select) {
  709.                 file_text.FrontPen = 2; /* Black on Orange */
  710.                 file_text.BackPen = 3;
  711.             } else {
  712.                 file_text.FrontPen = 3; /* Orange on Black */
  713.                 file_text.BackPen = 2;
  714.             }
  715.         } else {
  716.             sprintf(file_name,"%-30.30s %7ld",dirtable[file].dt_fname,
  717.             dirtable[file].dt_size);
  718.             if (dirtable[file].dt_select) {
  719.                 file_text.FrontPen = 2; /* Black on White */
  720.                 file_text.BackPen = 1;
  721.             } else {
  722.                 file_text.FrontPen = 1; /* White on Black  */
  723.                 file_text.BackPen = 2;
  724.             }
  725.         }
  726.     }
  727.  
  728.     /* Display the text */
  729.     PrintIText(rp,&file_text,0,0);
  730. }
  731.  
  732. /**********************************************************************
  733. *    sel_file - Select file
  734. *
  735. *    Purpose: To check if a file has been selected and the select
  736. *        or unselect it
  737. **********************************************************************/
  738. sel_file()
  739. {
  740.     int file,i;
  741.     char *ptr;
  742.  
  743.     if (message->MouseX < 45 || message->MouseX > 351)
  744.         return;
  745.     if (message->MouseY < 16 || message->MouseY >= (MAXFNAME*8+16))
  746.         return;
  747.     file = message->MouseY - 16;
  748.     file /= 8;
  749.     if((!numdir) || (file > MAXFNAME) || ((file+cur_index) > numdir))
  750.         return;
  751.  
  752.     /* Check to see if selection is a directory, or regular file    */
  753.     /* For now, only allow one directory to be selected at a time    */
  754.     if (dirtable[file+cur_index].dt_dir) {
  755.         for(i=0;i<numdir;i++)
  756.             if((dirtable[i].dt_dir)&&(i != file+cur_index))
  757.                 dirtable[i].dt_select = 0;
  758.         ptr = curdir + strlen(curdir) - 1;
  759.         if(dirtable[file+cur_index].dt_select ^= 1) 
  760.             sprintf(requestedcd,"%s%s%s",curdir,((*ptr == ':') ? "":"/"),
  761.             dirtable[file+cur_index].dt_fname);
  762.         else
  763.             strcpy(requestedcd,curdir);
  764.         dis_files(cur_index);
  765.         return;
  766.     }
  767.     dirtable[file+cur_index].dt_select ^= 1;
  768.     dis_name(file+cur_index,file);
  769. }
  770.  
  771. action_on_selected(gadgid) /* Copy,Delete,ShowILBM,List,DELETEDIR */
  772. int gadgid;
  773. {
  774.     struct IntuiMessage *message;
  775.     int i;
  776.     int j,k;
  777.     char filename[MAXCD+MAXCHAR+2];
  778.     char *ptr;
  779. #ifdef SHOW
  780.     char command[MAXCD+MAXCHAR+2+RAMSHOWLEN];/* See comments in #defines*/
  781. #endif
  782.  
  783.     /* At each iteration, check for any IntuiMessages that would signal
  784.        user wants to halt operation: GADGETUP(he hit a gadget) or
  785.        MOUSEBUTTONS(button press on something we dont recognize) */
  786.  
  787.     ModifyIDCMP(w,GADGETUP | MOUSEBUTTONS);
  788.     for (i=0;i<numdir;i++) {
  789.         if(message = (struct IntuiMessage *) GetMsg(w->UserPort)) {
  790.             ReplyMsg(message);
  791.             display_error("INTERRUPT : OPERATION HALTED.",0);
  792.             break; 
  793.         }
  794.  
  795.         if (dirtable[i].dt_select) {
  796.             ptr = curdir + strlen(curdir)-1;
  797.             if (*ptr == ':')
  798.                 sprintf(filename,"%s%s",curdir,dirtable[i].dt_fname);
  799.             else
  800.                 sprintf(filename,"%s/%s",curdir,dirtable[i].dt_fname);
  801.  
  802.             switch (gadgid) {
  803.                 case DELETE_GADGET:
  804.                     if(dirtable[i].dt_dir) {
  805.                         display_error("DELETE ERROR : FILE IS A DIRECTORY.",0);
  806.                         break;
  807.                     }
  808.                     if(!(DeleteFile(filename)))
  809.                     display_error("DELETE ERROR : COULD NOT DELETE REQUESTED FILE. ", IoErr());
  810.                     break;
  811.  
  812.                 case DELETEDIR_GADGET:
  813.                     if(!dirtable[i].dt_dir) {
  814.                         display_error("DELETEDIR ERROR : FILE IS NOT A DIRECTORY. ",0);
  815.                         break;
  816.                     }
  817.                     if(!(DeleteFile(filename)))
  818.                         display_error("DELETEDIR ERROR : COULD NOT DELETE REQUESTED DIRECTORY. ", IoErr());
  819.                     break;
  820.  
  821.                 case COPY_GADGET:
  822.                     copy(filename,cp_buf);
  823.                     break;
  824.  
  825. #ifdef SHOW
  826.                 case SHOW_GADGET:
  827.                     if(NILFD) {
  828.                         sprintf(command,"%s %s",RAMSHOW,filename);
  829.                         Execute(command,0,NILFD);
  830.                         dirtable[i].dt_select = 0;
  831.                         dis_files(cur_index);
  832.                     }
  833.                     break;
  834. #endif
  835.  
  836.                 case LIST_GADGET:
  837.                 /* K L U D G E */
  838.                     ptr = &filename;
  839.                     while((*ptr != ':')&&(*ptr != '\0')) ptr++;
  840.                     printf("%s\n",ptr);
  841.                     dirtable[i].dt_select = 0;
  842.                     break;
  843.  
  844.                 case RENAME_GADGET:
  845.                 /* NOTE: you must select the file to be renamed -
  846.                    this doesnt check cd_buf for a filename!    */
  847.                     if(!(Rename(filename,cp_buf))) 
  848.                         display_error("RENAME ERROR : CANNOT RENAME TO REQUESTED PATH. ", IoErr());
  849.                     break;
  850.  
  851.                 default:
  852.                 break;
  853.             } /*switch*/
  854.             if(RENAME_GADGET == gadgid)
  855.                 break; /* RENAME FIRST FILE SELECTED ONLY! */
  856.         } /* if selected */
  857.     } /* for all */
  858.  
  859. #ifdef SHOW
  860.     if((SHOW_GADGET == gadgid)||(LIST_GADGET == gadgid)) {
  861. #endif
  862. #ifndef SHOW
  863.     if(LIST_GADGET == gadgid) {
  864. #endif
  865.         dis_files(cur_index);
  866.     } else {
  867.         getdir(curdir);
  868.         new_dir();
  869.     }
  870.     ModifyIDCMP(w, WinIDCMP);
  871. }
  872.  
  873. par_dir(gadgid) /* Parent and Root */
  874. int gadgid;
  875. {
  876.     char *ptr;           /* With this, we may change curdir  */
  877.  
  878.     ModifyIDCMP(w,0);
  879.     ptr = curdir+strlen(curdir)-1;
  880.     if(PARENT_GADGET == gadgid)
  881.         for (;ptr >= curdir;ptr--) {
  882.              if (*ptr == ':') { 
  883.                 *(ptr+1) = 0; 
  884.                 break;
  885.             }
  886.             if (*ptr == '/') { 
  887.                 *ptr = 0;
  888.                 break;
  889.             }
  890.         }
  891.     else     /* Gadget was root. Scan back to :  */
  892.         for (;ptr >= curdir;ptr--) 
  893.             if (*ptr == ':') {
  894.                 *(ptr+1) = 0;
  895.                 break;
  896.             }
  897.  
  898.     getdir(curdir);
  899.     new_dir();
  900.     ModifyIDCMP(w,WinIDCMP);
  901.     return;
  902. }
  903.  
  904. /* The following function is used to compare two directory entries */
  905. cmp_dt(dt1,dt2)
  906. struct DirTable *dt1,*dt2;
  907. {
  908.    char *ptr1,*ptr2;
  909.    int c1,c2;
  910.  
  911.    for (ptr1=dt1->dt_fname,ptr2=dt2->dt_fname;*ptr1 && *ptr2;ptr1++,ptr2++) {
  912.     c1 = *ptr1;
  913.     c2 = *ptr2;
  914.  
  915.     if (c1 >= 'A' && c1 <= 'Z') {
  916.         c1 -= 'A';
  917.         c1 += 'a';
  918.        }
  919.  
  920.        if (c2 >= 'A' && c2 <= 'Z') {
  921.         c2 -= 'A';
  922.         c2 += 'a';
  923.        }
  924.  
  925.        if (c1 > c2)
  926.         return (-1);
  927.  
  928.        if (c1 < c2)
  929.         return (1);
  930.    }
  931.  
  932.    if (*ptr1)
  933.        return (-1);
  934.  
  935.    if (*ptr2)
  936.     return (1);
  937.  
  938.    return (0);
  939. }
  940.  
  941. copy(s,pc)
  942. char *s;
  943. char *pc;
  944. {
  945.     struct FileHandle  *copyin;
  946.     struct FileHandle  *copyout;
  947.     int iosize;
  948.     int actual;
  949.     char *copybuf;
  950.     char work[300];
  951.     struct FileLock *fl;
  952.     char *ptr;
  953.     char *ptr1;
  954.  
  955.     if (!(copyin = Open(s,MODE_OLDFILE)))
  956.         return;
  957.  
  958.     if (!*pc) {
  959.         display_error("COPY ERROR : NO DESTINATION PATH GIVEN.",0);
  960.         return;
  961.     }
  962.  
  963.     if ((fl = Lock(pc,ACCESS_READ))) {
  964.         UnLock(fl);
  965.         ptr = strlen(pc) + pc - 1;
  966.         for (ptr1=s+strlen(s)-1;ptr1 > s;ptr1--) {
  967.             if (*ptr1 == '/' || *ptr1 == ':')
  968.                 break;
  969.         }
  970.         if (*ptr1 == '/' || *ptr1 == ':')
  971.             ptr1++;
  972.         if (*ptr == ':')
  973.             sprintf(work,"%s%s",pc,ptr1);
  974.         else
  975.             sprintf(work,"%s/%s",pc,ptr1);
  976.     } else {
  977.         display_error("COPY ERROR : ILLEGAL DESTINATION PATH. ", IoErr());
  978.         Close(copyin);
  979.         return;
  980.     }
  981.  
  982.     if (!strcmp(work,s)) {
  983.         display_error("COPY ERROR : CANNOT COPY FILE TO ITSELF. ",0);
  984.         Close(copyin);
  985.         return;
  986.     }
  987.  
  988.     if (!(copyout = Open(work, MODE_NEWFILE))) {
  989.         display_error("COPY ERROR : COPY CANNOT WRITE TO REQUESTED PATH. ", IoErr());
  990.         Close(copyin);
  991.         return;
  992.     } else {
  993.         /* Determine the length of the file */
  994.         iosize = Seek(copyin, 0, OFFSET_END);
  995.         iosize = Seek(copyin, 0, OFFSET_BEGINING);
  996.  
  997.         /* Allocate memory for the copy buffer */
  998.         do {
  999.             copybuf = AllocMem(iosize, MEMF_PUBLIC|MEMF_CLEAR);
  1000.             if (copybuf == 0)
  1001.                 iosize = iosize/2;
  1002.         } while (copybuf == 0 & iosize > 512);
  1003.  
  1004.         /* Copy the file */
  1005.         do {
  1006.             actual = Read(copyin, copybuf, iosize);
  1007.             if (Write(copyout, copybuf, actual) != actual)
  1008.                 break;
  1009.         } while (actual == iosize);
  1010.  
  1011.         /* Free the copy buffer */
  1012.         FreeMem(copybuf, iosize);
  1013.  
  1014.         /* Close the input and output buffers */
  1015.         Close(copyout);
  1016.         Close(copyin);
  1017.     }
  1018. }
  1019.  
  1020. nullterm(str,len)    /* End a string with a null */
  1021. char *str;
  1022. int len;
  1023. {
  1024.     int i;
  1025.  
  1026.     str[len] = 0; 
  1027.     for (i=len;len >= 0;len--) {
  1028.         if (str[i] != ' ' && str[i])
  1029.             break;
  1030.         str[i] = 0;
  1031.     }
  1032. }
  1033.  
  1034. display_error(errormsg,doserrnum)
  1035. char *errormsg;
  1036. long doserrnum;
  1037. {
  1038.     strcpy(err_buf,errormsg);
  1039.     if(doserrnum)
  1040.         sprintf(err_buf,"%s (Dos Error %d)",err_buf,doserrnum);
  1041.     err_str.NumChars = strlen(err_buf);
  1042.     err_str.BufferPos = strlen(err_buf);
  1043.     RefreshGadgets(&Err_gad,w,NULL);
  1044. }
  1045.  
  1046. close_things()
  1047. {
  1048.     if (mask & WINDOW)
  1049.         CloseWindow(w);
  1050.  
  1051.     if (mask & GRAPHICS)
  1052.         CloseLibrary(GfxBase);
  1053.  
  1054.     (void) OpenWorkBench();
  1055.  
  1056.     if (mask & INTUITION)
  1057.         CloseLibrary(IntuitionBase);
  1058.  
  1059. #ifdef SHOW
  1060.     if(NILFD) {
  1061.         UnLock(RAMSHOWLOCK);
  1062.         DeleteFile(RAMSHOW);
  1063.         Close(NILFD);
  1064.     }
  1065. #endif
  1066.  
  1067.     if(mask & INITDIRLOCKOK) {
  1068.     CurrentDir(InitialCurrentDirLock);
  1069.     UnLock(CurrentDirLock);
  1070.     }
  1071. }
  1072.  
  1073. qsort( v, n, size, comp)
  1074. char *v;
  1075. int n;
  1076. int size;
  1077. int (*comp)();
  1078. {
  1079.     int gap, i, j, x, cnt;
  1080.     char temp, *p1, *p2;
  1081.  
  1082.     cnt = 0;
  1083.     for (gap=n/2; gap > 0 ; gap /= 2)
  1084.         for (i=gap; i<n; i++)
  1085.             for (j = i-gap; j >= 0; j -= gap)
  1086.                 if ( (*comp) ( (p1=v+j*size), (p2=v+(j+gap)*size) ) < 0) {
  1087.                     cnt++;
  1088.                     /* exchange them */
  1089.                     for (x=0; x<size; x++) {
  1090.                         temp = *p1;
  1091.                         *p1++ = *p2;
  1092.                         *p2++ = temp;
  1093.                     }
  1094.                 }
  1095.     return(cnt);
  1096. }
  1097.