home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / program / 575 / okami13b / msh.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-15  |  8.0 KB  |  382 lines

  1. /********************************************************************
  2.  
  3.          Mikro-Shell: Startprogramm fuer Okami-Shell
  4.          
  5.               Version 1.4
  6.  
  7.               WR 1.11.89
  8.               
  9.   Änderungen:
  10.   
  11. 18.02.90 Optional Übergabe der Konfigurationsdatei
  12. 01.03.90 Internes Kommando: echo
  13. 31.03.90 Übergabe mehrerer Konfigurationsdateien
  14.      internes Kommando: incl
  15. 10.05.90 Länge des Para-Strings in Pexec korrekt
  16.      Zeilenumbruch mit \ am Ende einer Zeile
  17. 28.12.90 Kommandozeile mit -c und Kommandos
  18.      internes Kommando: ver
  19. 05.03.91 interne Kommandos exit und wait
  20. 19.06.91 1.4: Steuersequenzen in echo
  21.  
  22. *******************************************************************/
  23. static char _M_ID_[]="@(#)Okami Microshell 1.4 - msh.c";
  24.  
  25. #include <stdio.h>
  26. #include <ctype.h>
  27. #include <osbind.h>
  28.  
  29. /* Die Include-Datei cmpdat.h wird von einem Okami-Script zum Compiler-
  30. ** Aufruf angelegt und enthält nur eine Zeile:
  31.  
  32.     #define _CMP_DAT "Datum, Uhrzeit"
  33.  
  34. ** Wer diese Datei nicht anlegen will, kann diese Zeile anstelle der
  35. ** jetzt folgenden include-Anweisung benutzen.
  36. */
  37.  
  38. #include <cmpdat.h>
  39.  
  40. /* Ein paar Makros                            */
  41.  
  42. #define StrEqu(a,b)    (!strcmp(a,b))        /* Test: Strings gleich */
  43. #define StrNEqu(a,b,n)    (!strncmp(a,b,n))    /* Test: Strings gleich */
  44. #define StrLast(S)    (*(S+strlen(S)-1))    /* String: letztes char.*/
  45.  
  46. /* Strings mit Programmname und Versionsnummer                */
  47.  
  48. char TPName[]=        "Okami Microshell";
  49. char TPVersion[]=    "1.4";
  50.  
  51. /* Weitere globale Variablen und defines                */
  52.  
  53. char KONFFILE[]=    "msh.inf";    /* Default bei argc==1        */
  54. #define CMDLEN        (3*80)
  55. #define ARGV0        "msh"        /* eigentlich: argv[0]        */
  56. #define EXITCODE    (-999)        /* Script beenden        */
  57.  
  58. short MsgFlag=1;            /* Flag für Meldungen        */
  59.  
  60.  
  61. /************************************************************************/
  62.  
  63. main(argc,argv)
  64. int argc;
  65. char *argv[];
  66. {
  67.   register int i;
  68.   short ExFlag=0;            /* 0: Script, 1: Kommando    */
  69.   int Erg;
  70.   int DoFlag=0;
  71.   
  72.   if (argc>1)
  73.     for (i=1;i<argc;i++)
  74.     {
  75.       if (argv[i][0]=='\0')    /* ja, das _kommt_ vor */
  76.         continue;
  77.  
  78.       if (StrEqu(argv[i],"-c"))
  79.       {
  80.     ExFlag=1;
  81.     continue;
  82.       }
  83.       if (ExFlag)
  84.     Erg=DoCom(argv[i]);
  85.       else 
  86.     Erg=msh(argv[i]);
  87.       DoFlag=1;
  88.     }
  89.  
  90.   if (!DoFlag)
  91.     Erg=msh(KONFFILE);
  92.  
  93.   return Erg;
  94. }
  95.  
  96. /************************************************************************
  97.  
  98.     msh: ein MSH-Script ausführen
  99.  
  100. ************************************************************************/
  101. msh(FName)
  102. char FName[];
  103. {
  104.   FILE *FPtr;                /* File-Ptr. Konf.datei     */
  105.   char    St[CMDLEN+1];            /* eingelesene Zeile        */
  106.   char    Para2[CMDLEN+1];        /* Hilfsstring            */
  107.   register char *Para;
  108.   char c;
  109.   int Erg;
  110.   
  111.   while (isspace(*FName)) FName++;
  112.  
  113.   if ((FPtr=fopen(FName,"r"))==NULL)
  114.   {
  115.     fputs(ARGV0,stdout);
  116.     fputs(": cannot open ",stdout);
  117.     puts(FName);
  118.      return -1;
  119.   }
  120.  
  121.   while (fgets(St,3*80,FPtr)!=NULL)
  122.   {
  123.     Para=St;
  124.  
  125.     while (isspace(*Para)) Para++;    /* führende Leerzeichen          */
  126.  
  127.     if (*Para=='\0' || *Para=='\n' || *Para=='#')
  128.       continue;
  129.  
  130.     for (;;)                /* endende Leerzeichen        */
  131.     {
  132.       c=StrLast(Para);
  133.       if (isspace(c))
  134.     StrLast(Para)='\0';
  135.       else
  136.     break;
  137.     }
  138.     
  139.     while(StrLast(Para)=='\\')        /* \ am Ende: Zeilenumbruch    */
  140.     {
  141.       StrLast(Para)='\0';
  142.       fgets(Para2,80,FPtr);
  143.       while (Para2[strlen(Para2)-1]=='\n')
  144.     Para2[strlen(Para2)-1]='\0';
  145.       strcat(Para,Para2);
  146.     }
  147.  
  148.     /* Kommando ausführen */
  149.  
  150.     Erg=DoCom(St);
  151.     if (Erg==EXITCODE)
  152.       break;    /* Script beenden */
  153.   }
  154.  
  155.   fclose(FPtr);
  156.   return Erg;
  157. }
  158.  
  159. /************************************************************************
  160.  
  161.     DoCom: ein MSH-Kommando ausführen
  162.  
  163. Return: EXITCODE: aktuelles Script beenden
  164.     sonst: Returncode
  165. ************************************************************************/
  166. int DoCom(Para)
  167. char *Para;
  168. {
  169.   char    *Com;
  170.   char Para2[CMDLEN+1];            /* Hilfsstring            */
  171.   int Ret=0;                /* Rückgabewert            */
  172.  
  173.   if (Para[0]=='-')            /* -: Meldung abschalten    */
  174.   {
  175.     MsgFlag=0;
  176.     return;
  177.   }
  178.   if (Para[0]=='+')            /* +: Meldung einschalten    */
  179.   {
  180.     MsgFlag=1;
  181.     return;
  182.   }
  183.  
  184.   for (Com=Para;*Para && !isspace(*Para);Para++);
  185.   if (*Para!='\0')
  186.     *Para++='\0';
  187.    
  188.   if (StrEqu(Com,"echo"))        /* internes Kommando: echo    */
  189.     Xputs(Para);
  190.  
  191.   else if (StrEqu(Com,"exit"))        /* internes Kommando: exit    */
  192.     return EXITCODE;
  193.       
  194.   else if (StrEqu(Com,"incl"))        /* internes Kommando: incl    */
  195.     msh(Para);
  196.  
  197.   else if (StrEqu(Com,"ver"))        /* internes Kommando: ver    */
  198.   {
  199.     fputs(TPName,stdout);        /* kein printf, dadurch wird    */
  200.     fputs(" Version ",stdout);        /* der Code zu lang        */
  201.     puts(TPVersion);
  202.     fputs("Compiled ",stdout);
  203.     puts(_CMP_DAT);
  204.   }
  205.  
  206.   else if (StrEqu(Com,"wait"))        /* internes Kommando: wait    */
  207.     Ret = DoWait(Para);
  208.     
  209.   else                /* Programm starten */
  210.   {
  211.     /* Kommentarmodus: Kommando ausgeben */
  212.     if (MsgFlag)
  213.     {
  214.       fputs(Com,stdout);
  215.       fputc(' ',stdout);
  216.       puts(Para);
  217.     }
  218.     
  219.     Para2[0]=(char)strlen(Para);
  220.     strcpy(Para2+1,Para);
  221.     if ((Ret=Pexec(0,Com,Para2,NULL))<0)
  222.     if (MsgFlag)
  223.     {
  224.       fputs(Com,stdout);
  225.       puts(": not found");
  226.     }
  227.   }
  228.  
  229.   return Ret;
  230. }
  231.  
  232.  
  233. /************************************************************************
  234.  
  235.     Xputs: wie puts, aber interpretiert Escape-Sequenzen mit \ und ^
  236.  
  237. ************************************************************************/
  238. Xputs(s)
  239. register char *s;
  240. {
  241.   for(;*s;s++)
  242.   {
  243.     switch(*s)
  244.     {
  245.       case '\\':
  246.         s++;
  247.         switch(*s)
  248.     {
  249.       case '\0':
  250.         return;
  251.       case 'n':
  252.         fputc('\n',stdout);
  253.         break;
  254.       case 't':
  255.         fputc('\t',stdout);
  256.         break;
  257.       case 'b':
  258.         fputc('\b',stdout);
  259.         break;
  260.       case 'c':
  261.         break;
  262.       default:
  263.         fputc(*s,stdout);
  264.     }
  265.     break;
  266.       case '^':
  267.         s++;
  268.     switch(*s)
  269.     {
  270.       case '\0':
  271.         return;
  272.       default:
  273.         fputc(*s-'A'+1,stdout);
  274.     }
  275.         break;
  276.       default:
  277.         fputc(*s,stdout);
  278.     }
  279.   }
  280.  
  281.   if (!(s[-1]=='c' && s[-2]=='\\'))
  282.     fputc('\n',stdout);
  283. }
  284.  
  285. /************************************************************************
  286.  
  287.     DoWait: das interne Kommando wait
  288.  
  289.     Syntax: wait ((ttmmmjj|*) HHMMSS|key)
  290.  
  291. Return: EXITCODE: User hat abgebrochen, sonst: Zeit ist erreicht
  292.  
  293. *************************************************************************/
  294. int DoWait(Para)
  295. char *Para;            /* Parameter des Wait-Kommandos */
  296. {
  297.   int Tag,Mon,Jahr,Hr,Min,Sek;
  298.   int SollDat,SollUhr;
  299.  
  300.   while(isspace(*Para)) Para++;
  301.  
  302.   /* Worauf warten? */
  303.   if (StrEqu(Para,"key"))    /* Tastendruck */
  304.   {
  305.     if ((Cconin()&0xff)==0x1b)
  306.       return EXITCODE;
  307.     else
  308.       return 0;
  309.   }
  310.  
  311.   /* ab hier: auf Datum und Uhrzeit warten */
  312.  
  313.   /* Datum beachten? */
  314.   if (*Para=='*') /* nein */
  315.   {
  316.     Tag = -1;
  317.     Para++;
  318.   }
  319.   else
  320.   {
  321.     scan(&Para,&Tag);
  322.     scan(&Para,&Mon);
  323.     scan(&Para,&Jahr);
  324.     Jahr+=1900;
  325.     Para++; /* Leerzeichen */
  326.   } 
  327.  
  328.   /* Uhrzeit scannen */
  329.   scan(&Para,&Hr);
  330.   scan(&Para,&Min);
  331.   scan(&Para,&Sek);
  332.   if (*Para) Para++;
  333.  
  334.   /* Umformen in long-Format */
  335.   if (Tag>=0)
  336.     SollDat =  (Tag   &15) | (Mon&7 )<<5 | ((Jahr-1980)&255)<<9;  
  337.   SollUhr   = ((Sek/2)&15) | (Min&63)<<5 |   (Hr       &31 )<<11;
  338.  
  339.   if (MsgFlag)
  340.   {
  341.     fputs("Waiting",stdout);
  342.     if (*Para)
  343.     {
  344.       fputs(" for ",stdout);
  345.       fputs(Para,stdout);
  346.     }
  347.     puts("... press ESC to abort");
  348.   }
  349.  
  350.   /* Warteschleife... */
  351.   for(;;)
  352.   {
  353.     /*
  354.       printf("Jetzt: %d %d, warte auf %d %d\n",
  355.       Tgetdate(),Tgettime(),SollDat,SollUhr);
  356.     */
  357.  
  358.     if (Tag>=0)
  359.     {
  360.       if (Tgettime()==SollUhr && Tgetdate()==SollDat)
  361.         return 0;
  362.     }
  363.     else
  364.       if (Tgettime()==SollUhr)
  365.         return 0;
  366.   
  367.     /* ESC gedrückt? */
  368.     if (Cconis())
  369.       if ((Cnecin()&0xff) == 0x1b)
  370.         return EXITCODE;
  371.   }
  372. }
  373.  
  374. /* entspricht sscanf(*Ptr,"%02d",adr);(*Ptr)+=2 */
  375. scan(Ptr,adr)
  376. char **Ptr;
  377. int *adr;
  378. {
  379.   *adr = 10*((*(*Ptr)++)-'0');
  380.   *adr +=    (*(*Ptr)++)-'0';
  381. }
  382.