home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / disks / misc / afcopy_v4.4 / sourcecode / afcopy.c < prev    next >
C/C++ Source or Header  |  1981-06-29  |  76KB  |  2,400 lines

  1. /*
  2.           ________   _______   _______   _______   _______   __    __
  3.          / ____  /\ / _____/\ / _____/\ / ___  /\ / ___  /\ / /\  / /\
  4.         / /\__/ / // /\____\// /\____\// /\_/ / // /\_/ / // / / / / /
  5.        / /_/_/ / // /_/_    / / /     / / // / // /_// / // /_/_/ / /
  6.       / ____  / // ____/\  / / /     / / // / // _____/ //_____  / /
  7.      / /\__/ / // /\___\/ / / /     / / // / // /\____\/ \____/ / /
  8.     / / / / / // / /     / /_/__   / /_// / // / /     ______/ / /
  9.    /_/ / / / //_/ /     /______/\ /______/ //_/ /     /_______/ /
  10.    \_\/  \_\/ \_\/      \______\/ \______\/ \_\/      \_______\/
  11.  
  12.                           HYDRA - Tension/LSD
  13.  
  14.                 AFCopy V4 is (C) 1993-5 Hydra/Tension/LSD
  15.  
  16.    This program was origonally written by me in PCQ Pascal, but I decided to
  17.    rewrite this program to use lots of new workbench 2.x / 3.x fuctions after
  18.    buying a lovely new Amiga 1200. :-)
  19.  
  20.    I just have to say, that after playing around with programming WB3.x I
  21.    love it,  it's SOoo easy with these tag doofers!  MUCH better than defining
  22.    loadsa structures, why people still support WB1.3 intuition beats me!
  23.  
  24.    And golly G O S H!!  I *really* do like REQTOOLS!!
  25.  
  26.  
  27. things to do that have been done
  28.  
  29. 1)  add invisible requester to main window when doing something (such as when
  30.     stat window is open or when user is editing config.
  31.     --> dont need it.
  32. 2)  make option for simple refresh window.. (to save mem, but induces slowdown
  33.     when reorganizing windows.. :-( )
  34.     --> shit idea, do last!!!
  35.     --> but might cure slowdown problem with OS 2.04!!!
  36. 3)  add options for lines_per_side and make window vertical size modifyable.
  37.     --> lines_per_side is now variable, but no option exists to change it once
  38.         program has been started (yet)
  39.     --> ok, it's possible to change it when the program is running now.
  40.         but it still needs an option in the config.
  41.     --> add code to resize window if it cant open with specified amount af
  42.         lines..
  43.     --> added lines per side in config. all ok,  i'll ad resize l8r
  44.  
  45. 5)  add adjustable colours (on directory/file items)
  46.     --> filecol/dircol/highlightcol are variables and saved in config.
  47.         still needs an option in the config section tho.
  48.     --> ok, now saved in config file!
  49. 9)  implement UG_CDC and UG_CDO (need to find what CurrentDir() Returns first)
  50.     --> done now, but do i need it (i have the option to have it) on (un)arc
  51. 12) add file exists checking
  52.     --> done
  53.     --> added autooverwrite to config too..
  54. 16) always update on rename
  55.     --> done!
  56. 23) implement protect!
  57.     --> done
  58. 28) add devicegads/usergads to edit config.. use a menu for this to save
  59.     on code size (ie, you dont have to have another window with loads of
  60.     gadget definitions...)
  61.     --> idea!  Create a window with two string inputs and a load of check
  62.         gadgets for the batch flags!  so when you select item from menu it comes
  63.         up with the window.
  64.     --> Do the same for the device gadgets but dont have check gadgets...
  65.         --> used rtgetstrings instead....
  66. 32) add auto overwrite to config.
  67.     --> done
  68. 27) change filenames[] to pointers and allocate/free memory when needed.
  69.     this will cut down on memory usage quite a bit and possibly allow for more
  70.     files to be displayed in one directory. (IE fonts: !!!!)
  71.     --> done!
  72. 15) make window open in middle of screen (or save position in config!)
  73.     --> opens in the middle!
  74. 30) add option to ExecCommand() for async.
  75.     --> done.
  76. 33) add ScreenToFront/Back on ExecCommand()
  77.     --> done
  78. 11) add samevolume checking to SWAP command and if it is then do a rename...
  79.     --> nope, just do a swap if a rename fails!
  80.     --> done
  81. 35) add font requester for gadget fonts and filename fonts
  82.     --> done!
  83. 34) possibly add more error checking to openmainscreen()
  84.     --> done
  85.  
  86. things to do....  (this list seems to get bigger and bigger!!!!)
  87.  
  88. 6)  start a notify on current directory,  update (or ask to update) if it
  89.     changes.
  90.     --> Usefull for clone/rename/(un)archive/clone....
  91.     --> also have a notify on the current device so as to update disk free...
  92. 7)  configureable middle gadgets. (to let user swap gadgets round)
  93.     --> but is there any point... ?
  94.     --> no !
  95. 8)  selection of archivers/archive name detection...
  96.     --> kind of done,  now recognised .ZIP files and use UNZIP
  97.         still needs to be user-defineable tho..
  98. 10) add amiga guide online help!! (shit, that'll take a while...)
  99. 13) disk inserted prompt - log to left/right or cancl
  100.     --> maybe add sommat in config to enable/disable/automate this ?
  101.     --> added!
  102.     --> dont work if you insert a disk in PC0: or DF1: tho,  only logs to df0:!!!
  103. 14) add keyboard support! (bollox that'll be a bummer!)
  104.     --> all comands can be done with keyboard
  105.     --> just add file selection and highlighting now..
  106. 17) add double click routine, and programmable file types.
  107.     --> that'll take some time :-)
  108.     --> do for version 4.x me thinks!!
  109.     --> double click to change dir is added, but not the programmable file types
  110.         this is a feature i may add in afcopy pro but not in v4
  111. 18) add size directory when double click on dirname.
  112.     --> rather cool idea!!
  113.     --> can't be double click, but maybe a menu option ?
  114. 19) add ZipWindow() hotkey
  115.     --> nope, use YAK instead!! (heheee)
  116. 20) save ZoomCoords in config!
  117. 21) save window coords in config
  118. 22) possibly add fuction in loadconfig for reading in the integers
  119.     so as to save on code size..
  120. 26) add use and cancel gadgets to config. make closewindow same as cancel
  121.     --> Nah...
  122. 29) update disk free when copying files (but have an option for this so as
  123.     not to cause slowdown when using floppies!)
  124. 31) add option to rename old or new file when copying file and destination file exists
  125. 32) add option to rename so that you can choose to rename the icon for the highlighted
  126.     file too..
  127. 36) reactivate window after executing an external command (much in the same
  128.     way as ShuffleScreens at the moment.)
  129. 37) add process indicator
  130. 38) delete files from list to avoid re-reading file list..
  131.  
  132. */
  133.  
  134. /* Not TOO many include files... (honest!!) */
  135.  
  136. #include <stdio.h>
  137. #include <stdlib.h>
  138. #include <string.h>
  139. #include <ctype.h>
  140. #include <time.h>
  141. #include <exec/types.h>
  142. #include <exec/memory.h>
  143. #include <exec/execbase.h>
  144. #include <exec/nodes.h>
  145. #include <exec/lists.h>
  146. #include <dos/dos.h>
  147. #include <dos/dostags.h>
  148. #include <dos/filehandler.h>
  149. #include <libraries/dos.h>
  150. #include <intuition/intuition.h>
  151. #include <intuition/gadgetclass.h>
  152. #include <libraries/reqtools.h>
  153. #include <libraries/dos.h>
  154.  
  155. #include <wb2cli.h>  /* for the correct PATH settings when run from WB */
  156.  
  157. #include <clib/exec_protos.h>
  158. #include <clib/dos_protos.h>
  159. #include <clib/intuition_protos.h>
  160. #include <clib/gadtools_protos.h>
  161. #include <clib/graphics_protos.h>
  162. #include <clib/diskfont_protos.h>
  163. #include <clib/reqtools_protos.h>
  164. #include <clib/wb_protos.h>
  165. #include <clib/alib_protos.h>
  166.  
  167. /* tell compiler vars in afcopyvars.h are NOT external. */
  168. #define MAIN
  169.  
  170. #include "username.h"
  171. #include "afcopy_defines.h"  /* defines */
  172. #include "afcopy_protos.h"   /* prototypes */
  173. #include "afcopy_vars.h"     /* variables */
  174. #include "afcopy_version.h"  /* version defines */
  175.  
  176. extern char *versionstring;
  177.  
  178. long __stack = 40000;          /* for recursive directory stuff.... */
  179.                                /* and lots of it toooo */
  180.  
  181. /* if you wanna test the max stack then goto ram:t in one window and ram: in the other
  182. then in the ram: window select the dir t and copy it to the other window... :-) */
  183.  
  184. ULONG last_sec=0,last_mic=0;
  185. LONG last_x=0,last_y=0;
  186.  
  187. void errormsg(char *errormsgstr)
  188. {
  189.   rtEZRequest (errormsgstr,okmsg,NULL,(struct TagItem *)&reqtags,NULL);
  190. }
  191.  
  192. void checkcustomscreenwindows( void )
  193. {
  194.   if (customscreenopen)
  195.   {
  196.     while (mysc->FirstWindow && mysc->FirstWindow->NextWindow)
  197.     {
  198.       errormsg("Please Close All Windows!");
  199.     };
  200.   }
  201. }
  202.  
  203. /*
  204.  *  Okay, lets get started with the coding now...
  205.  *  Please note all the sarcastic/patronising/funny comments on the rtEZRequest's!!
  206.  *  well,  *I* like them even if you dont! :-)
  207.  */
  208.  
  209. void strfcat(char *dest, char *source, int destlen)
  210. {
  211.   int pos=0,where=strlen(dest);
  212.  
  213.   while (where+pos<destlen && source[pos])
  214.   {
  215.     dest[where+pos]=source[pos];
  216.     pos++;
  217.   }
  218.   dest[where+pos]='\0';
  219. }
  220.  
  221. // small routine to test wether the end of a string equals the match string
  222. // usefull for checking filename extensions
  223.  
  224. BOOL endofstring(char *whole,char *match)
  225. {
  226.   short l1,l2;
  227.  
  228.   for (l1=strlen(whole)-1,l2=strlen(match)-1;
  229.        whole[l1]==match[l2] && l1>0 && l2>0 ;l1--,l2--);
  230.   if (l2==0 && whole[l1]==match[l2]) return(TRUE); else return(FALSE);
  231. }
  232.  
  233. BOOL iendofstring(char *whole,char *match)
  234. {
  235.   short l1,l2;
  236.  
  237.   for (l1=strlen(whole)-1,l2=strlen(match)-1;
  238.        toupper(whole[l1])==toupper(match[l2]) && l1>0 && l2>0 ;l1--,l2--);
  239.   if (l2==0 && toupper(whole[l1])==toupper(match[l2])) return(TRUE); else return(FALSE);
  240. }
  241.  
  242. /* this routine checks if memory has been allocated for a filename, if not it`ll
  243.  * allocate it for us.
  244.  */
  245.  
  246. BOOL allocmemforname(short side)
  247. {
  248.   if (totalfiles[side]+1>allocated[side])
  249.   {
  250.     if (filename[side][totalfiles[side]]=AllocMem(MAX_FILE_LEN+1,MEMF_PUBLIC))
  251.     {
  252.       allocated[side]++;
  253.     }
  254.   }
  255.   if (allocated[side]>totalfiles[side]) return(TRUE); else return(FALSE);
  256. }
  257.  
  258. /* this routine adds a filename to the bottom of the file list, it`ll allocate memory
  259.  * for the name too.
  260.  */
  261.  
  262. BOOL AddToFileList(short side,char *fname,LONG size,LONG type,BYTE tags)
  263. {
  264.   if (totalfiles[side]<MAX_FILES_IN_LIST && stricmp(fname,"") && size>=0 && type!=0 && allocmemforname(side))
  265.   {
  266.     strcpy(filename[side][totalfiles[side]],fname);
  267.     filesize[side][totalfiles[side]]=size;
  268.     filetype[side][totalfiles[side]]=type;
  269.     filetags[side][totalfiles[side]]=tags;
  270.     totalfiles[side]++;
  271.     return(TRUE);
  272.   }
  273.   else
  274.   {
  275.     return(FALSE);
  276.   }
  277. }
  278.  
  279. /* display a single filename and size in the correct colours
  280.  * at position y down the screen on the specified side.
  281.  */
  282. void displaysinglefile(short side,int ypos,int start)
  283. {
  284.   struct tm *TM;
  285.   time_t t;
  286.   if (filetags[side][start])
  287.   {
  288.     SetBPen(W->RPort,highlightcol);
  289.   }
  290.   else
  291.   {
  292.     SetBPen(W->RPort,NORMALCOL);
  293.   }
  294.  
  295.  
  296.   /* SET FOREGROUND COLOUR */
  297.  
  298.   if (filetype[side][start]>0)
  299.   {
  300.     strcpy(dummystring,"<DIR>");
  301.     SetAPen(W->RPort,dircol);
  302.   }
  303.   else
  304.   {
  305.     stci_d(dummystring,filesize[side][start]);
  306.     SetAPen(W->RPort,filecol);
  307.   }
  308.  
  309. /* use below when/if attrs are used....
  310.   switch(DisplayType[side])
  311.   {
  312.     case D_SIZE:
  313.       break;
  314.     case D_DATES:
  315.       t=__datecvt(filedate[side][start]);
  316.       TM=localtime(t);
  317.       strftime(dummystring, 9,"%d/%m/%y", TM);
  318.       break;
  319.     case D_ATTRIB:
  320.       break;
  321.   }
  322. until then use the IF below.
  323. */
  324.  
  325.   if (DisplayType[side]==D_DATES)
  326.   {
  327.     t=__datecvt(&filedate[side][start]);
  328.     TM=localtime(&t);
  329.     strftime(dummystring, 9,"%d/%m/%y", TM);
  330.   }
  331.   strncpy(outputstring,filename[side][start],32);
  332.   strpad(outputstring,32);
  333.   outputstring[31-strlen(dummystring)]=0;
  334.   strcat(outputstring," ");
  335.   strcat(outputstring,dummystring);
  336.  
  337.   /* OUTPUT TEXT */
  338.  
  339.   Move(W->RPort,filexpos[side]+2,topborder+FILEYPOS+FONTBASELINE+(FILEHEIGHT*ypos));
  340.   Text(W->RPort,outputstring,strlen(outputstring));
  341. }
  342.  
  343. /* this routine clears the are of the screen where a filename would have been
  344.  *
  345.  */
  346.  
  347. void wipefile(short side,int ypos)
  348. {
  349.   SetAPen(W->RPort,0);
  350.   SetBPen(W->RPort,0);
  351.   RectFill(W->RPort,filexpos[side]+1,topborder+1+FILEYPOS+(FILEHEIGHT*ypos)-1,
  352.                     filexpos[side]+FILEWIDTH-1,topborder+FILEYPOS+(FILEHEIGHT*(ypos+1))-1);
  353. }
  354.  
  355. /* displays the list of filenames on specified side starting from the specified offset
  356.  *
  357.  */
  358.  
  359. void displayfilelist(short side,int start)
  360. {
  361.   int loop=0;
  362.  
  363.   while (loop<lines_per_side)
  364.   {
  365.     if (start+loop <totalfiles[side])
  366.       displaysinglefile(side,loop,start+loop);
  367.     else
  368.       wipefile(side,loop);
  369.     loop++;
  370.   }
  371. }
  372.  
  373. /* updates the name in the path gadget with the string in cpath[]
  374.  *
  375.  */
  376.  
  377. void updatepath(short side)
  378. {
  379.     GT_SetGadgetAttrs(my_gads[G_Pathleft+side], W, NULL,
  380.                       GTST_String,   cpath[side],
  381.                       TAG_END);
  382. }
  383.  
  384. /* read a new directory.
  385.  *
  386.  */
  387.  
  388. void lognewdir(short side, char *path)
  389. {
  390.   if (path[0]!='\0')
  391.   {
  392.     addterm(path);
  393.     strncpy(cpath[side],path,MAX_PATH_LEN);
  394.     getfiles(side,cpath[side]);
  395.     updatepath(side);
  396.     displayoffset[side]=0;
  397.     displayfilelist(side,displayoffset[side]);
  398.   }
  399.   else
  400.   {
  401.     Updatedisplay(side);
  402.   }
  403. }
  404.  
  405. /* change to the parent directory of the current one.
  406.  *
  407.  */
  408.  
  409. void doparent(short side)
  410. {
  411.   char newpath[MAX_PATH_LEN+1];
  412.  
  413.   strcpy(newpath,cpath[side]);
  414.   getparent(newpath);
  415.  
  416.   /* is it already in root ? */
  417.  
  418.   if (stricmp(newpath,cpath[side]))
  419.   {
  420.     lognewdir(side,newpath);
  421.   }
  422.   else
  423.   {
  424.     findvolumes(currentside);
  425.   }
  426. }
  427.  
  428. void updateselected(short side)
  429. {
  430.   sprintf(dummystring,"%3d/%-3d %7d",selectedfiles[side],totalfiles[side],(int)(selectedsize[side] / 1024));
  431.   SetAPen(W->RPort,2);
  432.   SetBPen(W->RPort,0);
  433.   OutTextXY(W,filexpos[side]+2+(side*17),FONTBASELINE+topborder+3,dummystring);
  434. }
  435.  
  436. void selected(short side, int loop, BOOL yn)
  437. {
  438.   if (filetags[side][loop]!=yn)
  439.   {
  440.     if (yn)
  441.     {
  442.       selectedfiles[side]++;
  443.       selectedsize[side]+=filesize[side][loop];
  444.     }
  445.     else
  446.     {
  447.       selectedfiles[side]--;
  448.       selectedsize[side]-=filesize[side][loop];
  449.     }
  450.     filetags[side][loop]=yn;
  451.     updateselected(side);
  452.   }
  453. }
  454.  
  455. /* turns on and off the tags or reverses them.
  456.  *
  457.  */
  458.  
  459. void setmarks(short side,int action)
  460. {
  461.   int loop;
  462.   if (action!=REVERSE)
  463.   {
  464.     selectedfiles[side]=0;
  465.     selectedsize[side]=0;
  466.   }
  467.   for (loop=0;loop<totalfiles[side];loop++)
  468.   {
  469.     switch (action)
  470.     {
  471.       case MARK:
  472.         filetags[side][loop]=TRUE;
  473.         selectedfiles[side]++;
  474.         selectedsize[side]+=filesize[side][loop];
  475.         break;
  476.       case UNMARK:
  477.         filetags[side][loop]=FALSE;
  478.         break;
  479.       case REVERSE:
  480.         if (filetags[side][loop])
  481.         {
  482.           selected(side,loop,FALSE);
  483.         }
  484.         else
  485.         {
  486.           selected(side,loop,TRUE);
  487.         }
  488.         break;
  489.     }
  490.   }
  491.   updateselected(side);
  492. }
  493.  
  494. /* Display some info
  495.  *
  496.  */
  497.  
  498. void About(void)
  499. {
  500.   char outstr[500];
  501.  
  502.   sprintf(outstr,"AFCOPY V%d.%d (C) 1995 Hydra/Tension/LSD\n\n"
  503.                  "Written And Designed By Hydra/Tension/LSD\n"
  504.                  "Beta Tested By Blue Aardvark/TSN And Big W/TSN"
  505.                  ,VERSION,REVISION);
  506.   rtEZRequestTags(outstr,"I Like it!",NULL,NULL,
  507.                   RTGS_Flags, GSREQF_CENTERTEXT,
  508.                   RT_Window,W,TAG_END);
  509.   rtEZRequestTags("If you find any bugs or errors in AFCopy\n"
  510.                   "then >Please< contact me on any cool UK BBS\n"
  511.                   "so that I can fix em and make it better!",
  512.                   "Fair Enough!",NULL,NULL,
  513.                   RTGS_Flags, GSREQF_CENTERTEXT,RT_Window,W,TAG_END);
  514. }
  515.  
  516.  
  517. /* check to see if the CANCEL gadget has been pressed
  518.  *
  519.  */
  520.  
  521. int CheckStatCancel(void)
  522. {
  523.   struct IntuiMessage *imsg;
  524.   struct Gadget *gad;
  525.   int err=0;
  526.  
  527.   if (statw)    /* check window is open first!!! */
  528.                 /* this is the fix to the MakeDir() bug!!! */
  529.   {
  530.     if ((imsg = GT_GetIMsg(statw->UserPort)))
  531.     {
  532.       if (imsg->Class == IDCMP_GADGETUP)
  533.       {
  534.         gad=(struct Gadget *)imsg->IAddress;
  535.         if (gad->GadgetID==G_StatCancel)
  536.         {
  537.           err=1;
  538.         }
  539.       }
  540.       GT_ReplyIMsg(imsg);
  541.     }
  542.   }
  543.   return(err);
  544. }
  545.  
  546.  
  547. /* update the staus window with the filename and path(s) of the files being worked on
  548.  *
  549.  */
  550.  
  551. void UpdateStat(int amountleft,int amounttotal,char *functionstr,char *fromstr,char *tostr,char *fname)
  552. {
  553.   char outstr[74];
  554.   if (amounttotal!=0)
  555.   {
  556.     sprintf(outstr,"Function: %s  Selected: %d  Done: %d  Complete: %3.0f%%",functionstr,amounttotal,amounttotal-amountleft,((float)(amounttotal-amountleft)/(float)amounttotal)*100);
  557.     strpad(outstr,73);
  558.     outstr[72]='\0';
  559.     OutTextXY(statw,8,topborder+15+FONTBASELINE,outstr);
  560.   }
  561.   strncpy(outstr,fromstr,73);
  562.   strpad(outstr,73);
  563.   outstr[72]='\0';
  564.   OutTextXY(statw,8,topborder+15+9+FONTBASELINE,outstr);
  565.   strncpy(outstr,tostr,73);
  566.   strpad(outstr,73);
  567.   outstr[72]='\0';
  568.   OutTextXY(statw,8,topborder+15+18+FONTBASELINE,outstr);
  569.   strncpy(outstr,fname,73);
  570.   strpad(outstr,73);
  571.   outstr[72]='\0';
  572.   OutTextXY(statw,8,topborder+15+27+FONTBASELINE,outstr);
  573.   DrawBevelBox(statw->RPort,5,topborder+12,STATWIDTH-10,42,GT_VisualInfo,vi,TAG_DONE);
  574. }
  575.  
  576. /* checks to see if fname1 is in the same dir as dirname
  577.  * E.g. fname="sys:hydra/data.iff" dirname="sys:hydra" returns true!
  578.  */
  579.  
  580. int SameDir(char *fname1,char *dirname)
  581. {
  582.   char tempstr[MAX_PATH_LEN+1];
  583.  
  584.   strcpy(tempstr,fname1);
  585.   getparent(tempstr);
  586.   addterm(tempstr);
  587.   if (!stricmp(tempstr,dirname)) return(TRUE); else return(FALSE);
  588. }
  589.  
  590. /*
  591.  *
  592.  */
  593.  
  594. void Updatedisplay(short side)
  595. {
  596.   updatepath(side);
  597.   qsortfiles(side,0,totalfiles[side]-1);
  598.   updateslider(side,displayoffset[side]);
  599.   displayfilelist(side,displayoffset[side]);
  600.   DoDiskInfo(side,cpath[side]);
  601.   updateselected(side);
  602. }
  603.  
  604. void FreeNameList(struct List *FileList)
  605. {
  606.   struct Node *Current,*Next;
  607.  
  608.   if (Current=FileList->lh_Head)
  609.   {
  610.     while (FileList->lh_Head->ln_Succ)
  611.     {
  612.       Next=Current->ln_Succ;
  613.       if (Current->ln_Name)
  614.       {
  615.         free(Current->ln_Name);
  616.       }
  617.       Remove(Current);
  618.       FreeMem(Current,sizeof(struct Node));
  619.       Current=Next;
  620.     }
  621.   }
  622. }
  623.  
  624. struct Node *NewNameNode(struct List *NameList,char *str)
  625. {
  626.   struct Node *new=NULL;
  627.  
  628.   if (new=AllocMem(sizeof(struct Node),MEMF_PUBLIC))
  629.   {
  630.     new->ln_Name=strdup(str);
  631.     AddTail(NameList,new);
  632.   }
  633.   return(new);
  634. }
  635.  
  636. void dofuncerror(char *errorstr)
  637. {
  638.   Errors++; // do NOT relate ERRORS to nodes in list when in CMDline mode
  639.   NewNameNode(ErrorList,errorstr);
  640.   GT_SetGadgetAttrs(statgads[G_ErrorList], statw, NULL,
  641.                     GTLV_Labels, ErrorList,
  642.                     GTLV_Top, Errors-1, // errors is always > 0 if this is called!
  643.                     TAG_END);
  644. }
  645.  
  646. void DosError(char *msg,char *msg2,int errnum)
  647. {
  648.   char errmsg[401],iomsg[50]; /* allocate plenty of room */
  649.  
  650.   IoErrMsg(iomsg,errnum);
  651.   strcpy(errmsg,msg2);
  652.   strfcat(errmsg," ",400);
  653.   strfcat(errmsg,iomsg,400);
  654.   dofuncerror(errmsg);
  655. }
  656.  
  657.  
  658.  
  659.  
  660.  
  661.  
  662. struct Gadget *createProtGadgets(struct Gadget **glistptr, void *vi,
  663.     UWORD topborder, struct Gadget *gads[])
  664. {
  665.   struct NewGadget ng;
  666.   struct Gadget *gad;
  667.  
  668.   gad = CreateContext(glistptr);
  669.  
  670.   ng.ng_LeftEdge   = 5;
  671.   ng.ng_TopEdge    = 1+topborder;
  672.   ng.ng_Width      = 8;
  673.   ng.ng_Height     = 10;
  674.   ng.ng_TextAttr   = &ScreenFontAttr;
  675.   ng.ng_VisualInfo = vi;
  676.   ng.ng_Flags      = PLACETEXT_RIGHT;
  677.   ng.ng_GadgetID   = G_p_d;
  678.   ng.ng_GadgetText = "Delete";
  679.   gads[G_p_d] = gad = CreateGadget(CHECKBOX_KIND, gad, &ng,GTCB_Checked,TRUE,TAG_END);
  680.   ng.ng_TopEdge   += ng.ng_Height+2;
  681.   ng.ng_GadgetID   = G_p_e;
  682.   ng.ng_GadgetText = "Execute";
  683.   gads[G_p_e] = gad = CreateGadget(CHECKBOX_KIND, gad, &ng,GTCB_Checked,TRUE,TAG_END);
  684.   ng.ng_TopEdge   += ng.ng_Height+2;
  685.   ng.ng_GadgetID   = G_p_w;
  686.   ng.ng_GadgetText = "Write";
  687.   gads[G_p_w] = gad = CreateGadget(CHECKBOX_KIND, gad, &ng,GTCB_Checked,TRUE,TAG_END);
  688.   ng.ng_TopEdge   += ng.ng_Height+2;
  689.   ng.ng_GadgetID   = G_p_r;
  690.   ng.ng_GadgetText = "Read";
  691.   gads[G_p_r] = gad = CreateGadget(CHECKBOX_KIND, gad, &ng,GTCB_Checked,TRUE,TAG_END);
  692.   ng.ng_LeftEdge   = 105;
  693.   ng.ng_TopEdge    = 1+topborder;
  694.   ng.ng_GadgetID   = G_p_a;
  695.   ng.ng_GadgetText = "Archived";
  696.   gads[G_p_a] = gad = CreateGadget(CHECKBOX_KIND, gad, &ng,TAG_END);
  697.   ng.ng_TopEdge   += ng.ng_Height+2;
  698.   ng.ng_GadgetID   = G_p_s;
  699.   ng.ng_GadgetText = "Script";
  700.   gads[G_p_s] = gad = CreateGadget(CHECKBOX_KIND, gad, &ng,TAG_END);
  701.   ng.ng_TopEdge   += ng.ng_Height+2;
  702.   ng.ng_GadgetID   = G_p_p;
  703.   ng.ng_GadgetText = "Pure";
  704.   gads[G_p_p] = gad = CreateGadget(CHECKBOX_KIND, gad, &ng,TAG_END);
  705.   ng.ng_TopEdge   += ng.ng_Height+2;
  706.   ng.ng_GadgetID   = G_p_h;
  707.   ng.ng_GadgetText = "Hidden";
  708.   gads[G_p_h] = gad = CreateGadget(CHECKBOX_KIND, gad, &ng,TAG_END);
  709.  
  710.   return(gad);
  711. }
  712.  
  713. struct Window *OpenProtWindow(void)
  714.  
  715. {
  716.     return(OpenWindowTags(NULL,
  717.                           WA_Left,W->LeftEdge+210,
  718.                           WA_Top,W->TopEdge+50,
  719.                           WA_Height,65,
  720.                           WA_Width,220,
  721.                           WA_AutoAdjust,    FALSE,
  722.                           WA_DragBar,       TRUE,
  723.                           WA_DepthGadget,   TRUE,
  724.                           WA_Activate,      TRUE,
  725.                           WA_CloseGadget,   TRUE,
  726.                           WA_SimpleRefresh, FALSE,
  727.                           WA_IDCMP,         IDCMP_CLOSEWINDOW|IDCMP_VANILLAKEY,
  728.                           WA_Title,"File Protection Bits",
  729.                           WA_PubScreen, mysc,
  730.                           WA_Gadgets,protglist,
  731.                           TAG_END));
  732. }
  733.  
  734.  
  735. int EditProt( void )  /* returns -1 if failed or cancelled.. */
  736. {
  737.   struct IntuiMessage *imsg;
  738.   BOOL done=FALSE;
  739.   int prot=0;
  740.   if (createProtGadgets(&protglist, vi, topborder,protgads))
  741.   {
  742.     if ((protw=OpenProtWindow()))
  743.     {
  744.       do
  745.       {
  746.         Wait (1 << protw->UserPort->mp_SigBit);
  747.         if ((imsg = GT_GetIMsg(protw->UserPort)))
  748.         {
  749.           if (imsg->Class == IDCMP_CLOSEWINDOW)
  750.           {
  751.             done=TRUE;
  752.           }
  753.           GT_ReplyIMsg(imsg);
  754.         }
  755.       } while (!done);
  756.       CloseWindow(protw);
  757.  
  758.       if (!(protgads[G_p_d] ->Flags & GFLG_SELECTED)) prot+=1;
  759.       if (!(protgads[G_p_e] ->Flags & GFLG_SELECTED)) prot+=2;
  760.       if (!(protgads[G_p_w] ->Flags & GFLG_SELECTED)) prot+=4;
  761.       if (!(protgads[G_p_r] ->Flags & GFLG_SELECTED)) prot+=8;
  762.  
  763.       if (protgads[G_p_a] ->Flags & GFLG_SELECTED) prot+=16;
  764.       if (protgads[G_p_p] ->Flags & GFLG_SELECTED) prot+=32;
  765.       if (protgads[G_p_s] ->Flags & GFLG_SELECTED) prot+=64;
  766.       if (protgads[G_p_h] ->Flags & GFLG_SELECTED) prot+=128;
  767.     }
  768.     FreeGadgets(protglist);
  769.   }
  770.   if (!done) return(-1); else return(prot); /* done will be false if window didnt open or
  771.                                               cadgets weren't created. */
  772. }
  773.  
  774. /* returns the amount of files on a specified side that have been selected
  775.  * by the user
  776.  */
  777.  
  778. int AmountTagged(short side)
  779. {
  780.   int loop;
  781.   int retval=0;
  782.  
  783.   for (loop=0;loop<totalfiles[side];loop++)
  784.   {
  785.     if (filetags[side][loop]) retval++;
  786.   }
  787.   return(retval);
  788. }
  789.  
  790.  
  791. /***************
  792.  
  793.  main functions
  794.  
  795.  every gadget that has anything to do with files comes through here...
  796.  (including user gadgets with flags set to UG_SENDFILES)
  797.  
  798.  ***************/
  799.  
  800. #define DF_READNONE    0
  801. #define DF_READCURRENT 1
  802. #define DF_READOTHER   2    /* defines for reading dir after function */
  803. #define DF_READBOTH    3
  804.  
  805. void handlerefresh(void)
  806. {
  807.   struct IntuiMessage *imsg;
  808.   ULONG imsgClass;
  809.   UWORD imsgCode;
  810.   struct Gadget *gad;
  811.   while (imsg = GT_GetIMsg(W->UserPort))
  812.   {
  813.     gad = (struct Gadget *)imsg->IAddress;
  814.     imsgClass = imsg->Class;
  815.     imsgCode = imsg->Code;
  816.     GT_ReplyIMsg(imsg);
  817.     switch(imsgClass)
  818.     {
  819.       case IDCMP_REFRESHWINDOW:
  820.         GT_BeginRefresh(W);
  821.         GT_EndRefresh(W, TRUE);
  822.         UpdateMainWindow();
  823.         break;
  824.       case IDCMP_NEWSIZE:
  825.         iconised=!iconised;
  826.         if (!iconised)
  827.         {
  828.           UpdateMainWindow();
  829.         }
  830.         break;
  831.     }
  832.   }
  833. }
  834.  
  835. void CopyFileDetails(int from,int to,int which)
  836. {
  837.   if (totalfiles[to]<MAX_FILES_IN_LIST)
  838.   {
  839.     if (allocmemforname(to))
  840.     {
  841.       strcpy(filename[to][totalfiles[to]],filename[from][which]);
  842.       filetype[to][totalfiles[to]]=filetype[from][which];
  843.       filesize[to][totalfiles[to]]=filesize[from][which];
  844.       filedate[to][totalfiles[to]]=filedate[from][which];
  845.       filetags[to][totalfiles[to]]=0;
  846.       totalfiles[to]++;
  847.       selected(to,totalfiles[to]-1,TRUE);
  848.     }
  849.   }
  850. }
  851.  
  852. void Dofunction(int mode,short side)
  853. {
  854.   int errnum=0,loop=0,myprot=-1,where;
  855.   BOOL doall=FALSE,ok=FALSE,done=FALSE,cancel=FALSE,ignorebatcherrors;
  856.   int ReadDir=DF_READNONE;
  857.   short otherside=1-side;
  858.   char arcname[MAX_PATH_LEN+1],pathstr[MAX_PATH_LEN+1],tmpstr[MAX_PATH_LEN+1];
  859.   FILE *arcfile=NULL;
  860.   BPTR FL;
  861.   int amountleft;
  862.   int last_displayoffset=0;
  863.  
  864.   tempautooverwrite=FALSE;
  865.   Errors=0;
  866.   if (ErrorList=(struct List *)AllocMem(sizeof(struct List),MEMF_ANY))
  867.   {
  868.     NewList(ErrorList);
  869.  
  870.     if (selectedfiles[side]>0)
  871.     {
  872.       amountleft=selectedfiles[side];
  873.       switch (mode)
  874.       {
  875.         case G_Clone:
  876.         case G_Swap:
  877.         case G_Copy:
  878.           if (pathok[side] && pathok[otherside]) ok=TRUE;
  879.           break;
  880.         case G_Delete:
  881.           if (pathok[side]) ok=!deleteverify || rtEZRequest("Are you sure you\n want me to delete\nthese files ?","_Yes|_No!",NULL,(struct TagItem *)&reqtags,NULL);
  882.              /* Clever bit of coding on the above line!!!  (think about it!!!) */
  883.           break;
  884.         case G_Archive:
  885.           strcpy(arcname,cpath[otherside]);
  886.           if ((pathok[side]) && (rtGetString (arcname, MAX_PATH_LEN, "Enter Archive Name", NULL,RT_Window,W, TAG_END))
  887.               && (arcname[0]!='\0') )
  888.           {
  889.             ok=TRUE;
  890.           }
  891.           break;
  892.         case G_Rename:
  893.         case G_View:
  894.         case G_Read:
  895.         case G_Edit:
  896.         case G_Hear:
  897.         case G_Info:
  898.         case G_Execute:
  899.         case G_Run:
  900.         case G_Comment:
  901.         case G_Unarc:
  902.           if (pathok[side]) ok=TRUE;
  903.           break;
  904.         case G_Batch:
  905.           if (rtGetString(batchstring,MAX_COMMAND_LEN,"Batch",NULL,
  906.                                                         RTGS_TextFmt,"Enter Batch String\n"
  907.                                                                      "Use @F@ for full filename\n"
  908.                                                                      "@N@ for name\n"
  909.                                                                      "@E@ for extension\n"
  910.                                                                      "@<@ for current side\n"
  911.                                                                      "@>@ for other side\n\n"
  912.                                                                      "see instructions\n"
  913.                                                                      "for more details",
  914.                                                         RTGS_Flags, GSREQF_CENTERTEXT,
  915.                                                         RT_Window,W,
  916.                                                         TAG_END))
  917.           {
  918.             ignorebatcherrors=(nomessages) || (rtEZRequest("Ignore Errors Between Programs ?","_Yes|_No!",NULL,(struct TagItem *)&reqtags,NULL));
  919.             ok=TRUE;
  920.           }
  921.           break;
  922.         case G_Userleft0:
  923.         case G_Userleft1:
  924.         case G_Userleft2:
  925.         case G_Userleft3:
  926.         case G_Userleft4:
  927.         case G_Userleft5:
  928.         case G_Userleft6:
  929.         case G_Userleft7:
  930.         case G_Userleft8:
  931.         case G_Userleft9:
  932.         case G_Userleft10:
  933.         case G_Userleft11:
  934.         case G_Userleft12:
  935.         case G_Userleft13:
  936.         case G_Userleft14:
  937.           if (usergadflags[0][mode-G_Userleft0]!=0)
  938.           {
  939.             if (usergadflags[0][mode-G_Userleft0] & UG_SENDFILES)
  940.             {
  941.               ok=TRUE;
  942.             }
  943.             else
  944.             {
  945.               if (usergadflags[0][mode-G_Userleft0] & UG_CDC) cdto(cpath[side]);
  946.               if (usergadflags[0][mode-G_Userleft0] & UG_CDO) cdto(cpath[otherside]);
  947.               ExecCommand(usergadactual[0][mode-G_Userleft0],(usergadflags[0][mode-G_Userleft0] & UG_ASYNCH > 0) ? TRUE : FALSE,
  948.                                                              (usergadflags[0][mode-G_Userleft0] & UG_SHUFFLE > 0) ? TRUE : FALSE );
  949.               ReadDir=0;
  950.               if (usergadflags[0][mode-G_Userleft0] & UG_READC) ReadDir+=DF_READCURRENT;
  951.               if (usergadflags[0][mode-G_Userleft0] & UG_READO) ReadDir+=DF_READOTHER;
  952.             }
  953.           }
  954.           break;
  955.         case G_Userright0:
  956.         case G_Userright1:
  957.         case G_Userright2:
  958.         case G_Userright3:
  959.         case G_Userright4:
  960.         case G_Userright5:
  961.         case G_Userright6:
  962.         case G_Userright7:
  963.         case G_Userright8:
  964.         case G_Userright9:
  965.         case G_Userright10:
  966.         case G_Userright11:
  967.         case G_Userright12:
  968.         case G_Userright13:
  969.         case G_Userright14:
  970.           if (usergadflags[1][mode-G_Userright0]!=0)
  971.           {
  972.             if (usergadflags[1][mode-G_Userright0] & UG_SENDFILES)
  973.             {
  974.               ok=TRUE;
  975.             }
  976.             else
  977.             {
  978.               if (usergadflags[1][mode-G_Userright0] & UG_CDC) cdto(cpath[side]);
  979.               if (usergadflags[1][mode-G_Userright0] & UG_CDO) cdto(cpath[otherside]);
  980.               ExecCommand(usergadactual[1][mode-G_Userright0],(usergadflags[1][mode-G_Userright0] & UG_ASYNCH) > 0 ? TRUE : FALSE,
  981.                                                               (usergadflags[1][mode-G_Userright0] & UG_SHUFFLE) > 0 ? TRUE : FALSE );
  982.               ReadDir=0;
  983.               if (usergadflags[1][mode-G_Userright0] & UG_READC) ReadDir+=DF_READCURRENT;
  984.               if (usergadflags[1][mode-G_Userright0] & UG_READO) ReadDir+=DF_READOTHER;
  985.             }
  986.           }
  987.           break;
  988.         case G_Protect:
  989.           myprot=EditProt();
  990.           if (myprot!=-1) ok=TRUE;
  991.           break;
  992.       }
  993.       if (ok)
  994.       {
  995.         if (createStatGadgets(&statglist, vi, topborder,statgads))
  996.         {
  997.           if ((statw=OpenStatWindow()))
  998.           {
  999.             DrawBevelBox(statw->RPort,5,topborder+12,STATWIDTH-10,42,GT_VisualInfo,vi,TAG_DONE);
  1000.             SetFont(statw->RPort,ScreenFont);
  1001.             SetAPen(statw->RPort,2);
  1002.             if (pathok[side])
  1003.             {
  1004.               displayfilelist(side,0);
  1005.               do
  1006.               {
  1007.                 handlerefresh();
  1008.                 if (filetags[side][loop] && !(cancel=CheckStatCancel()) )
  1009.                 {
  1010.                   // new for v4.2
  1011.  
  1012.                   if (loop>=last_displayoffset+lines_per_side)
  1013.                   {
  1014.                     last_displayoffset=loop;
  1015.                     if (last_displayoffset>totalfiles[side]-lines_per_side) last_displayoffset=totalfiles[side]-lines_per_side;
  1016.                     displayfilelist(side,last_displayoffset);
  1017.                     updateslider(side,last_displayoffset);
  1018.                   }
  1019.  
  1020.                   // end new bit..
  1021.  
  1022.                   actuallytransferred=AT_NO;
  1023.  
  1024.                   strcpy(pathstr,cpath[side]);
  1025.                   addterm(pathstr);
  1026.                   strfcat(pathstr,filename[side][loop],MAX_PATH_LEN);
  1027.  
  1028.                   /** pathstr contains path+filename of currentfile **/
  1029.  
  1030.                   strcpy(tmpstr,cpath[otherside]);
  1031.                   addterm(tmpstr);
  1032.                   strfcat(tmpstr,filename[side][loop],MAX_PATH_LEN);
  1033.  
  1034.                   /** tmpstr contains otherside's path+filename of currentfile **/
  1035.  
  1036.                   switch(mode)  /* for filetype independant functions */
  1037.                   {
  1038.                     case G_Protect:
  1039.                       UpdateStat(amountleft,selectedfiles[side],"Protect",cpath[side],"",filename[side][loop]);
  1040.                       errnum=SetProtection(pathstr,myprot);
  1041.                       if (!errnum) DosError("Error Protecting File",pathstr,errnum);
  1042.                       break;
  1043.                     case G_View:
  1044.                       UpdateStat(amountleft,selectedfiles[side],"View",cpath[side],"",filename[side][loop]);
  1045.                       createstring(tmpstr,CommandString[C_View],side,loop,CS_ALL);
  1046.                       errnum=ExecCommand(tmpstr,FALSE,shufflescreens);
  1047.                       if (errnum && !nomessages) DosError("Error Viewing File",pathstr,errnum);
  1048.                       break;
  1049.                     case G_Read:
  1050.                       UpdateStat(amountleft,selectedfiles[side],"Read",cpath[side],"",filename[side][loop]);
  1051.                       createstring(tmpstr,CommandString[C_Read],side,loop,CS_ALL);
  1052.                       errnum=ExecCommand(tmpstr,FALSE,shufflescreens);
  1053.                       if (errnum && !nomessages) DosError("Error Reading File",pathstr,errnum);
  1054.                       break;
  1055.                     case G_Edit:
  1056.                       UpdateStat(amountleft,selectedfiles[side],"Edit",cpath[side],"",filename[side][loop]);
  1057.                       createstring(tmpstr,CommandString[C_Edit],side,loop,CS_ALL);
  1058.                       errnum=ExecCommand(tmpstr,FALSE,shufflescreens);
  1059.                       if (errnum && !nomessages) DosError("Error Editing File",pathstr,errnum);
  1060.                       break;
  1061.                     case G_Hear:
  1062.                       UpdateStat(amountleft,selectedfiles[side],"Hear",cpath[side],"",filename[side][loop]);
  1063.                       createstring(tmpstr,CommandString[C_Hear],side,loop,CS_ALL);
  1064.                       errnum=ExecCommand(tmpstr,FALSE,shufflescreens);
  1065.                       if (errnum && !nomessages) DosError("Error Hearing File",pathstr,errnum);
  1066.                       break;
  1067.                     case G_Info:
  1068.                       strcpy(tmpstr,filename[side][loop]);
  1069.                       if ((where=iposition(".INFO",tmpstr))>=0)
  1070.                       {
  1071.                         tmpstr[where]=0; // remove .INFO from string.
  1072.                       }
  1073.                       if (FL=Lock(cpath[side],ACCESS_READ))
  1074.                       {
  1075.                         WBInfo(FL,tmpstr,mysc);
  1076.                         UnLock(FL);
  1077.                       }
  1078.                       break;
  1079.                     case G_Execute:
  1080.                       UpdateStat(amountleft,selectedfiles[side],"Execute Script",cpath[side],"",filename[side][loop]);
  1081.                       createstring(tmpstr,CommandString[C_Execute],side,loop,CS_ALL);
  1082.                       errnum=ExecCommand(tmpstr,FALSE,shufflescreens);
  1083.                       if (errnum && !nomessages) DosError("Error Executing Script",pathstr,errnum);
  1084.                       break;
  1085.                     case G_Run:
  1086.                       UpdateStat(amountleft,selectedfiles[side],"Run Program",cpath[side],"",filename[side][loop]);
  1087.                       strcpy(tmpstr,"\"");
  1088.                       strcat(tmpstr,pathstr);
  1089.                       strcat(tmpstr,"\"");
  1090.                       if (errnum=rtGetString (tmpstr, MAX_PATH_LEN, "Modify Command Line", NULL,
  1091.                                        RTGS_GadFmt, "Run|Run Asynch|Cancel",
  1092.                                        RT_Window,W, TAG_END))
  1093.                       {
  1094.                         errnum=ExecCommand(tmpstr,errnum==2 ? TRUE : FALSE,shufflescreens);
  1095.                         if (errnum && !nomessages) DosError("Error Running Program",pathstr,errnum);
  1096.                       }
  1097.                       else
  1098.                       {
  1099.                         cancel=TRUE;
  1100.                       }
  1101.                       break;
  1102.                     case G_Archive:
  1103.                       UpdateStat(amountleft,selectedfiles[side],"Archive List",cpath[side],"",filename[side][loop]);
  1104.                       if (!arcfile)  /* is file open */
  1105.                       {   /* No,  then open it */
  1106.                         if ((arcfile=fopen("T:AFCopy.tmp","w"))==NULL)
  1107.                         {
  1108.                           errnum=IoErr();
  1109.                           if (errnum) DosError("Error Create Arc Temp File","T:AFCopy.TMP",errnum);
  1110.                         }
  1111.                       }
  1112.                       if (arcfile) /* is file open */
  1113.                       {
  1114.                         fprintf(arcfile,"%s\n",filename[side][loop]);  /* add filename to arcfile */
  1115.                       }
  1116.                       break;
  1117.                     case G_Unarc:
  1118.                       UpdateStat(amountleft,selectedfiles[side],"Un-Archive",cpath[side],"",filename[side][loop]);
  1119.                       cdto(cpath[otherside]);
  1120.                       if (iendofstring(filename[side][loop],".zip"))
  1121.                       {
  1122.                         strcpy(arcname,"unzip \"");
  1123.                       }
  1124.                       else
  1125.                       {
  1126.                         strcpy(arcname,CommandString[C_Unarc]);
  1127.                         strfcat(arcname," x \"",MAX_PATH_LEN);
  1128.                       }
  1129.                       strfcat(arcname,pathstr,MAX_PATH_LEN);
  1130.                       strfcat(arcname,"\"",MAX_PATH_LEN);
  1131.   //                    strfcat(arcname,cpath[otherside],MAX_PATH_LEN);
  1132.   //                    strfcat(arcname,"\"",MAX_PATH_LEN);
  1133.                       if (rtGetString (arcname, MAX_PATH_LEN, "Modify Command Line", NULL,RT_Window,W, TAG_END))
  1134.                       {
  1135.                         ReadDir=DF_READOTHER;
  1136.                         errnum=ExecCommand(arcname,FALSE,shufflescreens);
  1137.                         if (errnum && !nomessages) DosError("Error Running Unarchiver",CommandString[C_Unarc],errnum);
  1138.                       }
  1139.                       break;
  1140.                     case G_Batch:
  1141.                       UpdateStat(amountleft,selectedfiles[side],"Command Batch",cpath[side],"",filename[side][loop]);
  1142.                       createstring(tmpstr,batchstring,side,loop,CS_ALL);
  1143.                       errnum=ExecCommand(tmpstr,FALSE,shufflescreens);
  1144.                       if (errnum && !ignorebatcherrors) DosError("Error Running Program",pathstr,errnum);
  1145.                       break;
  1146.                     case G_Userleft0:
  1147.                     case G_Userleft1:
  1148.                     case G_Userleft2:
  1149.                     case G_Userleft3:
  1150.                     case G_Userleft4:
  1151.                     case G_Userleft5:
  1152.                     case G_Userleft6:
  1153.                     case G_Userleft7:
  1154.                     case G_Userleft8:
  1155.                     case G_Userleft9:
  1156.                     case G_Userleft10:
  1157.                     case G_Userleft11:
  1158.                     case G_Userleft12:
  1159.                     case G_Userleft13:
  1160.                     case G_Userleft14:
  1161.                       UpdateStat(amountleft,selectedfiles[side],"User Command",usergadnames[0][mode-G_Userleft0],"",filename[side][loop]);
  1162.  
  1163.                       strcpy(tmpstr,usergadactual[0][mode-G_Userleft0]);
  1164.                       if (usergadflags[0][mode-G_Userleft0] & UG_SENDFILES)
  1165.                       {
  1166.                         createstring(tmpstr,tmpstr,side,loop,CS_ALL);
  1167.                       }
  1168.                       else
  1169.                       {
  1170.                         createstring(tmpstr,tmpstr,side,loop,CS_NOFILES);
  1171.                       }
  1172.  
  1173.                       if (usergadflags[0][mode-G_Userleft0] & UG_MODIFY)
  1174.                       {
  1175.                         if (!rtGetString (tmpstr, MAX_PATH_LEN, "Modify Command Line", NULL,RT_Window,W, TAG_END)) cancel=TRUE;
  1176.                       }
  1177.                       if (!cancel)
  1178.                       {
  1179.                         if (usergadflags[0][mode-G_Userleft0] & UG_CDC) cdto(cpath[side]);
  1180.                         if (usergadflags[0][mode-G_Userleft0] & UG_CDO) cdto(cpath[otherside]);
  1181.                         errnum=ExecCommand(tmpstr,(usergadflags[0][mode-G_Userleft0] & UG_ASYNCH) > 0 ? TRUE : FALSE,
  1182.                                                   (usergadflags[0][mode-G_Userleft0] & UG_SHUFFLE) > 0 ? TRUE : FALSE );
  1183.                         if (errnum && !nomessages) DosError("Error Running Program",pathstr,errnum);
  1184.                         else
  1185.                         {
  1186.                           ReadDir=0;
  1187.                           if (usergadflags[0][mode-G_Userleft0] & UG_READC) ReadDir+=DF_READCURRENT;
  1188.                           if (usergadflags[0][mode-G_Userleft0] & UG_READO) ReadDir+=DF_READOTHER;
  1189.                         }
  1190.                       }
  1191.                       break;
  1192.                     case G_Userright0:
  1193.                     case G_Userright1:
  1194.                     case G_Userright2:
  1195.                     case G_Userright3:
  1196.                     case G_Userright4:
  1197.                     case G_Userright5:
  1198.                     case G_Userright6:
  1199.                     case G_Userright7:
  1200.                     case G_Userright8:
  1201.                     case G_Userright9:
  1202.                     case G_Userright10:
  1203.                     case G_Userright11:
  1204.                     case G_Userright12:
  1205.                     case G_Userright13:
  1206.                     case G_Userright14:
  1207.                       UpdateStat(amountleft,selectedfiles[side],"User Command",usergadnames[1][mode-G_Userright0],"",filename[side][loop]);
  1208.                       strcpy(tmpstr,usergadactual[1][mode-G_Userright0]);
  1209.                       if (usergadflags[1][mode-G_Userright0] & UG_SENDFILES)
  1210.                       {
  1211.                         createstring(tmpstr,tmpstr,side,loop,CS_ALL);
  1212.                       }
  1213.                       else
  1214.                       {
  1215.                         createstring(tmpstr,tmpstr,side,loop,CS_NOFILES);
  1216.                       }
  1217.  
  1218.                       if (usergadflags[1][mode-G_Userright0] & UG_MODIFY)
  1219.                       {
  1220.                         if (!rtGetString (tmpstr, MAX_PATH_LEN, "Modify Command Line", NULL,RT_Window,W, TAG_END)) cancel=TRUE;
  1221.                       }
  1222.                       if (!cancel)
  1223.                       {
  1224.                         if (usergadflags[1][mode-G_Userright0] & UG_CDC) cdto(cpath[side]);
  1225.                         if (usergadflags[1][mode-G_Userright0] & UG_CDO) cdto(cpath[otherside]);
  1226.                         errnum=ExecCommand(tmpstr,(usergadflags[1][mode-G_Userright0] & UG_ASYNCH) > 0 ? TRUE : FALSE,
  1227.                                                   (usergadflags[1][mode-G_Userright0] & UG_ASYNCH) > 0 ? TRUE : FALSE );
  1228.                         if (errnum && !nomessages) DosError("Error Running Program",pathstr,errnum);
  1229.                         else
  1230.                         {
  1231.                           ReadDir=0;
  1232.                           if (usergadflags[1][mode-G_Userright0] & UG_READC) ReadDir+=DF_READCURRENT;
  1233.                           if (usergadflags[1][mode-G_Userright0] & UG_READO) ReadDir+=DF_READOTHER;
  1234.                         }
  1235.                       }
  1236.                       break;
  1237.                     case G_Rename:
  1238.                       UpdateStat(amountleft,selectedfiles[side],"Rename",cpath[side],"",filename[side][loop]);
  1239.                       strcpy(tmpstr,pathstr);
  1240.                       if (rtGetString (tmpstr, MAX_PATH_LEN, "Enter New Name", NULL,RT_Window,W, TAG_END))
  1241.                       {
  1242.                         if (strcmp(tmpstr,pathstr)!=0)
  1243.                         {
  1244.                           Rename(pathstr,tmpstr);
  1245.                           errnum=IoErr();
  1246.                           if (errnum) DosError("Error Renaming File",pathstr,errnum);
  1247.                           else
  1248.                           {
  1249.                             ReadDir=DF_READCURRENT;
  1250.                           }
  1251.                         }
  1252.  
  1253.                       }
  1254.                       break;
  1255.                     case G_Comment:
  1256.                       UpdateStat(amountleft,selectedfiles[side],"Comment File",cpath[side],"",filename[side][loop]);
  1257.                       errnum=ModifyComment(pathstr,doall);
  1258.                       if (errnum==-1) doall=TRUE;
  1259.                       if (errnum>0) DosError("Error Commenting File",pathstr,errnum);
  1260.                       break;
  1261.                   }
  1262.                   if (filetype[side][loop]<0)  /* is it a DIR or a FILE */
  1263.                   {  /* FILE */
  1264.                     switch(mode)
  1265.                     {
  1266.                       case G_Delete:
  1267.                         UpdateStat(amountleft,selectedfiles[side],"Delete",cpath[side],"",filename[side][loop]);
  1268.                         errnum=filenuke(pathstr);
  1269.                         if (errnum>0) DosError("Error Deleting File",pathstr,errnum);
  1270.                         else
  1271.                         {
  1272.                           ReadDir=DF_READCURRENT;
  1273.                         }
  1274.                         break;
  1275.                       case G_Copy:
  1276.                         UpdateStat(amountleft,selectedfiles[side],"Copy",cpath[side],cpath[otherside],filename[side][loop]);
  1277.                         errnum=filecopy(pathstr,tmpstr);
  1278.                         if (errnum>0) DosError("Error Copying File",pathstr,errnum);
  1279.                         if (actuallytransferred==AT_YES)
  1280.                         {
  1281.                           CopyFileDetails(side,otherside,loop);
  1282.                         }
  1283.                         if (actuallytransferred==AT_OVERW)
  1284.                         {
  1285.                           ReadDir=DF_READOTHER;
  1286.                         }
  1287.                         break;
  1288.                       case G_Clone:
  1289.                         UpdateStat(amountleft,selectedfiles[side],"Clone",cpath[side],cpath[otherside],filename[side][loop]);
  1290.                         if (rtGetString (tmpstr, MAX_PATH_LEN, "Enter Clone Name", NULL,RT_Window,W, TAG_END))
  1291.                         {
  1292.                           if (stricmp(pathstr,tmpstr)!=0)
  1293.                           {
  1294.                             errnum=filecopy(pathstr,tmpstr);
  1295.                             if (errnum) DosError("Error Cloning File",pathstr,errnum);
  1296.                             else
  1297.                             {
  1298.                               ReadDir=DF_READOTHER;
  1299.                             }
  1300.                           }
  1301.                         }
  1302.                         break;
  1303.                       case G_Swap:
  1304.                         UpdateStat(amountleft,selectedfiles[side],"Swap",cpath[side],cpath[otherside],filename[side][loop]);
  1305.                         errnum=fileswap(pathstr,tmpstr);
  1306.                         if (errnum>0) DosError("Error Swapping File",pathstr,errnum);
  1307.                         if (ReadDir!=DF_READBOTH) ReadDir=DF_READCURRENT;
  1308.                         if (actuallytransferred==AT_YES)
  1309.                         {
  1310.                           CopyFileDetails(side,otherside,loop);
  1311.                         }
  1312.                         if (actuallytransferred==AT_OVERW)
  1313.                         {
  1314.                           ReadDir=DF_READBOTH;
  1315.                         }
  1316.                         break;
  1317.                     }
  1318.                   }
  1319.                   else
  1320.                   {  /* DIR */
  1321.                     switch(mode)
  1322.                     {
  1323.                       case G_Delete:
  1324.                         UpdateStat(amountleft,selectedfiles[side],"Delete",cpath[side],"",filename[side][loop]);
  1325.                         errnum=DirFunc(pathstr,NULL,mode);
  1326.                         if (errnum) DosError("Error Deleting Directory",pathstr,errnum);
  1327.                         else ReadDir=DF_READCURRENT;
  1328.                         break;
  1329.                       case G_Copy:
  1330.                         UpdateStat(amountleft,selectedfiles[side],"Copy",cpath[side],cpath[otherside],filename[side][loop]);
  1331.                         errnum=DirFunc(pathstr,tmpstr,mode);
  1332.                         ReadDir=DF_READOTHER;
  1333.                         if (errnum) DosError("Error Copying Directory",pathstr,errnum);
  1334.                         break;
  1335.                       case G_Clone:
  1336.                         UpdateStat(amountleft,selectedfiles[side],"Copy",cpath[side],cpath[otherside],filename[side][loop]);
  1337.                         if (rtGetString (tmpstr, MAX_PATH_LEN, "Enter Clone Name", NULL,RT_Window,W, TAG_END))
  1338.                         {
  1339.                           if (stricmp(pathstr,tmpstr)!=0)
  1340.                           {
  1341.                             errnum=DirFunc(pathstr,tmpstr,G_Copy);
  1342.                             if (errnum) DosError("Error Cloning Directory",pathstr,errnum);
  1343.                             ReadDir=DF_READOTHER;
  1344.                           }
  1345.                         }
  1346.                         break;
  1347.                       case G_Swap:
  1348.                         UpdateStat(amountleft,selectedfiles[side],"Swap",cpath[side],cpath[otherside],filename[side][loop]);
  1349.                         errnum=DirFunc(pathstr,tmpstr,mode);
  1350.                         if (errnum) DosError("Error Swaping Directory",pathstr,errnum);
  1351.                         ReadDir=DF_READBOTH;
  1352.                         break;
  1353.                     }
  1354.                   }
  1355.                   if (errnum==1) cancel=TRUE;
  1356.                   amountleft--;
  1357.                 }
  1358.                 loop++;
  1359.                 if (loop==totalfiles[side]) done=TRUE;
  1360.               }
  1361.               while (!cancel && !done);
  1362.             }
  1363.             switch(mode)
  1364.             {
  1365.               case G_Archive:
  1366.                 if (arcfile) /* if file is open */
  1367.                 {
  1368.                   fclose(arcfile);  /* close it */
  1369.                   if (!cancel) /* did user cancel function ? */
  1370.                   { /* nope */
  1371.                     ReadDir+=DF_READOTHER;
  1372.                     UpdateStat(amountleft,selectedfiles[side],"Archiving",cpath[side],"","");
  1373.                     cdto(cpath[side]);
  1374.                     strcpy(tmpstr,CommandString[C_Archive]);
  1375.                     strfcat(tmpstr," A -r \"",MAX_PATH_LEN);
  1376.                     strfcat(tmpstr,arcname,MAX_PATH_LEN);
  1377.                     strfcat(tmpstr,"\" @T:AFCopy.TMP",MAX_PATH_LEN);
  1378.                     errnum=ExecCommand(tmpstr,FALSE,shufflescreens);
  1379.                     if (errnum && !nomessages) /*cancel=*/DosError("Error Running Archiver",tmpstr,errnum);
  1380.                                                /* cancel not needed again! */
  1381.                   }
  1382.                   filenuke("T:AFCopy.TMP"); /* delete it */
  1383.                 }
  1384.                 break;
  1385.             }
  1386.             if (Errors)
  1387.             {
  1388.               rtEZRequest ("There Were Errors!",okmsg,NULL,(struct TagItem *)&reqtags,NULL);
  1389.             }
  1390.             CloseWindow(statw);
  1391.             statw=NULL;
  1392.           }
  1393.           FreeGadgets(statglist);
  1394.         }
  1395.       }
  1396.       if (ReadDir)
  1397.       {
  1398.         if (ReadDir==DF_READBOTH || ReadDir==DF_READCURRENT)
  1399.         {
  1400.           lognewdir(side,cpath[side]);
  1401.         }
  1402.  
  1403.         if (ReadDir==DF_READBOTH || ReadDir==DF_READOTHER)
  1404.         {
  1405.           lognewdir(otherside,cpath[otherside]);
  1406.         }
  1407.       }
  1408.       switch (mode)
  1409.       {
  1410.         case G_Copy:
  1411.         case G_Clone:
  1412.         case G_Swap:
  1413.           Updatedisplay(otherside);
  1414.           break;
  1415.       }
  1416.     }
  1417.     FreeNameList(ErrorList);
  1418.     FreeMem(ErrorList,sizeof (struct List));
  1419.   }
  1420.   updateslider(side,displayoffset[side]);
  1421.   displayfilelist(side,displayoffset[side]);
  1422.   if (tempautooverwrite) autooverwrite=FALSE; /* tempauto.. can only become true if
  1423.                                                  autooverwrite is off in the first place. */
  1424. }
  1425.  
  1426. void DosFunction( void )
  1427. {
  1428.   long asynch=FALSE;
  1429.  
  1430.   if (asynch=rtGetString (dosstr, MAX_COMMAND_LEN, "Enter Dos Command", NULL,
  1431.                           RTGS_GadFmt, "Run|Run Asynch|Cancel",
  1432.                           RT_Window,W, TAG_END))
  1433.   {
  1434.     ExecCommand(dosstr,asynch==2 ? TRUE : FALSE,shufflescreens);
  1435.   }
  1436.  
  1437. }
  1438.  
  1439. void pickscreen( void )
  1440. {
  1441.   struct rtScreenModeRequester *scrmodereq;
  1442.  
  1443.   if (scrmodereq = rtAllocRequestA (RT_SCREENMODEREQ, NULL))
  1444.   {
  1445.     if (rtScreenModeRequest (scrmodereq, "Select A Screen mode:",RTSC_Flags,SCREQF_GUIMODES,RT_Window,W,TAG_END))
  1446.     {
  1447.       useworkbenchscreen=FALSE;
  1448.       scrID=scrmodereq->DisplayID;
  1449.       scrH=scrmodereq->DisplayHeight < 256 ? 256 : scrmodereq->DisplayHeight;
  1450.     }
  1451.     else
  1452.     {
  1453.       scrID=-1;
  1454.       useworkbenchscreen=TRUE;
  1455.     }
  1456.   }
  1457. }
  1458.  
  1459.  
  1460. void closeafcopywindow( void )
  1461. {
  1462.   if (MainMenu)
  1463.   {
  1464.     ClearMenuStrip(W);
  1465.     FreeMenus(MainMenu);
  1466.     MainMenu=NULL;
  1467.   }
  1468.  
  1469.   if (W)
  1470.   {
  1471.     myproc->pr_WindowPtr = oldwinptr;
  1472.     CloseWindow(W);
  1473.     W=NULL;
  1474.   }
  1475.   if (glist)
  1476.   {
  1477.     FreeGadgets(glist);
  1478.     glist=NULL;
  1479.   }
  1480.   if (vi)
  1481.   {
  1482.     FreeVisualInfo(vi);
  1483.     vi=NULL;
  1484.   }
  1485.  
  1486.   if (mysc)
  1487.   {
  1488.     if (customscreenopen)
  1489.     {
  1490.       CloseScreen(mysc);  // when i put this in a for next loop it crashes!
  1491.       customscreenopen=FALSE;
  1492.     }
  1493.     else
  1494.     {
  1495.       UnlockPubScreen(NULL, mysc);
  1496.     }
  1497.     mysc=NULL;
  1498.   }
  1499. }
  1500.  
  1501. void openthescreen( void)
  1502. {
  1503.   BOOL ok=FALSE;
  1504.   short tries;
  1505.   do
  1506.   {
  1507.     if (useworkbenchscreen)
  1508.     {
  1509.       if (mysc = LockPubScreen(NULL)) ok=TRUE;
  1510.     }
  1511.     else
  1512.     {
  1513.       tries=0;
  1514.       do
  1515.       {
  1516.         strcpy(screenname,"AFCOPY");
  1517.         if (tries!=0)
  1518.         {
  1519.           sprintf(dummystring,"%d",tries);
  1520.           strcat(screenname,dummystring);
  1521.         }
  1522.         if (mysc = OpenScreenTags( NULL, SA_Left, 16,
  1523.                                SA_Top,   0,
  1524.                                SA_Width, 640,
  1525.                                SA_Height,  scrH,
  1526.                                SA_Depth, 3,
  1527.                                SA_Colors, &ScreenColors[0],
  1528.                                SA_Font,  &ScreenFontAttr,
  1529.                                SA_Type,  CUSTOMSCREEN,
  1530.                                SA_DisplayID, scrID,
  1531.                                SA_AutoScroll,  TRUE,
  1532.                                SA_Overscan,  OSCAN_TEXT,
  1533.                                SA_Pens, &DriPens[0],
  1534.                                SA_Title, screentitle,
  1535.                                SA_PubName,screenname,
  1536.                                TAG_DONE ))
  1537.         {
  1538.           PubScreenStatus(mysc,0);
  1539.           customscreenopen=TRUE;
  1540.           ok=TRUE;
  1541.         }
  1542.         else
  1543.         {
  1544.           tries++;
  1545.         }
  1546.       } while (tries<50 && !ok);
  1547.     }
  1548.     if (!ok)
  1549.     {
  1550.       errormsg("Error Opening Screen, Please Select\n"
  1551.                "a different screenmode or cancel the\n"
  1552.                "screenmode requester to open on the\n"
  1553.                "default public screen!");
  1554.       pickscreen();
  1555.     }
  1556.   } while (!ok);
  1557. }
  1558.  
  1559. BOOL openafcopywindow( void )
  1560. {
  1561.   BOOL retval=FALSE,done=FALSE;
  1562.  
  1563.   glist=NULL;
  1564.   W=NULL;
  1565.   mysc=NULL;
  1566.   vi=NULL;
  1567.   MainMenu=NULL;
  1568.   customscreenopen=FALSE;
  1569.  
  1570.   openthescreen();
  1571.  
  1572.   // Set Up Visual Info
  1573.  
  1574.   if (mysc)
  1575.   {
  1576.     if (mysc->Height<=256)
  1577.     {
  1578.       wtop=0;
  1579.     }
  1580.     else
  1581.     {
  1582.       if (customscreenopen)
  1583.       {
  1584.         wtop=11;
  1585.       }
  1586.       else
  1587.       {
  1588.         wtop=(mysc->Height-(lines_per_side*FILEHEIGHT+95)) / 2;
  1589.       }
  1590.     }
  1591.     if (vi = GetVisualInfo(mysc, TAG_DONE))
  1592.     {
  1593.       topborder = mysc->WBorTop + (mysc->Font->ta_YSize + 1);
  1594.       zoomcoords[3]=topborder; /* set height of iconified window to that of the topborder */
  1595.  
  1596.       do
  1597.       {
  1598.         if (W=OpenWindowTags(NULL,
  1599.                     WA_Left,(mysc->Width-640) / 2,
  1600.                     WA_Top,wtop,
  1601.                     WA_Width,640,
  1602.                     WA_MinWidth,640,
  1603.                     WA_MinHeight,lines_per_side*FILEHEIGHT+96,
  1604.                     WA_InnerHeight,lines_per_side*FILEHEIGHT+84,
  1605.                     WA_AutoAdjust,    FALSE,
  1606.                     WA_DragBar,       TRUE,
  1607.                     WA_DepthGadget,   TRUE,
  1608.                     WA_Activate,      TRUE,
  1609.                     WA_CloseGadget,   TRUE,
  1610.                     WA_SmartRefresh,  TRUE,
  1611.                     WA_Zoom,          zoomcoords,
  1612.                     WA_NewLookMenus,  TRUE,
  1613.                     WA_ReportMouse,   TRUE,
  1614.                     WA_IDCMP,
  1615.                              IDCMP_REFRESHWINDOW|
  1616.                              IDCMP_MENUPICK|
  1617.                              BUTTONIDCMP|
  1618.                              IDCMP_MOUSEBUTTONS|
  1619.                              IDCMP_CLOSEWINDOW|
  1620.                              ARROWIDCMP|
  1621.                              SCROLLERIDCMP|
  1622.                              IDCMP_VANILLAKEY|
  1623.                              IDCMP_RAWKEY|
  1624.                              IDCMP_DISKINSERTED|
  1625.                              IDCMP_ACTIVEWINDOW|
  1626.                              IDCMP_MOUSEMOVE|
  1627.                              IDCMP_NEWSIZE,
  1628.                     WA_Title,windowtitle,
  1629.                     WA_PubScreen, mysc,
  1630.                     WA_ScreenTitle,screentitle,
  1631.                     TAG_END))
  1632.         {
  1633.           myproc->pr_WindowPtr=W;
  1634.           done=TRUE;
  1635.         }
  1636.         else
  1637.         {
  1638.           lines_per_side--;
  1639.           if (lines_per_side<MIN_LINES_PER_SIDE)
  1640.           {
  1641.             done=TRUE;
  1642.           }
  1643.         }
  1644.       } while (!done);
  1645.  
  1646.       if (W)
  1647.       {
  1648.         if (createAllGadgets(&glist, vi, topborder,my_gads))
  1649.         {
  1650.           AddGList(W,glist,0,-1,NULL); // wonder if this'll work first time ?
  1651.           if (MainMenu = CreateMenus( MainNewMenu, GTMN_NewLookMenus,TRUE,TAG_DONE))
  1652.           {
  1653.             LayoutMenus(MainMenu,vi,GTMN_TextAttr, &ScreenFontAttr,GTMN_NewLookMenus,TRUE,TAG_DONE);
  1654.             SetMenuStrip(W,MainMenu);
  1655.             GT_RefreshWindow(W, NULL); /* just to make sure */
  1656.             SetFont(W->RPort,ScreenFont); /* set the font for the file names */
  1657.             retval=TRUE;
  1658.             RefreshGadgets(glist,W,NULL);
  1659.           } else MainMenu=NULL;
  1660.         }
  1661.       } else W=NULL;
  1662.     } else vi=NULL;
  1663.   }
  1664.   return(retval);
  1665. }
  1666.  
  1667.  
  1668. void resetslider(short side)
  1669. {
  1670.   GT_SetGadgetAttrs(my_gads[G_Sliderleft+side], W, NULL,
  1671.                     GTSC_Top, displayoffset[side],
  1672.                     GTSC_Total, totalfiles[side],
  1673.                     GTSC_Visible, totalfiles[side] < lines_per_side ? totalfiles[side] : lines_per_side,
  1674.                     TAG_END);
  1675. }
  1676.  
  1677. void UpdateMainWindow( void )
  1678. {
  1679.   GT_RefreshWindow(W,NULL);
  1680.   Updatedisplay(0);
  1681.   resetslider(0);
  1682.   Updatedisplay(1);
  1683.   resetslider(1);
  1684.   ActiveSide(currentside);
  1685. }
  1686.  
  1687. /****************************************************************************************
  1688.  
  1689.           Event Handler!
  1690.  
  1691. ****************************************************************************************/
  1692.  
  1693. void handleevent(UWORD what,UWORD code)
  1694.  
  1695. /* shove a GadgetID in WHAT */
  1696. /* if applicable slidergadget's code goes in CODE */
  1697. {
  1698.   switch(what)
  1699.   {
  1700.     case G_SortLeft:
  1701.       sortmode[0]++;
  1702.       if (sortmode[0]>SORT_MAX) sortmode[0]=SORT_MIN;
  1703.       qsortfiles(0,0,totalfiles[0]-1);
  1704.       displayfilelist(0,displayoffset[0]);
  1705.       break;
  1706.     case G_SortRight:
  1707.       sortmode[1]++;
  1708.       if (sortmode[1]>SORT_MAX) sortmode[1]=SORT_MIN;
  1709.       qsortfiles(1,0,totalfiles[1]-1);
  1710.       displayfilelist(1,displayoffset[1]);
  1711.       break;
  1712.     case G_DisplayLeft:
  1713.       DisplayType[0]++;
  1714.       if (DisplayType[0]>DISPLAY_MAX) DisplayType[0]=DISPLAY_MIN;
  1715.       displayfilelist(0,displayoffset[0]);
  1716.       break;
  1717.     case G_DisplayRight:
  1718.       DisplayType[1]++;
  1719.       if (DisplayType[1]>DISPLAY_MAX) DisplayType[1]=DISPLAY_MIN;
  1720.       displayfilelist(1,displayoffset[1]);
  1721.       break;
  1722.     case G_Deviceleft0:
  1723.     case G_Deviceleft1:
  1724.     case G_Deviceleft2:
  1725.     case G_Deviceleft3:
  1726.     case G_Deviceleft4:
  1727.     case G_Deviceleft5:
  1728.     case G_Deviceleft6:
  1729.     case G_Deviceleft7:
  1730.     case G_Deviceleft8:
  1731.     case G_Deviceleft9:
  1732.     case G_Deviceleft10:
  1733.     case G_Deviceleft11:
  1734.       currentside=0;
  1735.       lognewdir(0,devicegadactual[0][what-G_Deviceleft0]);
  1736.       break;
  1737.     case G_Deviceright0:
  1738.     case G_Deviceright1:
  1739.     case G_Deviceright2:
  1740.     case G_Deviceright3:
  1741.     case G_Deviceright4:
  1742.     case G_Deviceright5:
  1743.     case G_Deviceright6:
  1744.     case G_Deviceright7:
  1745.     case G_Deviceright8:
  1746.     case G_Deviceright9:
  1747.     case G_Deviceright10:
  1748.     case G_Deviceright11:
  1749.       currentside=1;
  1750.       lognewdir(1,devicegadactual[1][what-G_Deviceright0]);
  1751.       break;
  1752.     case G_Regetleft:
  1753.     case G_Pathleft:
  1754.       currentside=0;
  1755.       lognewdir(0,((struct StringInfo *)my_gads[G_Pathleft]->SpecialInfo)->Buffer);
  1756.       break;
  1757.     case G_Regetright:
  1758.     case G_Pathright:
  1759.       currentside=1;
  1760.       lognewdir(1,((struct StringInfo *)my_gads[G_Pathright]->SpecialInfo)->Buffer);
  1761.       break;
  1762.     case G_Parentleft:
  1763.       currentside=0;
  1764.       if (pathok[0]) doparent(0);
  1765.       break;
  1766.     case G_Parentright:
  1767.       currentside=1;
  1768.       if (pathok[1]) doparent(1);
  1769.       break;
  1770.     case G_Makedir:
  1771.       Makedir(currentside);
  1772.       break;
  1773.     case G_Mark:
  1774.       setmarks(currentside,MARK);
  1775.       displayfilelist(currentside,displayoffset[currentside]);
  1776.       break;
  1777.     case G_Unmark:
  1778.       setmarks(currentside,UNMARK);
  1779.       displayfilelist(currentside,displayoffset[currentside]);
  1780.       break;
  1781.     case G_Reverse:
  1782.       setmarks(currentside,REVERSE);
  1783.       displayfilelist(currentside,displayoffset[currentside]);
  1784.       break;
  1785.     case G_Rename:
  1786.     case G_Copy:
  1787.     case G_Clone:
  1788.     case G_Swap:
  1789.     case G_Delete:
  1790.     case G_View:
  1791.     case G_Read:
  1792.     case G_Edit:
  1793.     case G_Hear:
  1794.     case G_Info:
  1795.     case G_Execute:
  1796.     case G_Run:
  1797.     case G_Comment:
  1798.     case G_Archive:
  1799.     case G_Unarc:
  1800.     case G_Batch:
  1801.     case G_Protect:
  1802.     case G_Userleft0:
  1803.     case G_Userleft1:
  1804.     case G_Userleft2:
  1805.     case G_Userleft3:
  1806.     case G_Userleft4:
  1807.     case G_Userleft5:
  1808.     case G_Userleft6:
  1809.     case G_Userleft7:
  1810.     case G_Userleft8:
  1811.     case G_Userleft9:
  1812.     case G_Userleft10:
  1813.     case G_Userleft11:
  1814.     case G_Userleft12:
  1815.     case G_Userleft13:
  1816.     case G_Userleft14:
  1817.     case G_Userright0:
  1818.     case G_Userright1:
  1819.     case G_Userright2:
  1820.     case G_Userright3:
  1821.     case G_Userright4:
  1822.     case G_Userright5:
  1823.     case G_Userright6:
  1824.     case G_Userright7:
  1825.     case G_Userright8:
  1826.     case G_Userright9:
  1827.     case G_Userright10:
  1828.     case G_Userright11:
  1829.     case G_Userright12:
  1830.     case G_Userright13:
  1831.     case G_Userright14:
  1832.       Dofunction(what,currentside);
  1833.       break;
  1834.     case G_Dos:
  1835.       DosFunction();
  1836.       break;
  1837.     case G_Volumes:
  1838.       findvolumes(currentside);
  1839.       break;
  1840.     case G_Sliderleft:
  1841.       currentside=0;
  1842.       displayoffset[0]=code;
  1843.       displayfilelist(0,displayoffset[0]);
  1844.       break;
  1845.     case G_Sliderright:
  1846.       currentside=1;
  1847.       displayoffset[1]=code;
  1848.       displayfilelist(1,displayoffset[1]);
  1849.  
  1850.   }
  1851. }
  1852.  
  1853. void handlekey(UWORD key)
  1854. {
  1855.   int id=-1;
  1856.   switch (key)
  1857.   {
  1858.     case 'a':
  1859.     case 'A': id=G_Read; break;
  1860.     case 'b':
  1861.     case 'B': id=G_Batch; break;
  1862.     case 'c':
  1863.     case 'C': id=G_Copy; break;
  1864.     case 'd':
  1865.     case 'D': id=G_Delete; break;
  1866.     case 'e':
  1867.     case 'E': id=G_Edit; break;
  1868.     /* f-g */
  1869.     case 'h':
  1870.     case 'H': id=G_Hear; break;
  1871.     case 'i':
  1872.     case 'I': id=G_Info; break;
  1873.     /* j-k */
  1874.     case 'l':
  1875.     case 'L': id=G_Volumes; break;
  1876.     case 'm':
  1877.     case 'M': id=G_Makedir; break;
  1878.     /* n */
  1879.     case 'o':
  1880.     case 'O': id=G_Clone; break;
  1881.     case 'p':
  1882.     case 'P': id=G_Protect; break;
  1883.     /* q */
  1884.     case 'r':
  1885.     case 'R': id=G_Rename; break;
  1886.     case 's':
  1887.     case 'S': id=G_Swap; break;
  1888.     case 't':
  1889.     case 'T': id=G_Comment; break;
  1890.     case 'u':
  1891.     case 'U': id=G_Unarc; break;
  1892.     case 'v':
  1893.     case 'V': id=G_View; break;
  1894.     /* w */
  1895.     case 'x':
  1896.     case 'X': id=G_Execute; break;
  1897.     /* y */
  1898.     case 'z':
  1899.     case 'Z': id=G_Archive; break;  /* Z is for ZIP !! */
  1900.     case '#': id=G_Run; break;
  1901.     case '+': id=G_Mark; break;
  1902.     case '-': id=G_Unmark; break;
  1903.     case '*': id=G_Reverse; break;
  1904.     case '/': id=G_Parentleft+currentside; break;
  1905.     case '.': id=G_Regetleft+currentside; break;
  1906.   }
  1907.   if (id!=-1) handleevent(id,0);
  1908. }
  1909.  
  1910. void checkfileselect(int Code,int MouseX,int MouseY,LONG action,BOOL CheckDoubleClick)
  1911. {
  1912.   short side,oldside=currentside,fileid,lineid;
  1913.   ULONG sec,mic;
  1914.   char newpath[MAX_PATH_LEN+1];
  1915.  
  1916.  
  1917.   if (active)
  1918.   {
  1919.     for (side=0;side<=1;side++)
  1920.     {
  1921.       if (inrect(MouseX,MouseY,
  1922.                  filexpos[side],
  1923.                  topborder+FILEYPOS,
  1924.                  filexpos[side]+FILEWIDTH,
  1925.                  topborder+FILEYPOS+(FILEHEIGHT*lines_per_side)))
  1926.       {
  1927.         ActiveSide(currentside);
  1928.         if ((oldside==side && (Code==SELECTDOWN)) || (Code==MENUNULL))
  1929.         {
  1930.           currentside=side;
  1931.           lineid=((MouseY-topborder-FILEYPOS) / FILEHEIGHT);
  1932.           if (lineid>=0 && lineid<lines_per_side)
  1933.           {
  1934.             fileid=lineid+displayoffset[currentside];
  1935.             if (fileid < totalfiles[currentside])
  1936.             {
  1937.               switch (Code)
  1938.               {
  1939.                 case SELECTDOWN :
  1940.                   switch(action)
  1941.                   {
  1942.                     case SELECTTOGGLE:
  1943.                       if (filetags[currentside][fileid])
  1944.                       {
  1945.                         selected(currentside,fileid,FALSE);
  1946.                         mouseaction=SELECTUNSET;
  1947.                       }
  1948.                       else
  1949.                       {
  1950.                         selected(currentside,fileid,TRUE);
  1951.                         mouseaction=SELECTSET;
  1952.                       }
  1953. /*                      filetags[currentside][fileid]=!filetags[currentside][fileid];
  1954.                       if (filetags[currentside][fileid])
  1955.                       {
  1956.                         mouseaction=SELECTSET;
  1957.                       }
  1958.                       else
  1959.                       {
  1960.                         mouseaction=SELECTUNSET;
  1961.                       }
  1962. */
  1963.                       break;
  1964.                     case SELECTSET:
  1965.                       if (!filetags[currentside][fileid])
  1966.                       {
  1967.                         selected(currentside,fileid,TRUE);
  1968.                       }
  1969.                       break;
  1970.                     case SELECTUNSET:
  1971.                       if (filetags[currentside][fileid])
  1972.                       {
  1973.                         selected(currentside,fileid,FALSE);
  1974.                       }
  1975.                       break;
  1976.                   }
  1977.                   displaysinglefile(currentside,lineid,fileid);
  1978.                   CurrentTime(&sec,&mic);
  1979.                   if (! (DoubleClick(last_sec,last_mic,sec,mic) && (MouseX==last_x && MouseY==last_y && CheckDoubleClick)))
  1980.                   {
  1981.                     last_x=MouseX;
  1982.                     last_y=MouseY;
  1983.                     last_sec=sec;
  1984.                     last_mic=mic;
  1985.                     break;
  1986.                   }
  1987.                 case MENUNULL :
  1988.                   if (filetype[currentside][fileid]>0)
  1989.                   {
  1990.                     last_x=0;
  1991.                     last_y=0;
  1992.                     strcpy(newpath,cpath[currentside]);
  1993.                     //((struct StringInfo *)my_gads[G_Pathleft+currentside]->SpecialInfo)->Buffer);
  1994.                     if (AddPart(newpath,filename[currentside][fileid],MAX_PATH_LEN))
  1995.                     {
  1996.                       lognewdir(currentside,newpath);
  1997.                     }
  1998.                   }
  1999.                   break;
  2000.               }
  2001.             }
  2002.           }
  2003.         }
  2004.         else
  2005.         {
  2006.           if (Code==SELECTDOWN) currentside=side;
  2007.         }
  2008.       }
  2009.     }
  2010.   }
  2011. }
  2012.  
  2013.  
  2014.  
  2015. #define T_TAG TRUE
  2016. #define T_UNTAG FALSE
  2017.  
  2018. void Rectangle(struct Window *W,UWORD x1,UWORD y1,UWORD x2,UWORD y2)
  2019. {
  2020.   Move(W->RPort,x1,y1);
  2021.   Draw(W->RPort,x1,y2);
  2022.   Draw(W->RPort,x2,y2);
  2023.   Draw(W->RPort,x2,y1);
  2024.   Draw(W->RPort,x1,y1);
  2025. }
  2026.  
  2027. void ActiveSide(short side)
  2028. {
  2029.   DrawBevelBox(W->RPort,
  2030.                filexpos[side]-1,
  2031.                topborder+FILEYPOS-1,
  2032.                FILEWIDTH+3,
  2033.                (FILEHEIGHT*lines_per_side)+2,
  2034.                GT_VisualInfo,vi,TAG_DONE);
  2035.   DrawBevelBox(W->RPort,
  2036.                filexpos[1-side]-1,
  2037.                topborder+FILEYPOS-1,
  2038.                FILEWIDTH+3,
  2039.                (FILEHEIGHT*lines_per_side)+2,
  2040.                GT_VisualInfo,vi,GTBB_Recessed,TRUE,TAG_DONE);
  2041. }
  2042.  
  2043.  
  2044. void modtags(short side,int tmode,char *patt)
  2045. {
  2046.   int loop;
  2047.   char match[83];
  2048.   if (pathok[side])
  2049.   {
  2050.     ParsePatternNoCase(patt,match,82);
  2051.     for (loop=0;loop<totalfiles[side];loop++)
  2052.     {
  2053.       if (MatchPatternNoCase(match,filename[side][loop]))
  2054.       {
  2055.         selected(side,loop,tmode);
  2056.       }
  2057.     }
  2058.     displayfilelist(side,displayoffset[side]);
  2059.   }
  2060. }
  2061.  
  2062. void GroupTag(short side,int tmode)
  2063. {
  2064.   if (rtGetString (patt, 40, "Enter Pattern To Match Files", NULL,RT_Window,W, TAG_END))
  2065.   {
  2066.     modtags(side,tmode,patt);
  2067.   }
  2068. }
  2069.  
  2070.  
  2071. int handlemenu(int num,int item)
  2072. {
  2073.   char cfgname[MAX_PATH_LEN+1];
  2074.   int quit=FALSE;
  2075.   switch(num)
  2076.   {
  2077.     case 0:
  2078.       switch(item)
  2079.       {
  2080.         case 0:
  2081.           About();
  2082.           break;
  2083.         case 1:
  2084.           rtEZRequest("To change directory use the RIGHT mouse button.\n"
  2085.                       "bet it took you ages to figure that one out!!",
  2086.                       "It sure did!",NULL,(struct TagItem *)&reqtags,NULL);
  2087.           rtEZRequest("For more help look at the instructions section\n"
  2088.                       "in AFCopy.Guide!",
  2089.                       "Oh, Okay then.",NULL,(struct TagItem *)&reqtags,NULL);
  2090.           break;
  2091.         case 2:
  2092.           checkcustomscreenwindows();
  2093.           quit=TRUE;
  2094.           break;
  2095.       }
  2096.       break;
  2097.     case 1:
  2098.       strcpy(cfgname,DEFAULTCONFIGNAME);
  2099.       switch(item)
  2100.       {
  2101.         case 0:
  2102.           quit=!EditConfig();
  2103.           break;
  2104.         case 1:
  2105.           /* file selector need to go here!!! */
  2106.           if (rtGetString (cfgname, MAX_PATH_LEN, "Enter Config File Name To Load", NULL,RT_Window,W, TAG_END))
  2107.           {
  2108.             if (cfgname[0]!='\0') LoadConfig(cfgname);
  2109.             checkcustomscreenwindows();
  2110.             closeafcopywindow();
  2111.             if (!(quit=!openafcopywindow()))
  2112.             {
  2113.               UpdateMainWindow();
  2114.             }
  2115.           }
  2116.           break;
  2117.         case 2:
  2118.           SaveConfig(DEFAULTCONFIGNAME);
  2119.           break;
  2120.         case 3:
  2121.           /* file selector need to go here!!! */
  2122.           if (rtGetString (cfgname, MAX_PATH_LEN, "Enter Config File Name To Save As", NULL,RT_Window,W, TAG_END))
  2123.           {
  2124.             if (cfgname[0]!='\0') SaveConfig(cfgname);
  2125.           }
  2126.           break;
  2127.        }
  2128.        break;
  2129.     case 2: /* Misc Menu */
  2130.       switch(item)
  2131.       {
  2132.         case 0:
  2133.           GroupTag(currentside,T_TAG);
  2134.           break;
  2135.         case 1:
  2136.           GroupTag(currentside,T_UNTAG);
  2137.           break;
  2138.         case 2:
  2139.           DoFormat();
  2140.           break;
  2141.       }
  2142.       break;
  2143.   }
  2144.   return(quit);
  2145. }
  2146.  
  2147. #define C_RIGHT 78
  2148. #define C_LEFT  79
  2149.  
  2150. void handlerawkey(UWORD key)
  2151. {
  2152.   switch(key)
  2153.   {
  2154.     case C_RIGHT:
  2155.       currentside=1;
  2156.       break;
  2157.     case C_LEFT:
  2158.       currentside=0;
  2159.       break;
  2160.   }
  2161. }
  2162.  
  2163. void handleidcmp(void)
  2164. {
  2165.   struct IntuiMessage *imsg,*imsgo;
  2166.   struct Gadget *gad;
  2167.   BOOL done = FALSE;
  2168.   char whatdisk[5]="DFx:";
  2169.  
  2170.   if (imsg=AllocMem(sizeof(struct IntuiMessage),MEMF_PUBLIC))
  2171.   {
  2172.     while (!done)
  2173.     {
  2174.       Wait (1L << W->UserPort->mp_SigBit);
  2175.       while (imsgo = GT_GetIMsg(W->UserPort))
  2176.       {
  2177.         CopyMem(imsgo,imsg,sizeof(struct IntuiMessage));
  2178.         GT_ReplyIMsg(imsgo);
  2179.  
  2180.         gad = (struct Gadget *)imsg->IAddress;
  2181.         switch(imsg->Class)
  2182.         {
  2183.           case IDCMP_MOUSEMOVE:
  2184.             if (imsg->IAddress==W)
  2185.             {
  2186.               if (mouseupdn==104) checkfileselect(mouseupdn,imsg->MouseX,imsg->MouseY,mouseaction,FALSE);
  2187.             }
  2188.             else
  2189.             {
  2190.               mouseaction=SELECTTOGGLE;
  2191.             }
  2192.             if (gad==my_gads[G_Sliderright] || gad==my_gads[G_Sliderleft]) handleevent(gad->GadgetID,imsg->Code);
  2193.             break;
  2194.           case IDCMP_GADGETDOWN:
  2195.           case IDCMP_GADGETUP:
  2196.             handleevent(gad->GadgetID,imsg->Code);
  2197.             ActiveSide(currentside);
  2198.             break;
  2199.           case IDCMP_VANILLAKEY:
  2200.             handlekey(imsg->Code);
  2201.             ActiveSide(currentside);
  2202.             break;
  2203.           case IDCMP_RAWKEY:
  2204.             handlerawkey(imsg->Code);
  2205.             ActiveSide(currentside);
  2206.             break;
  2207.           case IDCMP_MENUPICK:
  2208.             if (handlemenu(MENUNUM(imsg->Code),ITEMNUM(imsg->Code)))
  2209.             {
  2210.               done = TRUE;
  2211.               break;
  2212.             }
  2213.           case IDCMP_MOUSEBUTTONS:
  2214.             mouseupdn=imsg->Code;
  2215.             checkfileselect(imsg->Code,imsg->MouseX,imsg->MouseY,SELECTTOGGLE,TRUE);
  2216.             break;
  2217.           case IDCMP_CLOSEWINDOW:
  2218.             checkcustomscreenwindows();
  2219.             done = TRUE;
  2220.             break;
  2221.           case IDCMP_INACTIVEWINDOW:
  2222.             active=FALSE;
  2223.             break;
  2224.           case IDCMP_ACTIVEWINDOW:
  2225.             active=TRUE;
  2226.             break;
  2227.           case IDCMP_NEWSIZE:
  2228.             iconised=!iconised;
  2229.             if (!iconised)
  2230.             {
  2231.               UpdateMainWindow();
  2232.             }
  2233.             /* do something here, or shall we ? no, i dont think we will.  Oh well */
  2234.             break;
  2235.           case IDCMP_DISKINSERTED:
  2236.             if (!ignoreinserteddisks && !iconised)
  2237.             {
  2238.               whatdisk[2]='0'+imsg->Code;
  2239.               switch (rtEZRequest("Disk Inserted!  Log it ?","_Left|_Right|_CANCEL",NULL,(struct TagItem *)&reqtags,NULL))
  2240.               {
  2241.                 case 1:
  2242.                   lognewdir(0,whatdisk);
  2243.                   break;
  2244.                 case 2:
  2245.                   lognewdir(1,whatdisk);
  2246.                   break;
  2247.               }
  2248.             }
  2249.             break;
  2250.         }
  2251.       }
  2252.     }
  2253.     FreeMem(imsg,sizeof (struct IntuiMessage));
  2254.   }
  2255. }
  2256.  
  2257. int GetFont( void )
  2258. {
  2259.   if ((ScreenFontAttr.ta_Flags & FPB_DISKFONT) != FPB_DISKFONT)
  2260.   {
  2261.     ScreenFont=OpenDiskFont(&ScreenFontAttr);
  2262.   }
  2263.   else
  2264.   {
  2265.     ScreenFont=OpenFont(&ScreenFontAttr);
  2266.   }
  2267.   if (ScreenFont)
  2268.   {
  2269.     return(TRUE);
  2270.   }
  2271.   else
  2272.   {
  2273.     rtEZRequest ("Could Open Font",okmsg,NULL,(struct TagItem *)&reqtags,NULL);
  2274.     return(FALSE);
  2275.   }
  2276. }
  2277.  
  2278. void PickFont( void )
  2279. {
  2280.   struct rtFontRequester *fontreq;
  2281.   if (fontreq = rtAllocRequestA (RT_FONTREQ, NULL))
  2282.   {
  2283.     fontreq->Flags = FREQF_FIXEDWIDTH;
  2284.     if (rtFontRequest (fontreq, "Pick a font",RTFO_MinHeight,8,RTFO_MaxHeight,8,TAG_END))
  2285.     {
  2286.       strcpy(ScreenFontAttr.ta_Name,fontreq->Attr.ta_Name);
  2287.       ScreenFontAttr.ta_YSize=fontreq->Attr.ta_YSize;
  2288.       ScreenFontAttr.ta_Style=fontreq->Attr.ta_Style;
  2289.       ScreenFontAttr.ta_Flags=fontreq->Attr.ta_Flags;
  2290.     }
  2291.     rtFreeRequest (fontreq);
  2292.   }
  2293.   else
  2294.   {
  2295.     rtEZRequest ("Out of memory!", okmsg, NULL, NULL);
  2296.   }
  2297. }
  2298.  
  2299. void freeallocated(short side )
  2300. {
  2301.   int loop;
  2302.  
  2303.   for (loop=0;loop<allocated[side];loop++)
  2304.   {
  2305.     FreeMem(filename[side][loop],MAX_FILE_LEN+1);
  2306.   }
  2307. }
  2308.  
  2309.  
  2310. void main(int argc,char **argv)
  2311. {
  2312.   struct WBStartup *WBmsg;
  2313.   struct WBArg *WBarg;
  2314.   char configname[MAX_PATH_LEN+1]=DEFAULTCONFIGNAME;
  2315.  
  2316.   if (argc==0)
  2317.   {
  2318.     WBmsg=(struct WBStartup *)argv;
  2319.     if (WBmsg->sm_NumArgs>1)
  2320.     {
  2321.       WBarg=WBmsg->sm_ArgList;
  2322.       WBarg++;
  2323.       if (WBarg->wa_Name && WBarg->wa_Lock)
  2324.       {
  2325.         if (NameFromLock(WBarg->wa_Lock,configname,MAX_PATH_LEN))
  2326.         {
  2327.           if (!AddPart(configname,WBarg->wa_Name,MAX_PATH_LEN))
  2328.           {
  2329.             strcpy(configname,DEFAULTCONFIGNAME);
  2330.           }
  2331.         }
  2332.       }
  2333.     }
  2334.   }
  2335.   else
  2336.   {
  2337.     if (argc==2) strcpy(configname,argv[1]);
  2338.   }
  2339.  
  2340.   WB2CLI((struct WBStartup *)argv,4000,DOSBase);  /* so you get the default path! */
  2341.   myproc = (struct Process *)FindTask (NULL);
  2342.   if (!(
  2343.        (ReqToolsBase = (struct ReqToolsBase *) OpenLibrary (REQTOOLSNAME, REQTOOLSVERSION))
  2344.        ||
  2345.        (ReqToolsBase = (struct ReqToolsBase *) OpenLibrary ("DH0:Libs/"REQTOOLSNAME, REQTOOLSVERSION))
  2346.        )
  2347.      )
  2348.   {
  2349.     puts("You need \"reqtools.library\" V38 or higher to run AFCopy!\n"
  2350.          "You should find it in the AFCopy Archive! and it needs to be in LIBS:\n"
  2351.          "Install file and try program again");
  2352.   }
  2353.   else
  2354.   {
  2355.     if ((GadToolsBase = OpenLibrary("gadtools.library", 37)) == NULL )
  2356.     {
  2357.       rtEZRequest ("Could Not Open\n\"gadtools.library\" V37+",okmsg,NULL,(struct TagItem *)&reqtags,NULL);
  2358.     }
  2359.     else
  2360.     {
  2361.       oldwinptr = myproc->pr_WindowPtr;
  2362.       blankusergads();
  2363.       setdefaultconfig();
  2364.       if (!LoadConfig(configname))
  2365.       {
  2366.         if (rtEZRequest("Config Not Loaded!\nSave defaults ?","Yes|No!",NULL,NULL))
  2367.         {
  2368.           SaveConfig(DEFAULTCONFIGNAME);
  2369.         }
  2370.       }
  2371.       if (GetFont())
  2372.       {
  2373.         sprintf(screentitle,"AFCopy"
  2374. #ifdef CPU020
  2375.         " 68020 Version!"
  2376. #endif
  2377. #ifdef CPU000
  2378.         " 68000 Version"
  2379. #endif
  2380.         " %d.%d (C) 1993-5 Hydra!/Tension",VERSION,REVISION);
  2381.         sprintf(windowtitle,"AFCOPY V%d.%d",VERSION,REVISION);
  2382.         SetProgramName(windowtitle);
  2383.         if (openafcopywindow())
  2384.         {
  2385.           lognewdir(0,cpath[0]);
  2386.           lognewdir(1,cpath[1]);
  2387.           ActiveSide(0);
  2388.           handleidcmp();  /* start looking for input.. */
  2389.         }
  2390.         if (W) closeafcopywindow();
  2391.         CloseFont(ScreenFont);
  2392.       }
  2393.       CloseLibrary(GadToolsBase);                      /* close libs */
  2394.     }
  2395.     CloseLibrary ((struct Library *)ReqToolsBase);
  2396.   }
  2397.   if (outputconfile) Close(outputconfile);
  2398.   freeallocated(0);
  2399.   freeallocated(1);
  2400. }