home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / pocketbk / comms / x_sun_psio / code / psmain.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-21  |  58.5 KB  |  2,219 lines

  1. /* (C) Tim Graves 20th April 1994
  2.    This code is supplied AS IS. no warrantee either expressed or implied 
  3.    is provided. This code may be freeley modified and modified as long as my
  4.    origional authorship is acknowledged. 
  5.    
  6.    Tim Graves
  7.     Sun Microsystems
  8.      
  9.      */
  10. /* a set of routines for transfering data between the Psion and the Sun machines
  11.    where possible I have provided a sensible wrapper for the low level function
  12.    This program should be started BEFORE the suncom program on the psion */
  13. #include <stdio.h>
  14. #include "psion.h"
  15. #include "psmain.h"
  16. #include "psfilt.h"
  17. #define MAXSEND 200
  18. /*#define DEBUG 1*/
  19. /*#define PDEBUG 1*/
  20.  
  21. static char * vsn = "@(#) psmain.c 3.24@(#)" ;
  22. int pscs() ;
  23. int sunsum() ;
  24.  
  25. int cmlist(), cmspeed(), cmmkdir(), cmtmode(), cmget(), cmput(), cmsetp(), cmdiscon() ;
  26. #ifdef PDEBUG
  27. int cmdebug() ;
  28. #endif
  29. int cmtrans(), cmtransreset(), cmfilechksum() ;
  30. int cmhelp(), cmecho(), cmignore(), cmsystem(), cmrun() ;
  31. int cmgetenv(), cmdumpv(), cmsetv(), cmunsetv(), cmifusetv();
  32. int cmrm(), cmcs() ;
  33. int cmforeach(), cmfilter(),cmfilterprint() ;
  34. int cmexclude(), cmexclprint(), cmrlist(), cmbackup(), cminfo(), cmsetwriteflag() ;
  35. int cmlcd(), cmrcd(), cmlpwd(), cmrpwd(), cmftransinfo(), cmftransreset();
  36. int cmproclist(), cmprocprot(), cmprockill(), cmprocshut() ;
  37. char * findvar() ;
  38. int running ;
  39. int level ;
  40. int linecmd ;
  41. int dovsnchk ;
  42. int debugargs = FALSE ;
  43. int debugrun = FALSE ;
  44. int runtype, finish ;
  45. int debugcall = FALSE ;
  46. int logfile = FALSE ;
  47. char * lfname ;
  48.  
  49. extern int debuglink ;
  50. extern int debugpath ;
  51. extern int debugbackup ;
  52. extern int filechksum ;
  53. extern char psfname[] ;
  54. /* the following count good and bad blocks transmitted / recieved in pslib */
  55. extern int transgood, transbad, recgood, recbad ;
  56. /* the following count the file block level good / bad blocks counted in pslib */
  57. extern int ftransgood, ftransbad, frecgood, frecbad ;
  58.  
  59. /* command parsing structures, the command name (primary key), the number
  60.    of arguments (secondary key) and the function to call which will be
  61.    passed two parameters, an int (argc) and the value array (char * argv[]), then the usage text followed by the help text */
  62. struct cmdstruct cmds[] = {
  63.     {"get", 2, 1, cmget, "path [sun filename]",
  64.        "gets a file from the psion to the sun, optionaly using a different filename\n filename only can contain wildcards in which case multiple files are got,\nno sun filename is applicable in this case"},
  65.     {"put", 2, 1, cmput, "path [sun filename]",
  66.        "Puts a file to the psion from the sun, optionaly using a different filename"},
  67.     {"lcd", 1, 1, cmlcd, "path",
  68.        "Changes the current working directory on the sun to <path>. Is behaves\nin roughly the same manner as cd in the shells"},
  69.     {"rcd", 1, 1, cmrcd, "path",
  70.        "Changes the current working directory on the psion (Initialy set to M:)\nto <path> similar to the cd command in ftp"},
  71.     {"lpwd", 0, 0, cmlpwd,"",
  72.        "Prints the current working directory on the Sun ala shell pwd commands"},
  73.     {"rpwd", 0, 0, cmrpwd, "",
  74.        "Printe the current working directory on the psion"},
  75.     {"sum", 2, 1, cmcs, "path [sun|psion]",
  76.        "Computes a checksum on the path given either on the sun or the psion (default)\n"} ,
  77.     {"filesum", 1, 0, cmfilechksum, "[on|off]",
  78.        "Turns on checksums at the binary transfer level, adds saftey at\nthe cost of speed\nIf no argunents prints the current status"} ,
  79.     {"foreach", MAXARGS-3, 2, cmforeach, "list_filename cmd [args]", 
  80.        "Opens the list_filename which contains a list of psion file names IN PSION\nPATHS FORMAT and executes cmd with its args followed by the filenames"},
  81.     {"list", 2, 1, cmlist, "path [sun filename]",
  82.        "Lists a path on the psion optionaly storing the information in a file"},
  83.     {"rlist", 2, 1, cmrlist, "path [sun filename]",
  84.        "Produces a listing of path and all files below it, optionaly storing the information in sun filename"},
  85.     {"info", 1 ,1, cminfo, "path",
  86.        "Provides info on the file size, its access modes and its type"},
  87.     {"setro", 1, 1, cmsetwriteflag, "path",
  88.        "Sets the path to be read only"},
  89.     {"setrw", 1, 1, cmsetwriteflag, "path",
  90.        "Sets the path to be read write"},
  91.     {"mkdir", 1, 1, cmmkdir, "path",
  92.         "Creates a directory on the psion"} ,
  93.     {"rm", 1, 1, cmrm, "path",
  94.         "Removes the path from the psion"},
  95.     {"fast", 0, 0, cmspeed, "",
  96.         "Turns the data screen of on the psion, this will slightly speed things up"},
  97.     {"display", 0, 0, cmspeed, "",
  98.         "Turns the data screen on on the psion, this may slow things down"},
  99.     {"binary", 0, 0, cmtmode, "",
  100.         "Uses the binary transfer mode, this is non error checking and is the default"},
  101.     {"run", MAXARGS, 1, cmrun, "pscmd_filename [args]",
  102.         "Reads the command file pscmd and executes the instructions in it, a new level of\nvariables is created and variables manipulated in side this new level will not affect\nvariables from lower levels (Like to the shells). Any arguments to run will be saved in a\nsequence of variables arg0 (the command name) arg1 (first arg) arg2 (second arg) etc. Any \nexisting variables will be copied to the new level"},
  103.     {"source", 1, 1, cmrun, "pscmd_filename",
  104.         "Reads the command file and executes the instructions in it. No new variable level\nis created and any variable manipulation affects the existing level. No arg variables\n are created. It is expected that source will be used to load in configurations"},
  105.     {"which", 1, 1, cmrun, "pscmd_filename",
  106.         "Similar to the csh which command, locates the first occurence of\n pscmd_filename in the current path"},
  107.     {"!", MAXARGS, 0, cmsystem, "unix command string",
  108.         "Executes the unix command string via the system call, only variable interpretation is\nperformed before the command is executed"},
  109.     {"#", MAXARGS, 0, cmignore, "text",
  110.         "Ignores the remainder of the line, a comment indicator, intended to be used in \npscmd files"},
  111.     {"REM", MAXARGS, 0, cmignore, "text",
  112.         "Ignores the remainder of the line, a comment indicator, intended to be used in \npscmd files"},
  113.     {"Rem", MAXARGS, 0, cmignore, "text",
  114.         "Ignores the remainder of the line, a comment indicator, intended to be used in \npscmd files"} ,
  115.     {"echo", MAXARGS, 0, cmecho, "text",
  116.         "echoes the text back, intended to be used in pscmd files"},
  117.     {"setv", 2, 1, cmsetv, "varname [varvalue]",
  118.         "Associates varvalue with varname in the variables list, replacing any previous value\nif required. If varvalue is not present the null string is used"},
  119.     {"unsetv", 1, 1, cmunsetv, "varname",
  120.         "Removes the varname from the variables list"}, 
  121.     {"getenv", 3, 1, cmgetenv, "unixname psionvarname defaultvalue", 
  122.         "Gets the unix variable unixname from the unix environment and\noptionaly calls it a different name psionname if the variable does not\nexist use defaultvalue"},
  123.     {"printv", 0, 0, cmdumpv, "",
  124.         "Prints out the current variables list"},
  125.     {"ifusetv", 2, 2, cmifusetv, "varname value",
  126.         "If varname is already set do nothing, otherwise set varname to value"} ,
  127.     {"vars", 0, 1, cmdumpv, "Not a command, see help",
  128.        "Variables are set using setv and printv, to use a variable it must be a word\non its own enclosed in square brackets e.g. [varname], the word will be\nsubstituted for the text of the variable, e.g. echo [arg0] will print out\nthe commands name if envoked by run."},
  129.     {"specialvars1",0,0,cmdumpv,"Not a command, see help",
  130.         "Special Variables\npath\tA : seperated list of locations run will use to find its pscmd files\nrmcheck\tChecks with you that you realy want to delete the file (like rm -i)\nbackupnocheck\tStops the system asking you to exit all psion applications before\trunning the backup (usefull for scripts)\nautofilefilter\tCauses all file transfers to be checked to see if there is a conversion\n\tfilter to be run during the transfer\ndebugargs\tIf set the system will print debugging info for argument parsing\ndebuglink\tIf set the system will print debugging info for the data link\ndebugpath\tIf set the system will print out path handling debuging info"},
  131.     {"specialvars2", 0, 0, cmdumpv, "Not a command see help",
  132.          "debugrun\tIf set the system will print debugging info about run\ndebugcall (level) If set the system will printout (very verbose) subroutine call debuging info\ndebugbackup\tIf set the system will print backup debugging calls\nverbose\tIf set the system will display transfer statistics\ndolower\tIf set maps all psion paths for get and put to lower case\nchksumwarn\tIf set this computes checksums on the psion and sun files \nand produces a warning if these differ after a get / put\nchksumcorrect\tIf set this will attempt to correct on discovering a \nchecksum error between the sun / psion after a get / put"},
  133.     {"specialvars3", 0, 0, cmdumpv, "Not a command see help",
  134.         "backupnodo\tIf set the backup and restore systems do not actialy get / put files\nbut instead print out what would happen (usefull for backup)\nbackupask\tIf set asks before backingup each file, usefull for\ninteractive backupsrestoreask\tIf set asks before restoring each file (usefull for\ninteractive restores"},
  135.     {"help", 1, 0, cmhelp, "[cmdname]",
  136.         "Prints out the help message for cmdname or the list of available commands if there is\nno cmdname"},
  137.     {"usage", 1, 0, cmhelp, "[cmdname]",
  138.         "Prints out the usage text for cmdname or the list of available commands if there is\nno cmdname"}, 
  139.     {"addfilter",3, 3, cmfilter,"direction (in/out/restore) filesuffix, pscmd",
  140.         "Sets up a filter in the given directionto run pscmd on all files with\nsuffix suffix the pscmd file should exist before the filter is called\nrestore filters are called to restore the filt to its state before a put"},
  141.     {"delfilter",2, 2, cmfilter,"direction (in/out/restore) filesuffix, pscmd",
  142.         "Removes a filter with suffix and pscmd in direction"},
  143.     {"printfilters",0,0,cmfilterprint, "",
  144.         "Prints the list of current filters"},
  145.     {"addexcl", 1,1,cmexclude,"path",
  146.         "Adds path to the exclude list for backups\n"} ,
  147.     {"delexcl", 1,1,cmexclude,"path",
  148.         "Removes path from the backup exclude list\n"},
  149.     {"printexcl",0,0,cmexclprint, "",
  150.         "Prints the current list of files excluded from the backup\n"},
  151.     {"backup",2,2,cmbackup,"path backuppath",
  152.         "Recursivley copies from path on the psion to backup path\nomiting excluded files (see addexcl, delexcl, printexcl"},
  153.     {"ibackup",2,2,cmbackup, "path backuppath",
  154.         "Same as backup but this function only extracts modified files"},
  155.     {"restore",2,2,cmbackup,"path restorepath",
  156.         "Recursivley copies to path on the psion from restore path\nomiting excluded files (see addexcl, delexcl, printexcl"},
  157.     {"irestore",2,2,cmbackup, "path restorepath",
  158.         "Same as backup but this function only extracts modified files"},    
  159. #ifdef PDEBUG
  160.     {"pdebug" ,2,1, cmdebug, "on|off [psion_filename]",
  161.         "Starts / stops psion debugging to the [psion_filename].\nIf [psion_filename] is not given it uses M:\\debug.txt,\n[psion_filename] is truncated before the logging information is written each time"},
  162. #endif
  163.     {"transinfo", 0, 0, cmtrans, "",
  164.         "Prints information about the number of good and bad\nblocks transmited and recieved"},
  165.     {"transreset", 0, 0, cmtransreset, "",
  166.         "Resets the good and bad block counts for transmision and recieve"},
  167.     {"ftransinfo", 0, 0, cmftransinfo, "",
  168.         "Prints information about the number of good and bad\nblocks transmited and recieved for the file checksums"},
  169.     {"ftransreset", 0, 0, cmftransreset, "",
  170.         "Resets the good and bad block counts for transmision and recieve\n for the file checksums"},
  171.     {"proclist", 2, 0, cmproclist, "[process_pattern [filename]]",
  172.         "Lists processes found matching process_pattern on the psion.\nprocess_pattern defaults to * (all). If filename is given the output\nwill be written to filename. In this case process_pattern MUST\nbe specified"},
  173.     {"procprotect", 1, 0, cmprocprot, "[on|off]",
  174.         "Turns on / off process kill protection for system processes and suncom\non the psion, if no argument is enables protection. TURNONG PROTECTION OFF IS DEFINATLEY NOT ADVISED"},
  175.     {"prockill", 1, 1, cmprockill, "process_pattern",
  176.         "Kills processes matching process_pattern on the psion. unless process\nkill protection is turned off (procprotect off) system processes and\nsuncom will not be killed"},
  177.     {"shutdown", 1, 1, cmprocshut, "process_pattern",
  178.         "Sends a shutdown message to the processes matching process_pattern on the psion\nNot all processes can handle this (E.g. suncom and OPL processes) though\nall the builtin applications can"},
  179.     {"pause", 0, 0, cmdiscon, "",
  180.         "Exit the sun end of the comms link without effecting the psion\nNOTE you should only use this in shell scripts as the psion will detect\na period of inactivity and powerdown, currently the software cannot cope with this !"},
  181.     {"quit", 0, 0, cmdiscon, "",
  182.         "Instruct the psion end of the link to exit then exit the sun end"}
  183.         } ;
  184.  
  185. main (argc, argv, environ)
  186. int argc ;
  187. char * argv[] ;
  188. char * environ[] ;
  189. {
  190.  
  191.    int restart ;
  192.    int talk ;
  193.    char devname[100] ;
  194.  
  195.    if (debugcall >= 1)
  196.     fprintf(stderr, "CALL: Main\n") ;
  197.    /* init any argv dependent variables to their default state */
  198.    restart = FALSE ;
  199.    talk = FALSE ;
  200.    devname[0] ='\0' ;
  201.    dovsnchk = TRUE ;
  202.    finish = QUIT ;
  203.    runtype = FALSE ;
  204.    logfile = FALSE ;
  205.    /* init the variable handler code */
  206.    initvars() ;
  207.  
  208.  
  209.    /* handle any command line switches */
  210.    /* we must have at least one value in argv and it must start with
  211.       a - to have any command line switches NOTE due to this restriction
  212.       no psion command interpreter command may start with - though they
  213.       may also have flags as the routine below will break on the first
  214.       arg it finds that does not start with a - */
  215.  
  216.    /* remove the command name */
  217.    argv ++ ;
  218.    argc -- ;
  219.    while (argc > 0)
  220.    {
  221.    /* break out of the loop if required */
  222.     if(argv[0][0] != '-')
  223.         break ;
  224.     /* -var variable, value set up the variables */
  225.     if (strcmp (argv[0], "-var") == 0 )
  226.     {
  227.         /* use the next argument as the variable and the following
  228.            one as the value unless the next argument starts with a
  229.             - in which case just set the variable*/
  230.         if (argc < 2)
  231.         {
  232.             /* no variable name */
  233.             useage() ;
  234.         }
  235.         if (argc == 2)
  236.         {
  237.             /* variable name but no value and at end of the args */
  238.             cmsetv(2,argv) ;
  239.             argc -= 2;
  240.             argv += 2;
  241.             continue ;
  242.         }
  243.         if (argv[2][0] == '-')
  244.         {
  245.             cmsetv(2,argv) ;
  246.             argc -= 2 ;
  247.             argv += 2 ;
  248.             continue ;
  249.         }
  250.         else
  251.         {
  252.             cmsetv (3,argv) ;
  253.             argc -= 3 ;
  254.             argv -= 3;
  255.             continue ;
  256.         }        
  257.     }
  258.     /* -log [fname], log the comms sequence to [fname] if [fname] is 
  259.        not present use DEFAULTLOG */
  260.     if (strcmp(argv[0], "-log") == 0)
  261.     {
  262.         logfile = TRUE ;
  263.         if (argc == 1) /* no [fname] as we are at ther end of 
  264.                           the arg list */
  265.         {
  266.             lfname = DEFAULTLOG ;
  267.             argc -- ;
  268.             argv ++ ;
  269.         }
  270.         else 
  271.         if (argv[1][0] == '-') /* if no [fname] as next arg is a flag */
  272.         {
  273.             lfname = DEFAULTLOG ;
  274.             argc -- ;
  275.             argv ++ ;
  276.         }
  277.         else
  278.         {
  279.             lfname = argv[1] ;
  280.             argc -= 2 ;
  281.             argv += 2 ;
  282.         }
  283.         if (freopen (lfname, "w", stderr) == NULL)
  284.         {
  285.             printf("ERROR - opening log file %s\n") ;
  286.             exit (1) ;
  287.         }
  288.         printf("Logging to %s\n", lfname) ;
  289.         debugcall = 5 ;
  290.         continue ;
  291.     }
  292.        /* -r initiate the coms link with a running suncom program 
  293.           on the psion, we do this by calling psinit with a true falue,
  294.           if we want a cold start call psinit with a FALSE parameter */
  295.     if (strcmp(argv[0], "-r") == 0)
  296.     {
  297.         restart = TRUE ;
  298.         argc -- ;
  299.         argv ++ ;
  300.         continue ;
  301.     }
  302.     /* -t - give cmdline parameters dump */
  303.     if (strcmp(argv[0], "-t") == 0)
  304.     {
  305.         talk = TRUE ;
  306.         argc -- ;
  307.         argv ++ ;
  308.         continue ;
  309.     }
  310.     /* -q on exiting (has effect in batch only) quit (default) */
  311.     if (strcmp(argv[0], "-q") == 0)
  312.     {
  313.         finish = QUIT ;
  314.         argc -- ;
  315.         argv ++ ;
  316.         continue ;
  317.     }
  318.     /* -p on exiting (has effect in batch only) pause instead of quit */
  319.     if (strcmp(argv[0], "-p") == 0)
  320.     {
  321.         finish = PAUSE ;
  322.         argc -- ;
  323.         argv ++ ;
  324.         continue ;
  325.     }
  326.     /* -b batch mode, dont be verbose etc */
  327.     if (strcmp(argv[0], "-b") == 0)
  328.     {
  329.         runtype = BATCH ;
  330.         argc -- ;
  331.         argv ++ ;
  332.         continue ;
  333.     }
  334.     /* -i interactive mode, oposite of batch mode assumed if no command line commands given */
  335.     if (strcmp(argv[0], "-i") == 0)
  336.     {
  337.         runtype = INTERACTIVE ;
  338.         argc -- ;
  339.         argv ++ ;
  340.         continue ;
  341.     }
  342.     /* -d next arg contains the name of the serial device, default to /dev/ttya*/
  343.     if (strcmp(argv[0], "-d") == 0)
  344.     {
  345.         if (argc < 2)
  346.             useage() ;
  347.         strcpy(devname, argv[1]) ;
  348.         /* shift along the arguments */
  349.         argc -= 2 ;
  350.         argv += 2 ;
  351.         continue ;
  352.     }
  353.     if (strcmp(argv[0], "-nv") == 0)
  354.     {
  355.         dovsnchk = FALSE ;
  356.         argc -- ;
  357.         argv ++ ;
  358.         continue ;
  359.     }
  360.     if (strcmp(argv[0], "-v") == 0)
  361.     {
  362.         dovsnchk = TRUE ;
  363.         argc -- ;
  364.         argv ++ ;
  365.         continue ;
  366.     }
  367.    }
  368.  
  369.    /* if there are any args left (argc > 0) we are running batch else interactive, only work this out is we have not had a runtype previously set */
  370.    if (runtype == FALSE) ;
  371.     if (argc > 0)
  372.         runtype = BATCH ;
  373.     else
  374.         runtype = INTERACTIVE ;
  375.  
  376.    psinit(restart, devname) ;
  377.    initfilters() ;
  378.    initexclude() ;
  379.    
  380.    /* we have to load this variable first otherwise the system wont find the
  381.       ~/.psrc.pscmd file */
  382.    loadvar("HOME", "HOME", environ) ;
  383.  
  384.    if (dovsnchk == FALSE)
  385.    {
  386.     pssetdefvsn() ;
  387.    }
  388.    if (runtype = INTERACTIVE)
  389.        printf("Suncom program version %s, psion program version, 3.24,\n (C) Tim Graves, Sun Microsystems 1994-1995\n", psversion()) ;
  390.    /* check that the psion code is atleast version 2 otherwise the system
  391.       will fail as the path specifications will differ and the tranfer of
  392.       any path information (required for virtualy anything) will fail */
  393.    if (psvsnlt(SUNCOM_VERSION_REQUIRED))
  394.    {
  395.        versiontolow("Psion program", SUNCOM_VERSION_REQUIRED, TRUE) ;
  396.    }
  397.    /* if the suncom version supports process operations FORCE process protection to be ON */
  398.    if (!psvsnlt(MINIMUM_PROCESS_REQUIRED))
  399.        pspo(TRUE) ;
  400.  
  401.    runpscom(argc, argv) ;
  402. }
  403.  
  404. useage()
  405. {
  406.     if (debugcall >= 1)
  407.         fprintf(stderr, "CALL: usage\n") ;
  408.     fprintf(stderr, "Useage: psion [-v|-nv] [-i|-b] [-p|-q] [-r] [-d devname] [cmds] [-var varable_name [variable_value]] [-log [logname]]\n") ;
  409.     exit() ;
  410. }
  411.  
  412. dodebugargs(argc, argv)
  413. int argc ;
  414. char * argv[] ;
  415. {
  416.     int i ;
  417.     if (debugcall < 2)
  418.         return ;
  419.     fprintf(stderr, "argc = (%d) ", argc) ;
  420.     for (i = 0 ; i < argc ; i ++)
  421.         fprintf(stderr, "argv[%d] = (%s) ", i, argv[i]) ;
  422.     fprintf(stderr,"\n") ;
  423. }
  424.  
  425. runpscom(argc, argv)
  426. int argc ;
  427. char * argv[] ;
  428. {
  429.    if (debugcall >= 1)
  430.    {
  431.     fprintf(stderr,"CALL: Runpscom\n") ;
  432.     dodebugargs(argc, argv) ;
  433.    }
  434.  
  435.    /* run a rc file */
  436.    runrc() ;
  437.    /* if there are args, use them otherwise call the command interpreter */
  438.    if (argc == 0)
  439.    {
  440.     /* at least initialy we are using the cmd input */
  441.     linecmd = TRUE ;
  442.     cmdintrprt() ;
  443.    }
  444.    else
  445.    {
  446.     /* we are definatley not using the command line input */
  447.     linecmd = FALSE ;
  448.        /* handle the command line we do this by passing the argc and argv
  449.        values direct to the command interpreter which execuret them once */
  450.     cmdrun(argc, argv) ;
  451.     /* we are running in a batch type mode here, determine whether to quit of pause */
  452.     if (finish == QUIT)
  453.         cmdintr("quit") ;
  454.     else
  455.         cmdintr("pause") ;
  456.    }
  457.    psshutdown(0) ;
  458. }
  459. int cmdintrprt()
  460. {
  461.     char cmdstring [300] ;
  462.  
  463.     if (debugcall >= 1)
  464.         fprintf(stderr,"CALL: cmdintrprt\n") ;
  465.     /* read the cmdstring and untill it returns false execute it */
  466.     running = TRUE ;
  467.     do
  468.     {
  469.         if (linecmd)
  470.             printf("%d, CMD> ", level) ;
  471. #ifdef DEBUG
  472.         printf("getting input\n") ;
  473. #endif
  474.         fgets(cmdstring,sizeof(cmdstring),stdin) ;
  475. #ifdef DEBUG
  476.         printf("Got input (%s)\n",cmdstring) ;
  477. #endif
  478.         cmdintr(cmdstring) ;
  479.     }
  480.     while (running) ;
  481.     return (TRUE) ;
  482. }
  483.  
  484. int cmdintr(str)
  485. char * str ;
  486. {
  487.     char args[MAXARGS] [255] ;
  488.     char *argv[MAXARGS] ;
  489.     int res ;
  490.     int ctr ;
  491.     int lenstr ;
  492.     int argln ;
  493.     int argc ;
  494.     int white ;
  495.  
  496.     if (debugcall >= 1)
  497.     {
  498.         fprintf(stderr, "CALL: cmdintr(%s)\n", str) ;
  499.     }
  500.     /* remove any whitespace at the end of the line */
  501.     ctr = strlen(str) -1 ;
  502.     while((ctr > 0) && isspace(str[ctr]))
  503.     {
  504.         str[ctr] = '\0' ;
  505.         ctr -- ;
  506.     }
  507.  
  508.     /* debug if required */
  509.     if (debugargs)
  510.         printf("Command line = :%s:\n", str) ;
  511.     /* up the level if required */
  512.     level ++ ;
  513.     /* parse the string into its arguments */
  514.     white = FALSE ;
  515.     argc = 0 ;
  516.     argln = 0 ;
  517.     lenstr = strlen(str) ;
  518.     for (ctr = 0 ; ctr <= lenstr ; ctr ++ )
  519.     {
  520.         /* if whitespace next argument */
  521.         if (isspace(str[ctr]))
  522.         {
  523.             if (white == FALSE)
  524.             {
  525.                 /* terminate the line */
  526.                 args[argc][argln] = '\0' ;
  527.                 /* copy the pointer across to argv */ ;
  528.                 argv[argc] = args[argc] ;
  529.                 argc ++ ;
  530.                 argln = 0 ;
  531.                 white = TRUE ;
  532.                 if (argc == MAXARGS)
  533.                     return(BAD) ;
  534.             }
  535.             continue ;
  536.         }
  537.         args[argc][argln] = str[ctr] ;
  538.         argln ++ ;
  539.         white = FALSE ;
  540.     }
  541.     /* terminate the last command */
  542.     args[argc][argln] = '\0' ;
  543.     argv[argc] = args[argc] ;
  544.     argc ++ ;
  545.     /* scan the args list, if the first character of any arg is [
  546.        treat the arg as a variable, lop of the end of it (assumed to be ])
  547.        and find its value, if there is no equivalent, complain and return*/
  548.     for(ctr = 0 ; ctr < argc ; ctr ++)
  549.     {
  550.         if (args[ctr][0] == '[' )
  551.         {
  552.             args[ctr][strlen(args[ctr])-1] = '\0' ;
  553.             argv[ctr] = findvar(args[ctr] +1) ;
  554.             if (argv[ctr] == NULL)
  555.             {
  556.                 printf("No Such Variable %s\n", args[ctr]+1);
  557.                 level -- ;
  558.                 return(OK) ;
  559.             }
  560.         }
  561.     }
  562.  
  563.     /* unless the line was zero length OR a comment 
  564.        execute the command */
  565.     /* store the resule */
  566.     res = cmdrun(argc, argv) ;
  567.     /* now reduce the level */
  568.     level -- ;
  569.  
  570.     return(res);
  571. }
  572.  
  573. int cmdrun (argc, argv)
  574. int argc ;
  575. char  *argv[] ;
  576. {
  577.     int i ;
  578.     int cmdmax ;
  579.  
  580.     if (debugcall >= 1)
  581.     {
  582.         fprintf(stderr, "CALL: cmdrun\n") ;
  583.         dodebugargs(argc, argv) ;
  584.     }
  585.  
  586.     cmdmax = sizeof(cmds) / sizeof(cmds[1]) ;
  587.  
  588.     if (debugargs)
  589.     {
  590.     /* print the arguments */
  591.         printf("argc %d\n", argc) ;
  592.         for (i = 0 ; i < argc ; i ++ )
  593.                printf("argv[%d] = %s\n", i, argv[i]) ;
  594.     }
  595.  
  596.     /* run down the parameters list to find a command that matches the 
  597.        string and arguments, then call the appropriate function */
  598.     for (i = 0 ; i < cmdmax ; i ++ )
  599.     {
  600.         /* if the command is the same */
  601.         if (strcmp(argv[0], cmds[i].cmdname) == 0) 
  602.         {
  603.             /* if the args are within the permited range */
  604.             if (((argc -1) >= cmds[i].minargs) && ((argc -1) <= cmds[i].maxargs))
  605.             {
  606.                 /* execute the command pass the argc and argv */
  607.                 return(cmds[i].cmdfn(argc, argv));
  608.             }
  609.         }
  610.     }
  611.     if (i == cmdmax)
  612.         printf("Error Cmd not known\n") ;
  613. }
  614.  
  615. cmtmode(argc, argv)
  616. int argc ;
  617. char *argv [];
  618. {
  619.     if (debugcall >= 1)
  620.     {
  621.         fprintf(stderr, "CALL: cmtmode\n") ;
  622.         dodebugargs(argc, argv) ;
  623.     }
  624.     /* set the app-ropriate transfer mode */
  625.     if (strcmp(argv[0], "ascii") == 0)
  626.         printf("ASCII mode is nolonger supported\n") ;
  627.     else if (strcmp(argv[0], "xmodem") == 0)
  628.     {
  629.         /* do some version checking (it will be nice when we rev 
  630.         to version three of suncom and all this can be removed */
  631.         if (psvsnlt(MINIMUM_XMDM_REQUIRED))
  632.         {
  633.             versiontolow(argv[0], MINIMUM_XMDM_REQUIRED, 0) ;
  634.             return (OK) ;
  635.         }
  636.         psxmodem() ;
  637.     }
  638.     else
  639.         psbinary() ;
  640.     return(OK) ;
  641. }
  642.  
  643. cmlist(argc, argv)
  644. int argc ;
  645. char * argv[] ;
  646. {
  647.     FILE *fd ;
  648.  
  649.     if (debugcall >= 1)
  650.     {
  651.         fprintf(stderr, "CALL: cmlist\n") ;
  652.         dodebugargs(argc, argv) ;
  653.     }
  654.     fd = NULL ;
  655.     if (argc == 3) /* send output to a file */
  656.         if ((fd = fopen(argv[2], "w")) == NULL)
  657.         {
  658.             printf("%s, Bad file %s\n", argv[0], argv[2]) ;
  659.             return(BAD) ;
  660.         }
  661.     pssetpath(argv[1]) ;
  662.     pslp(fd) ;
  663.     if (argc == 3)
  664.         fclose(fd) ;
  665.     return(OK) ;
  666. }
  667. cmrm(argc, argv)
  668. int argc ;
  669. char * argv[] ;
  670. {
  671.     char ch[10];
  672.     if (debugcall >= 1)
  673.     {
  674.         fprintf(stderr, "CALL: cmrm\n") ;
  675.         dodebugargs(argc, argv) ;
  676.     }
  677.     /* if the VAR_RMCHECK variable is set ensure that this is what the user 
  678.        realy wants to do */
  679.     if (findvar(VAR_RMCHECK) != NULL)
  680.     {
  681.         printf("rm %s (y/n)\n", argv[1]) ;
  682.         fgets(ch, sizeof(ch),stdin);
  683.         if ((ch[0] == 'y') || (ch[0] == 'Y'))
  684.         {
  685.             pssetpath(argv[1]) ;
  686.             psrp() ;
  687.         }
  688.     }
  689.     else
  690.     {
  691.         pssetpath(argv[1]) ;
  692.         psrp() ;
  693.     }
  694.     return (OK) ;
  695. }
  696.  
  697. cmmkdir(argc, argv)
  698. int argc ;
  699. char * argv[] ;
  700. {
  701.     if (debugcall >= 1)
  702.     {
  703.         fprintf(stderr, "CALL: cmmkdir\n") ;
  704.         dodebugargs(argc, argv) ;
  705.     }
  706.     if (argc-1 == 1)
  707.     {
  708.         printf("Creating directory %s\n", argv[1]) ;
  709.         pssetpath(argv[1]) ;
  710.         psmd() ;
  711.     }
  712.     return(OK) ;
  713. }
  714.  
  715. cmecho(argc, argv)
  716. int argc ;
  717. char * argv[] ;
  718. {
  719.     if (debugcall >= 1)
  720.     {
  721.         fprintf(stderr, "CALL: cmecho\n") ;
  722.         dodebugargs(argc, argv) ;
  723.     }
  724.     while(--argc > 0)
  725.         printf((argc > 1) ? "%s " : "%s\n", *++argv) ;
  726.     return(OK) ;
  727. }
  728.  
  729. cmignore(argc, argv)
  730. int argc ;
  731. char * argv[] ;
  732. {
  733.     if (debugcall >= 1)
  734.     {
  735.         fprintf(stderr, "CALL: cmignore\n") ;
  736.         dodebugargs(argc, argv) ;
  737.     }
  738.     return (OK) ;
  739. }
  740.  
  741. cmgetenv(argc, argv)
  742. int argc ;
  743. char * argv[] ;
  744. {
  745.     int diffnames ;
  746.     int defval ;
  747.     int varexists ;
  748.  
  749.     if (debugcall >= 1)
  750.     {
  751.         fprintf(stderr, "CALL: cmtgetenv\n") ;
  752.         dodebugargs(argc, argv) ;
  753.     }
  754.     varexists = diffnames = defval = FALSE ;
  755.     /* figure out how the variables are supposed to work */
  756.     if (argc == 3) /* different names but no default */
  757.         diffnames = TRUE ;
  758.  
  759.     if (argc== 4) /* different names and default */
  760.         diffnames = defval = TRUE ;
  761.  
  762.     /* get the darn things */
  763.     varexists = diffnames ? loadvar(argv[1], argv[2], environ) : loadvar(argv[1], argv[1], environ) ;
  764.  
  765.     if (varexists)
  766.         return(OK) ;
  767.  
  768.     /* the var does not exist in the unix environment if there is a default use that */
  769.     if (defval)
  770.         /* we dont need to check if there are different names, there
  771.            must be to allow us to have got to this stage */
  772.            addvar(argv[2], argv[3]) ;
  773.     return (OK) ;
  774. }
  775. cmdumpv (argc, argv)
  776. int argc ;
  777. char * argv[] ;
  778. {
  779.     if (debugcall >= 1)
  780.     {
  781.         fprintf(stderr, "CALL: cmdumpv\n") ;
  782.         dodebugargs(argc, argv) ;
  783.     }
  784.     /* just dump all the variables */
  785.     dumpvars() ;
  786.     return(OK) ;
  787. }
  788.  
  789. cmsetv(argc, argv) 
  790. int argc ;
  791. char * argv[] ;
  792. {
  793.     if (debugcall >= 1)
  794.     {
  795.         fprintf(stderr, "CALL: cmsetv\n") ;
  796.         dodebugargs(argc, argv) ;
  797.     }
  798.     if (argc == 2)
  799.         addvar(argv[1], "") ;
  800.     else
  801.         addvar(argv[1], argv[2]) ;
  802.     /* there are some special variables, which also need to set C variables*/
  803.     if (strncmp(argv[1], "debug", 5) != 0)
  804.         return(OK) ;
  805.     /* handle the special cases */
  806.     if (strcmp(argv[1], "debugargs") == 0)
  807.         debugargs = TRUE ;
  808.     else if (strcmp(argv[1], "debugcall") == 0)
  809.     {
  810.         if (logfile)
  811.         {
  812.            printf("Logging enabled, changing debug call will affect loging information\n") ;
  813.         }
  814.         if (argc == 2)
  815.             debugcall = TRUE ;
  816.         else
  817.         {
  818.             sscanf(argv[2], "%d", &debugcall) ;
  819.         }
  820.         printf("Call debuging now at level %d\n", debugcall) ;
  821.     }
  822.     else if (strcmp(argv[1], "debuglink") == 0)
  823.         debuglink = TRUE ;
  824.     else if (strcmp(argv[1], "debugpath") == 0)
  825.         debugpath= TRUE ;
  826.     else if (strcmp(argv[1], "debugrun") == 0)
  827.         debugrun = TRUE ;
  828.     else if (strcmp(argv[1], "debugbackup") == 0)
  829.         debugbackup = TRUE ;
  830.     /* checksums only work once we get to MINIMUM_FILE_CHECKSUM_REQUIRED */
  831.     else if ((strcmp(argv[1], VAR_CHKSUM_WARN) == 0) || (strcmp(argv[1], VAR_CHKSUM_CORRECT) == 0))
  832.         if (psvsnlt(MINIMUM_FILE_CHECKSUM_REQUIRED))
  833.         {
  834.             versiontolow("setv chksumwarn / setv chksumcorrect", MINIMUM_FILE_CHECKSUM_REQUIRED, FALSE) ;
  835.             /* unset the variable */
  836.             delvar (argv[1]) ;
  837.         }
  838.     return(OK) ;
  839. }
  840.  
  841. cmunsetv(argc, argv)
  842. int argc ;
  843. char * argv[] ;
  844. {
  845.     if (debugcall >= 1)
  846.     {
  847.         fprintf(stderr, "CALL: cmunsetv\n") ;
  848.         dodebugargs(argc, argv) ;
  849.     }
  850.     delvar(argv[1]) ;
  851.     /* there are some special variables, which also need to set C variables*/
  852.     if (strncmp(argv[1], "debug", 5) != 0)
  853.         return(OK) ;
  854.     /* handle the special cases */
  855.     if (strcmp(argv[1], "debugargs") == 0)
  856.         debugargs = FALSE ;
  857.     else if (strcmp(argv[1], "debuglink") == 0)
  858.         debuglink = FALSE ;
  859.     else if (strcmp(argv[1], "debugpath") == 0)
  860.         debugpath= FALSE ;
  861.     else if (strcmp(argv[1], "debugcall") == 0)
  862.          {
  863.             if (logfile)
  864.                printf("Logging enabled, debugcall cannot be changed\n") ;
  865.         else
  866.             debugcall = FALSE ;
  867.           }
  868.     else if (strcmp(argv[1], "debugrun") == 0)
  869.         debugrun = FALSE ;
  870.     else if (strcmp(argv[1], "debugbackup") == 0)
  871.         debugbackup = FALSE ;
  872.     return(OK) ;
  873. }
  874.  
  875. cmifusetv(argc, argv) 
  876. int argc ;
  877. char * argv[] ;
  878. {
  879.     /* if the variable is not set setit else leave allone */
  880.     char * ptr ;
  881.     if (debugcall >= 1)
  882.     {
  883.         fprintf(stderr, "CALL: cmifusetv\n") ;
  884.         dodebugargs(argc, argv) ;
  885.     }
  886.     ptr = findvar(argv[1]) ;
  887.  
  888.     if (ptr == NULL)
  889.     {
  890.         addvar(argv[1], argv[2]) ;
  891.     }
  892.     return(OK) ;
  893. }
  894.  
  895. cmsystem(argc, argv)
  896. int argc ;
  897. char * argv[] ;
  898. {
  899.     char command [10000] ;
  900.  
  901.     if (debugcall >= 1)
  902.     {
  903.         fprintf(stderr, "CALL: cmsystem\n") ;
  904.         dodebugargs(argc, argv) ;
  905.     }
  906.     command[0] = '\0' ;
  907.  
  908.     while (-- argc > 0)
  909.     {
  910.         strcat (command, *++argv) ;
  911.         strcat (command, " ") ;
  912.     }
  913.     if (system (command) >= 0) 
  914.         return(OK) ;
  915.     else
  916.         return(BAD) ;
  917. }
  918.  
  919. cmhelp(argc, argv)
  920. int argc ;
  921. char * argv[];
  922. {
  923.     int cmdmax, ctr ;
  924.  
  925.     if (debugcall >= 1)
  926.     {
  927.         fprintf(stderr, "CALL: cmhelp\n") ;
  928.         dodebugargs(argc, argv) ;
  929.     }
  930.     cmdmax = sizeof(cmds) / sizeof(cmds[1]) ;
  931.  
  932.     /* if there is no arg just print out the list of commands */
  933.     if (argc == 1)
  934.     {
  935.        printf("%s, list of available commands is\n", argv[0]) ;
  936.        for (ctr = 0 ; ctr < cmdmax ; ctr ++)
  937.           printf("%s\n", cmds[ctr].cmdname) ;
  938.        return(OK) ;
  939.     }
  940.     /* else find the command and pring out the message */
  941.     for (ctr = 0 ; ctr < cmdmax ; ctr++)
  942.     {
  943.         if (strcmp(cmds[ctr].cmdname, argv[1]) == 0)
  944.         {
  945.             /* are we help or usage ? */
  946.             if (strcmp(argv[0], "help") == 0)
  947.                printf("help for %s\n%s\n", argv[1], cmds[ctr].helptext) ;
  948.             else
  949.             {
  950.                printf("Usage: %s %s\n", argv[1], cmds[ctr].usage) ;
  951.                printf("Argument count, Min %d, Max %d\n", cmds[ctr].minargs, cmds[ctr].maxargs) ;
  952.             }
  953.             
  954.             return(OK) ;
  955.         }
  956.     }
  957.     printf("%s: %s not found\n", argv[0], argv[1]) ;
  958.     return (OK) ;
  959. }
  960.  
  961. cmrun(argc, argv)
  962. int argc ;
  963. char * argv [] ;
  964. {
  965.     /* execute a script, open the file (suffix .pscmd)
  966.        and execute the commands in it to EOF. I guess this MAY expand
  967.        to be a command language given time !
  968.        NOTE as this is used in a subroutine recursive run commands
  969.        are feasible  and variables are correctly handled */
  970.        FILE *fd ;
  971.        char cmdline[1000] ;
  972.        char cmdfile [1000] ;
  973.        int ctr ;
  974.        char varname[50] ;
  975.        char * path ;
  976.        int source, which ;
  977.  
  978.     if (debugcall >= 1)
  979.     {
  980.         fprintf(stderr, "CALL: cmrun\n") ;
  981.         dodebugargs(argc, argv) ;
  982.     }
  983.        source = FALSE ;
  984.        which = FALSE ;
  985.        if (strcmp(argv[0], "which") == 0)
  986.        {
  987.            which = TRUE ;
  988.        }
  989.        
  990.        if (strcmp(argv[0], "source") == 0)
  991.        {
  992.         source = TRUE ;
  993.        }
  994.  
  995.        /* if path is set use it, otherwise us "." as the path */
  996.        if ((path = findvar("path")) == NULL)
  997.        {
  998.         path = "." ;
  999.     }
  1000.            
  1001.        /* locate the command */
  1002.        if (pscmdpath(argv[1], path, cmdfile) == NULL)
  1003.        {
  1004.         printf("Error, %s not found\n", argv[1]) ;
  1005.         return(OK) ;
  1006.        }
  1007.  
  1008.        if ((fd = fopen(cmdfile, "r")) == NULL)
  1009.        {
  1010.         fprintf(stderr, "Error in opening %s\n", argv[1]) ;
  1011.         return(BAD) ;
  1012.        }
  1013.        
  1014.        /* if we have got here we know that the file exists and is readable,
  1015.           report back on the file details if which == TRUE and tidy up */
  1016.        if (which == TRUE)
  1017.        {
  1018.            fclose(fd) ;
  1019.            printf("run %s would use: %s\n", argv[1], cmdfile) ;
  1020.            return (OK) ;
  1021.        }
  1022.  
  1023.        /* go up one variable stack level if we are running 
  1024.           otherwise we are sourcing so stay put 
  1025.           We do not do anything with args if we are sourcing as the 
  1026.           sourced files are used to setup variables etc, not
  1027.           run programs */
  1028.        if (source == FALSE)
  1029.        {
  1030.            upvarlevel() ;
  1031.  
  1032.             /* firet remove "run" from the argument list */
  1033.             argc -- ;
  1034.             argv ++ ;
  1035.             /* then setup all the parameters */
  1036.             for(ctr = 0 ; ctr < argc ; ctr ++)
  1037.             {
  1038.              sprintf(varname, "arg%d", ctr ) ;
  1039.              addvar(varname, argv[ctr]) ;
  1040.             }
  1041.        }
  1042.  
  1043.        while (fgets(cmdline, 1000, fd) != NULL)
  1044.        {
  1045.         /* remove the newline ae the end of the string */
  1046.         cmdline[strlen(cmdline) -1] = '\0' ;
  1047.         if (debugrun)
  1048.             printf("Cmd :%s:\n", cmdline) ;
  1049.         if (cmdintr(cmdline) != OK)
  1050.             break ;
  1051.        }
  1052.        /* go down one level if we are running */
  1053.        if (source == FALSE)
  1054.        {
  1055.            downvarlevel() ;
  1056.        }
  1057.     
  1058.        fclose (fd) ;
  1059.        return (OK) ;
  1060. }
  1061.  
  1062. cmspeed(argc, argv)
  1063. int argc ;
  1064. char * argv[] ;
  1065. {
  1066.     if (debugcall >= 1)
  1067.     {
  1068.         fprintf(stderr, "CALL: cmspeed\n") ;
  1069.         dodebugargs(argc, argv) ;
  1070.     }
  1071.     if (strcmp(argv[0], "fast")== 0)
  1072.     {
  1073.         psverboseoff() ;
  1074.         psscreenoff() ;
  1075.     }
  1076.     else
  1077.     {
  1078.         psverboseon() ;
  1079.         psscreenon() ;
  1080.     }
  1081.     return (OK) ;
  1082. }
  1083.  
  1084. cmforeach(argc, argv)
  1085. int argc ;
  1086. char * argv[] ;
  1087. {
  1088.     char psionname[300] ;
  1089.     char getcmd[300] ;
  1090.     char pspath[255] ;
  1091.     FILE *fd ;
  1092.     int ctr ;
  1093.  
  1094.     if (debugcall >= 1)
  1095.     {
  1096.         fprintf(stderr, "CALL: cmforeach\n") ;
  1097.         dodebugargs(argc, argv) ;
  1098.     }
  1099.     /* for each of the files in the list in the file of the first arg
  1100.        build a command line composed of the remaining arguments and append
  1101.        the parameters, them call the command interpreter */
  1102.     /* now call a routine to read the filenames and 
  1103.        parse them into part dir fame
  1104.        and to get each one individualy */
  1105.  
  1106.     if ((fd = fopen(argv[1], "r")) == NULL)
  1107.     {
  1108.         printf("%s error on opening names file\n", argv[0]) ;
  1109.         return(BAD) ;
  1110.     }
  1111.  
  1112.     while (fgets(psionname, 300, fd) != NULL)
  1113.     {
  1114.         if (debugrun)
  1115.             printf("Foreach input :%s:\n", psionname) ;
  1116.         /* if required remove the trailing \n from the string */
  1117.         if (psionname[strlen(psionname)] == '\n')
  1118.             psionname[strlen(psionname) -1] == '\0' ;
  1119.         if (debugrun)
  1120.             printf("Foreach, output path%s\n",  pspath) ;
  1121.         /* create the command */
  1122.         /* init the string */
  1123.         getcmd[0] = '\0' ;
  1124.  
  1125.         /* first build the command from the strings handed to foreach */
  1126.         for (ctr = 2 ; ctr < argc ; ctr ++)
  1127.         {
  1128.             strcat(getcmd, argv[ctr]) ;
  1129.             strcat(getcmd, " ") ;
  1130.         }
  1131.  
  1132.         /* now append the partition, directory and file details */
  1133.         strcat (getcmd, psionname) ;
  1134.         cmdintr(getcmd) ;
  1135.     }
  1136.     fclose(fd) ;
  1137.     return(OK) ;
  1138. }
  1139.     
  1140. cmget(argc, argv)
  1141. int argc ; 
  1142. char * argv[] ;
  1143. {
  1144.  
  1145.     time_t timestart, timeend ;
  1146.     int timediff ;
  1147.     int res ;
  1148.     char listcmd[255] ;
  1149.     char getcmd[255] ;
  1150.     char psionname[300] ;
  1151.     char pspath[255] ;
  1152.     int sunchksum, psionchksum ;
  1153.     int startrecgood, startrecbad, endrecgood, endrecbad ;
  1154.     FILE *fd ;
  1155.  
  1156.     if (debugcall >= 1)
  1157.     {
  1158.         fprintf(stderr, "CALL: cmget\n") ;
  1159.         dodebugargs(argc, argv) ;
  1160.     }
  1161.     /* if the filename contains a * then do a list to put the names
  1162.        into a file and then get each file individualy, in this
  1163.        case we can only operate with the local and remote filenames
  1164.        being the same */
  1165.     if (strchr(argv[1], '*') != NULL)
  1166.     {
  1167.         if (argc == 3)
  1168.             printf("Sorry cannot use specific recieving names with wildcard get (yet)\n") ;
  1169.         /* set the list parameter up */
  1170.         strcpy (listcmd, "list ") ;
  1171.         /* create the other information */
  1172.         strcat (listcmd, argv[1]) ; /* the path name */
  1173.         strcat (listcmd, " ") ;
  1174.         strcat (listcmd, "/tmp/filenames") ; /* the temp filename */
  1175.         /* call cmdintr to do the work for us */
  1176.         if (cmdintr(listcmd) != OK)
  1177.             return(BAD) ;
  1178.         /* now build a foreach command to handle the filenames */
  1179.         strcpy(getcmd, "foreach /tmp/filenames get") ;
  1180.         /* call the command interpreter to get the files */
  1181.         cmdintr(getcmd) ;
  1182.         fclose(fd) ;
  1183.         return(OK) ;
  1184.     }
  1185.     if (findvar(VAR_DOLOWERPATH) != NULL)
  1186.         lowerpath(argv[1]) ;
  1187.  
  1188.     if (argc == 2)
  1189.     {
  1190.         if (findvar(VAR_VERBOSE) != NULL)
  1191.             printf("Getting one file %s\n", argv[1]) ;
  1192.         pssetpath(argv[1]) ;
  1193.         time(×tart) ;
  1194.         startrecgood = recgood ;
  1195.         startrecbad = recbad ;
  1196.         res = psrecfile("") ;
  1197.         endrecgood = recgood ;
  1198.         endrecbad = recbad ;
  1199.     }
  1200.     else
  1201.     {
  1202.         if (findvar(VAR_VERBOSE) != NULL)
  1203.             printf("Getting %s to %s\n", argv[1], argv[2]) ;
  1204.         pssetpath(argv[1]) ;
  1205.         startrecgood = recgood ;
  1206.         startrecbad = recbad ;
  1207.         time(×tart) ;
  1208.         res = psrecfile(argv[2]) ;
  1209.         endrecgood = recgood ;
  1210.         endrecbad = recbad ;
  1211.     }
  1212.     time(&timeend) ;
  1213.     
  1214.     if (res != OK)
  1215.     {
  1216.         printf("File not transfered\n") ;
  1217.         return(OK) ;
  1218.     }
  1219.  
  1220.     timediff = (int) timeend - timestart ;
  1221.     if (timediff == 0)
  1222.         timediff = 1 ;
  1223.  
  1224.     if (findvar(VAR_VERBOSE) != NULL)
  1225.     {
  1226.         printf("Transfer time %d, bytes %d, speed %d (bytes / sec)\n", timediff, pstrans(), (int) pstrans()/timediff) ;
  1227.         printf ("transmission information good blocks %d, bad blocks %d\n", endrecgood - startrecgood, endrecbad - startrecbad) ;
  1228.     }
  1229.         
  1230.     /* if VAR_CHKSUM_WARN is in effect check is the checksums are
  1231.        different on the filenames, if VAR_CHKSUM_CORRECT redo the get
  1232.        we have to do this BEFORE any filtering takes place */
  1233.     if ((findvar(VAR_CHKSUM_WARN) != NULL) || (findvar(VAR_CHKSUM_CORRECT) != NULL))
  1234.     {
  1235.         /* get the sun chksum */
  1236.         if (argc == 2)
  1237.             sunchksum = sunsum(psfname) ;
  1238.         else
  1239.             sunchksum = sunsum(argv[2]) ;
  1240.         /* get the psion chksum (we can assume that the psion path 
  1241.            has already been set )*/
  1242.         psionchksum = pscs() ;
  1243.         if ((findvar(VAR_CHKSUM_WARN) != NULL) && (sunchksum != psionchksum))
  1244.             printf("Warning, the psion and sun check sums disagree (sun = %d, psion = %d)\n", sunchksum, psionchksum) ;
  1245.         if (((findvar(VAR_CHKSUM_CORRECT)) != NULL) && (sunchksum != psionchksum))
  1246.         {
  1247.             /* if VAR_BAD_CHKSUM_SAVE is in place move the bad file
  1248.                so I can look at it later */
  1249.             if (findvar(VAR_BAD_CHKSUM_SAVE) != NULL)
  1250.             {
  1251.                 char cmd[2000] ;
  1252.                 char newname[1000] ;
  1253.                 /* create the new file name */
  1254.                 if (argc == 2)
  1255.                     strcpy(newname, psfname) ;
  1256.                 else
  1257.                     strcpy(newname, argv[2]) ;
  1258.                 sprintf(cmd, "mv %s ", newname) ; 
  1259.                 strcat (newname, "XXXXXX") ;
  1260.                 mktemp(newname) ;
  1261.                 strcat(cmd, newname) ;
  1262.                 if (findvar(VAR_VERBOSE) != NULL)
  1263.                     printf("Saving incorrect version using :%s:\n", cmd) ;
  1264.                 system(cmd) ;
  1265.             } /* if we do not save the filer unlink the old version */
  1266.             else
  1267.             {
  1268.                 /* remove the local file */
  1269.                 if (argc == 2)
  1270.                     unlink(psfname) ;
  1271.                 else
  1272.                     unlink(argv[2]) ;
  1273.             }
  1274.             /* if VAR_CHKSUM_CORRECT redo the get, we must disable 
  1275.                file filtering though otherwise nasty things could 
  1276.                happen. we do this by moving up a variable level, 
  1277.                this enables us to unset the VAR_FILEFILT variable 
  1278.                with impunity */
  1279.             if (findvar(VAR_VERBOSE) != NULL)
  1280.                 printf("A Checksum difference has been detected, regetting the file\n") ;
  1281.             /* go up a variable stack level */
  1282.             /* this is realy starting to get somewhat nasty 
  1283.                having to to this but it appears to work */
  1284.             upvarlevel() ;
  1285.             /* remove VAR_FILEFILT */
  1286.             delvar(VAR_FILEFILT) ;
  1287.             /* build a command list */
  1288.             strcpy(getcmd, "get ") ;
  1289.             strcat(getcmd, argv[1]) ;
  1290.             if (argc == 3)
  1291.             {
  1292.                 strcat(getcmd, " ") ;
  1293.                 strcat(getcmd, argv[2]) ;
  1294.             }
  1295.             /* redo the get command, if this also fails we are 
  1296.                OK as the code is all safe to call recursivly as we 
  1297.                do things at a higher variable level */
  1298.             cmdintr(getcmd) ;                
  1299.             /* drop down the variable level, this resets the 
  1300.                variables to the previous state and restores 
  1301.                VAR_FILE_FILT if it was set */
  1302.             downvarlevel() ;
  1303.         }
  1304.     }
  1305.     /* is file filtering enabled ? */
  1306.     if (findvar(VAR_FILEFILT) != NULL)
  1307.     {
  1308.         if (argc == 2)
  1309.         {
  1310.             /* we are dealing with a direct get from the same file, psfname is already setup*/
  1311.             filefilt(INFILTER,psfname) ;
  1312.         }
  1313.         else
  1314.         {
  1315.             /* the file was grabbed into argv[2] */
  1316.             filefilt(INFILTER,argv[2]) ;
  1317.         }
  1318.     }
  1319.     return(OK) ;
  1320. }
  1321.  
  1322. getfilefiles(fname)
  1323. char * fname ;
  1324. {
  1325.     /* scan each of the filenames and then get it */
  1326.     FILE *fd ;
  1327.     char psionname[300] ;
  1328.     char pspath[255] ;
  1329.     char cmdname[300] ;
  1330.  
  1331.     if (debugcall >= 1)
  1332.     {
  1333.         fprintf(stderr, "CALL: getfilefiles from %s\n",fname) ;
  1334.     }
  1335.     if ((fd = fopen(fname, "r")) == NULL)
  1336.     {
  1337.         printf("Wildcard get error on opening names file\n") ;
  1338.         return(BAD) ;
  1339.     }
  1340.  
  1341.     while (fgets(psionname, 300, fd) != NULL)
  1342.     {
  1343.         /* if required remove the trailing \n from the string */
  1344.         if (psionname[strlen(psionname)] == '\n')
  1345.             psionname[strlen(psionname) -1] == '\0' ;
  1346.         /* create the get command */
  1347.         strcpy (cmdname, "get ") ;
  1348.         strcat (cmdname, pspath) ;
  1349.         cmdintr(cmdname) ;
  1350.     }
  1351. }
  1352.  
  1353. cmput(argc, argv)
  1354. int argc ; 
  1355. char * argv[] ;
  1356. {
  1357.     time_t timestart, timeend ;
  1358.     int timediff ;
  1359.     int res ;
  1360.     int sunchksum, psionchksum ;
  1361.     char putcmd [255] ;
  1362.     int starttransgood, starttransbad ;
  1363.     int endtransgood, endtransbad ;
  1364.  
  1365.     if (debugcall >= 1)
  1366.     {
  1367.         fprintf(stderr, "CALL: cmput\n") ;
  1368.         dodebugargs(argc, argv) ;
  1369.     }
  1370.     /* map the path to lower case if desired */
  1371.     if (findvar(VAR_DOLOWERPATH) != NULL)
  1372.         lowerpath(argv[1]) ;
  1373.  
  1374.     /* send the path, do this here so that the next call to psgetfname will have the correct value installed and we can use it for filt output filtering */
  1375.     pssetpath(argv[1]) ;
  1376.     /* is file filtering enabled ? */
  1377.     if (findvar(VAR_FILEFILT) != NULL)
  1378.     {
  1379.         if (argc == 2)
  1380.         {
  1381.             /* we are dealing with a direct put from the same file, we need to setup psfname */
  1382.             psgetfname() ;
  1383.             filefilt(OUTFILTER,psfname) ;
  1384.         }
  1385.         else
  1386.         {
  1387.             /* the file is being sent from argv[2] */
  1388.             filefilt(OUTFILTER,argv[2]) ;
  1389.         }
  1390.     }
  1391.  
  1392.     if (argc-1 == 1)
  1393.     {
  1394.         if (findvar(VAR_VERBOSE) != NULL)
  1395.             printf("putting one file %s\n", argv[1]) ;
  1396.         starttransgood = transgood ;
  1397.         starttransbad = transbad ;
  1398.         time(×tart) ;
  1399.         res = pssendfile("") ;
  1400.         endtransgood = transgood ;
  1401.         endtransbad = transbad ;
  1402.     }
  1403.     else
  1404.     {
  1405.         if (findvar(VAR_VERBOSE) != NULL)
  1406.             printf("putting %s from %s\n", argv[1], argv[2]) ;
  1407.         starttransgood = transgood ;
  1408.         starttransbad = transbad ;
  1409.         time(×tart) ;
  1410.         res = pssendfile(argv[2]) ;
  1411.         endtransgood = transgood ;
  1412.         endtransbad = transbad ;
  1413.     }
  1414.     time(&timeend) ;
  1415.  
  1416.     /* if res != OK skip the next bit, we cant leave the function in case there is a restore filter */
  1417.     if (res == OK)
  1418.     {
  1419.         timediff = (int) timeend - timestart ;
  1420.         if (timediff == 0)
  1421.             timediff = 1 ;
  1422.     
  1423.         if (findvar(VAR_VERBOSE) != NULL)
  1424.         {
  1425.             printf("Transfer time %d, bytes %d, speed %d (bytes / sec)\n", timediff, pstrans(), (int) pstrans()/timediff) ;
  1426.             printf ("transmission information good blocks %d, bad blocks %d\n", endtransgood - starttransgood, endtransbad - starttransbad) ;
  1427.         }
  1428.         /* if VAR_CHKSUM_WARN is in effect check is the checksums are
  1429.            different on the filenames, if VAR_CHKSUM_CORRECT redo the get
  1430.            we have to do this BEFORE any filtering takes place */
  1431.         if ((findvar(VAR_CHKSUM_WARN) != NULL) || (findvar(VAR_CHKSUM_CORRECT) != NULL))
  1432.         {
  1433.             /* get the sun chksum */
  1434.             if (argc == 2)
  1435.                 sunchksum = sunsum(psfname) ;
  1436.             else
  1437.                 sunchksum = sunsum(argv[2]) ;
  1438.             /* get the psion chksum (we can assume that the psion path 
  1439.                has already been set )*/
  1440.             psionchksum = pscs() ;
  1441.             if ((findvar(VAR_CHKSUM_WARN) != NULL) && (sunchksum != psionchksum))
  1442.                 printf("Warning, the psion and sun check sums disagree (sun = %d, psion = %d)\n", sunchksum, psionchksum) ;
  1443.             if (((findvar(VAR_CHKSUM_CORRECT)) != NULL) && (sunchksum != psionchksum))
  1444.             {
  1445.                 /* if VAR_CHKSUM_CORRECT redo the put, we must disable 
  1446.                    file filtering though otherwise nasty things could 
  1447.                    happen. we do this by moving up a variable level, 
  1448.                    this enables us to unset the VAR_FILEFILT variable 
  1449.                    with impunity */
  1450.                 if (findvar(VAR_VERBOSE) != NULL)
  1451.                     printf("A Checksum difference has been detected, re-putting the file\n") ;
  1452.                 /* go up a variable stack level */
  1453.                 /* this is realy starting to get somewhat nasty 
  1454.                    having to to this but it appears to work */
  1455.                 upvarlevel() ;
  1456.                 /* remove VAR_FILEFILT */
  1457.                 delvar(VAR_FILEFILT) ;
  1458.                 /* remove the VAR_RMCHECK so we dont
  1459.                    get asked about removing the file */
  1460.                 delvar(VAR_RMCHECK) ;
  1461.                 /* remove the file */
  1462.                 /* build the command list *
  1463.                 sprintf(putcmd, "rm %s", argv[1]) ;
  1464.                 /* do the remove */
  1465.                 cmdintr(putcmd) ;
  1466.                 /* redo the put */
  1467.                 /* build a command list */
  1468.                 strcpy(putcmd, "put ") ;
  1469.                 strcat(putcmd, argv[1]) ;
  1470.                 if (argc == 3)
  1471.                 {
  1472.                     strcat(putcmd, " ") ;
  1473.                     strcat(putcmd, argv[2]) ;
  1474.                 }
  1475.                 /* redo the put command, if this also fails we are 
  1476.                    OK as the code is all safe to call recursivly as we 
  1477.                    do things at a higher variable level and all 
  1478.                    variables are local that would be changed*/
  1479.                 cmdintr(putcmd) ;                
  1480.                 /* drop down the variable level, this resets the 
  1481.                    variables to the previous state and restores 
  1482.                    VAR_FILE_FILT if it was set */
  1483.                 downvarlevel() ;
  1484.             }
  1485.         }
  1486.     }
  1487.     /* we may have we have mangled the file by using the output filter,
  1488.        call the restore filter to reset it */
  1489.     if (findvar(VAR_FILEFILT) != NULL)
  1490.     {
  1491.         if (argc == 2)
  1492.         {
  1493.             /* psfname is already correctly set just call with 
  1494.                the restore filter*/
  1495.             filefilt(RESTFILTER,psfname) ;
  1496.         }
  1497.         else
  1498.         {
  1499.             filefilt(RESTFILTER, argv[2]) ;
  1500.         }
  1501.     }
  1502.  
  1503.     return(OK) ;
  1504. }
  1505.  
  1506. cmdiscon(argc, argv)
  1507. int argc ; 
  1508. char * argv[] ;
  1509. {
  1510.     if (debugcall >= 1)
  1511.     {
  1512.         fprintf(stderr, "CALL: cmdiscon\n") ;
  1513.         dodebugargs(argc, argv) ;
  1514.     }
  1515.     running = FALSE ; /* tell the command interpreter loop to quit */
  1516.     if (strcmp(argv[0], "quit") == 0)
  1517.     {
  1518.         /* if this is in batch mode, be quiet */
  1519.         if (runtype != BATCH)
  1520.             printf("Disconnecting and closing down psion\n") ;
  1521.         psdc() ;
  1522.         return(DISCONN) ;
  1523.     }
  1524.     else /* we are exiting the sun end of the prog but not the psion end */
  1525.     {
  1526.         /* if this is in batch mode, be quiet */
  1527.         if (runtype != BATCH)
  1528.             printf("Disconnecting and leaving psion active\n") ;
  1529.         return(DISCONN) ;
  1530.     }
  1531.  
  1532. }
  1533. cmfilter(argc, argv)
  1534. int argc ; 
  1535. char * argv[] ;
  1536. {
  1537.     int filtertype ;
  1538.     if (debugcall >= 1)
  1539.     {
  1540.         fprintf(stderr, "CALL: cmfilter\n") ;
  1541.         dodebugargs(argc, argv) ;
  1542.     }
  1543.     /* are we adding or removing a filter ? */
  1544.     if (strcmp(argv[0], "addfilter") == 0)
  1545.     {
  1546.         /* is this an input or output or restore filter ? */
  1547.         if (strcmp(argv[1], "in") == 0)
  1548.             filtertype = INFILTER ;
  1549.         else if (strcmp(argv[1], "restore") == 0)
  1550.             filtertype = RESTFILTER ;
  1551.         else
  1552.             filtertype = OUTFILTER ;
  1553.         /* lets setup the filter */
  1554.         setupfilter(filtertype, argv[2], argv[3]) ;
  1555.     }
  1556.     else
  1557.     {
  1558.         /* is this an input or output or restore filter ? */
  1559.         if (strcmp(argv[1], "in") == 0)
  1560.             filtertype = INFILTER ;
  1561.         else if (strcmp(argv[1], "restore") == 0)
  1562.             filtertype = RESTFILTER ;
  1563.         else
  1564.             filtertype = OUTFILTER ;
  1565.         /* lets setup the filter */
  1566.         removefilter(filtertype, argv[2]) ;
  1567.     }
  1568.  
  1569.         return (OK) ;
  1570. }
  1571. cmfilterprint(argc, argv)
  1572. int argc ;
  1573. char * argv[] ;
  1574. {
  1575.     if (debugcall >= 1)
  1576.     {
  1577.         fprintf(stderr, "CALL: cmfilterprint\n") ;
  1578.         dodebugargs(argc, argv) ;
  1579.     }
  1580.     printfilters() ;
  1581.     return (OK) ;
  1582. }
  1583. cmexclprint(argc, argv)
  1584. int argc ;
  1585. char * argv[] ;
  1586. {
  1587.     if (debugcall >= 1)
  1588.     {
  1589.         fprintf(stderr, "CALL: cmexclprint\n") ;
  1590.         dodebugargs(argc, argv) ;
  1591.     }
  1592.     printexclude() ;
  1593.     return (OK) ;
  1594. }
  1595.  
  1596. cmexclude(argc, argv)
  1597. int argc ;
  1598. char * argv[] ;
  1599. {
  1600.     if (debugcall >= 1)
  1601.     {
  1602.         fprintf(stderr, "CALL: cmexclude\n") ;
  1603.         dodebugargs(argc, argv) ;
  1604.     }
  1605.     /* all backup related paths must be in lower case ! */
  1606.     lowerpath(argv[1]) ;
  1607.     if (strcmp(argv[0], "addexcl") == 0)
  1608.         setupexclude(argv[1]) ;
  1609.     else
  1610.         removeexclude(argv[1]) ;
  1611.     return (OK) ;
  1612. }
  1613.  
  1614. cmrlist(argc, argv)
  1615. int argc ;
  1616. char * argv[] ;
  1617. {
  1618.     FILE *fd ;
  1619.     if (debugcall >= 1)
  1620.     {
  1621.         fprintf(stderr, "CALL: cmrlist\n") ;
  1622.         dodebugargs(argc, argv) ;
  1623.     }
  1624.     if (psvsnlt(MINIMUM_FILE_STAT_REQUIRED))
  1625.     {
  1626.         versiontolow(argv[0],MINIMUM_FILE_STAT_REQUIRED, FALSE) ;
  1627.         return ;
  1628.     }
  1629.     /* are we saving this to a file ? */
  1630.     if (argc == 2)
  1631.     {
  1632.         /* do the listing */
  1633.         psrlist (argv[1], NULL) ;
  1634.     }
  1635.     else
  1636.     {
  1637.         if ((fd = fopen(argv[2], "w")) == NULL)
  1638.         {
  1639.             printf("Error, cant open %s for output\n", argv[2]) ;
  1640.             return (OK) ;
  1641.         }
  1642.         psrlist(argv[1], fd) ;
  1643.         fclose(fd) ;
  1644.     }
  1645.     return (OK) ;
  1646. }
  1647.  
  1648. cmbackup(argc, argv)
  1649. int argc ;
  1650. char * argv[] ;
  1651. {
  1652.     if (debugcall >= 1)
  1653.     {
  1654.         fprintf(stderr, "CALL: cmbackup\n") ;
  1655.         dodebugargs(argc, argv) ;
  1656.     }
  1657.     if (psvsnlt(MINIMUM_FILE_STAT_REQUIRED))
  1658.     {
  1659.         versiontolow(argv[0],MINIMUM_FILE_STAT_REQUIRED, FALSE) ;
  1660.         return ;
  1661.     }
  1662.     /* what are we doing ? */
  1663.     if (strcmp(argv[0] , "ibackup") == 0)
  1664.         psbackup(argv[1], argv[2], TRUE) ;
  1665.     else if (strcmp(argv[0], "backup") == 0)
  1666.         psbackup(argv[1], argv[2], FALSE) ;
  1667.     else if (strcmp(argv[0], "irestore") == 0)
  1668.         psrestore(argv[1], argv[2], TRUE) ;
  1669.     else if (strcmp(argv[0], "restore") == 0)
  1670.         psrestore(argv[1], argv[2], FALSE) ;
  1671.     return (OK) ;
  1672. }
  1673.  
  1674. cmfilechksum(argc, argv)
  1675. int argc ;
  1676. char * argv[] ;
  1677. {
  1678.     if (debugcall >= 1)
  1679.     {
  1680.         fprintf(stderr, "CALL: cmfilechksum\n") ;
  1681.         dodebugargs(argc, argv) ;
  1682.     }
  1683.     if (argc == 1)
  1684.     {
  1685.         /* status enquiry */
  1686.         printf("File transfer checksumming is %s\n", filechksum ? "on" : "off") ;
  1687.         return(OK) ;
  1688.     }
  1689.     if (psvsnlt(MINIMUM_FILE_CHKSUM_REQUIRED))
  1690.     {
  1691.         versiontolow(argv[0],MINIMUM_FILE_CHKSUM_REQUIRED,FALSE);
  1692.         return(OK) ;
  1693.     }
  1694.     if (strcmp(argv[1],"on") == 0)
  1695.     {
  1696.         psfc(TRUE) ; /* get the pslib to turn file checksumming on */
  1697.         if (findvar(VAR_VERBOSE) != NULL)
  1698.             printf("Checksums within file transfers enabled\n") ;
  1699.     }
  1700.     else
  1701.     if (strcmp(argv[1],"off") == 0)
  1702.     {
  1703.         psfc(FALSE) ; /* get the pslib to turn file checksumming off */
  1704.         if (findvar(VAR_VERBOSE) != NULL)
  1705.             printf("Checksums within file transfers enabled\n") ;
  1706.     }
  1707.     else
  1708.         printf("Error, only on or off are valid arguments\n") ;
  1709.     return(OK) ;
  1710. }
  1711.  
  1712. cmcs(argc, argv)
  1713. int argc ;
  1714. char * argv[] ;
  1715. {
  1716.     int  ps ;
  1717.     int cs ;
  1718.     
  1719.     if (debugcall >= 1)
  1720.     {
  1721.         fprintf(stderr, "CALL: cmcs\n") ;
  1722.         dodebugargs(argc, argv) ;
  1723.     }
  1724.     /* are we operating on the sun of the psion ? */
  1725.     ps = TRUE ;
  1726.     if ((argc == 3) && (strcmp(argv[2], "sun") == 0))
  1727.        ps = FALSE ;
  1728.     if (ps)
  1729.     {
  1730.         if (psvsnlt(MINIMUM_FILE_CHECKSUM_REQUIRED))
  1731.         {
  1732.             versiontolow(argv[0], MINIMUM_FILE_CHECKSUM_REQUIRED, FALSE) ;
  1733.             return (OK) ;
  1734.         }
  1735.         pssetpath(argv[1]) ;
  1736.         if (psep())
  1737.         {
  1738.             cs = pscs() ;
  1739.             printf("Checksum is %ld\n", cs) ;
  1740.             return (OK) ;
  1741.         }
  1742.         else
  1743.         {
  1744.             printf("Error, %s does not exist\n", argv[1]) ;
  1745.             return (OK) ;
  1746.         }
  1747.     }
  1748.     else /* we are working on the sun */
  1749.     {
  1750.         cs = sunsum (argv[1]) ;
  1751.         if (cs == BADPARAM)
  1752.         {
  1753.             printf("Error, %s does not exist\n", argv[1]) ;
  1754.             return (OK) ;
  1755.         }
  1756.         else
  1757.         {
  1758.             printf("Checksum is %d\n", cs) ;
  1759.             return (OK) ;
  1760.         }
  1761.     }
  1762. }
  1763.  
  1764. long psgetmodtime() ;
  1765. cminfo(argc, argv)
  1766. int argc ;
  1767. char * argv[] ;
  1768. {
  1769.     int size, rw,atts ;
  1770.     char tmp [100] ;
  1771.     long modtime ;
  1772.     char * timeptr ;
  1773.     if (debugcall >= 1)
  1774.     {
  1775.         fprintf(stderr, "CALL: cminfo\n") ;
  1776.         dodebugargs(argc, argv) ;
  1777.     }
  1778.     if (psvsnlt(MINIMUM_FILE_STAT_REQUIRED))
  1779.     {
  1780.         versiontolow(argv[0],MINIMUM_FILE_STAT_REQUIRED, FALSE) ;
  1781.         return ;
  1782.     }
  1783.  
  1784.     /* set the path */
  1785.     pssetpath(argv[1]) ;
  1786.     rw = psgetrw() ;
  1787.     atts = psgetatts() ;
  1788.     size = psgetfsize() ;
  1789.     modtime = psgetmodtime() ;
  1790.     timeptr = ctime(&modtime) ;
  1791.     /* decode the attributes */
  1792.     tmp[0] = 0 ;
  1793.     if (atts & PSFILEDIR)
  1794.         strcat(tmp, "DIRECTORY ") ;
  1795.     if (atts & PSFILETEXT)
  1796.         strcat(tmp, "TEXT ") ;
  1797.     if (atts & PSFILEFILE)
  1798.         strcat(tmp, "FILE ") ;
  1799.     if (atts & PSFILEHIDDEN)
  1800.         strcat(tmp, "HIDDEN ") ;
  1801.     if (atts & PSFILESYSTEM)
  1802.         strcat(tmp, "SYSTEM ") ;
  1803.     if (atts & PSFILEVOLUME)
  1804.         strcat(tmp, "VOLUMEDIR ") ;
  1805.     
  1806.     printf("Information on %s\n", argv[1]) ;
  1807.     printf("Size %d\n", size) ;
  1808.     printf("Access is %s\n", rw == PSFILERW ? "Read / Write" : "Read only") ;
  1809.     printf("Attributes are %s\n", tmp) ;
  1810.     /* if this is not a file the mod date makes no sense */
  1811.     if (atts & PSFILEFILE)
  1812.         printf("Last modification time is %s\n", timeptr) ;
  1813.     return (OK) ;
  1814. }
  1815.     
  1816. cmsetwriteflag(argc, argv)
  1817. int argc ;
  1818. char * argv[] ;
  1819. {
  1820.     if (debugcall >= 1)
  1821.     {
  1822.         fprintf(stderr, "CALL: cmsetwriteflag\n") ;
  1823.         dodebugargs(argc, argv) ;
  1824.     }
  1825.     if (psvsnlt(MINIMUM_FILE_STAT_REQUIRED))
  1826.     {
  1827.         versiontolow(argv[0],MINIMUM_FILE_STAT_REQUIRED, FALSE) ;
  1828.         return (OK);
  1829.     }
  1830.     pssetpath(argv[1]) ;
  1831.     if (strcmp(argv[0],"setro") == 0)
  1832.     {
  1833.         pssetro() ;
  1834.     }
  1835.     else
  1836.     {
  1837.         pssetrw() ;
  1838.     }
  1839.     return (OK) ;
  1840. }
  1841.  
  1842. cmrcd(argc, argv)
  1843. int argc ;
  1844. char * argv[] ;
  1845. {
  1846.     if (debugcall >= 1)
  1847.     {
  1848.         fprintf(stderr, "CALL: cmrcd\n") ;
  1849.         dodebugargs(argc, argv) ;
  1850.     }
  1851.     if (psvsnlt(MINIMUM_RCD_REQUIRED))
  1852.     {
  1853.         versiontolow(argv[0],MINIMUM_RCD_REQUIRED, FALSE) ;
  1854.         return (OK);
  1855.     }
  1856.     pssetpath(argv[1]) ;
  1857.     if (psrcd() != OK)
  1858.     {
  1859.         printf("ERROR: in rcd to %s remote CWD is unchanged\n", argv[1]) ;
  1860.     }
  1861.     return (OK) ;
  1862. }
  1863.  
  1864.  
  1865. cmlcd(argc, argv)
  1866. int argc ;
  1867. char * argv[] ;
  1868. {
  1869.     if (debugcall >= 1)
  1870.     {
  1871.         fprintf(stderr, "CALL: cmlcd\n") ;
  1872.         dodebugargs(argc, argv) ;
  1873.     }
  1874.     if (chdir(argv[1]))
  1875.     {
  1876.         printf("ERROR: Problem in changing CWD to %s, CWD is unchanged\n", argv[1]) ;
  1877.     }
  1878.     return (OK) ;
  1879. }
  1880.  
  1881. cmlpwd(argc, argv)
  1882. int argc ;
  1883. char * argv[] ;
  1884. {
  1885.     char tmp[1024] ;
  1886.     if (debugcall >= 1)
  1887.     {
  1888.         fprintf(stderr, "CALL: cmlpwd\n") ;
  1889.         dodebugargs(argc, argv) ;
  1890.     }
  1891.     if (getcwd(tmp, 1024) == NULL)
  1892.     {
  1893.         printf("ERROR: cant get pwd\n") ;
  1894.         return (OK) ;
  1895.     }
  1896.     /* print the directory */
  1897.     printf("%s\n", tmp) ;
  1898.     return (OK) ;
  1899. }
  1900.  
  1901. cmrpwd(argc, argv)
  1902. int argc ;
  1903. char * argv[] ;
  1904. {
  1905.     char tmp [1024] ;
  1906.     if (debugcall >= 1)
  1907.     {
  1908.         fprintf(stderr, "CALL: cmrpwd\n") ;
  1909.         dodebugargs(argc, argv) ;
  1910.     }
  1911.     if (psvsnlt(MINIMUM_RPWD_REQUIRED))
  1912.     {
  1913.         versiontolow(argv[0],MINIMUM_RPWD_REQUIRED, FALSE) ;
  1914.         return (OK);
  1915.     }
  1916.     psgetpwd(tmp) ;
  1917.     printf("CWD on psion is %s\n", tmp) ;
  1918.     return (OK) ;
  1919. }
  1920. cmtrans(argc, argv)
  1921. int argc ;
  1922. char * argv[] ;
  1923. {
  1924.     if (debugcall >= 1)
  1925.     {
  1926.         fprintf(stderr, "CALL: cmtrans\n") ;
  1927.         dodebugargs(argc, argv) ;
  1928.     }
  1929.     printf("Transmited blocks, good = %d, bad = %d\n", transgood, transbad) ;
  1930.     printf("Recieved blocks, good = %d, bad = %d\n", recgood, recbad) ;
  1931.     return(OK) ;
  1932. }
  1933. cmtransreset(argc, argv)
  1934. int argc ;
  1935. char * argv[] ;
  1936. {
  1937.     if (debugcall >= 1)
  1938.     {
  1939.         fprintf(stderr, "CALL: cmtransreset\n") ;
  1940.         dodebugargs(argc, argv) ;
  1941.     }
  1942.     transgood = 0 ;
  1943.     transbad = 0 ;
  1944.     recgood = 0 ;
  1945.     recbad = 0 ;
  1946.     if (findvar(VAR_VERBOSE) != NULL)
  1947.         printf("Reset transmited and recieved good / bad block count\n") ;
  1948.     return(OK) ;
  1949. }
  1950. cmftransinfo(argc, argv)
  1951. int argc ;
  1952. char * argv[] ;
  1953. {
  1954.     if (debugcall >= 1)
  1955.     {
  1956.         fprintf(stderr, "CALL: cmftrans\n") ;
  1957.         dodebugargs(argc, argv) ;
  1958.     }
  1959.     printf("File Transmited blocks, good = %d, bad = %d\n", ftransgood, ftransbad) ;
  1960.     printf("File Recieved blocks, good = %d, bad = %d\n", frecgood, frecbad) ;
  1961.     return(OK) ;
  1962. }
  1963. cmftransreset(argc, argv)
  1964. int argc ;
  1965. char * argv[] ;
  1966. {
  1967.     if (debugcall >= 1)
  1968.     {
  1969.         fprintf(stderr, "CALL: cmftransreset\n") ;
  1970.         dodebugargs(argc, argv) ;
  1971.     }
  1972.     ftransgood = 0 ;
  1973.     ftransbad = 0 ;
  1974.     frecgood = 0 ;
  1975.     frecbad = 0 ;
  1976.     if (findvar(VAR_VERBOSE) != NULL)
  1977.         printf("Reset transmited and recieved good / bad block count for files\n") ;
  1978.     return(OK) ;
  1979. }
  1980. #ifdef PDEBUG
  1981. static char pdebugfname [100] = "" ;
  1982. cmdebug(argc, argv)
  1983. int argc ;
  1984. char * argv[] ;
  1985. {
  1986.     int result ;
  1987.     char * dbgfname ;
  1988.     char tmp [200] ;
  1989.     if (debugcall >= 1)
  1990.     {
  1991.         fprintf(stderr, "CALL: cmdebug\n") ;
  1992.         dodebugargs(argc, argv) ;
  1993.     }
  1994.     /* can the suncom prog on the psion support debugging ? */
  1995.     if (psvsnlt(MINIMUM_DEBUG_REQUIRED))
  1996.     {
  1997.         versiontolow(argv[0], MINIMUM_DEBUG_REQUIRED, FALSE) ;
  1998.         return(OK) ;
  1999.     }
  2000.     /* what versionn of the command (turn on or off)*/
  2001.     if (strcmp(argv[1], "off") == 0)
  2002.     {
  2003.         if (strlen(pdebugfname) == 0)
  2004.         {
  2005.             printf("Psion debugging is not enabled at this time and therefore cant be turned off\n");
  2006.             return(OK) ;
  2007.         }
  2008.         result = psenddebug() ;
  2009.         if (result == BADCMD)
  2010.             printf("Your version of suncom has been compiled without debugging support\ndebugging functions are not available to you\n") ;
  2011.         if (result == BAD)
  2012.             printf("There was a problem in closing the log file on the psion\n") ;
  2013.         /* allow the file to be used in the debug list now its closed */
  2014.         sprintf(tmp, "delexcl %s", pdebugfname) ;
  2015.         cmdintr(tmp) ;
  2016.         pdebugfname[0] = '\0' ;
  2017.         return(OK) ;
  2018.     }
  2019.     else /* turn the debugging on */
  2020.     {
  2021.         if ((int)strlen(pdebugfname) >= (int)1)
  2022.         {
  2023.             printf("Psion debugging is already active. it must be shutdown before reissuing this command\n") ;
  2024.             return(OK);
  2025.         }
  2026.         /* are we using the default file or a user specified file ? */
  2027.         if (argc == 3) /* user specified */
  2028.             dbgfname = argv[2] ;
  2029.         else /* system specified */
  2030.             dbgfname = PSIONLOG ;
  2031.         result = psstartdebug(dbgfname) ;
  2032.         strcpy(pdebugfname, dbgfname) ;
  2033.         /* stop the backup routines trying to access the file */
  2034.         sprintf(tmp, "addexcl %s", pdebugfname) ;
  2035.         cmdintr(tmp) ;
  2036.         if (result == OK)
  2037.             return (OK) ;
  2038.         else if (result == BADCMD)
  2039.         {
  2040.             printf("Your version of suncom has been compiled without debugging support\ndebugging functions are not available to you\n") ;
  2041.             return(OK) ;
  2042.         }
  2043.         else
  2044.         /* result was BADOPEN */
  2045.         printf("ERROR: Error in opening the log file on the psion\n") ;
  2046.         if (findvar(VAR_HELPFULL) != NULL)
  2047.         {
  2048.             printf("ERROR: This may be due to:\n") ;
  2049.             printf("1/ The file exists but is unable to be deleted (posibly in use)\n") ;
  2050.             printf("2/ The file exists but is non writable (posibly ROM SSD or read only flag set\n") ;
  2051.             printf("3/ The pathname cannot be created, check that all directories exist\n") ;
  2052.         }
  2053.         return(OK) ;
  2054.     }
  2055. }
  2056. /* end of code commented out under PDEBUG #define */
  2057. #endif
  2058. /* process functions */
  2059. cmproclist(argc, argv)
  2060. int argc ;
  2061. char * argv[] ;
  2062. {
  2063.     FILE *fd ;
  2064.     if (debugcall >= 1)
  2065.     {
  2066.         fprintf(stderr, "CALL: cmproclist\n") ;
  2067.         dodebugargs(argc, argv) ;
  2068.     }
  2069.     /* can the suncom prog on the psion support debugging ? */
  2070.     if (psvsnlt(MINIMUM_PROCESS_REQUIRED))
  2071.     {
  2072.         versiontolow(argv[0], MINIMUM_PROCESS_REQUIRED, FALSE) ;
  2073.         return(OK) ;
  2074.     }
  2075.     /* no arguments */
  2076.     if (argc == 1)
  2077.     {
  2078.         return(pspl(NULL, "*")) ;
  2079.     }
  2080.     /* just a pattern */
  2081.     if (argc == 2)
  2082.     {
  2083.         return(pspl(NULL, argv[1])) ;
  2084.     }
  2085.     /* pattern and filename */
  2086.     if ((fd = fopen(argv[2], "w")) == NULL)
  2087.     {
  2088.         printf("ERROR: Cant open %s to write the process listing\n", argv[2]) ;
  2089.         return(OK) ;
  2090.     }
  2091.     return(pspl(fd, argv[1])) ;
  2092. }
  2093.  
  2094. cmprocprot(argc, argv)
  2095. int argc ;
  2096. char * argv[] ;
  2097. {
  2098.     char ch[10] ;
  2099.     if (debugcall >= 1)
  2100.     {
  2101.         fprintf(stderr, "CALL: cmprocprot\n") ;
  2102.         dodebugargs(argc, argv) ;
  2103.     }
  2104.     /* can the suncom prog on the psion support debugging ? */
  2105.     if (psvsnlt(MINIMUM_PROCESS_REQUIRED))
  2106.     {
  2107.         versiontolow(argv[0], MINIMUM_DEBUG_REQUIRED, FALSE) ;
  2108.         return(OK) ;
  2109.     }
  2110.     /* if no args turn it on */
  2111.     if (argc == 1)
  2112.     {
  2113.         return(pspo(TRUE)) ;
  2114.     }
  2115.     /* if argv[1] == off turn it off (BAD MOVE !) */
  2116.     if ((argc == 2) && (strcmp(argv[1], "off") == 0))
  2117.     {
  2118.         /* has the user agreed we can do this with no double check ? */
  2119.         if (findvar(VAR_PROCPROC_NO_CHECK) == NULL)
  2120.         {
  2121.             printf("Are you sure you want to turn of process kill protection ?\n") ;
  2122.             fgets(ch, sizeof(ch),stdin);
  2123.             if ((ch[0] == 'y') || (ch[0] == 'Y'))
  2124.                 return(pspo(FALSE)) ;
  2125.             else
  2126.                 return(OK) ;
  2127.         }
  2128.         else 
  2129.         {
  2130.             /* they have agreed to do this dam silly thing without 
  2131.                  a check (WHAT A FOOL) */
  2132.             return(pspo(FALSE)) ;
  2133.         }
  2134.     }
  2135.     /* they have not explicitly requested an off so TURN IT ON */
  2136.     return(pspo(TRUE)) ;
  2137. }
  2138.  
  2139. cmprockill(argc, argv)
  2140. int argc ;
  2141. char * argv[] ;
  2142. {
  2143.     char ch[10] ;
  2144.     if (debugcall >= 1)
  2145.     {
  2146.         fprintf(stderr, "CALL: cmprockill\n") ;
  2147.         dodebugargs(argc, argv) ;
  2148.     }
  2149.     /* can the suncom prog on the psion support debugging ? */
  2150.     if (psvsnlt(MINIMUM_PROCESS_REQUIRED))
  2151.     {
  2152.         versiontolow(argv[0], MINIMUM_PROCESS_REQUIRED, FALSE) ;
  2153.         return(OK) ;
  2154.     }
  2155.     /* do they REALY want to kill processes ? */
  2156.     if (findvar(VAR_PROCKILL_NO_CHECK) == NULL)
  2157.     {
  2158.         printf("Are you sure you want to kill processes with the pattern %s ?(Any unsaved work in the process WILL BE LOST !)\n", argv[1]) ;
  2159.         fgets(ch, sizeof(ch),stdin);
  2160.         if ((ch[0] == 'y') || (ch[0] == 'Y'))
  2161.             return(pspk(argv[1])) ;
  2162.         else
  2163.                 return(OK) ;
  2164.         }
  2165.     else 
  2166.     {
  2167.         /* they have agreed to do this dam silly thing without 
  2168.              a check (WHAT A FOOL) */
  2169.         return(pspk(argv[1])) ;
  2170.     }
  2171. }
  2172. cmprocshut(argc, argv)
  2173. int argc ;
  2174. char * argv[] ;
  2175. {
  2176.     char ch[10] ;
  2177.     if (debugcall >= 1)
  2178.     {
  2179.         fprintf(stderr, "CALL: cmprockill\n") ;
  2180.         dodebugargs(argc, argv) ;
  2181.     }
  2182.     /* can the suncom prog on the psion support debugging ? */
  2183.     if (psvsnlt(MINIMUM_PROCESS_SHUTDOWN_REQUIRED))
  2184.     {
  2185.         versiontolow(argv[0], MINIMUM_PROCESS_SHUTDOWN_REQUIRED, FALSE) ;
  2186.         return(OK) ;
  2187.     }
  2188.     
  2189.     return(psps(argv[1])) ;
  2190.     
  2191. }
  2192.  
  2193. lowerpath(string)
  2194. char * string ;
  2195. {
  2196.     int i, len;
  2197.     len = strlen(string) ;
  2198.     for (i = 0 ; i < len; i ++)
  2199.         string[i] = tolower(string[i]) ;
  2200. }
  2201. versiontolow(fn,vsn,fatal)
  2202. char * fn, *vsn ;
  2203. int fatal;
  2204. {
  2205.     printf("Function %s requires version %s of suncom, you have version %s\n",fn, vsn, psversion()) ;    
  2206.     printf("Please contact Tim Graves at Sun Microsystems (tim.graves@uk.sun.com)\n") ;
  2207.     printf("for a later release of this software\n");
  2208.     if (fatal)
  2209.     {
  2210.         printf("THIS IS A FATAL INCOMPATIBILITY, program exiting\n") ;
  2211.         psdc() ;
  2212.         return ;
  2213.     }
  2214.     else
  2215.     {
  2216.         printf("This is not a fatal problem, other functions may still work\n") ;
  2217.     }
  2218. }
  2219.