home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / program / 590 / source / msh.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-06  |  8.0 KB  |  382 lines

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