home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 074.lha / CShell / Sources / comm2.c < prev    next >
C/C++ Source or Header  |  1986-11-20  |  14KB  |  614 lines

  1. /*
  2.  * COMM2.C
  3.  *
  4.  * (c)1986 Matthew Dillon     9 October 1986
  5.  *
  6.  * Version 2.07M by Steve Drew 10-Sep-87
  7.  *
  8.  */
  9.  
  10. #include "shell.h"
  11. typedef struct FileInfoBlock FIB;
  12.  
  13. /* Casting conveniences */
  14. #define BPTR_TO_C(strtag, var)    ((struct strtag *)(BADDR( (ULONG) var)))
  15. #define PROC(task)        ((struct Process *)task)
  16. #define ROOTNODE        ((struct RootNode *)DOSBase->dl_Root)
  17. #define CLI(proc)        (BPTR_TO_C(CommandLineInterface, proc->pr_CLI))
  18.  
  19. /* Externs */
  20. extern int has_wild;            /* flag set if any arg has a ? or * */
  21. extern struct DosLibrary *DOSBase;    /* dos library base pointer         */
  22.  
  23. /* globals */
  24. int cp_update;
  25. int cp_date;
  26.  
  27. do_abortline()
  28. {
  29.    Exec_abortline = 1;
  30.    return (0);
  31. }
  32.  
  33. do_return()
  34. {
  35.    Exec_abortline = 1;
  36.    if (Src_stack) {
  37.        FILE *ptr = (FILE *)Src_base[Src_stack - 1];
  38.        ptr->_bp = ptr->_bend;
  39.        ptr->_flags |= _EOF;
  40. /*     fseek (Src_base[Src_stack - 1], 0L, 2); */
  41.       return ((ac < 2) ? 0 : atoi(av[1]));
  42.    } else {
  43.       main_exit ((ac < 2) ? 0 : atoi(av[1]));
  44.    }
  45. }
  46.  
  47. /*
  48.  * STRHEAD
  49.  *
  50.  * place a string into a variable removing everything after and including
  51.  * the 'break' character or until a space is found in the string.
  52.  *
  53.  * strhead varname breakchar string
  54.  *
  55.  */
  56.  
  57. do_strhead()
  58. {
  59.    register char *str = av[3];
  60.    char bc = *av[2];
  61.  
  62.    while (*str && *str != bc)
  63.       ++str;
  64.    *str = '\0';
  65.    set_var (LEVEL_SET, av[1], av[3]);
  66.    return (0);
  67. }
  68.  
  69. do_strtail()
  70. {
  71.    register char *str = av[3];
  72.    char bc = *av[2];
  73.  
  74.    while (*str && *str != bc)
  75.       ++str;
  76.    if (*str)
  77.       ++str;
  78.    set_var (LEVEL_SET, av[1], str);
  79.    return (0);
  80. }
  81.  
  82.  
  83.  
  84. /*
  85.  * if -f file (exists) or:
  86.  *
  87.  * if A < B   <, >, =, <=, >=, !=, where A and B are either:
  88.  * nothing
  89.  * a string
  90.  * a value (begins w/ number)
  91.  */
  92.  
  93. do_if(garbage, com)
  94. char *garbage;
  95. {
  96.    char *v1, *v2, *v3, result, num;
  97.    int n1, n2;
  98.    struct FileLock *lock;
  99.  
  100.    switch (com) {
  101.    case 0:
  102.       if (If_stack && If_base[If_stack - 1]) {
  103.      If_base[If_stack++] = 1;
  104.      break;
  105.       }
  106.       result = num = 0;
  107.  
  108.       if (!strcmp(av[1],"-f")) {
  109.            if (ac == 3 && (lock=(struct FileLock *)Lock(av[2], ACCESS_READ))) {
  110.                UnLock(lock);
  111.                result = 1;
  112.            }
  113.        goto do_result;
  114.       }
  115.       if (ac <= 2) {       /* if $var; */
  116.      if (ac == 1 || strlen(av[1]) == 0 || (strlen(av[1]) == 1 && *av[1] == ' '))
  117.         goto do_result;
  118.      result = 1;
  119.      goto do_result;
  120.       }
  121.       if (ac != 4) {
  122.      ierror(NULL, 500);
  123.      break;
  124.       }
  125.       v1 = av[1]; v2 = av[2]; v3 = av[3];
  126.       while (*v1 == ' ')
  127.      ++v1;
  128.       while (*v2 == ' ')
  129.      ++v2;
  130.       while (*v3 == ' ')
  131.      ++v3;
  132.       if (*v1 >= '0' && *v1 <= '9') {
  133.      num = 1;
  134.      n1 = atoi(v1);
  135.      n2 = atoi(v3);
  136.       }
  137.       while (*v2) {
  138.      switch (*v2++) {
  139.      case '>':
  140.         result |= (num) ? (n1 >  n2) : (strcmp(v1, v3) > 0);
  141.         break;
  142.      case '<':
  143.         result |= (num) ? (n1 <  n2) : (strcmp(v1, v3) < 0);
  144.         break;
  145.      case '=':
  146.         result |= (num) ? (n1 == n2) : (strcmp(v1, v3) ==0);
  147.         break;
  148.      default:
  149.         ierror (NULL, 503);
  150.         break;
  151.      }
  152.       }
  153. do_result:
  154.       If_base[If_stack++] = !result;
  155.       break;
  156.    case 1:
  157.       if (If_stack > 1 && If_base[If_stack - 2])
  158.      break;
  159.       if (If_stack)
  160.      If_base[If_stack - 1] ^= 1;
  161.       break;
  162.    case 2:
  163.       if (If_stack)
  164.      --If_stack;
  165.       break;
  166.    }
  167.    disable = (If_stack) ? If_base[If_stack - 1] : 0;
  168.    if (If_stack >= MAXIF) {
  169.       fprintf(stderr,"If's too deep\n");
  170.       disable = If_stack = 0;
  171.       return(-1);
  172.       }
  173.    if (forward_goto) disable = If_base[If_stack - 1] = 0;
  174.    return (0);
  175. }
  176.  
  177. do_label()
  178. {
  179.    char aseek[32];
  180.  
  181.    if (Src_stack == 0) {
  182.       ierror (NULL, 502);
  183.       return (-1);
  184.    }
  185.    
  186.    sprintf (aseek, "%ld %d", Src_pos[Src_stack-1], If_stack);
  187.    set_var (LEVEL_LABEL + Src_stack - 1, av[1], aseek);
  188.    if (!strcmp(av[1],get_var(LEVEL_SET,V_GOTOFWD)))
  189.       forward_goto = 0;
  190.    return (0);
  191. }
  192.  
  193. do_goto()
  194. {
  195.    int new;
  196.    long pos;
  197.    char *lab;
  198.  
  199.    if (Src_stack == 0) {
  200.       ierror (NULL, 502);
  201.    } else {
  202.       lab = get_var (LEVEL_LABEL + Src_stack - 1, av[1]);
  203.       if (lab == NULL) {
  204.      forward_goto = 1;
  205.      set_var (LEVEL_SET, V_GOTOFWD, av[1]);
  206.      return(0);
  207.       } else {
  208.      pos = atoi(lab);
  209.      fseek (Src_base[Src_stack - 1], pos, 0);
  210.      Src_pos[Src_stack - 1] = pos;
  211.      new = atoi(next_word(lab));
  212.      for (; If_stack < new; ++If_stack)
  213.         If_base[If_stack] = 0;
  214.      If_stack = new;
  215.       }
  216.    }
  217.    Exec_abortline = 1;
  218.    return (0);        /* Don't execute rest of this line */
  219. }
  220.  
  221.  
  222. do_inc(garbage, com)
  223. char *garbage;
  224. {
  225.    char *var;
  226.    char num[32];
  227.  
  228.    if (ac == 3)
  229.       com = atoi(av[2]);
  230.    var = get_var (LEVEL_SET, av[1]);
  231.    if (var) {
  232.       sprintf (num, "%d", atoi(var)+com);
  233.       set_var (LEVEL_SET, av[1], num);
  234.    }
  235.    return (0);
  236. }
  237.  
  238. do_input()
  239. {
  240.    char in[256], *p,*s;
  241.    int i;
  242.    
  243.    for (i=1; i < ac; ++i) {
  244.       if ((gets(in)) != 0) {
  245.      for(p = in; *p; p = s) {
  246.         s = next_word(p);
  247.         if (*s) *(s-1) = 0xA0;
  248.      }
  249.          set_var (LEVEL_SET, av[i], in);
  250.       }
  251.    }
  252.    return (0);
  253. }
  254.  
  255. do_ver()
  256. {
  257.    puts (VERSION);
  258.    return (0);
  259. }
  260.  
  261.  
  262. do_ps()
  263. {
  264.     /* this code fragment based on ps.c command by Dewi Williams */
  265.  
  266.     register ULONG     *tt;        /* References TaskArray        */
  267.     register int     count;        /* loop variable        */
  268.     register UBYTE     *port;        /* msgport & ptr arith        */
  269.     register struct Task *task;    /* EXEC descriptor        */
  270.     char         strbuf[64];    /* scratch for btocstr()    */
  271.     char         cmd[40];    /* holds cmd name        */
  272.     char         *btocstr();    /* BCPL BSTR to ASCIIZ        */
  273.  
  274.     tt = (unsigned long *)(BADDR(ROOTNODE->rn_TaskArray));
  275.  
  276.     printf("Proc Command Name      CLI Type    Pri.  Address  Directory\n");
  277.     Forbid();        /* need linked list consistency */
  278.  
  279.     for (count = 1; count <= (int)tt[0] ; count++) {/* or just assume 20?*/
  280.         if (tt[count] == 0) continue;        /* nobody home */
  281.  
  282.         /* Start by pulling out MsgPort addresses from the TaskArray
  283.          * area. By making unwarranted assumptions about the layout
  284.          * of Process and Task structures, we can derive these
  285.          * descriptors. Every task has an associated process, since
  286.          * this loop drives off a CLI data area.
  287.          */
  288.  
  289.         port = (UBYTE *)tt[count];
  290.         task = (struct Task *)(port - sizeof(struct Task));
  291.  
  292.         /* Sanity check just in case */
  293.         if (PROC(task)->pr_TaskNum == 0 || PROC(task)->pr_CLI == 0)
  294.             continue;        /* or complain? */
  295.  
  296.             
  297.             printf("%2d   %-20.20s %-11.11s %3d  %8lx  %s\n",
  298.                count,btocstr(CLI(PROC(task))->cli_CommandName, cmd),
  299.                task->tc_Node.ln_Name,
  300.                task->tc_Node.ln_Pri,task,
  301.                btocstr(CLI(PROC(task))->cli_SetName, strbuf)); 
  302.  
  303.     }
  304.     Permit();        /* outside critical region */
  305.     return(0);
  306. }
  307.  
  308.  
  309. char *
  310. btocstr(b, buf)
  311. ULONG    b;
  312. char    *buf;
  313. {
  314.     register char    *s;
  315.  
  316.     s = (char *)BADDR(b);    /* Shift & get length-prefixed str */
  317.     movmem(s +1, buf, s[0]);
  318.     buf[s[0]] = '\0';
  319.     return buf;
  320. }
  321.  
  322.  
  323. /*
  324.  * CP [-d] [-u] file file
  325.  * CP [-d] [-u] file file file... destdir
  326.  * CP [-r][-u][-d] dir dir dir... destdir
  327.  */
  328.  
  329. char *errstr;           /* let's be alittle more informative */
  330. do_copy()
  331. {
  332.    register int recur, ierr;
  333.    register char *destname;
  334.    register char destisdir;
  335.    register FIB *fib;
  336.    int i,opt;
  337.  
  338.    errstr = "";
  339.    ierr = 0;
  340.  
  341.    fib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
  342.  
  343.    opt = get_opt("rud",&i);
  344.    recur     = (opt & 0x01);
  345.    cp_update = (opt & 0x02);
  346.    cp_date   = (!(opt & 0x04)); /* the default is keep orignal file date */
  347.  
  348.    destname = av[ac - 1];
  349.  
  350.    if (ac < i + 2) {
  351.       ierr = 500;
  352.       goto done;
  353.    }
  354.  
  355.    destisdir = isdir(destname);
  356.    if (ac > i + 2 && !destisdir) {
  357.       ierr = 507;
  358.       goto done;
  359.    }
  360.  
  361.    /*
  362.     * copy set:                   reduce to:
  363.     *     file to file              file to file
  364.     *     dir  to file (NOT ALLOWED)
  365.     *     file to dir              dir to dir
  366.     *     dir  to dir              dir to dir
  367.     *
  368.     */
  369.  
  370.    for (; i < ac - 1; ++i) {
  371.       short srcisdir = isdir(av[i]);
  372.       if (srcisdir && has_wild && (ac >2)) /* hack to stop dir's from */
  373.       continue;               /* getting copied if specified */
  374.                        /* from wild expansion */
  375.       if (CHECKBREAK())
  376.      break;
  377.       if (srcisdir) {
  378.      struct FileLock *srcdir, *destdir;
  379.      if (!destisdir) {
  380.         if (destdir = (struct FileLock *)Lock(destname, ACCESS_READ)) {
  381.            UnLock(destdir);
  382.            ierr = 507;          /* disallow dir to file */
  383.            goto done;
  384.         }
  385.         if (destdir = (struct FileLock *)CreateDir(destname))
  386.            UnLock(destdir);
  387.         destisdir = 1;
  388.      }
  389.      if (!(destdir = (struct FileLock *)Lock(destname, ACCESS_READ))) {
  390.         ierr = 205;
  391.         errstr = destname;
  392.         goto done;
  393.      }
  394.      if (!(srcdir = (struct FileLock *)Lock(av[i], ACCESS_READ))) {
  395.         ierr = 205;
  396.         errstr = av[i];
  397.         UnLock(destdir);
  398.         goto done;
  399.      }
  400.      ierr = copydir(srcdir, destdir, recur);
  401.      UnLock(srcdir);
  402.      UnLock(destdir);
  403.      if (ierr)
  404.         break;
  405.       } else {                /* FILE to DIR,   FILE to FILE   */
  406.      struct FileLock *destdir, *srcdir, *tmp;
  407.      char *destfilename;
  408.  
  409.      srcdir = (struct FileLock *)(Myprocess->pr_CurrentDir);
  410.  
  411.      if ((tmp = (struct FileLock *)Lock(av[i], ACCESS_READ)) == NULL || !Examine(tmp,fib)){
  412.         if (tmp) UnLock(tmp);
  413.         ierr = 205;
  414.         errstr = av[i];
  415.         goto done;
  416.      }
  417.      UnLock(tmp);
  418.      if (destisdir) {
  419.         destdir = (struct FileLock *)Lock(destname, ACCESS_READ);
  420.         destfilename = fib->fib_FileName;
  421.      } else {
  422.         destdir = srcdir;
  423.         destfilename = destname;
  424.      }
  425.      printf(" %s..",av[i]);
  426.      fflush(stdout);
  427.      ierr = copyfile(av[i], srcdir, destfilename, destdir);
  428.      if (destisdir)
  429.         UnLock(destdir);
  430.      if (ierr)
  431.         break;
  432.       }
  433.    }
  434. done:
  435.    FreeMem(fib, (long)sizeof(*fib));
  436.    if (ierr) {
  437.       ierror(errstr, ierr);
  438.       return(20);
  439.    }
  440.    return(0);
  441. }
  442.  
  443.  
  444. copydir(srcdir, destdir, recur)
  445. register struct FileLock *srcdir, *destdir;
  446. {
  447.    struct FileLock *cwd;
  448.    register FIB *srcfib;
  449.    register struct FileLock *destlock, *srclock;
  450.    int ierr;
  451.    static int level;
  452.  
  453.    level++;
  454.    ierr = 0;
  455.    srcfib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
  456.    if (Examine(srcdir, srcfib)) {
  457.       while (ExNext(srcdir, srcfib)) {
  458.      if (CHECKBREAK())
  459.         break;
  460.      if (srcfib->fib_DirEntryType < 0) {
  461.         printf("%*s%s..",(level-1) * 6," ",srcfib->fib_FileName);
  462.         fflush(stdout);
  463.         ierr = copyfile(srcfib->fib_FileName,srcdir,srcfib->fib_FileName,destdir);
  464.         if (ierr)
  465.            break;
  466.      } else {
  467.         if (recur) {
  468.            cwd = (struct FileLock *)CurrentDir(srcdir);
  469.            if (srclock = (struct FileLock *)Lock(srcfib->fib_FileName, ACCESS_READ)) {
  470.           CurrentDir(destdir);
  471.           if (!(destlock = (struct FileLock *)
  472.                 Lock(srcfib->fib_FileName))) {
  473.              destlock = (struct FileLock *)CreateDir(srcfib->fib_FileName);
  474.              printf("%*s%s (Dir)....[Created]\n",(level-1) * 6,
  475.                 " ",srcfib->fib_FileName);
  476.  
  477.             /* UnLock and re Lock if newly created
  478.                for file_date() to work properly
  479.             */   
  480.              if (destlock) UnLock(destlock);
  481.              destlock = (struct FileLock *)Lock(srcfib->fib_FileName);             
  482.           }
  483.           else
  484.              printf("%*s%s (Dir)\n",(level-1) * 6," ",srcfib->fib_FileName);
  485.           if (destlock) {
  486.              ierr = copydir(srclock, destlock, recur);
  487.              UnLock(destlock);
  488.           } else {
  489.              ierr = (int)((long)IoErr());
  490.           }
  491.           UnLock(srclock);
  492.            } else {
  493.           ierr = (int)((long)IoErr());
  494.            }
  495.            CurrentDir(cwd);
  496.            if (ierr)
  497.           break;
  498.         }
  499.      }
  500.       }
  501.    } else {
  502.       ierr = (int)((long)IoErr());
  503.    }
  504.    --level;
  505.    FreeMem(srcfib, (long)sizeof(FIB));
  506.    return(ierr);
  507. }
  508.  
  509.  
  510. copyfile(srcname, srcdir, destname, destdir)
  511. char *srcname, *destname;
  512. struct FileLock *srcdir, *destdir;
  513. {
  514.    struct FileLock *cwd;
  515.    struct FileHandle *f1, *f2;
  516.    struct DateStamp *ds;
  517.    long i;
  518.    int stat,ierr;
  519.    char *buf;
  520.    struct DPTR *dp, *dps = NULL;
  521.  
  522.    buf = (char *)AllocMem(8192L, MEMF_PUBLIC|MEMF_CLEAR);
  523.    if (buf == NULL) {
  524.       ierr = 103;
  525.       goto fail;
  526.    }
  527.  
  528.    ierr = 0;
  529.    cwd = (struct FileLock *)CurrentDir(srcdir);
  530.    f1 = Open(srcname, MODE_OLDFILE);
  531.    if (f1 == NULL) {
  532.       errstr = srcname;
  533.       ierr = 205;
  534.       goto fail;
  535.    }
  536.    dps = dopen(srcname,&stat);
  537.    ds = &dps->fib->fib_Date;
  538.    CurrentDir(destdir);
  539.    if (cp_update  && (dp = dopen (destname, &stat))) {
  540.     long desttime,srctime;
  541.     struct DateStamp *dd;
  542.  
  543.     dd = &dp->fib->fib_Date;
  544.     desttime = dd->ds_Days * 86400 + dd->ds_Minute * 60 +
  545.                        dd->ds_Tick/TICKS_PER_SECOND;
  546.     srctime     = ds->ds_Days * 86400 + ds->ds_Minute * 60 +
  547.                        ds->ds_Tick/TICKS_PER_SECOND;
  548.  
  549.     if (srctime <= desttime &&
  550.       !strcmp(dps->fib->fib_FileName,dp->fib->fib_FileName)) {
  551.         dclose(dp);
  552.         Close(f1);
  553.         printf("..not newer\n");
  554.         goto fail;
  555.     }
  556.     dclose(dp);
  557.    }
  558.    f2 = Open(destname, MODE_NEWFILE);
  559.    if (f2 == NULL) {
  560.       Close(f1);
  561.       ierr = (int)((long)IoErr());
  562.       errstr = destname;
  563.       goto fail;
  564.    }
  565.    while (i = Read(f1, buf, 8192L))
  566.       if (Write(f2, buf, i) != i) {
  567.      ierr = (int)((long)IoErr());
  568.      break;
  569.       }
  570.    Close(f2);
  571.    Close(f1);
  572.    if (!ierr)  {
  573.       if (cp_date) file_date(ds,destname);
  574.       printf("..copied\n");
  575.    }
  576.    else {
  577.       DeleteFile(destname);
  578.    }
  579. fail:
  580.    dclose(dps);
  581.    if (buf)
  582.       FreeMem(buf, 8192L);
  583.    CurrentDir(cwd);
  584.    return(ierr);
  585. }
  586.  
  587.  
  588. file_date(date,name)
  589. struct DateStamp *date;
  590. char *name;
  591. {
  592.     UBYTE *ptr;
  593.     struct MsgPort *task;
  594.     struct FileLock *dirlock;
  595.     struct DPTR *tmp; 
  596.     int stat;
  597.     long ret, dos_packet();
  598.  
  599.     if (!(task = (struct MsgPort *)DeviceProc(name)))
  600.     return(1);
  601.     if (tmp = dopen(name, &stat)) {
  602.     dirlock = (struct FileLock *)ParentDir(tmp->lock);
  603.     ptr = (UBYTE *)AllocMem(64L,MEMF_PUBLIC);
  604.     strcpy((ptr + 1),tmp->fib->fib_FileName);
  605.     *ptr = strlen(tmp->fib->fib_FileName);
  606.     dclose(tmp);
  607.     ret = dos_packet(task,34L,NULL,dirlock,
  608.                  (ULONG)&ptr[0] >> 2L,date);
  609.     FreeMem(ptr,64L);
  610.     UnLock(dirlock);
  611.     }
  612. }
  613.  
  614.