home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Programming / DOpus4-GPL / Program / rexx.c < prev    next >
C/C++ Source or Header  |  2000-01-27  |  7KB  |  243 lines

  1. /*
  2.  
  3. Directory Opus 4
  4. Original GPL release version 4.12
  5. Copyright 1993-2000 Jonathan Potter
  6.  
  7. This program is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU General Public License
  9. as published by the Free Software Foundation; either version 2
  10. of the License, or (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. All users of Directory Opus 4 (including versions distributed
  22. under the GPL) are entitled to upgrade to the latest version of
  23. Directory Opus version 5 at a reduced price. Please see
  24. http://www.gpsoft.com.au for more information.
  25.  
  26. The release of Directory Opus 4 under the GPL in NO WAY affects
  27. the existing commercial status of Directory Opus 5.
  28.  
  29. */
  30.  
  31. #include "dopus.h"
  32.  
  33. #define MAXRXOUTSTANDING 300
  34. #define RXERRORIMGONE 100
  35. #define RXERRORNOCMD 30
  36.  
  37. static struct RexxMsg *oldrxmsg;
  38. static int rexx_closing;
  39. static long replies_pending;
  40.  
  41. void rexx_dispatch(allfuncs)
  42. int allfuncs;
  43. {
  44.     struct RexxMsg *msg;
  45.     int dontreply,a,cmd;
  46.     char *command;
  47.  
  48.     while (msg=(struct RexxMsg *)GetMsg(arexx_port)) {
  49.         if ((!RexxSysBase || !(IsRexxMsg(msg))) &&
  50.             msg->rm_Node.mn_Node.ln_Type!=NT_REPLYMSG) {
  51.  
  52.             struct DOpusMessage *dopusmsg;
  53.             struct DOpusArgsList *arglist;
  54.  
  55.             dopusmsg=(struct DOpusMessage *)msg;
  56.  
  57.             switch (dopusmsg->command) {
  58.                 case DOPUSMSG_GETVIS:
  59.                     fill_out_visinfo((struct VisInfo *)dopusmsg->data,NULL);
  60.                     break;
  61.                 case DOPUSMSG_GETNEXTFILE:
  62.                     arglist=(struct DOpusArgsList *)dopusmsg->data;
  63.                     if (arglist->single_file) {
  64.                         strcpy(arglist->file_data,arglist->single_file);
  65.                         arglist->single_file=NULL;
  66.                     }
  67.                     else if (arglist->file_list) {
  68.                         struct Directory *entry;
  69.  
  70.                         entry=(struct Directory *)arglist->file_list;
  71.                         strcpy(arglist->file_data,dopus_curwin[arglist->file_window]->directory);
  72.                         TackOn(arglist->file_data,entry->name,256);
  73.                         arglist->last_select=arglist->file_list;
  74.  
  75.                         entry=entry->next;
  76.                         while (entry) {
  77.                             if (entry->type<0 && entry->selected) break;
  78.                             entry=entry->next;
  79.                         }
  80.  
  81.                         arglist->file_list=(APTR)entry;
  82.                     }
  83.                     else arglist->file_data[0]=0;
  84.                     break;
  85.                 case DOPUSMSG_UNSELECTFILE:
  86.                     arglist=(struct DOpusArgsList *)dopusmsg->data;
  87.                     if (arglist->last_select) {
  88.                         unselect(arglist->file_window,arglist->last_select);
  89.                         arglist->last_select=NULL;
  90.                     }
  91.                     break;
  92.                 case DOPUSMSG_GETPRINTDIR:
  93.                     get_printdir_data((struct PrintDirData *)dopusmsg->data);
  94.                     break;
  95.             }
  96.             ReplyMsg((struct Message *)dopusmsg);
  97.         }
  98.         else if (RexxSysBase) {
  99.             if (msg->rm_Node.mn_Node.ln_Type==NT_REPLYMSG) {
  100.                 if (msg->rm_Args[1]) rexx_msg_reply(msg);
  101.                 DeleteArgstring(msg->rm_Args[0]);
  102.                 DeleteRexxMsg(msg);
  103.                 --replies_pending;
  104.             }
  105.             else {
  106.                 command=(char *)msg->rm_Args[0];
  107.                 while (*command>0 && *command<=' ') ++command;
  108.                 msg->rm_Result1=0;
  109.                 msg->rm_Result2=0;
  110.                 dontreply=0;
  111.                 if (rexx_closing) msg->rm_Result1=RXERRORIMGONE;
  112.                 else {
  113.                     oldrxmsg=msg;
  114.                     for (cmd=0;commandlist[cmd].name;cmd++) {
  115.                         a=strlen(commandlist[cmd].name);
  116.                         if ((LStrnCmpI(commandlist[cmd].name,command,a))==0 &&
  117.                             (command[a]==0 || isspace(command[a]))) {
  118.                             func_global_function=0;
  119.                             rexxdisp(msg,&commandlist[cmd],command+a);
  120.                             if (!allfuncs || func_global_function==FUNC_ICONIFY ||
  121.                                 func_global_function==FUNC_QUIT) break;
  122.                             if (func_global_function) {
  123.                                 char buf[10];
  124.  
  125.                                 rexx_result_code=0;
  126.                                 rexx_return_value=0;
  127.                                 internal_function(func_global_function,rexx_global_flag,NULL,NULL);
  128.                                 func_global_function=0;
  129.                                 lsprintf(buf,"%ld",rexx_return_value);
  130.                                 rexx_set_return(msg,rexx_result_code,buf);
  131.                             }
  132.                             break;
  133.                         }
  134.                     }
  135.                     if (!commandlist[cmd].name) {
  136.                         rexx_command(msg->rm_Args[0],msg);
  137.                         dontreply=1;
  138.                     }
  139.                 }
  140.                 oldrxmsg=NULL;
  141.                 if (!dontreply) ReplyMsg((struct Message *)msg);
  142.             }
  143.         }
  144.         else if (msg->rm_Node.mn_Node.ln_Type!=NT_REPLYMSG)
  145.             ReplyMsg((struct Message *)msg);
  146.     }
  147. }
  148.  
  149. struct RexxMsg *send_rexx_command(command,replyfunc,msg)
  150. char *command;
  151. int (*replyfunc)();
  152. struct RexxMsg *msg;
  153. {
  154.     struct MsgPort *rxport;
  155.     struct RexxMsg *RexxMsg;
  156.  
  157.     if (!RexxSysBase || replies_pending>MAXRXOUTSTANDING-1 ||
  158.         !command || !command[0]) return(NULL);
  159.  
  160.     if ((RexxMsg=(struct RexxMsg *)
  161.         CreateRexxMsg(arexx_port,"dopus",str_arexx_portname)) &&
  162.         (RexxMsg->rm_Args[0]=(STRPTR)CreateArgstring(command,(long)strlen(command)))) {
  163.  
  164.         RexxMsg->rm_Action=RXCOMM;
  165.         RexxMsg->rm_Args[1]=(STRPTR)replyfunc;
  166.         RexxMsg->rm_Args[2]=(STRPTR)msg;
  167.         RexxMsg->rm_Node.mn_Node.ln_Name="REXX";
  168.  
  169.         Forbid();
  170.         if (rxport=FindPort("REXX"))
  171.             PutMsg(rxport,(struct Message *)RexxMsg);
  172.         Permit();
  173.         if (rxport) {
  174.             ++replies_pending;
  175.             return(RexxMsg);
  176.         }
  177.         else DeleteArgstring(RexxMsg->rm_Args[0]);
  178.     }
  179.     if (RexxMsg) DeleteRexxMsg(RexxMsg);
  180.     return(NULL);
  181. }
  182.  
  183. void rexx_msg_reply(msg)
  184. struct RexxMsg *msg;
  185. {
  186.     struct RexxMsg *oldmsg;
  187.  
  188.     if ((oldmsg=(struct RexxMsg *)(msg->rm_Args[2]))) {
  189.         rexx_set_return(oldmsg,msg->rm_Result1,(char *)msg->rm_Result2);
  190.         ReplyMsg((struct Message *)oldmsg);
  191.     }
  192. }
  193.  
  194. struct RexxMsg *rexx_command(command,syncmsg)
  195. char *command;
  196. struct RexxMsg *syncmsg;
  197. {
  198.     struct RexxMsg *msg;
  199.  
  200.     if (!command || !command[0]) msg=NULL;
  201.     else if (syncmsg) msg=send_rexx_command(command,(APTR)&rexx_msg_reply,syncmsg);
  202.     else msg=send_rexx_command(command,NULL,NULL);
  203.     return(msg);
  204. }
  205.  
  206. void rexx_set_return(msg,rc,result)
  207. struct RexxMsg *msg;
  208. int rc;
  209. char *result;
  210. {
  211.     str_last_rexx_result[0]=0;
  212.  
  213.     if (msg && RexxSysBase) {
  214.         if (rc || !result || !(msg->rm_Action&(1<<RXFB_RESULT))) {
  215.             msg->rm_Result1=rc;
  216.             msg->rm_Result2=0;
  217.         }
  218.         else {
  219.             msg->rm_Result1=0;
  220.             msg->rm_Result2=(long)CreateArgstring(result,strlen(result));
  221.             strcpy(str_last_rexx_result,result);
  222.         }
  223.     }
  224.     else if (result) strcpy(str_last_rexx_result,result);
  225. }
  226.  
  227. void close_rexx_port()
  228. {
  229.     if (RexxSysBase) {
  230.         rexx_closing=1;
  231.         if (oldrxmsg) {
  232.             oldrxmsg->rm_Result1=RXERRORIMGONE;
  233.             ReplyMsg((struct Message *)oldrxmsg);
  234.             oldrxmsg=NULL;
  235.         }
  236.         while (replies_pending) {
  237.             if (!FindPort("REXX")) break;
  238.             WaitPort(arexx_port);
  239.             rexx_dispatch(0);
  240.         }
  241.     }
  242. }
  243.