home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 3 / CDPDIII.bin / pd / utilities / dirutils / visualshell / src / main_vsh.c < prev    next >
C/C++ Source or Header  |  1992-10-28  |  9KB  |  324 lines

  1.             /*********************************
  2.          *                               *
  3.          *   Visual Shell v1.17  10/92   *
  4.          *                               *
  5.          *     by Torsten Jürgeleit      *
  6.          *                               *
  7.          *         vsh main part         *
  8.          *                               *
  9.          *********************************/
  10.  
  11.     /* Includes */
  12.  
  13. #include "includes.h"
  14.  
  15.     /* Defines */
  16.  
  17. #define MAX_ARGUMENTS        4
  18.  
  19. #define ARGUMENT_LEFT        0
  20. #define ARGUMENT_RIGHT        1
  21. #define ARGUMENT_HIDE        2
  22. #define ARGUMENT_REMOVE        3
  23.  
  24. #define    CTOB(cptr)        ((BPTR)((ULONG)cptr >> 2))   /* Convert C ptr to BCPL ptr */
  25. #define    BTOC(bptr)        ((VOID *)((ULONG)bptr << 2))   /* Convert BCPL ptr to C ptr */
  26.  
  27. #define MIN_VSH_WIDTH        (USHORT)640   /* NTSC resolution */
  28. #define MIN_VSH_HEIGHT        (USHORT)200
  29.  
  30. #define VSH_PROCESS_NAME    "VSh v1.17 for CLI %ld"
  31. #define VSH_PROCESS_NAME_LEN    25
  32. #define VSH_PROCESS_STACK_SIZE    4096
  33. #define VSH_PROCESS_PRIORITY    0
  34.  
  35.     /* Structures */
  36.  
  37. struct StartupMsg {
  38.     struct Message  sm_Message;
  39.     struct Process  *sm_CLIProcess;
  40.     struct Window   *sm_ConWindow;
  41.     struct Device   *sm_ConDevice;
  42.     struct ConUnit  *sm_ConUnit;
  43.     BYTE    *sm_LeftPath;    /* path for left file requester */
  44.     BYTE    *sm_RightPath;    /* path for right file requester */
  45.     USHORT    sm_Flags;    /* used for HIDE flag */
  46. };
  47.     /* Globals */
  48.  
  49. struct ArpBase  *ArpBase;
  50.  
  51.     /* Statics */
  52.  
  53. STATIC struct ProcessControlBlock  seg_pcb;
  54. STATIC struct StartupMsg           seg_sm;
  55.  
  56. STATIC BYTE process_name[VSH_PROCESS_NAME_LEN + 1],
  57.         *vsh_segment = "l:VShSegment",
  58.         *template = "Left,Right,HIDE/S,REMOVE/S",
  59.         *xtra_help = "\nVSh v1.17 - Copyright © 1992 Torsten Jürgeleit\n\n"
  60.              "Usage: VSh [Left] [Right] [REMOVE] [HIDE]\n"
  61.              "\t[Left]   = path for left file requester\n"
  62.              "\t[Right]  = path for right file requester\n"      
  63.              "\t[HIDE]   = start VSh in hide mode\n"
  64.              "\t[REMOVE] = remove VSh segment from resident list\n";
  65.     /* Prototypes */
  66.  
  67. LONG _main(BYTE *arg_line, LONG arg_len);
  68. BYTE *check_path(BYTE *path);
  69. BOOL check_valid_start(struct Process  *proc, struct StartupMsg  *sm);
  70. struct Window  *get_con_window(struct Process  *proc, struct StartupMsg  *sm);
  71. LONG start_vsh_segment(struct Process  *proc, struct StartupMsg  *sm);
  72.  
  73.     /* Pragmas */
  74.  
  75. #pragma regcall(_main(a0,d0))
  76. #pragma regcall(check_path(a0))
  77. #pragma regcall(check_valid_start(a0,a1))
  78. #pragma regcall(get_con_window(a0,a1))
  79. #pragma regcall(start_vsh_segment(a0,a1))
  80.  
  81.     /* Main - parses arguments and starts main segment */
  82.  
  83.    LONG
  84. _main(BYTE *arg_line, LONG arg_len)
  85. {
  86.    LONG return_code = RETURN_FAIL;
  87.  
  88.    /* First open ARP library */
  89.    if (!(ArpBase = OpenLibrary(ArpName, ArpVersion))) {
  90.       Write(Output(), "Need arp.library v39+\n", 22L);
  91.    } else {
  92.       BYTE   *argv[MAX_ARGUMENTS];
  93.       USHORT i;
  94.  
  95.       /* Clear argument array */
  96.       for (i = 0; i < MAX_ARGUMENTS; i++) {
  97.      argv[i] = NULL;
  98.       }
  99.  
  100.       /* Parse command line arguments */
  101.       if (GADS(arg_line, arg_len, xtra_help, &argv[0], template) < 0) {
  102.      Puts(argv[0]);
  103.       } else {
  104.  
  105.      /* Check arguments */
  106.      if (argv[ARGUMENT_REMOVE]) {
  107.         LONG usage;
  108.  
  109.         /* Remove VSh segment from ARP resident list */
  110.         if (usage = RemResidentPrg(vsh_segment)) {
  111.            Printf("%s is [%ld] in use\n", vsh_segment, usage);
  112.         } else {
  113.            return_code = RETURN_OK;
  114.         }
  115.      } else {
  116.         struct StartupMsg  *sm = &seg_sm;
  117.         BOOL error = FALSE;
  118.  
  119.         if (argv[ARGUMENT_HIDE]) {
  120.  
  121.            /* Set HIDE flag */
  122.            sm->sm_Flags = 1;
  123.         }
  124.         if (argv[ARGUMENT_LEFT]) {
  125.  
  126.            /* Check given path for left file requester */
  127.            if (!(sm->sm_LeftPath = check_path(argv[ARGUMENT_LEFT]))) {
  128.           error = TRUE;
  129.            }
  130.         } else {
  131.            sm->sm_LeftPath = NULL;
  132.         }
  133.         if (argv[ARGUMENT_RIGHT]) {
  134.  
  135.            /* Check given path for right file requester */
  136.            if (!(sm->sm_RightPath = check_path(argv[ARGUMENT_RIGHT]))) {
  137.           error = TRUE;
  138.            }
  139.         } else {
  140.            sm->sm_RightPath = NULL;
  141.         }
  142.         if (error == FALSE) {
  143.            struct ResidentProgramNode  *rpn;
  144.            BPTR seg;
  145.  
  146.            /* Check if VSh segment is already in ARP resident list */
  147.            if (rpn = ObtainResidentPrg(vsh_segment)) {
  148.           ReleaseResidentPrg(rpn->rpn_Segment);
  149.            } else {
  150.  
  151.           /* Add VSh segment to ARP resident list */
  152.           if (!(seg = LoadPrg(vsh_segment + 2)) &&
  153.                         !(seg = LoadPrg(vsh_segment))) {
  154.              Printf("Can't load '%s'\n", vsh_segment);
  155.           } else {
  156.              if (!(rpn = AddResidentPrg(seg, vsh_segment))) {
  157.             Printf("Can't add '%s' to ARP resident list\n",
  158.                                    vsh_segment);
  159.             UnLoadPrg(seg);
  160.              }
  161.           }
  162.            }
  163.  
  164.            /* If VSh segment found then start it */
  165.            if (rpn) {
  166.           struct Process  *proc = (struct Process *)FindTask(NULL);
  167.  
  168.           if (check_valid_start(proc, sm) == TRUE) {
  169.              return_code = start_vsh_segment(proc, sm);
  170.           }
  171.            }
  172.         }
  173.      }
  174.       }
  175.       CloseLibrary(ArpBase);
  176.    }
  177.    return(return_code);
  178. }
  179.     /* Check path for file requester */
  180.  
  181.    STATIC BYTE *
  182. check_path(BYTE *path)
  183. {
  184.    struct FileInfoBlock  *fib;
  185.    BPTR lock;
  186.    BYTE *error_msg = NULL;
  187.  
  188.    if (!(lock = Lock(path, (LONG)SHARED_LOCK))) {
  189.       error_msg = "Can't lock path '%s'\n";
  190.    } else {
  191.       if (!(fib = AllocMem((LONG)sizeof(struct FileInfoBlock), (LONG)
  192.                                 MEMF_PUBLIC))) {
  193.      error_msg = "Out of memory\n";
  194.       } else {
  195.      if (Examine(lock, fib) == DOSFALSE) {
  196.         error_msg = "Examine() failed\n";
  197.      } else {
  198.         if (fib->fib_DirEntryType < 0) {
  199.            error_msg = "'%s' isn't a directory\n";
  200.         }
  201.      }
  202.      FreeMem(fib, (LONG)sizeof(struct FileInfoBlock));
  203.       }
  204.       UnLock(lock);
  205.    }
  206.    if (error_msg) {
  207.       Printf(error_msg, path);
  208.       path = NULL;
  209.    }
  210.    return(path);
  211. }
  212.     /* Check for a valid start of VSh */
  213.  
  214.    STATIC BOOL
  215. check_valid_start(struct Process  *proc, struct StartupMsg  *sm)
  216. {
  217.    struct CommandLineInterface  *con_cli;
  218.    struct Window                *con_win;
  219.    BYTE *error_msg = NULL;
  220.    BOOL success = FALSE;
  221.  
  222.    /* VSh startet from CLI ? */
  223.    if (con_cli = BTOC(proc->pr_CLI)) {
  224.  
  225.       /* VSh started with RUN ? */
  226.       if (con_cli->cli_Background == DOSTRUE) {
  227.      error_msg = "Don't start VSh with RUN !";
  228.       } else {
  229.      struct FileHandle  *con_output_fh = BTOC(proc->pr_COS);
  230.  
  231.      /* VSh startet from ConMan console window ? */
  232.      if ((struct FileHandle *)con_output_fh->fh_Arg1 != con_output_fh) {
  233.         error_msg = "Need a ConMan console window !";
  234.      } else {
  235.         if (!(con_win = get_con_window(proc, sm))) {
  236.            error_msg = "Can't find console window !";
  237.         } else {
  238.  
  239.            /* Check window dimension */
  240.            if (con_win->WScreen->Width < MIN_VSH_WIDTH) {
  241.           error_msg = "Workbench screen to small (min. 640) !";
  242.            } else {
  243.           struct TextFont  *con_tf = con_win->RPort->Font;
  244.  
  245.           /* Check text font used by this CLI */
  246.           if (con_tf->tf_XSize != 8 || con_tf->tf_YSize != 8 ||
  247.                     (con_tf->tf_Flags & FPF_PROPORTIONAL)) {
  248.              error_msg = "Only 8x8 nonproportional fonts allowed !";
  249.           } else {
  250.  
  251.              /* Check if VSh already started for this CLI */
  252.              SPrintf(&process_name[0], VSH_PROCESS_NAME,
  253.                               proc->pr_TaskNum);
  254.              if (FindPort(&process_name[0])) {
  255.             error_msg = "Can't start VSh for this CLI twice !";
  256.              } else {
  257.             success = TRUE;
  258.              }
  259.           }
  260.            }
  261.         }
  262.      }
  263.       }
  264.       if (error_msg) {
  265.      Puts(error_msg);
  266.       }
  267.    }
  268.    return(success);
  269. }
  270.     /* Get pointer to the console window our process started from */
  271.  
  272.    STATIC struct Window *
  273. get_con_window(struct Process  *proc, struct StartupMsg  *sm)
  274. {
  275.    struct Window    *win = NULL;
  276.    struct IOStdReq  *req;
  277.    struct InfoData  *id;
  278.  
  279.    if (((struct Task *)proc)->tc_Node.ln_Type == NT_PROCESS) {
  280.       if (id = AllocMem((LONG)sizeof(struct InfoData), (LONG)MEMF_PUBLIC)) {
  281.      if (dos_packet((struct MsgPort *)proc->pr_ConsoleTask, (LONG)
  282.                    ACTION_DISK_INFO, CTOB(id)) == DOSTRUE) {
  283.         win              = (struct Window *)id->id_VolumeNode;
  284.         req              = (struct IOStdReq *)id->id_InUse;
  285.         sm->sm_ConWindow = win;
  286.         sm->sm_ConDevice = req->io_Device;
  287.         sm->sm_ConUnit   = (struct ConUnit *)req->io_Unit;
  288.      }
  289.      FreeMem(id, (LONG)sizeof(struct InfoData));
  290.       }
  291.    }
  292.    return(win);
  293. }
  294.     /* Start VSh segment */
  295.  
  296.    STATIC LONG
  297. start_vsh_segment(struct Process  *proc, struct StartupMsg  *sm)
  298. {
  299.    struct ProcessControlBlock  *pcb = &seg_pcb;
  300.    LONG return_code = RETURN_FAIL;
  301.  
  302.    /* Init process control block and start VSh segment */
  303.    pcb->pcb_StackSize = VSH_PROCESS_STACK_SIZE;
  304.    pcb->pcb_Pri       = VSH_PROCESS_PRIORITY;
  305.    pcb->pcb_Control   = PRF_NOCLI;
  306.    if (ASyncRun(vsh_segment, NULL, pcb) < 0) {
  307.       Printf("Can't run '%s'\n", vsh_segment);
  308.    } else {
  309.       struct MsgPort  *mp = &proc->pr_MsgPort;
  310.  
  311.       /* Init startup msg and send it to VSh segment */
  312.       sm->sm_Message.mn_ReplyPort = mp;
  313.       sm->sm_Message.mn_Length    = sizeof(struct StartupMsg);
  314.       sm->sm_CLIProcess           = proc;
  315.       PutMsg(pcb->pcb_WBProcess, &sm->sm_Message);
  316.  
  317.       /* Wait for reply of startup msg */
  318.       WaitPort(mp);
  319.       GetMsg(mp);
  320.       return_code = RETURN_OK;
  321.    }
  322.    return(return_code);
  323. }
  324.