Annotation of uae/src/od-amiga/ami-rexx.c, revision 1.1.1.1

1.1       root        1:  /*
                      2:   * UAE - The Un*x Amiga Emulator
                      3:   * 
                      4:   * ami-rexx.c
                      5:   * 
                      6:   * Copyright 1996 Samuel Devulder.
                      7:   *
                      8:   * History:
                      9:   *     05/09/97: Added UAEEXE support.
                     10:   */
                     11: 
                     12: #include <proto/exec.h>
                     13: #include <proto/rexxsyslib.h>
                     14: #include <proto/dos.h>
                     15: #ifndef __SASC
                     16: #include <proto/alib.h>
                     17: #endif
                     18: 
                     19: #include <rexx/storage.h>
                     20: #include <rexx/errors.h>
                     21: 
                     22: /* this prevent a conflict between <rexx/rexxio.h> and <sys/dirent.h> */
                     23: #undef DT_DIR 
                     24: 
                     25: /****************************************************************************/
                     26: 
                     27: #include "sysconfig.h"
                     28: #include "sysdeps.h"
                     29: 
                     30: #include "uae.h"
                     31: #include "config.h"
                     32: #include "options.h"
                     33: #ifdef __GNUC__
                     34: #include "../include/memory.h" /* or else gcc includes machdep/memory.h */
                     35: #endif
                     36: #include "custom.h"
                     37: #include "readcpu.h"
                     38: #include "newcpu.h"
                     39: #include "disk.h"
                     40: #include "gui.h"
                     41: #include "sound.h"
                     42: #include "gensound.h"
                     43: #include "uaeexe.h"
                     44: #include "threaddep/penguin.h"
                     45: #include "xwin.h"
                     46: 
                     47: #include <ctype.h>
                     48: 
                     49: /****************************************************************************/
                     50: 
                     51: #define UAE_PORTNAME    "UAE"
                     52: #define RESULT_LEN      1024
                     53: #define PORT_LEN        80
                     54: #define CMD_LEN         1024
                     55: 
                     56: typedef struct
                     57: {
                     58:     char port[PORT_LEN];
                     59:     char cmd_on[CMD_LEN];
                     60:     char cmd_off[CMD_LEN];
                     61: } gui_rexx_s;
                     62: 
                     63: enum {LED_POW, LED_DF0, LED_DF1, LED_DF2, LED_DF3,
                     64:       NAME_DF0, NAME_DF1, NAME_DF2, NAME_DF3,
                     65:       ON_EXIT,
                     66:       GUI_REXX_MAX};
                     67: 
                     68: /****************************************************************************/
                     69: 
                     70: int  rexx_init(void);
                     71: void rexx_exit(void);
                     72: void rexx_led(int led, int on);
                     73: void rexx_filename(int num, char *name);
                     74: void rexx_handle_events(void);
                     75: 
                     76: /****************************************************************************/
                     77: 
                     78: #ifdef __GNUC__
                     79: struct RxsLib
                     80: #else
                     81: struct Library
                     82: #endif
                     83:                         *RexxSysBase;
                     84: static struct MsgPort   *ARexxPort;
                     85: static gui_rexx_s        gui_rexx[GUI_REXX_MAX];
                     86: static char              RESULT[RESULT_LEN];
                     87: static int               led_state[5];
                     88: 
                     89: static int   ADDRESS(char *hostname, char *cmd);
                     90: static int   matchstr(char **line,char *pat);
                     91: static void  extractstr(char **line, char *result, int len);
                     92: static int   matchnum(char **line);
                     93: 
                     94: /****************************************************************************/
                     95: 
                     96: extern int quit_program;                                 /* ami-gui.c */
                     97: extern void activate_debugger(void);                     /* debug.c */
                     98: extern char *to_unix_path(char *s);                      /* ami-disk.c */
                     99: extern char *from_unix_path(char *s);                    /* ami-disk.c */
                    100: 
                    101: /****************************************************************************/
                    102: 
                    103: int rexx_init(void)
                    104: {
                    105:     quit_program = 0;
                    106:     RexxSysBase = (void*)OpenLibrary("rexxsyslib.library",0L);
                    107:     if(!RexxSysBase) {
                    108:         fprintf(stderr, "Can't find rexxsyslib.library!\n");
                    109:         return 1;
                    110:     }
                    111:     if(FindPort(UAE_PORTNAME)) {
                    112:         fprintf(stderr, "Port \"%s\" already exists!\n",UAE_PORTNAME);
                    113:         return 1;    
                    114:     }
                    115:     ARexxPort = CreatePort(UAE_PORTNAME,0);
                    116:     if(!ARexxPort) {
                    117:         fprintf(stderr, "Failed to open AREXX port \"%s\"!\n",UAE_PORTNAME);
                    118:         return 1;
                    119:     }
                    120:     fprintf(stderr,"Rexx port \"%s\" installed.\n", UAE_PORTNAME);
                    121:     rexx_handle_events();
                    122:     return 0;
                    123: }
                    124: 
                    125: /****************************************************************************/
                    126: 
                    127: void rexx_exit(void)
                    128: {
                    129:     if(ARexxPort) {
                    130:         struct RexxMsg *msg;
                    131:         gui_rexx_s *gui = &gui_rexx[ON_EXIT];
                    132: 
                    133:         if(gui->port[0] && gui->cmd_on[0]) {
                    134:             if(ADDRESS(gui->port, gui->cmd_on) != RC_OK) {
                    135:                 fprintf(stderr,"%s:%s:%s\n", gui->port,
                    136:                                              gui->cmd_on,
                    137:                                              RESULT);
                    138:             }
                    139:             gui->port[0] = '\0';
                    140:          }
                    141:         Forbid();
                    142:         while((msg = (struct RexxMsg*)GetMsg(ARexxPort))) {
                    143:            msg->rm_Result1 = RC_ERROR;
                    144:            msg->rm_Result2 = NULL;
                    145:            ReplyMsg((void*)msg);
                    146:         }
                    147:         DeletePort(ARexxPort);
                    148:         Permit();
                    149:         ARexxPort = NULL;
                    150:     }
                    151:     if(RexxSysBase) {
                    152:         CloseLibrary((void*)RexxSysBase);
                    153:         RexxSysBase = NULL;
                    154:     }
                    155: }
                    156: 
                    157: /****************************************************************************/
                    158: 
                    159: static int EJECT(char *line)
                    160: {
                    161:     int drive = matchnum(&line);
                    162:     if(drive<0 || drive>3) return RC_WARN;
                    163:     disk_eject(drive);
                    164:     sprintf(RESULT,"Drive %d ejected",drive);
                    165:     return RC_OK;
                    166: }
                    167: 
                    168: /****************************************************************************/
                    169: 
                    170: static int INSERT(char *line)
                    171: {
                    172:     int drive = matchnum(&line);
                    173:     if(drive<0 || drive>3) return RC_WARN;
                    174:     if(disk_empty(drive)) {
                    175:         char buff[256];
                    176:         char *name;
                    177:         extractstr(&line, buff, 256);
                    178:         name = to_unix_path(buff);
                    179:         disk_insert(drive, name);
                    180:         free(name);
                    181:     } else {
                    182:         sprintf(RESULT,"Drive %d not empty!",drive);
                    183:         return RC_WARN;
                    184:     }
                    185:     return RC_OK;
                    186: }
                    187: 
                    188: /****************************************************************************/
                    189: 
                    190: static void QUIT(void)
                    191: {
                    192:     broken_in = 1;
                    193:     regs.spcflags |= SPCFLAG_BRK;
                    194:     quit_program = 1;
                    195: }
                    196: 
                    197: /****************************************************************************/
                    198: 
                    199: static int QUERY(char *line)
                    200: {
                    201:     char *res = NULL;
                    202:     int   alc = 0;
                    203: 
                    204:     if     (matchstr(&line, "LED_POW"))  res = led_state[0]?"1":"0";
                    205:     else if(matchstr(&line, "LED_DF0"))  res = led_state[1]?"1":"0";
                    206:     else if(matchstr(&line, "LED_DF1"))  res = led_state[2]?"1":"0";
                    207:     else if(matchstr(&line, "LED_DF2"))  res = led_state[3]?"1":"0";
                    208:     else if(matchstr(&line, "LED_DF3"))  res = led_state[4]?"1":"0";
                    209:     else if(matchstr(&line, "NAME_DF0")) res = from_unix_path(currprefs.df[0]), alc = 1;
                    210:     else if(matchstr(&line, "NAME_DF1")) res = from_unix_path(currprefs.df[1]), alc = 1;
                    211:     else if(matchstr(&line, "NAME_DF2")) res = from_unix_path(currprefs.df[2]), alc = 1;
                    212:     else if(matchstr(&line, "NAME_DF3")) res = from_unix_path(currprefs.df[3]), alc = 1;
                    213:     else if(matchstr(&line, "FAKEJOYSTICK")) res = currprefs.fake_joystick?"1":"0";
                    214:     else if(matchstr(&line, "DISPLAY"))  res = inhibit_frame?"0":"1";
                    215:     else if(matchstr(&line, "FRAMERATE")) {
                    216:         sprintf(RESULT,"%d",currprefs.framerate);
                    217:         return RC_OK;
                    218:     } else if(matchstr(&line, "SOUND")) {
                    219:         sprintf(RESULT,"%d",sound_available?currprefs.produce_sound:-1);
                    220:         return RC_OK;
                    221:     } 
                    222:     else return RC_ERROR;
                    223: 
                    224:     if(res) {
                    225:         strncpy(RESULT, res, RESULT_LEN);
                    226:         if(alc) free(res);
                    227:     }
                    228:     return RC_OK;
                    229: }
                    230: 
                    231: /****************************************************************************/
                    232: 
                    233: static int FEEDBACK(char *line)
                    234: {
                    235:     gui_rexx_s *gui = NULL;
                    236: 
                    237:     if     (matchstr(&line,"LED_POW"))  gui = &gui_rexx[LED_POW];
                    238:     else if(matchstr(&line,"LED_DF0"))  gui = &gui_rexx[LED_DF0];
                    239:     else if(matchstr(&line,"LED_DF1"))  gui = &gui_rexx[LED_DF1];
                    240:     else if(matchstr(&line,"LED_DF2"))  gui = &gui_rexx[LED_DF2];
                    241:     else if(matchstr(&line,"LED_DF3"))  gui = &gui_rexx[LED_DF3];
                    242:     else if(matchstr(&line,"NAME_DF0")) gui = &gui_rexx[NAME_DF0];
                    243:     else if(matchstr(&line,"NAME_DF1")) gui = &gui_rexx[NAME_DF1];
                    244:     else if(matchstr(&line,"NAME_DF2")) gui = &gui_rexx[NAME_DF2];
                    245:     else if(matchstr(&line,"NAME_DF3")) gui = &gui_rexx[NAME_DF3];
                    246:     else if(matchstr(&line,"ON_EXIT"))  gui = &gui_rexx[ON_EXIT];
                    247:     else return RC_ERROR;
                    248: 
                    249:     while(1) {
                    250:         if(matchstr(&line, "ADDRESS") ||
                    251:            matchstr(&line, "PORT")) {
                    252:             extractstr(&line, gui->port, PORT_LEN);
                    253:         } else if(matchstr(&line,"COMMAND") ||
                    254:                   matchstr(&line,"CMD") ||
                    255:                   matchstr(&line,"CMD_ON")) {
                    256:             extractstr(&line, gui->cmd_on,  CMD_LEN);
                    257:         } else if(matchstr(&line,"CMD_OFF")) {
                    258:             extractstr(&line, gui->cmd_off, CMD_LEN);
                    259:         } else break;
                    260:     }
                    261:     return RC_OK;
                    262: }
                    263: 
                    264: /****************************************************************************/
                    265: 
                    266: static int VERSION(char *line)
                    267: {
                    268:     if(matchstr(&line,"STRING")) {
                    269:         sprintf(RESULT,
                    270:                 "UAE-%d.%d.%d � by Bernd Schmidt & contributors, "
                    271:                 "Amiga Port by Samuel Devulder.",
                    272:                 (version / 100) % 10, (version / 10) % 10, version % 10);
                    273:     } else if(matchstr(&line,"NUM")) {
                    274:         sprintf(RESULT,"%d",version);
                    275:     } else if(matchstr(&line,"AUTHOR")) {
                    276:         sprintf(RESULT,"� by Bernd Schmidt & contributors");
                    277:     } else if(matchstr(&line,"PORT")) {
                    278:         sprintf(RESULT,"Amiga Port by Samuel Devulder");
                    279:     } else return RC_ERROR;
                    280:     return RC_OK;
                    281: }
                    282: 
                    283: /****************************************************************************/
                    284: 
                    285: static int FRAMERATE(char *line)
                    286: {
                    287:     int num;
                    288:     num = matchnum(&line);
                    289:     if(num>=1 && num<=20) {
                    290:         currprefs.framerate = num;
                    291:     } else {
                    292:         sprintf(RESULT,"Invalid frame rate: %d\n", num);
                    293:         return RC_WARN;
                    294:     }
                    295:     return RC_OK;
                    296: }
                    297: 
                    298: /****************************************************************************/
                    299: 
                    300: static int FAKEJOYSTICK(char *line)
                    301: {
                    302:     if     (matchstr(&line,"ON"))     currprefs.fake_joystick = 2;
                    303:     else if(matchstr(&line,"OFF"))    currprefs.fake_joystick = 0;
                    304:     else if(matchstr(&line,"TOGGLE")) currprefs.fake_joystick =
                    305:                                       currprefs.fake_joystick?0:2;
                    306:     else return RC_ERROR;
                    307:     return RC_OK;
                    308: }
                    309: 
                    310: /****************************************************************************/
                    311: 
                    312: static int DISPLAY(char *line)
                    313: {
                    314:     if     (matchstr(&line,"ON"))     inhibit_frame = 0;
                    315:     else if(matchstr(&line,"OFF"))    inhibit_frame = 1;
                    316:     else if(matchstr(&line,"TOGGLE")) inhibit_frame = inhibit_frame?0:1;
                    317:     else return RC_ERROR;
                    318:     return RC_OK;
                    319: }
                    320: 
                    321: /****************************************************************************/
                    322: 
                    323: static int SOUND(char *line)
                    324: {
                    325:     if(!sound_available) {
                    326:         sprintf(RESULT,"Sound not available!");
                    327:         return RC_WARN;
                    328:     }
                    329: 
                    330:     if     (matchstr(&line,"ON"))     currprefs.produce_sound = 2;
                    331:     else if(matchstr(&line,"OFF"))    currprefs.produce_sound = 1;
                    332:     else if(matchstr(&line,"BEST"))   currprefs.produce_sound = 3;
                    333:     else if(matchstr(&line,"TOGGLE")) currprefs.produce_sound =
                    334:                                       currprefs.produce_sound<=1?2:1;
                    335:     else return RC_ERROR;
                    336:     return RC_OK;
                    337: }
                    338: 
                    339: /****************************************************************************/
                    340: 
                    341: static int UAEEXE(char *line)
                    342: {
                    343:     if(uaeexe(line)) {
                    344:         sprintf(RESULT,"Remote CLI failed!");
                    345:         return RC_WARN;
                    346:     }
                    347:     return RC_OK;
                    348: }
                    349: 
                    350: /****************************************************************************/
                    351: 
                    352: static int process_cmd(char *line)
                    353: {
                    354:     RESULT[0] = '\0';
                    355:     if     (matchstr(&line, "EJECT"))        return EJECT(line);
                    356:     else if(matchstr(&line, "INSERT"))       return INSERT(line);
                    357:     else if(matchstr(&line, "QUERY"))        return QUERY(line);
                    358:     else if(matchstr(&line, "FEEDBACK"))     return FEEDBACK(line);
                    359:     else if(matchstr(&line, "VERSION"))      return VERSION(line);
                    360:     else if(matchstr(&line, "BYE"))          QUIT();
                    361:     else if(matchstr(&line, "QUIT"))         QUIT();
                    362:     else if(matchstr(&line, "DEBUG"))        activate_debugger();
                    363:     else if(matchstr(&line, "RESET"))        m68k_reset();
                    364:     else if(matchstr(&line, "DISPLAY"))      return DISPLAY(line);
                    365:     else if(matchstr(&line, "FRAMERATE"))    return FRAMERATE(line);
                    366:     else if(matchstr(&line, "FAKEJOYSTICK")) return FAKEJOYSTICK(line);
                    367:     else if(matchstr(&line, "SOUND"))        return SOUND(line);
                    368:     else if(matchstr(&line, "UAEEXE"))       return UAEEXE(line);
                    369:     else return RC_ERROR;
                    370:     return RC_OK;
                    371: }
                    372: 
                    373: /****************************************************************************/
                    374: 
                    375: void rexx_handle_events(void)
                    376: {
                    377:     struct RexxMsg *msg;
                    378:     while((msg = (struct RexxMsg*)GetMsg(ARexxPort))) {
                    379:         if(!(msg->rm_Action & RXCOMM)) {
                    380:             fprintf(stderr,"Unknown action '%08X' recieved!\n",
                    381:                     msg->rm_Action);
                    382:             continue;
                    383:         }
                    384:         msg->rm_Result1 = process_cmd(msg->rm_Args[0]);
                    385:         msg->rm_Result2 = NULL;
                    386:         if(msg->rm_Action & RXFF_RESULT) {
                    387:             msg->rm_Result2 = (LONG)CreateArgstring(RESULT,strlen(RESULT));
                    388:         }
                    389:         ReplyMsg((void*)msg);
                    390:     }
                    391: }
                    392: 
                    393: /****************************************************************************/
                    394: 
                    395: void rexx_led(int led, int on)
                    396: {
                    397:     gui_rexx_s *gui = NULL;
                    398: 
                    399:     if(led < 0 || led > 4) return;
                    400:     led_state[led] = on;
                    401: 
                    402:     if(led == 0) gui = &gui_rexx[LED_POW];
                    403:     if(led == 1) gui = &gui_rexx[LED_DF0];
                    404:     if(led == 2) gui = &gui_rexx[LED_DF1];
                    405:     if(led == 3) gui = &gui_rexx[LED_DF2];
                    406:     if(led == 4) gui = &gui_rexx[LED_DF3];
                    407: 
                    408:     if(gui->port[0] && gui->cmd_on[0] && gui->cmd_off[0]) {
                    409:         if(ADDRESS(gui->port, on ? gui->cmd_on : gui->cmd_off) != RC_OK) {
                    410:             fprintf(stderr,"%s:%s:%s\n", gui->port,
                    411:                                          on ? gui->cmd_on : gui->cmd_off,
                    412:                                          RESULT);
                    413:         }
                    414:     }
                    415: }
                    416: 
                    417: /****************************************************************************/
                    418: 
                    419: void rexx_filename(int num, char *filename)
                    420: {
                    421:     gui_rexx_s *gui = NULL;
                    422:     if(num < 0 || num > 3) return;
                    423:     gui = &gui_rexx[NAME_DF0 + num];
                    424:     if(gui->port[0] && gui->cmd_on[0]) {
                    425:         char buf[CMD_LEN];
                    426:         if(!(filename = from_unix_path(filename))) return;
                    427:         sprintf(buf, gui->cmd_on, filename);
                    428:         free(filename);
                    429:         if(ADDRESS(gui->port, buf) != RC_OK) {
                    430:             fprintf(stderr,"%s:%s:%s\n", gui->port, buf, RESULT);
                    431:         }
                    432:     }
                    433: }
                    434: 
                    435: /****************************************************************************/
                    436: /* send a message to an AREXX port.
                    437:  */
                    438: static int ADDRESS(char *hostname, char *cmd)
                    439: {
                    440:     struct MsgPort *RexxPort,
                    441:                    *ReplyPort;
                    442:     struct RexxMsg *HostMsg,
                    443:                    *answer;
                    444:     int result = RC_WARN;
                    445: 
                    446:     if(!stricmp(hostname, "COMMAND")) {
                    447:         return SystemTagList(cmd,NULL);
                    448:     }
                    449: 
                    450:     if((RexxPort = (void *)FindPort(hostname))) {
                    451:         if((ReplyPort = (void *)CreateMsgPort())) {
                    452:             if((HostMsg = CreateRexxMsg(ReplyPort, NULL, hostname))) {
                    453:                 if((HostMsg->rm_Args[0] = CreateArgstring(cmd,strlen(cmd)))) {
                    454:                     HostMsg->rm_Action  = RXCOMM | RXFF_RESULT;
                    455:                     PutMsg(RexxPort, (void*)HostMsg);
                    456:                     WaitPort(ReplyPort);
                    457:                     while(!(answer = (void *)GetMsg(ReplyPort)));
                    458:                     result = answer->rm_Result1;
                    459:                     if(result == RC_OK) {
                    460:                         if(answer->rm_Result2) {
                    461:                         strncpy(RESULT,(char *)answer->rm_Result2,RESULT_LEN);
                    462:                         DeleteArgstring((char *)answer->rm_Result2);
                    463:                         } else RESULT[0] = '\0';
                    464:                     }
                    465:                     DeleteArgstring(HostMsg->rm_Args[0]);
                    466:                 } else strcpy(RESULT, "Can't create argstring!");
                    467:                 DeleteRexxMsg(HostMsg);
                    468:             } else strcpy(RESULT, "Can't create rexx message!");
                    469:             DeleteMsgPort(ReplyPort);
                    470:         } else strcpy(RESULT, "Can't alloc reply port!");
                    471:     } else sprintf(RESULT, "Port \"%s\" not found!",hostname);
                    472:     return result;
                    473: }
                    474: 
                    475: /****************************************************************************/
                    476: /* argument parsing routines
                    477:  */
                    478: static int matchstr(char **line,char *pat)
                    479: {
                    480:     char *s = *line;
                    481:     char match = 0;
                    482:     while(isspace(*s)) ++s;
                    483:     if(*s=='\"' || *s== '\'') match = *s++;
                    484:     while(*s && (tolower(*s)==tolower(*pat)) && (!match || *s!=match)) {++s;++pat;}
                    485:     if(match && *s==match && s[1]) ++s;
                    486:     if(!*pat && (!*s || isspace(*s))) {
                    487:         while(isspace(*s)) ++s;
                    488:         *line = s;
                    489:         return 1;
                    490:     }
                    491:     return 0;
                    492: }
                    493: 
                    494: /****************************************************************************/
                    495: 
                    496: static void extractstr(char **line, char *result, int len)
                    497: {
                    498:     char *s    = *line;
                    499:     char match = 0;
                    500: 
                    501:     while(isspace(*s)) ++s;
                    502: 
                    503:     if(*s=='\"' || *s=='\'') match = *s++;
                    504:     while(*s && *s != match) {
                    505:         if(*s == '\\' && (s[1] == '\'' || s[1] == '\"')) ++s;
                    506:         if(len > 1) {*result++ = *s;--len;}
                    507:         ++s;
                    508:         if(!match && isspace(*s)) break;
                    509:     }
                    510:     if(match && *s == match) ++s;
                    511:     while(isspace(*s)) ++s;
                    512: 
                    513:     *result  = '\0';
                    514:     *line    = s;
                    515: }
                    516: 
                    517: /****************************************************************************/
                    518: 
                    519: static int matchnum(char **line)
                    520: {
                    521:     char *s = *line, match = 0;
                    522:     int sign = 1, num = 0;
                    523: 
                    524:     while(isspace(*s)) ++s;
                    525:     if(*s=='\"' || *s=='\'') match = *s++;
                    526:     if(*s=='-') {sign = -1;++s;}
                    527:     if(*s=='+') ++s;
                    528:     while(isspace(*s)) ++s;
                    529:     while(*s>='0' && *s<='9') num = num*10 + (*s++ - '0');
                    530:     if(match && *s==match && s[1]) ++s;
                    531:     while(isspace(*s)) ++s;
                    532:     *line = s;
                    533:     return sign>0?num:-num;
                    534: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.