home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / archiver / zoossr06 / zooshell.c < prev    next >
C/C++ Source or Header  |  1993-07-08  |  15KB  |  625 lines

  1. /*
  2.  *    ZOOSHELL.C
  3.  *    A GEM-based shell for painlessly invoking the ZOO archiver
  4.  *    Author: Steve Yelvington
  5.  *        Internet <steve@thelake.mn.org>
  6.  *        GEnie S.YELVINGTO2
  7.  *    This program is hereby released to the public domain.
  8.  *    You are solely responsible for any use you make of it.
  9.  */
  10.  
  11. #define VERSION    "ZOOSHELL Version 0.6 beta"
  12.  
  13. #ifdef APSTART    /* If using APSTART.O instead of DSTART.O, */
  14.         /* some kludgery to get around peculiarities of dLibs */
  15. #define NULL (void *)(0)
  16. #define exit Pterm
  17. #define FALSE    (0)
  18. #define TRUE    (!FALSE)
  19. #define ERROR    (-1)
  20. int    errno;
  21. #else
  22. #include <stdio.h>
  23. #endif
  24.  
  25. #include <osbind.h>    /* Atari operating system bindings */
  26. #include <gemfast.h>    /* you may prefer gemdefs.h and obdefs.h */
  27. #include <macros.h>    /* abs, loword/hiword, etc. */
  28. #include <limits.h>    /* standard limits such as PATHSIZ */
  29. #include <string.h>    /* values returned by string functions */
  30.  
  31. #include "zooshell.h"     /* file generated by resource editor */
  32.  
  33. #define RESOURCE_FILE    "zooshell.rsc"
  34.  
  35. #define STDOUT        1    /* GEMDOS handle */
  36. #define STDPRN        3    /* GEMDOS handle */
  37. #define CON        2    /* BIOS   device number */
  38.  
  39. OBJECT *menubar;    /* pointer for resource menu */
  40. char cwd[PATHSIZE];    /* current working directory */
  41. char zoottp[PATHSIZE];    /* name of ZOO program */
  42. int m_hidden;        /* mouse hidden flag */
  43. char mycmd[256];    /* command buffer for launching ZOO */
  44. char myargs[256];    /* argument buffer for launching ZOO */
  45. int confh,outfh;    /* file handles for redirection */
  46.  
  47. extern char *h_ex[],     /* help screens from zoohelp.c */
  48.     *h_rest[], *h_view[], 
  49.     *h_spec[], *h_buttons[];
  50.  
  51. /*
  52.  * Function: g_clrscr()
  53.  * Returns: void
  54.  * Description: Instructs GEM to redraw the workspace 
  55.  */
  56. void g_clrscr()
  57.     {
  58.     int x,y,w,h;
  59.     wind_get(0,WF_FULLXYWH,&x,&y,&w,&h);  /* get desktop dimensions */
  60.     form_dial(FMD_START,1,1,1,1,x,y,w,h); /* this may be unnecessary */
  61.     form_dial(FMD_FINISH,1,1,1,1,x,y,w,h); /* generate redraw msg */
  62.     }
  63.  
  64.  
  65. /*
  66.  * Function: hide_mouse
  67.  * Returns: void
  68.  * Description: hide the mouse and set the m_hidden flag
  69.  */
  70. void hide_mouse()
  71.     {
  72.     if (m_hidden) return;
  73.     graf_mouse(M_OFF,NULL);
  74.     m_hidden = TRUE;
  75.     }
  76.  
  77. /*
  78.  * Function: show_mouse
  79.  * Returns: void
  80.  * Description: if the mouse is hidden, show the mouse and set the flag
  81.  */
  82. void show_mouse()
  83.     {
  84.     if (m_hidden)
  85.         {
  86.         graf_mouse(M_ON,NULL);
  87.         m_hidden = FALSE;
  88.         }
  89.     }
  90.  
  91. /*
  92.  * Function: show_about()
  93.  * Returns: void
  94.  * Description: Shows the ABOUTBOX until 4-second timeout or mouse click
  95.  * Note: This function uses the GEMFAST evnx_multi function, which is
  96.  *       available in C source code if you don't have GEMFAST.
  97.  */
  98. void show_about()
  99.     {
  100.     OBJECT *aboutbox;
  101.     XMULTI xm;
  102.     int x,y,w,h;
  103.     static long delay;
  104.     delay = 4*1000L;
  105.     rsrc_gaddr(0,ABOUTBOX, &aboutbox);
  106.     hide_mouse();
  107.     form_center(aboutbox, &x, &y, &w, &h);
  108.     form_dial(FMD_START,1,1,1,1,x,y,w,h);
  109.     form_dial(FMD_GROW,1,1,1,1,x,y,w,h);
  110.     objc_draw(aboutbox, 0, 10, x, y, w, h);
  111.     show_mouse();
  112.     /* now wait for timer, keyboard or button activity */
  113.     xm.mflags = MU_TIMER|MU_KEYBD|MU_BUTTON;
  114.         xm.mtlocount = loword(delay);
  115.         xm.mthicount = hiword(delay);
  116.         xm.mbclicks = 1;            /* wait for single  */
  117.         xm.mbmask   = 1;            /* click of left    */
  118.         xm.mbstate  = 1;            /* button           */
  119.     evnx_multi(&xm);
  120.     form_dial(FMD_SHRINK,1,1,1,1,x,y,w,h);
  121.     form_dial(FMD_FINISH,1,1,1,1,x,y,w,h);
  122.     }
  123.  
  124.  
  125. /*
  126.  * Function: do_dialog
  127.  * Returns: index of exit object
  128.  * Description: This smart wrapper for form_dial handles centering, etc.
  129.  */
  130. int do_dialog(ind)
  131.     int ind;
  132.     {
  133.     OBJECT *form;
  134.     int exit_obj;
  135.     int x,y,w,h;
  136.     rsrc_gaddr(0,ind,&form);
  137.     hide_mouse();
  138.     form_center(form, &x, &y, &w, &h);
  139.     form_dial(FMD_START,1,1,1,1,x,y,w,h);
  140.     form_dial(FMD_GROW,1,1,1,1,x,y,w,h);
  141.     objc_draw(form, 0, 10, x, y, w, h);
  142.     show_mouse();
  143.     exit_obj = form_do(form, 0);
  144.     hide_mouse();
  145.     form_dial(FMD_SHRINK,1,1,1,1,x,y,w,h);
  146.     form_dial(FMD_FINISH,1,1,1,1,x,y,w,h);
  147.     form[exit_obj].ob_state = NORMAL;
  148.     show_mouse();
  149.     return(exit_obj);
  150.     }
  151.  
  152.  
  153. /*
  154.  * Function: forcedir
  155.  * Returns: void
  156.  * Description: combines set-drive and set-path functions into one call
  157.  */
  158. void forcedir(d)
  159.     char *d;
  160.     {
  161.     Dsetdrv(((int)d[0]) - 'A');
  162.     Dsetpath(&d[2]);
  163.     }
  164.  
  165. /*
  166.  * Function: change_dir
  167.  * Returns: void
  168.  * Description: Prompt user with a file selector and change directories
  169.  *              as appropriate
  170.  */
  171. void change_dir()
  172.     {
  173.     char file[14];
  174.     int status;
  175.     char *p;
  176.     file[0] = '\0';
  177.     getcwd(cwd,PATHSIZE);
  178.     strupr(cwd);
  179.     status = fsel_exinput(cwd,file, &status, "Select directory for output");
  180.     if (p=strrchr(cwd,'\\'))
  181.         *p = '\0';
  182.     if (status)
  183.         forcedir(cwd);
  184.     }
  185.  
  186. /*
  187.  * Function: fsel
  188.  * Returns: 0 if [CANCEL], 1 if [OK]
  189.  * Description:  Display the GEM file selector, including a prompt if
  190.  *               one is supplied. The path and default filename will
  191.  *               be shown, if supplied. Convert the user's input into
  192.  *               a complete filename and copy the result into the
  193.  *               supplied buffer.
  194.  *
  195.  * Side effects: fsel remembers the previous values of inpath and default
  196.  *               filename and uses them if those args are NULL
  197.  */
  198.  
  199. int fsel(prompt, path, insel, filename)
  200.     char *prompt, /* message to user, or NULL */
  201.          *path,  /* initial path, or NULL */
  202.              *insel, /* initial filename, or NULL */
  203.              *filename;    /* 128-byte buffer for full selected name */
  204.     {
  205.     static char xpath[128], xinsel[14];
  206.     char *p;
  207.     int button;
  208.     if (!prompt)
  209.         prompt = "Please choose a file";
  210.     if (!path)
  211.         {
  212.         xpath[0] = Dgetdrv() + 'A';
  213.         xpath[1] = ':';
  214.         Dgetpath(&xpath[2],(int)(xpath[0]-'A'+1));
  215.         strcat(xpath,"\\*.*");
  216.         path = xpath;
  217.         }
  218.     if (!strchr(path,':'))    /* nonabsolute path */
  219.         {
  220.         xpath[0] = Dgetdrv() + 'A';
  221.         xpath[1] = ':';
  222.         Dgetpath(&xpath[2],(int)(xpath[0]-'A'+1));
  223.         strcat(xpath,"\\");
  224.         strcat(xpath,path);
  225.         }
  226.     else if (path != xpath)
  227.         strcpy(xpath,path);
  228.     if (insel)
  229.         strcpy(xinsel,insel);
  230.     fsel_exinput(xpath,xinsel,&button,prompt);        
  231.     if (!button)
  232.         return button;
  233.     strcpy(filename,xpath);
  234.     if (p = strrchr(filename,'\\'))
  235.         *++p = '\0';
  236.     else if (p = strrchr(filename,':'))
  237.         *++p = '\0';
  238.     else if (p = strchr(filename,'*'))
  239.         *p = '\0';
  240.     else 
  241.         {
  242.         strcat(filename,"\\");
  243.         p = filename + strlen(filename);
  244.         }
  245.     strcpy(p,xinsel);
  246.     return button;
  247.     }
  248.  
  249. /*
  250.  * Function: Bconws
  251.  * Returns: void
  252.  * Description: Like Cconws, but to redirection-proof BIOS device
  253.  */
  254. void Bconws(dev,s)
  255.     int dev;
  256.     char *s;
  257.     {
  258.     while (*s)
  259.         Bconout(dev,*s++);
  260.     }
  261.  
  262. /*
  263.  * Function: xparse_args
  264.  * Returns: void
  265.  * Description: Parse a command line into an argv array
  266.  *              (modified from dlibs)
  267.  */
  268. void xparse_args(cmdln, argv)
  269.     char *cmdln;
  270.     register char *argv[];
  271.     {
  272.     register char *p;
  273.     static char delim[] = " \t\r\n";
  274.     if(p = strtok(cmdln, delim))
  275.         {
  276.         do
  277.             {
  278.             *argv++ = p;
  279.             }
  280.             while(p = strtok(NULL, delim));
  281.         }
  282.     }
  283.  
  284. /*
  285.  * Function: xsystem
  286.  * Returns:  the value returned by a child process
  287.  * Description: this is a simple, system()-like interface to
  288.  *              invoke fork/wait in a palatable fashion. It's
  289.  *              modified from dlibs; basically this is system()
  290.  *              without the _shell_p support. I don't want to
  291.  *              pass commands to a shell because I don't want
  292.  *              to give it the opportunity to mangle the args
  293.  *              ... this lets me control exactly what ZOO sees.
  294.  */
  295. int xsystem(command)
  296.     register char *command;
  297.     {
  298.     register char *p;
  299.     char rv[2];
  300.     char cmdln[1024];
  301.     char *args[64];
  302.     if(!command)
  303.         return(ERROR);
  304.     strcpy(cmdln, command);
  305.     xparse_args(cmdln, args);
  306.     p = args[0];
  307.     forkvpe(p, args, NULL);
  308.     wait(rv);
  309.     return((rv[1] == 0) ? rv[0] : rv[1]);
  310.     }
  311.  
  312. /*
  313.  * Function: exzoo
  314.  * Returns: void
  315.  * Description: Prompt the user for a ZOO file name. Then, if flag is
  316.  *              true, prompt the user for a file to process. Build
  317.  *              a command line including the cmd argument, and then
  318.  *              clear the screen and invoke xsystem. Restore the
  319.  *              GEM screen afterward.
  320.  */
  321. void exzoo(cmd,flag,prompt)
  322.     char *cmd;
  323.     int flag;
  324.     char *prompt;
  325.     {
  326.     char insel[14];
  327.     int rv;
  328.     insel[0] = '\0';
  329.     strcpy(mycmd,zoottp);
  330.     strcat(mycmd,cmd);
  331.     if (!fsel("Choose ZOO file to process","*.ZOO",insel,myargs))
  332.         return;
  333.     strcat(mycmd," ");
  334.     strcat(mycmd,myargs);
  335.     if (strcmp(cmd,"-backup") ==0)
  336.         strcat(mycmd," *");
  337.     if (flag)    /* get more args */
  338.         {
  339.         myargs[0] = '\0';
  340.         if (!fsel(prompt,"*.*",insel,myargs))
  341.             return;
  342.         strcat(mycmd," ");
  343.         strcat(mycmd,myargs);
  344.         }
  345.     /* now clear the screen, run ZOO, and restore the screen */
  346.     menu_bar(menubar,FALSE);
  347.     hide_mouse();
  348.     Bconws(CON,"\033E\033e");    /* cls, home, cursor on */
  349.     Bconws(CON,"Setting current directory: ");
  350.     Bconws(CON,cwd);
  351.     Bconws(CON,"\r\n");
  352.     forcedir(cwd);
  353.     Bconws(CON,"Current directory set to: ");
  354.     Bconout(CON,Dgetdrv() + 'A');
  355.     Bconout(CON,':');
  356.     {
  357.         char buf[PATHSIZE];
  358.         Dgetpath(buf, Dgetdrv()+1);
  359.         Bconws(CON,buf);
  360.     }
  361.     Bconws(CON,"\r\n");
  362.     Bconws(CON,"Executing command xsystem( ");
  363.     Bconws(CON,mycmd);
  364.     Bconws(CON," )\r\n");
  365.     if ((rv = xsystem(mycmd)) < 0)
  366.         {
  367.         show_mouse();
  368.         form_error(abs(rv));
  369.         }
  370.     else
  371.         {
  372.         Bconws(CON,"\a**** Strike any key to continue ****");
  373.         Bconin(CON);
  374.         }
  375.     Bconws(CON,"\033E\033f");    /* cls, home, cursor off */
  376.     g_clrscr();
  377.     menu_bar(menubar,TRUE);
  378.     show_mouse();
  379.     }
  380.  
  381.  
  382. /*
  383.  * Function: notimpl
  384.  * Returns: void
  385.  * Description: Displays informative message for unimplemented features
  386.  */
  387. void notimpl()
  388.     {
  389.     form_alert(1,"[0][That option is|not yet|implemented][Sorry]");
  390.     }
  391.  
  392. /*
  393.  * Function: load_resource
  394.  * Returns: TRUE if the resource was loaded, else FALSE.
  395.  * Description: This is just a standard wrapper.
  396.  */
  397. int load_resource(rfile)
  398.     char *rfile;
  399.     {
  400.     if (!rsrc_load(rfile))
  401.         {
  402.         form_alert(1,"[0][Can't find|resource file][EXIT]");
  403.         return(FALSE);
  404.         }
  405.     return(TRUE);
  406.     }
  407.  
  408.  
  409.  
  410. /*
  411.  * Function: prt_output
  412.  * Returns: TRUE or FALSE depending on whether redirection succeeded.
  413.  * Description: Redirects GEMDOS console output to the printer device.
  414.  *              If the printer is not ready, redirection is considered
  415.  *              to have failed.
  416.  */
  417. int prt_output()
  418.     {
  419.     if (!Cprnos())
  420.         {
  421.         form_alert(1,"[0][Printer not ready!][Oops]");
  422.         return FALSE;
  423.         }
  424.     confh = Fdup(STDOUT);
  425.     if (confh < 0)
  426.         {
  427.         form_alert(1,"[0][Fdup() failed!][Oops]");
  428.         form_error(abs(confh));
  429.         return FALSE;
  430.         }
  431.     outfh = Fopen("PRN:",1);
  432.  
  433.     if (outfh < -3)
  434.         {
  435.         form_alert(1,"[0][Fopen() failed!][Oops]");
  436.         form_error(abs(outfh));
  437.         return FALSE;
  438.         }
  439.  
  440.     if (Fforce(STDOUT,outfh))
  441.         {
  442.         form_alert(1,"[0][Fforce() failed!][Oops]");
  443.         return FALSE;
  444.         }
  445.     return TRUE;
  446.     }
  447.  
  448. /*
  449.  * Function: restore_output
  450.  * Returns: void
  451.  * Description: Close redirected file handles and restore the originals.
  452.  */
  453. void restore_output()
  454.     {
  455.     if (outfh)
  456.         {
  457.         Fclose(outfh);
  458.         outfh = 0;
  459.         }
  460.     Fforce(STDOUT,confh);
  461.     }
  462.  
  463. /*
  464.  * Function: do_menuitem
  465.  * Returns: void
  466.  * Description: Respond to a user's menu action; dispatch appropriately.
  467.  */
  468. void do_menuitem(title,item)
  469.     int title, item;
  470.     {
  471.     menu_tnormal(menubar,title,TRUE);
  472.     menu_tnormal(menubar,item,TRUE);
  473.     switch (item)
  474.         {
  475.         case MNABOUT :
  476.             do_dialog(ABOUTBOX);
  477.             return;
  478.         case QUIT :
  479.             g_clrscr();
  480.             rsrc_free();
  481.             appl_exit();
  482.             exit(0); 
  483.         case CHDIR :
  484.             change_dir();
  485.             return;
  486.  
  487.         /* the help functions */
  488.         case WHATIS :
  489.             do_dialog(FWHATIS);
  490.             return;
  491.         case HELPEX   :
  492.             frm_dsdial(h_ex, h_buttons, TRUE);
  493.             return;
  494.         case HELPREST :
  495.             frm_dsdial(h_rest, h_buttons, TRUE);
  496.             return;
  497.         case HELPVIEW :
  498.             frm_dsdial(h_view, h_buttons, TRUE);
  499.             return;
  500.         case HELPSPEC :
  501.             frm_dsdial(h_spec, h_buttons, TRUE);
  502.             return;
  503.  
  504.         /* the rest of the cases will spawn ZOO */
  505.  
  506.         /* here are the adds */
  507.         case ADD :
  508.             exzoo("-add",TRUE,"Choose file to add");
  509.             break;
  510.         case MOVE :
  511.             exzoo("-move",TRUE,"Choose file to move");
  512.             break;
  513.         case BACKUP :
  514.             exzoo("-backup",FALSE,NULL);
  515.             break;
  516.         case COMMENT :
  517.             exzoo("-comment",FALSE,NULL);
  518.             break;
  519.         /* here are the extracts */
  520.         case EXTRACT :
  521.             exzoo("x",FALSE,NULL);
  522.             break;
  523.         case PRINT :
  524.             notimpl();
  525.             break;
  526.         case PRINTPRN :
  527.             notimpl();
  528.             break;
  529.         case RESTORE :
  530.             exzoo("x//",FALSE,NULL);
  531.             break;
  532.         case RELATIVE :
  533.             exzoo("x.//",FALSE,NULL);
  534.             break;    
  535.         case LIST :
  536.             exzoo("-list",FALSE,NULL);
  537.             break;
  538.         case LISTPRN :
  539.             if (prt_output())
  540.                 {
  541.                 exzoo("-list",FALSE,NULL);
  542.                 restore_output();
  543.                 }
  544.             break;
  545.         case TEST :
  546.             exzoo("-test",FALSE,NULL);
  547.             break;
  548.         default:
  549.             notimpl();
  550.             break;
  551.         }
  552.     }
  553.  
  554. /*
  555.  * Function: maintevent
  556.  * Returns: void
  557.  * Description: Call the GEMFAST evnx_multi function and wait for
  558.  *              a menu message. Pass the results to do_menuitem.
  559.  * Note: This function uses the GEMFAST evnx_multi function, which is
  560.  *       available in C source code if you don't have GEMFAST.
  561.  */
  562. void mainevent()
  563.     {
  564.     XMULTI xm;
  565.     int events;
  566.     xm.mflags = MU_MESAG;
  567.     while (1) 
  568.         {
  569.         events = evnx_multi(&xm);
  570.         if (events & MU_MESAG) 
  571.             if (xm.msgbuf[0] == MN_SELECTED) 
  572.                 do_menuitem(xm.msgbuf[3], xm.msgbuf[4]);
  573.                 
  574.         }
  575.     }
  576.  
  577. /*
  578.  * Function: main
  579.  * Returns: Only returns on failure, in which case an error value is set.
  580.  * Description: Initialize GEM, load the resource, find ZOO, and otherwise
  581.  *              prepare for mainevent.
  582.  */
  583. main()
  584.     {
  585.     void g_clrscr();
  586.     char *pfindfile();
  587.     char *fullpath();
  588.     char *p;
  589.     appl_init();
  590.     g_clrscr();
  591.     if (!load_resource(RESOURCE_FILE))
  592.         {
  593.         appl_exit();
  594.         exit(-1);
  595.         }
  596.     rsrc_gaddr(0,MENUBAR, &menubar);
  597.     menu_bar(menubar,TRUE);
  598.     graf_mouse(ARROW,NULL);
  599.     show_about();
  600.     cwd[0] = Dgetdrv() + 'A';
  601.     cwd[1] = ':';
  602.     Dgetpath(&cwd[2],(int)(cwd[0]-'A'+1));
  603.     
  604.     if (access("ZOO.TTP",0))
  605.         p = fullpath(NULL,"ZOO.TTP");
  606.     else if (!(p = pfindfile(NULL,"ZOO.TTP",NULL)))
  607.         {
  608.         if (!fsel("Where is the ZOO program?","ZOO*.TTP",NULL,zoottp))
  609.             {
  610.             form_alert(1,"[0][ZOO.TTP must be available][Exit]");
  611.             appl_exit();
  612.             exit(-1);
  613.             }
  614.         }
  615.     strcpy(zoottp,p);
  616.     strcat(zoottp," ");
  617.     mainevent();
  618.     /* There should be no path to this, but just to be safe ... */
  619.     g_clrscr();
  620.     rsrc_free();
  621.     appl_exit(); 
  622.     } 
  623.  
  624. /* EOF */
  625.