home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / pocketbk / comms / x_sun_psio / code / pslib.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-21  |  36.1 KB  |  1,811 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 <ctype.h>
  15. #include <sys/termios.h>
  16. #include <fcntl.h>
  17. #include <string.h>
  18. #include "psion.h"
  19. #define MAXSEND 200
  20. #define DEFVSNSTR "2.3"
  21.  
  22. static char vsn[]= "@(#) pslib.c 3.17@(#)" ;
  23. char pspath[255] = "";
  24. char pspart[10] = "" ;
  25. char psdir [255] = "";
  26. char psfname[30] = "";
  27. int pspathset ;
  28. int tmode ;
  29. int transct ;
  30. int debuglink = FALSE ;
  31. extern int debugcall ;
  32. extern int logfile ;
  33. extern int dovsnchk ;
  34. char version[100] ="X" ;
  35. /* the following are for counting good and bad blocks on 
  36.    transmision and recieve*/
  37. int transgood = 0;
  38. int transbad = 0 ;
  39. int recgood = 0 ;
  40. int recbad = 0;
  41. /* the following are for counting good and bad blocks on 
  42.    transmision and recieve*/
  43. int ftransgood = 0;
  44. int ftransbad = 0 ;
  45. int frecgood = 0 ;
  46. int frecbad = 0;
  47. /* used to indicate file transfers with checksums */
  48. int filechksum = FALSE ;
  49. int devid;
  50. struct termios initial, modified ;
  51. #ifndef SVR4
  52. char dehex() ;
  53. int idehex() ;
  54. #else
  55. char dehex(char *) ;
  56. int idehex(char *) ;
  57. #endif
  58.  
  59. psisset(qn)
  60. int qn ;
  61. {
  62.     if (debugcall >= 3)
  63.     {
  64.         fprintf(stderr, "CALL: psisset (qn = %d)\n", qn) ;
  65.         fflush(stderr) ;
  66.     }
  67.     if (qn == PATH)
  68.         return(pspathset) ;
  69.     else
  70.         return (BADPARAM) ;
  71. }
  72.  
  73. pstrans()
  74. {
  75.     if (debugcall >= 3)
  76.     {
  77.         fprintf(stderr, "CALL: pstrans()\n") ;
  78.         fflush(stderr) ;
  79.     }
  80.     return(transct) ;
  81. }
  82.  
  83. psinit(restart, devname)
  84. int restart ;
  85. char * devname ;
  86. {
  87.    if (debugcall >= 3)
  88.    {
  89.     fprintf(stderr, "CALL: psinit (restart = %d, devname = %s)\n", restart, devname) ;
  90.     fflush(stderr) ;
  91.    }
  92.    devid = 0 ;
  93.    tmode = BINARY ;
  94.    psinitlink(devname) ;
  95.    /* is we are doing a restart we send the online cmd by hand
  96.       WITHOUT waiting for any fancy XCMD> prompts to come back
  97.       to us */
  98.    if (restart)
  99.     psrestart() ;
  100.    else
  101.        psreply("XONLINE") ;
  102.    psbinary() ;
  103. }
  104.  
  105. psrestart()
  106. {
  107.     char length[5] ;
  108.  
  109.     if (debugcall >= 1 )
  110.     {
  111.         fprintf(stderr, "CALL: psrestart()\n") ;
  112.         fflush(stderr) ;
  113.     }
  114.     /* cheat the system for the restart mode only. to have got here 
  115.        we know that the link opened correctley */
  116.     /* we are not looking for the sync char so call putline1 directly and
  117.        tell it not to sync up (the > will have been losk somewhere in 
  118.        the previous psion process */
  119.     psputline1("ol",FALSE) ;
  120.     psreply("XONLINE") ;
  121.     pspath[0] = '\0' ;
  122.     pssp("m:") ;
  123.     
  124. }
  125.  
  126. psinitlink(devstr) 
  127. char * devstr ;
  128. {
  129.     if (debugcall >= 3)
  130.     {
  131.         fprintf(stderr, "CALL: psinitlink (devstr = %s)\n", devstr) ;
  132.         fflush(stderr) ;
  133.     }
  134.     if (strlen(devstr) == 0)
  135.     {
  136.         if ((devid = open(DEVFILE, O_RDWR , 0)) == -1)
  137.             pserror ("Error in opening device\n") ;
  138.     }
  139.     else
  140.     {
  141.         if ((devid = open(devstr, O_RDWR, 0)) == -1)
  142.             pserror ("Error in openint device\n") ;
  143.     }
  144.  
  145.     /* we need to remove the echo as it confuses the psion (tremendously!) */
  146.     /* first get the current structure for storage and modification*/
  147.     ioctl(devid, TCGETS, &initial);
  148.     ioctl(devid, TCGETS, &modified);
  149.     /* remove the echo line */
  150.     modified.c_lflag = modified.c_lflag & ~ECHO ;
  151.     /* stop it from doing any flay input processing */
  152.     modified.c_lflag = modified.c_lflag & ~IEXTEN ;
  153.     /* setup the input and output speeds */
  154.     modified.c_cflag = B9600 | CS8 | CREAD | ( B9600 << IBSHIFT ) ;
  155.     /* remove incomming parity checks */
  156.     modified.c_iflag = modified.c_iflag & ~INPCK ;
  157.     /* remove CR on input, make life a bit easier on the input routing coding ! */
  158.     modified.c_iflag = modified.c_iflag | IGNCR ; 
  159.     /* strip down to 7 characters */
  160.     modified.c_iflag = modified.c_iflag | ISTRIP ;
  161.     /* Install xon/xoff flow control */
  162.     /*modified.c_iflag = modified.c_iflag | IXON | IXOFF ;*/
  163.     /* remove flow control */
  164.     modified.c_iflag = modified.c_iflag & ~IXON ;
  165.     modified.c_iflag = modified.c_iflag & ~IXOFF ;
  166.     modified.c_cflag = modified.c_cflag & ~CRTSCTS ;
  167.     /* remove cannonical processing, this is more cpu / interupt
  168.        intensive but does enable the new checksumming protocol
  169.        to work */
  170.     /* modified.c_lflag = modified.c_lflag & ~ICANON ; */
  171.     /* ensure that on output we only send newline, not CRNL */
  172.     modified.c_oflag = modified.c_oflag | ONLRET ;
  173.     /* and just to make sure remove the output processing facility */
  174.     modified.c_oflag = modified.c_oflag & ~OPOST ;
  175.     /* set the new params */
  176.     ioctl(devid, TCSETS, &modified) ;
  177.  
  178. }
  179.  
  180. /* reset the terminal device and close the link down */
  181. psshutdown(ret)
  182. int ret ;
  183. {
  184.     if (debugcall >= 3)
  185.     {
  186.         fprintf(stderr, "CALL psshutdown (ret = %d)\n", ret) ;
  187.         fflush(stderr) ;
  188.     }
  189.     /* we need to reset the terminal flags to their initial state ! */
  190.     ioctl (devid, TCSETS, &initial) ;
  191.  
  192.     if (devid != -1)
  193.         close (devid) ;
  194.         
  195.         
  196.     
  197.         exit(ret) ;
  198. }
  199.  
  200. /* send a command to the psion */
  201. pscommand (msg)
  202. char * msg ;
  203. {
  204.     if (debugcall >= 3)
  205.     {
  206.         fprintf(stderr, "CALL: pscommand (msg = %s)\n", msg) ;
  207.         fflush(stderr) ;
  208.     }
  209.     psputline(msg) ;
  210. }
  211. psputline(str)
  212. char * str ;
  213. {
  214.     if (debugcall >= 4)
  215.     {
  216.         fprintf(stderr, "CALL: psputline (str = :%s:)\n", str) ;
  217.         fflush(stderr) ;
  218.     }
  219.     psputline1(str, TRUE) ;
  220. }    
  221. psputline1(str, getgt)
  222. char * str;
  223. int getgt ;
  224. {
  225.     int len, chksum ;
  226.     char msg [1000] ;
  227.     char tmp [10] ;
  228.     char resp[10] ;
  229.     if (debugcall >= 4)
  230.     {
  231.         fprintf(stderr, "CALL: psputline1 (str = :%s:)\n", str) ;
  232.         fflush(stderr) ;
  233.     }
  234.     /* if getgt then hunt for the > otherwise skip this bit */
  235.     if (getgt == TRUE)
  236.     {
  237.         /* wait for the psion to send > to indicate it's ready */
  238.         tmp[0] = ' ' ;
  239.         while (tmp[0] != '>')
  240.         {
  241.             psreadstr(tmp, 10) ;
  242.             if (debuglink)
  243.                 printf("putline: got %c as sync char\n", tmp[0]) ;
  244.             if (logfile)
  245.             {
  246.                 fprintf(stderr, "putline: got %c as sync char\n", tmp[0]) ;
  247.                 fflush(stderr) ;
  248.             }
  249.         }
  250.     }
  251.     /* get the length */
  252.     len = strlen(str) ;
  253.     /* calculate the checksum */
  254.     chksum = 0 ;
  255.     dochksum(&chksum, str, len) ;
  256.     /* compose the output line */
  257.     sprintf(msg, "$%2.2X%s$%2.2X", len, str, chksum) ;
  258.     /* send the line across */
  259.     write (devid, msg, strlen(msg)) ;
  260.     /* do the debugging stuff */
  261.     if (debuglink)
  262.         printf("Sent :%s:\n", msg) ;
  263.     if (logfile)
  264.         fprintf(stderr, "> %s\n", msg) ;
  265.     /* wait for the response */
  266.     resp[0] = 'R' ;
  267.     while (resp[0] != 'O')
  268.     {
  269.         /* get the response */
  270.         psreadstr(resp,10) ;
  271.         if (resp[0] != 'O')
  272.         {
  273.             /* we need to resend here */
  274.             write(devid, msg, strlen(msg)) ;
  275.             if (debuglink)
  276.                 printf("putline: Resent last block (%s)\n", msg) ;
  277.             if (logfile)
  278.             {
  279.                 fprintf(stderr, "putline: Resent last block (%s)\n", msg) ;
  280.                 fflush(stderr) ;
  281.             }
  282.             transbad ++ ;
  283.         }
  284.     }
  285.     transgood ++ ;
  286.     if (debuglink)
  287.         printf("OK transmited (%s)\n", msg) ;
  288.     if (logfile)
  289.     {
  290.         fprintf(stderr, "OK transmited (%s)\n", msg) ;
  291.         fflush(stderr) ;
  292.     }
  293. }
  294.  
  295.  
  296. /* get a line of text from the psion, remove any newlines etc */
  297. psreadstr(string, count)
  298. char * string ;
  299. int count ;
  300. {
  301.     int ctr ;
  302.     if (debugcall >= 3)
  303.     {
  304.         fprintf(stderr, "CALL: psreadstr (string OMITED, count = %d)\n",  count) ;
  305.         fflush(stderr) ;
  306.     }
  307.     ctr = 0 ;
  308.     ctr = read(devid, string, count) ;
  309.     string[ctr -1] = '\0' ;
  310.     if (string[ctr - 1] == '\n') ;
  311.        string[ctr - 1] == '\0' ; 
  312. }
  313.  
  314. psresponse(str)
  315. char * str ;
  316. {
  317.     int len, chksum, pchksum ;
  318.     char msg[1000] ;
  319.     char tmp[1000] ;
  320.     char lenstr[4] ;
  321.     char chkstr[4] ;
  322.     if (debugcall >= 3)
  323.     {
  324.         fprintf(stderr, "CALL psresponse (OMITED)\n") ;
  325.         fflush (stderr) ;
  326.     }
  327.     /* init the checksums to be different */
  328.     chksum = 1 ;
  329.     pchksum = 0 ;
  330.     /* repeat untill the checksums are the same */
  331.     while (pchksum != chksum) 
  332.     {
  333.         /* get the string */
  334.         psreadstr(tmp, 1000) ;
  335.         
  336.         /* get the first 3 bytes, these are the length of the data */
  337.         strncpy(lenstr, tmp, 3) ;
  338.         /* as strncpy may not terminate the string */
  339.         lenstr[3] = '\0' ;
  340.         /* convert the length data. NOTE the psion does not zero pad
  341.            so we have to do this our selves */
  342.         if (lenstr[1] == ' ')
  343.             lenstr[1] = '0' ;
  344.         if (lenstr[2] == ' ')
  345.             lenstr[2] == '0' ;
  346.         len = idehex(lenstr+1) ;
  347.         /* read the main data */
  348.         strncpy(msg, tmp+3, len) ;
  349.         /* as strncpy may not terminate the string */
  350.         msg[len] = '\0' ;
  351.         /* read the 3 bytes of chksum data */
  352.         strncpy(chkstr, tmp+3+len, 3) ;
  353.         /* as strncpy may not terminate the string */
  354.         chkstr[3] = '\0' ;
  355.         /* convert the checksum again note the zero padding problem*/
  356.         if (chkstr[1] == ' ') 
  357.             chkstr[1] = '0' ;
  358.         if (chkstr[2] == ' ')
  359.             chkstr[2] = '0' ;
  360.         pchksum =  idehex(chkstr+1) ;
  361.         /* calculate the real chksum */
  362.         chksum = 0 ;
  363.         dochksum(&chksum, msg, len) ;
  364.         /* if the chksums are the same send 'O' otherwise send R */
  365.         if (chksum == pchksum)
  366.         {
  367.             write(devid, "O", 1) ;
  368.             if (debuglink)
  369.                 printf("Recieved datablock OK (lenstr = %s, msg = :%s: chkstr = %s)\n", lenstr, msg, chkstr) ;
  370.             if (logfile)
  371.             {
  372.                 fprintf(stderr, "Recieved datablock OK (lenstr = %s, msg = :%s:, chkstr = %s)\n", lenstr, msg, chkstr) ;
  373.                 fflush(stderr) ;
  374.             }
  375.         }
  376.         else
  377.         {
  378.             recbad ++ ;
  379.             write(devid, "R", 1) ;
  380.             if (debuglink)
  381.                 printf("Error on recieving data block (lenstr = %s, msg = :%s: chkstr = %s)\n", lenstr, msg, chkstr) ;
  382.             if (logfile)
  383.             {
  384.                 fprintf(stderr, "Error on recieving data block (lenstr = %s, msg = :%s: chkstr = %s)\n", lenstr, msg, chkstr) ;
  385.                 fflush(stderr) ;
  386.             }
  387.         }
  388.     }
  389.     recgood ++ ;
  390.     /* copy the string */
  391.     strcpy(str, msg) ;
  392.     if (debuglink)
  393.         printf("Len %d, Got:%s:\n", strlen(str), str) ;
  394.     if (logfile)
  395.     {
  396.         fprintf(stderr, "< %s\n", str) ;
  397.         fflush (stderr) ;
  398.     }
  399. }
  400.  
  401. /* send a file to the psion, remove the file if it exists. if we have been 
  402.    passed a null string use the file name we are sending as the local files name
  403.    */
  404. pssendfile(fname)
  405. char * fname ;
  406. {
  407.     if (debugcall >= 3)
  408.     {
  409.         fprintf(stderr, "CALL: pssendfile (fname = %s)\n", fname) ;
  410.         fflush(stderr) ;
  411.     }
  412.     /* then parse pspath to extract the filename component */
  413.     psgetfname() ;
  414.     /* first remove the target file if required */
  415.     psclearfile() ;
  416.     if ( strlen(fname) == 0)
  417.     {
  418.         return(psgf(psfname)) ;
  419.     }
  420.     else
  421.         return(psgf(fname)) ;
  422.     /* the above command is misnamed as if refers to getting a file on the psion ! */
  423. }
  424.  
  425.     
  426. /* we have an error, print the message ans shutdown */
  427. pserror(str)
  428. char * str ;
  429. {
  430.     if (debugcall >= 3)
  431.     {
  432.         fprintf(stderr, "CALL: pserror (str = %s)\n", str) ;
  433.         fflush(stderr) ;
  434.     }
  435.     fprintf(stderr, "%s\n", str) ;
  436.     psshutdown(6) ;
  437. }
  438.  
  439. psgf(fname)
  440. char * fname ;
  441. {
  442.     if (debugcall >= 3)
  443.     {
  444.         fprintf(stderr, "CALL: psgf (fname = %s)\n", fname) ;
  445.         fflush(stderr) ;
  446.     }
  447.     if (tmode == ASCII)
  448.     {
  449.         printf("ASCII mode is nolonger supported\n");
  450.         return(BAD) ;
  451.     }
  452.     else if (tmode == XMDM)
  453.         return(psgfx(fname)) ;
  454.     else
  455.         return(psgfb(fname)) ;
  456. }
  457.  
  458. /* send the file named in the parameter to the psion. this assumes that the 
  459.    file does not exist on the psion and that the remote path is correct
  460.    then send a hex file */
  461.  
  462. int psgfb(fname)
  463. char * fname ;
  464. {
  465.     FILE *fd ;
  466.     char sendstr [255], tmpstr [10], binbuff[255], tmpbuff[255];
  467.     char ch ;
  468.     int ctr ;
  469.     int binctr ;
  470.     int binsum ;
  471.     int ln ;
  472.     int fileid ;
  473.     int i ;
  474.  
  475.     if (debugcall >= 3)
  476.     {
  477.         fprintf(stderr, "CALL: psgfb(fname = %s)\n", fname) ;
  478.         fflush(stderr) ;
  479.     }
  480.     transct = 0 ;
  481.  
  482.     if ((fileid = open(fname, O_RDONLY , 0)) == -1)
  483.     {
  484.        printf("Error in puting %s, not found on local machine\n", fname) ;
  485.        return(BAD) ;
  486.     }
  487.  
  488.     pscommand("gf") ;
  489.  
  490.     psreply("XSTARTGET") ;
  491.     if (psquery("XBADOPEN") == TRUE)
  492.     {
  493.         if (findvar(VAR_HELPFULL) != NULL)
  494.         {
  495.             printf("HELP: Error in getting file from the psion, cannot open it.\n") ; 
  496.             printf("HELP: Either the disk is full, there are to many files or the directory\n") ;
  497.             printf("HELP: does not exist\n") ;
  498.         }
  499.            return (BAD);
  500.      }
  501.  
  502.     ctr = 0 ;
  503.     ln = 0 ;
  504.  
  505.     while ((ln = read(fileid, binbuff, MAXSEND / 2)) > 0)
  506.     {
  507.         tmpbuff[0] = '\0' ; /* init the output string */
  508.         for (i = 0 ; i < ln ; i ++ )
  509.         {
  510.             pstoas(binbuff[i], tmpstr) ; /* convert the byte and add it to the string */
  511.             strcat(tmpbuff, tmpstr) ;
  512.         }
  513.         /* are we working with file transfer level binary 
  514.            checksumming turned on ? if so do stuff */
  515.         if (filechksum == TRUE)
  516.         {
  517.             binsum = 0 ;
  518.             dochksum(&binsum, binbuff, ln) ;
  519.             /* insert the checksum into the data string */
  520.             sprintf(sendstr, "%2.2X%s", binsum,tmpbuff) ;
  521.         }
  522.         else
  523.         {
  524.             /* no checksumming but we need to copy the string over */
  525.             sprintf(sendstr,"%s", tmpbuff) ;
  526.         }
  527.         /* we now have the output stream, lets send it */
  528.            psputline(sendstr) ;
  529.            /* if we are using file transfer level binary checksumming lets make sure it all worked OK */
  530.            if (filechksum == TRUE) 
  531.            {
  532.                /* init the response buffer */
  533.                strcpy(tmpbuff, "XB") ;
  534.                while (strcmp(tmpbuff, "XG") != 0)
  535.                {
  536.                    /* get the response */
  537.                    psresponse(tmpbuff) ;
  538.                    if (strcmp(tmpbuff, "XG") != 0)
  539.                    {
  540.                        /* we need to resend */
  541.                        psputline(sendstr) ;
  542.                        if (debuglink)
  543.                            printf("putfile: Resent last block (%s)\n", sendstr) ;    
  544.                        if (logfile)
  545.                        {
  546.                            fprintf(stderr, "putfile: Resent last block (%s)\n", sendstr) ;
  547.                            fflush(stderr) ;
  548.                        }
  549.                        /* increment the bad count */
  550.                        ftransbad ++ ;
  551.                    }
  552.                }
  553.                /* good block transfer, increment the count */
  554.                ftransgood ++ ;
  555.            }
  556.            ctr = 0 ;
  557.         transct += ln ; /* increment the number of bytes sent */
  558.     }
  559.  
  560.     psputline("XE") ;
  561.     psreply("XENDGET") ;
  562.     close(fileid) ;
  563.     return(OK) ;
  564. }
  565.  
  566. pstoas(ch, str) 
  567. char ch ;
  568. char * str ;
  569. {
  570.     int msn, lsn ;
  571.     int tmp ;
  572.     if (debugcall >= 6)
  573.     {
  574.         fprintf(stderr, "CALL: pstoas (OMITED)\n") ;
  575.         fflush(stderr) ;
  576.     }
  577.     tmp = ch & 0xFF ;
  578.     msn = ((int) tmp) / 16 ;
  579.     lsn = (int) tmp - (msn * 16) ;
  580.     str[0] = 'A' + msn ;
  581.     str[1] = 'A' + lsn ;
  582.     str[2] = '\0' ;
  583. }
  584.  
  585. psrecfile(fname)
  586. char * fname ;
  587. {
  588.     /* parse the name to get the filename component */
  589.     /* if the file exists remotley */
  590.     if (debugcall >= 3)
  591.     {
  592.         fprintf(stderr, "CALL: psrecfile (fname = %s)\n", fname) ;
  593.         fflush(stderr) ;
  594.     }
  595.     if (psep())
  596.     {
  597.         if (strlen(fname) == 0)
  598.         {
  599.             psgetfname() ;
  600.             return(pspf(psfname)) ;
  601.         }
  602.         else
  603.             return(pspf(fname)) ;
  604.     }
  605. }
  606.  
  607. /* call the appropriate transfer method */
  608. int pspf(fname)
  609. char * fname ;
  610. {
  611.     if (debugcall >= 3)
  612.     {
  613.         fprintf(stderr, "CALL: pspf (fname = %s)\n", fname) ;
  614.         fflush(stderr) ;
  615.     }
  616.     if (tmode == ASCII)
  617.     {
  618.         printf("ASCII mode is nolonger supported\n") ;
  619.         return(BAD) ;
  620.     }
  621.     else if (tmode == XMDM)
  622.         return(pspfx(fname)) ;
  623.     else
  624.         return(pspfb(fname)) ;
  625. }
  626.  
  627. int pspfb(fname)
  628. char * fname ;
  629. {
  630.     FILE *fd ;
  631.     char recstr [255], tmpstr [10], binbuff[255] ;
  632.     char ch, dehex() ;
  633.     int fileid, ctr, len, binctr ;
  634.     int pcs, scs ;
  635.     if (debugcall >= 3)
  636.     {
  637.         fprintf(stderr, "CALL: pspfb (fname = %s)\n", fname) ;
  638.         fflush(stderr) ;
  639.     }
  640.  
  641.     transct = 0 ;
  642.  
  643.     if ((fileid = open(fname, O_WRONLY |O_CREAT, 420)) == -1)
  644.     {
  645.        printf("ERROR: Cant open file (%s) to recieve the data\n", fname) ;
  646.        return (BAD);
  647.     }
  648.  
  649.     pscommand("pf") ;
  650.  
  651.     psreply("XSTARTPUT") ;
  652.     if (psquery("XBADOPEN"))
  653.     {
  654.         if (findvar(VAR_HELPFULL) != NULL)
  655.             printf("Error in put, cannot open the file on the psion\n") ;
  656.         return (BAD) ;
  657.     }
  658.  
  659.     psresponse(recstr) ;
  660.     while (strcmp(recstr, "XE") != 0)
  661.     {
  662.         /* if we are file level checksumming the flow control is somewhat different */
  663.         if (filechksum == TRUE)
  664.         {
  665.             pcs = 0 ;
  666.             scs = 1 ;
  667.             while (pcs != scs)
  668.             {
  669.                 ctr = 0 ;
  670.                 /* extract the chksum */
  671.                 /* note, the psion does not pad the first space if it is zero so */
  672.                 if (recstr[ctr] == ' ')
  673.                     recstr[ctr] = '0' ;
  674.                 pcs = idehex(recstr) ;
  675.                 ctr += 2 ; /* skip over the checksum and un munge the line as normal */
  676.                 binctr = 0 ;
  677.                 len = strlen(recstr) ;
  678.                 while ( ctr <= (len - 2))
  679.                 {
  680.                     binbuff[binctr] = dehex(recstr + ctr) ; /* get the char */
  681.                     ctr += 2 ; /* increment the hex counter */
  682.                     binctr ++ ; /* inc the binary counter */
  683.                 }
  684.                 /* now calculate the chksum on the decoded binary string */
  685.                 scs = 0 ;
  686.                 dochksum(&scs,binbuff,binctr) ;
  687.                 /* if they agree just acknowledge, write the log entries and carry on */
  688.                 if (pcs == scs)
  689.                 {
  690.                     psputline("G") ;
  691.                     if (debuglink)
  692.                         printf("Recieved file datablock OK (len = %d, msg = :%s: chk = %2.2X)\n", len, recstr +2 , pcs) ;
  693.                     if (logfile)
  694.                     {
  695.                         fprintf(stderr,"Recieved file datablock OK (len = %d, msg = :%s: chk = %2.2X)\n", len, recstr +2 , pcs) ;
  696.                         fflush(stderr) ;
  697.                     }
  698.                 }
  699.                 else
  700.                 {
  701.                     /* increment the bad counter */
  702.                     frecbad ++ ;
  703.                     /* request a resend */
  704.                     psputline("B") ;
  705.                     /* do the log file stuff */
  706.                     if (debuglink)
  707.                         printf("Error Recieving file datablock (len = %d, msg = :%s: chk = %2.2X)\n", len, recstr +2 , pcs) ;
  708.                     if (logfile)
  709.                     {
  710.                         fprintf(stderr,"Error Recieving file datablock (len = %d, msg = :%s: chk = %2.2X)\n", len, recstr +2 , pcs) ;
  711.                         fflush(stderr) ;
  712.                     }
  713.                     /* get the resent line */
  714.                     psresponse(recstr) ;
  715.                 }
  716.             }
  717.             write(fileid, binbuff, binctr) ;
  718.             transct += binctr; /* increment the transfered counter by the number of bytes written */
  719.             /* increment the good block count */
  720.             frecgood ++ ;
  721.         }
  722.         else /* no file level check summing */
  723.         {
  724.             ctr = 0 ;
  725.             binctr = 0 ;
  726.             len = strlen(recstr) ;
  727.             while ( ctr <= (len - 2))
  728.             {
  729.             binbuff[binctr] = dehex(recstr + ctr) ; /* get the char */
  730.                 ctr += 2 ; /* increment the hex counter */
  731.                 binctr ++ ; /* inc the binary counter */
  732.             }
  733.             write(fileid, binbuff, binctr) ;
  734.             transct += binctr; /* increment the transfered counter by the number of bytes written */
  735.         }
  736.         /* get the next block */
  737.         psresponse(recstr) ;
  738.     }
  739.  
  740.     psquery("XENDPUT") ;
  741.     close(fileid) ;
  742.     return(OK) ;
  743.  
  744. }
  745.  
  746. int idehex (str)
  747. char * str ;
  748. {
  749.    char ch ;
  750.    int tmp ;
  751.    char tmpstr[6] ;
  752.  
  753.    if (debugcall >= 6)
  754.    {
  755.     fprintf(stderr, "CALL: idehex (OMITED)\n") ;
  756.     fflush(stderr) ;
  757.    }
  758.    tmpstr[0] = '0' ;
  759.    tmpstr[1] = 'x' ;
  760.    tmpstr[2] = str[0] ;
  761.    tmpstr[3] = str[1] ;
  762.    tmpstr[4] = '\0' ;
  763.  
  764.    sscanf(tmpstr, "%i", &tmp) ;
  765.    return (tmp) ;
  766. }
  767.  
  768. char dehex (str)
  769. char * str ;
  770. {
  771.    char ch ;
  772.    int tmp ;
  773.    char tmpstr[6] ;
  774.  
  775.    if (debugcall >= 6)
  776.    {
  777.     fprintf(stderr, "CALL: dehex (OMITED)\n") ;
  778.     fflush(stderr) ;
  779.    }
  780.    tmpstr[0] = '0' ;
  781.    tmpstr[1] = 'x' ;
  782.    tmpstr[2] = str[0] ;
  783.    tmpstr[3] = str[1] ;
  784.    tmpstr[4] = '\0' ;
  785.  
  786.    sscanf(tmpstr, "%i", &tmp) ;
  787.  
  788.    ch = (char) tmp ;
  789.    return (ch) ;
  790. }
  791.  
  792. psscreenoff()
  793. {
  794.     if (debugcall >= 3)
  795.     {
  796.         fprintf(stderr, "CALL: psscreenoff ()\n") ;
  797.         fflush(stderr) ;
  798.     }
  799.     pscommand("is") ;
  800.     if (psquery ("XYES") == 1)
  801.         pssc() ;
  802.         
  803. }
  804.  
  805. psscreenon()
  806. {
  807.     if (debugcall >= 3)
  808.     {
  809.         fprintf(stderr, "CALL: psscreenon ()\n") ;
  810.         fflush(stderr) ;
  811.     }
  812.     pscommand("is") ;
  813.     if (psquery ("XNO") == 1)
  814.         pssc() ;
  815.         
  816. }
  817.  
  818. pssc()
  819. {
  820.     if (debugcall >= 3)
  821.     {
  822.         fprintf(stderr, "CALL: pssc()\n") ;
  823.         fflush(stderr) ;
  824.     }
  825.     pscommand("sc") ;
  826.     psreply("XOK") ;
  827. }
  828.  
  829. psverboseoff()
  830. {
  831.     if (debugcall >= 3)
  832.     {
  833.         fprintf(stderr, "CALL: psverboseoff()\n") ;
  834.         fflush(stderr) ;
  835.     }
  836.     pscommand("iv") ;
  837.     if (psquery ("XYES") == 1)
  838.         psvb() ;
  839.         
  840. }
  841.  
  842. psverboseon()
  843. {
  844.     if (debugcall >= 3)
  845.     {
  846.         fprintf(stderr, "CALL: psverboseon()\n") ;
  847.         fflush(stderr) ;
  848.     }
  849.     pscommand("iv") ;
  850.     if (psquery ("XNO") == 1)
  851.         psvb() ;
  852.         
  853. }
  854.  
  855. char * psversion()
  856. {
  857.     char vsnstr[100] ;
  858.  
  859.     if (debugcall >= 3)
  860.     {
  861.         fprintf(stderr, "CALL: psversion()\n") ;
  862.         fflush(stderr) ;
  863.     }
  864.     /* if the first char of version is X we have not got the version
  865.        yet so get it and store it, otherwise just return the pointer
  866.        to the version string */
  867.     if (version[0] == 'X')
  868.     {
  869.         psvn(vsnstr) ;
  870.         /* copy from the second char as the first will be X */
  871.         strcpy(version, &vsnstr[1]) ;
  872.         /* if the first char is B (the psion will return XBADCMD
  873.            if it doesnot support version checking yet) run pssetdefvsn */
  874.         if (version[0] == 'B')
  875.             pssetdefvsn() ;
  876.     }
  877.     return (version) ;
  878. }
  879.  
  880. /* compare psion vsn string to sun vsn string, if the psion one is later return
  881.    GREATERTHAN, if they are the same EQUAL otherwise LESSTHAN */
  882. psvsncmp(vsstr)
  883. char * vsstr ;
  884. {
  885.     char * psvnstr ;
  886.     char * ps1, *ps2, *ps3, *ps4 ;
  887.     char * ss1, *ss2, *ss3, *ss4 ;
  888.     char nstr[1] ;
  889.     int pint, vint ;
  890.  
  891.     if (debugcall >= 3)
  892.     {
  893.         fprintf(stderr, "CALL: psvsncmp(vsstr = %s)\n", vsstr) ;
  894.         fflush(stderr) ;
  895.     }
  896.     /* first ensure that we have the correct version */
  897.     psvnstr = psversion() ;
  898.  
  899.     /* initialise the nstr */
  900.     nstr[0] = '\0' ;
  901.  
  902.     /* now extract the strings */
  903.     ps1 = psvnstr ;
  904.     ss1 = vsstr ;
  905.  
  906.     /* locate the next . */
  907.     psvnstr = strchr(psvnstr, '.') ;
  908.     vsstr = strchr(vsstr, '.') ;
  909.     if (psvnstr == NULL)
  910.         psvnstr = nstr ;
  911.     else
  912.         psvnstr ++;/* skip over the . */
  913.     if (vsstr == NULL)
  914.         vsstr = nstr ;
  915.     else
  916.         vsstr ++ ; /* see above */
  917.     
  918.     ps2 = psvnstr;
  919.     ss2 = vsstr ;
  920.     /*  and the next */
  921.     psvnstr = strchr(psvnstr, '.') ;
  922.     vsstr = strchr(vsstr, '.') ;
  923.     if (psvnstr == NULL)
  924.         psvnstr = nstr ;
  925.     else
  926.         psvnstr ++;/* skip over the . */
  927.     if (vsstr == NULL)
  928.         vsstr = nstr ;
  929.     else
  930.         vsstr ++ ; /* see above */
  931.     
  932.     ps3 = psvnstr ;
  933.     ss3 = vsstr ;
  934.     /* and the last */
  935.     psvnstr = strchr(psvnstr, '.') ;
  936.     vsstr = strchr(vsstr, '.') ;
  937.     if (psvnstr == NULL)
  938.         psvnstr = nstr ;
  939.     else
  940.         psvnstr ++;/* skip over the . */
  941.     if (vsstr == NULL)
  942.         vsstr = nstr ;
  943.     else
  944.         vsstr ++ ; /* see above */
  945.  
  946.     ps4 = psvnstr ;
  947.     ss4 = vsstr ;
  948.  
  949.     /* do the first test */
  950.     pint = atoi(ps1) ;
  951.     vint = atoi(ss1) ;
  952.  
  953.     if (pint > vint)
  954.         return (GREATERTHAN) ;
  955.     else if (pint < vint)
  956.         return (LESSTHAN) ;
  957.     pint = atoi(ps2) ;
  958.     vint = atoi(ss2) ;
  959.  
  960.     if (pint > vint)
  961.         return (GREATERTHAN) ;
  962.     else if (pint < vint)
  963.         return (LESSTHAN) ;
  964.     pint = atoi(ps3) ;
  965.     vint = atoi(ss3) ;
  966.  
  967.     if (pint > vint)
  968.         return (GREATERTHAN) ;
  969.     else if (pint < vint)
  970.         return (LESSTHAN) ;
  971.     pint = atoi(ps4) ;
  972.     vint = atoi(ss4) ;
  973.  
  974.     if (pint > vint)
  975.         return (GREATERTHAN) ;
  976.     else if (pint < vint)
  977.         return (LESSTHAN) ;
  978.  
  979.     /* they would appear to be the same */
  980.     return (EQUAL) ;
  981. }
  982.  
  983.  
  984. psvsngt(vsn)
  985. char * vsn ;
  986. {
  987.     if (debugcall >= 3)
  988.     {
  989.         fprintf(stderr, "CALL: psvsngt(vsn = %s)\n",vsn) ;
  990.         fflush(stderr) ;
  991.     }
  992.     /* if dovsnchk is FALSE i.e. just dont do version checking
  993.        just return FALSE */
  994.     if (dovsnchk == FALSE)
  995.         return (FALSE) ;
  996.     if (psvsncmp(vsn) == GREATERTHAN)
  997.         return (TRUE) ;
  998.     else
  999.         return(FALSE) ;
  1000. }
  1001.  
  1002. psvsnlt(vsn)
  1003. char * vsn ;
  1004. {
  1005.     if (debugcall >= 3)
  1006.     {
  1007.         fprintf(stderr, "CALL: psvsnlt(vsn = %s)\n",vsn) ;
  1008.         fflush(stderr) ;
  1009.     }
  1010.     /* if dovsnchk is FALSE i.e. just dont do version checking
  1011.        just return FALSE */
  1012.     if (dovsnchk == FALSE)
  1013.         return (FALSE) ;
  1014.     if (psvsncmp(vsn) == LESSTHAN)
  1015.         return(TRUE) ;
  1016.     else
  1017.         return(FALSE) ;
  1018. }
  1019.  
  1020. psvsneq(vsn)
  1021. char * vsn ;
  1022. {
  1023.     if (debugcall >= 3)
  1024.     {
  1025.         fprintf(stderr, "CALL: psvsneq(vsn = %s)\n",vsn) ;
  1026.         fflush(stderr) ;
  1027.     }
  1028.     /* if dovsnchk is FALSE i.e. just dont do version checking
  1029.        just return FALSE */
  1030.     if (dovsnchk == FALSE)
  1031.         return (FALSE) ;
  1032.     if (psvsncmp(vsn) == EQUAL)
  1033.         return(TRUE) ;
  1034.     else
  1035.         return(FALSE) ;
  1036. }
  1037. pssetdefvsn()
  1038. {
  1039.     if (debugcall >= 3)
  1040.     {
  1041.         fprintf(stderr, "CALL: pssetdefvsn()\n") ;
  1042.         fflush(stderr) ;
  1043.     }
  1044.     /* set the default version string */
  1045.     strcpy(version, DEFVSNSTR) ;
  1046. }
  1047.  
  1048. psvn(vsnstr)
  1049. char * vsnstr ;
  1050. {
  1051.     if (debugcall >= 3)
  1052.     {
  1053.         fprintf(stderr, "CALL: psvn(OMITED)\n") ;
  1054.         fflush(stderr) ;
  1055.     }
  1056.     pscommand("vn") ;
  1057.     psresponse(vsnstr) ;
  1058. }
  1059.  
  1060. psvb()
  1061. {
  1062.     if (debugcall >= 3)
  1063.     {
  1064.         fprintf(stderr, "CALL: psvb()\n") ;
  1065.         fflush(stderr) ;
  1066.     }
  1067.     pscommand("vb") ;
  1068.     psreply("XOK") ;
  1069. }
  1070.  
  1071. psds()
  1072. {
  1073.     char path[255] ;
  1074.  
  1075.     if (debugcall >= 3)
  1076.     {
  1077.         fprintf(stderr, "CALL: psds()\n") ;
  1078.         fflush(stderr) ;
  1079.     }
  1080.     pscommand("ds") ;
  1081.     psreply("XSTART") ;
  1082.     psresponse(path) ;
  1083.     psreply("XEND") ;
  1084. }
  1085. psgetpwd(path)
  1086. char * path ;
  1087. {
  1088.     char tmp[1024] ;
  1089.     if (debugcall >= 3)
  1090.     {
  1091.         fprintf(stderr, "CALL: psgetpwd()\n") ;
  1092.         fflush(stderr) ;
  1093.     }
  1094.     pscommand("pp") ;
  1095.     psresponse(tmp) ;
  1096.     /* remove the X at the start of the line */
  1097.     strcpy (path, &tmp[1]) ;
  1098. }
  1099.  
  1100. psbinary()
  1101. {
  1102.     if (debugcall >= 3)
  1103.     {
  1104.         fprintf(stderr, "CALL: psbinary()\n") ;
  1105.         fflush(stderr) ;
  1106.     }
  1107.     pscommand("ia") ;
  1108.     if (psquery("XYES") == 1)
  1109.     {
  1110.         pstm() ;    
  1111.         tmode = BINARY ;
  1112.     }
  1113.  
  1114. }
  1115. psxmodem()
  1116. {
  1117.     if (debugcall >= 3)
  1118.     {
  1119.         fprintf(stderr, "CALL: psxmodem()\n") ;
  1120.         fflush(stderr) ;
  1121.     }
  1122.     pscommand("ix") ;
  1123.     if (psquery("XNO") == 1)
  1124.     {
  1125.         pstx() ;
  1126.         tmode = XMDM ;
  1127.     }
  1128. }
  1129.  
  1130. pstm()
  1131. {
  1132.     if (debugcall >= 3)
  1133.     {
  1134.         fprintf(stderr, "CALL: pstm()\n") ;
  1135.         fflush(stderr) ;
  1136.     }
  1137.     pscommand("tm") ;
  1138.     psreply("XOK") ;
  1139. }
  1140.  
  1141. pstx()
  1142. {
  1143.     if (debugcall >= 3)
  1144.     {
  1145.         fprintf(stderr, "CALL: pstm()\n") ;
  1146.         fflush(stderr) ;
  1147.     }
  1148.     pscommand("tx") ;
  1149.     psreply("XOK") ;
  1150. }
  1151.  
  1152. int psquery(str)
  1153. char * str ;
  1154. {
  1155.     char tmp[100] ;
  1156.     if (debugcall >= 3)
  1157.     {
  1158.         fprintf(stderr, "CALL: psquery(str = %s)\n",str) ;
  1159.         fflush(stderr) ;
  1160.     }
  1161.     psresponse(tmp) ;
  1162.     if (strcmp(tmp, str) == 0)
  1163.        return(TRUE) ;
  1164.     else
  1165.        return (FALSE) ;
  1166. }
  1167.  
  1168. psclearfile() 
  1169. {
  1170.     if (debugcall >= 3)
  1171.     {
  1172.         fprintf(stderr, "CALL: psclearfile()\n") ;
  1173.         fflush(stderr) ;
  1174.     }
  1175.     if (psep() == TRUE)
  1176.         psrp() ;
  1177. }
  1178.  
  1179. psep()
  1180. {
  1181.     if (debugcall >= 3)
  1182.     {
  1183.         fprintf(stderr, "CALL: psep()\n") ;
  1184.         fflush(stderr) ;
  1185.     }
  1186.     pscommand("ep") ;
  1187.     return(psquery("XYES") == 1);
  1188. }
  1189.  
  1190. psrp()
  1191. {
  1192.     if (debugcall >= 3)
  1193.     {
  1194.         fprintf(stderr, "CALL: psrp()\n") ;
  1195.         fflush(stderr) ;
  1196.     }
  1197.     pscommand("rp") ;
  1198.     if (!psquery("XOK"))
  1199.         printf("ERROR: Cant remove the file on the psion\n") ;
  1200. }
  1201.  
  1202. psmd()
  1203. {
  1204.     if (debugcall >= 3)
  1205.     {
  1206.         fprintf(stderr, "CALL: psmd()\n") ;
  1207.         fflush(stderr) ;
  1208.     }
  1209.     pscommand("md");
  1210.     psquery("XOK") ;
  1211. }
  1212.  
  1213. psrl()
  1214. {
  1215.     if (debugcall >= 3)
  1216.     {
  1217.         fprintf(stderr, "CALL: psrl()\n") ;
  1218.         fflush(stderr) ;
  1219.     }
  1220.     pscommand("rl") ;
  1221.     psreply("XOK") ;
  1222. }
  1223.  
  1224.  
  1225. pslp(fd)
  1226. FILE *fd ;
  1227. {
  1228.     if (debugcall >= 3)
  1229.     {
  1230.         fprintf(stderr, "CALL: pslp(OMITED FD)\n") ;
  1231.         fflush(stderr) ;
  1232.     }
  1233.     pscommand("lp") ;
  1234.     psldir(fd) ;
  1235. }
  1236. psldir(fd)
  1237. FILE *fd ;
  1238. {
  1239.     char txt[255] ;
  1240.     if (debugcall >= 3)
  1241.     {
  1242.         fprintf(stderr, "CALL: psldir(OMITED FD)\n") ;
  1243.         fflush(stderr) ;
  1244.     }
  1245.     if (psquery("XSTARTLIST"))
  1246.         while(1)
  1247.         {
  1248.             psresponse(txt) ;
  1249.             if (strcmp (txt, "XENDLIST") == 0)
  1250.                 break ;
  1251.             else if (strcmp(txt,"XBADPATH") == 0)
  1252.             {
  1253.                 if (findvar(VAR_HELPFULL) != NULL)
  1254.                     printf("HELP: Error in listing files, bad path specified\n") ;
  1255.                 break ;
  1256.             }
  1257.             if (fd == NULL)
  1258.                 printf("File :%s\n", txt) ;
  1259.             else
  1260.                 fprintf(fd, "%s\n", txt) ;
  1261.         }
  1262. }
  1263.  
  1264. psdc()
  1265. {
  1266.     if (debugcall >= 3)
  1267.         fprintf(stderr, "CALL: psdc()\n") ;
  1268.     pscommand("dc") ;
  1269.     psreply("XDISCONNECTED") ;
  1270.     psshutdown(0) ;
  1271. }
  1272.  
  1273. psreply (expected)
  1274. char * expected ;
  1275. {
  1276.    char tmp[1000] ;
  1277.  
  1278.     if (debugcall >= 3)
  1279.     {
  1280.         fprintf(stderr, "CALL: psreply(expected = %s)\n",expected) ;
  1281.         fflush(stderr) ;
  1282.     }
  1283.    psresponse(tmp) ;
  1284.  
  1285.    if (strcmp(tmp, expected) == 0)
  1286.     return;
  1287.    printf("ERROR, Protocol violation, expected (%s), got (%s), exiting\n",expected, tmp) ;
  1288.    psshutdown(1);
  1289. }
  1290.  
  1291. psdt (txt)
  1292. char * txt ;
  1293. {
  1294.     char tmp [1000] ;
  1295.     if (debugcall >= 3)
  1296.     {
  1297.         fprintf(stderr, "CALL: psdt(txt = %s)\n",txt) ;
  1298.         fflush(stderr) ;
  1299.     }
  1300.     strcpy (tmp, "dt ") ;
  1301.     strcat (tmp, txt) ;
  1302.     pscommand (tmp) ;
  1303.     psreply("XOK") ;
  1304. }
  1305.  
  1306. pssetpath(path)
  1307. char * path ;
  1308. {
  1309.     if (debugcall >= 3)
  1310.     {
  1311.         fprintf(stderr, "CALL: pssetpath(path = %s)\n",path) ;
  1312.         fflush(stderr) ;
  1313.     }
  1314.     if (strcmp(path, pspath) == 0)
  1315.         return ;
  1316.     pssp(path) ;
  1317.  
  1318. }
  1319.  
  1320. pssp(path)
  1321. char *path ;
  1322. {
  1323.     char tmp[100] ;
  1324.  
  1325.     if (debugcall >= 3)
  1326.     {
  1327.         fprintf(stderr, "CALL: pssp(path = %s)\n",path) ;
  1328.         fflush(stderr) ;
  1329.     }
  1330.     /* if the stored name is the same as the current name save on 
  1331.        transmitting information */
  1332.     strcpy(pspath, path) ;
  1333.     strcpy(tmp, "sp ") ;
  1334.     strcat(tmp, pspath) ;
  1335.  
  1336.     pscommand(tmp) ;
  1337.     psreply ("XOK") ;
  1338. }
  1339.  
  1340. ispathset()
  1341. {
  1342.     if (debugcall >= 3)
  1343.     {
  1344.         fprintf(stderr, "CALL: ispathset()\n") ;
  1345.         fflush(stderr) ;
  1346.     }
  1347.     return(strlen(pspath)) ;
  1348. }
  1349.  
  1350. psgetfname() 
  1351. {
  1352.     char * tmp ;
  1353.  
  1354.     if (debugcall >= 3)
  1355.     {
  1356.         fprintf(stderr, "CALL: psgetfname()\n") ;
  1357.         fflush(stderr) ;
  1358.     }
  1359.     /* find the last \ in the remaining name, this will be the
  1360.     end of the directory component */
  1361.     tmp = strrchr(pspath, '\\') ;
  1362.     /* if tmp is NULL there is no \ i.e. we are dealing with a local 
  1363.        pathname not an absolute pathname */
  1364.     if (tmp == NULL)
  1365.     {
  1366.         strcpy (psfname, pspath) ;
  1367.     }
  1368.     else
  1369.     {
  1370.         /* tmp will point to the \ so increment by one */
  1371.         tmp ++ ;
  1372.         /* extract the filename from pspath using tmp */
  1373.         strcpy (psfname, tmp) ;
  1374.     }
  1375. }
  1376.  
  1377. psgetfsize()
  1378. {
  1379.     char tmp[100] ;
  1380.     if (debugcall >= 3)
  1381.     {
  1382.         fprintf(stderr, "CALL: psgetfsize()\n") ;
  1383.         fflush(stderr) ;
  1384.     }
  1385.     
  1386.     pscommand("sz") ;
  1387.     psresponse(tmp) ;
  1388.     if (strcmp(tmp, "XBADPATH") == 0)
  1389.         return(0) ;
  1390.     return (atoi(tmp+1)) ;
  1391. }
  1392.  
  1393. psgetrw()
  1394. {
  1395.     char tmp[100] ;
  1396.     if (debugcall >= 3)
  1397.     {
  1398.         fprintf(stderr, "CALL: psgetrw()\n") ;
  1399.         fflush(stderr) ;
  1400.     }
  1401.     pscommand("rw") ;
  1402.     psresponse(tmp) ;
  1403.     if (strcmp(tmp, "XBADPATH") == 0)
  1404.         return(PSBADPATH) ;
  1405.     else if (strcmp(tmp, "XRW") == 0)
  1406.         return(PSFILERW) ;
  1407.     else
  1408.         return(PSFILERO) ;
  1409. }
  1410. int pscs()
  1411. {
  1412.     char tmp[100] ;
  1413.     int ret ;
  1414.     if (debugcall >= 3)
  1415.     {
  1416.         fprintf(stderr, "CALL: pscs ()\n");
  1417.         fflush(stderr) ;
  1418.     }
  1419.     pscommand("cs") ;
  1420.     psresponse(tmp) ; /* get the STARTSUM out of the way */
  1421.     psresponse(tmp) ; /* good or bad open ? */
  1422.     if (strcmp(tmp, "XBADOPEN") == 0)
  1423.         return(PSBADPATH) ;
  1424.     psresponse(tmp) ;
  1425.     if (strcmp(tmp, "XBADSUM") == 0)
  1426.         return(PSBADPATH) ;
  1427.     sscanf(tmp+1 /* skip over the X */, "%d", &ret) ;
  1428.     if (debugcall >= 3)
  1429.     {
  1430.         fprintf(stderr, "INLINE: pscs return string is :%s:\n", tmp) ;
  1431.         fprintf(stderr, "INLINE: pscs return value is %d\n", ret);
  1432.         fflush(stderr) ;
  1433.     }
  1434.     psresponse(tmp) ;/* get the ENDSUM line */
  1435.     return (ret) ;
  1436. }
  1437.  
  1438. psgetatts()
  1439. {
  1440.     char tmp [100] ;
  1441.     int atts ;
  1442.     if (debugcall >= 3)
  1443.     {
  1444.         fprintf(stderr, "CALL: psgetatts()\n") ;
  1445.         fflush(stderr) ;
  1446.     }
  1447.     pscommand("ft") ;
  1448.     psresponse(tmp) ;
  1449.     atts = 0 ;
  1450.     if (strcmp(tmp, "XBADPATH") == 0)
  1451.         return(PSBADPATH) ;
  1452.     else if (strstr(tmp,"DIR") != NULL)
  1453.         atts = atts | PSFILEDIR ;
  1454.     else if (strstr(tmp,"TEXT") != NULL)
  1455.         atts = atts | PSFILETEXT ;
  1456.     else if (strstr(tmp,"HIDDEN") != NULL)
  1457.         atts = atts | PSFILEHIDDEN ;
  1458.     else if (strstr(tmp, "SYSTEM") != NULL)
  1459.         atts = atts | PSFILESYSTEM ;
  1460.     else if (strstr(tmp, "VOLUME") != NULL)
  1461.         atts = atts | PSFILEVOLUME ;
  1462.     /* if the atts do not say this is a directory, its a file but not a text file */
  1463.     if (strstr(tmp, "DIR") == NULL)
  1464.         atts = atts | PSFILEFILE ;
  1465.     return (atts) ;
  1466. }
  1467. psrcd()
  1468. {
  1469.     char tmp [1024] ;
  1470.     char ch ;
  1471.     if (debugcall >= 3)
  1472.         fprintf(stderr, "CALL: psrcd()\n") ;
  1473.     /* Are we dealing with a partition ? */
  1474.     if ((strlen(pspath) == 2) && (pspath[1] == ':'))
  1475.     {
  1476.         /* this is a partition. Check that it's valid and then 
  1477.            just cd straight there */
  1478.         ch = isupper(pspath[0]) ? tolower(pspath[0]) : pspath[0] ;
  1479.         if ((ch == 'a') || (ch == 'b') || (ch == 'c') || (ch == 'm'))
  1480.         {
  1481.             /* set the path to be terminated with a \ */
  1482.             strcpy (tmp,pspath) ;
  1483.             strcat (tmp, "\\") ;
  1484.             pssetpath(tmp) ;
  1485.             pscommand("cd") ;
  1486.             if (!psquery("XOK"))
  1487.             {
  1488.                 return(BAD) ;
  1489.             }
  1490.             return(OK) ;
  1491.         }
  1492.         printf("ERROR: Invalid devicename %s\n", pspath) ;
  1493.         return (BAD) ;
  1494.     }
  1495.     /* check that the already downloaded path exists and is a directory
  1496.        BEFORE we try to change to it */
  1497.     if (! psep())
  1498.         return (BAD) ;
  1499.     /* check that it's a directory */
  1500.     if (!(psgetatts () & PSFILEDIR))
  1501.         return (BAD) ;
  1502.     /* we need to append a \ to the end of the path */
  1503.     strcpy (tmp, pspath) ;
  1504.     strcat (tmp, "\\") ;
  1505.     pssetpath (tmp) ;
  1506.     pscommand("cd") ;
  1507.     if (!psquery("XOK"))
  1508.     {
  1509.         printf ("ERROR: remote command failed to set remote directory\n") ;
  1510.         return (BAD) ;
  1511.     }
  1512.     return (OK) ;
  1513. }
  1514. /* start debugging on the psion, assume tha path has been set and the file does not exist */
  1515. pssd() 
  1516. {
  1517.     char resp[100] ;
  1518.     if (debugcall >= 3)
  1519.     {
  1520.         fprintf(stderr, "CALL: pssd ()\n");
  1521.         fflush(stderr) ;
  1522.     }
  1523.     pscommand("sd") ; /* send the command */
  1524.     psresponse(resp) ; /* get the responnse */
  1525.     if (strcmp (resp, "XGOODOPEN") == 0)
  1526.     {
  1527.        return (OK) ;
  1528.     }
  1529.     else if (strcmp(resp, "XBADCMD") == 0)
  1530.     {
  1531.        return (BADCMD) ;
  1532.     }
  1533.     else
  1534.        return (BAD) ;
  1535. }
  1536.  
  1537. psstartdebug(pth)
  1538. char * pth ;
  1539. {
  1540.     if (debugcall >= 3)
  1541.     {
  1542.         fprintf(stderr, "CALL: psstartdebug ()\n");
  1543.         fflush(stderr) ;
  1544.     }
  1545.     pssetpath(pth) ;
  1546.     /* if it exist, remove it */
  1547.     psclearfile() ;
  1548.     /* start the debugging */
  1549.     return(pssd()) ;
  1550. }
  1551. psenddebug()
  1552. {
  1553.     if (debugcall >= 3)
  1554.     {
  1555.         fprintf(stderr, "CALL: psenddebug ()\n");
  1556.         fflush(stderr) ;
  1557.     }
  1558.     return (psed()) ;
  1559. }
  1560. /* end debugging on the psion */
  1561. psed()
  1562. {
  1563.     char resp [100] ;
  1564.     if (debugcall >= 3)
  1565.     {
  1566.         fprintf(stderr, "CALL: psed ()\n");
  1567.         fflush(stderr) ;
  1568.     }
  1569.     pscommand("ed") ;
  1570.     psresponse (resp) ;
  1571.     if (strcmp(resp, "XGOODCLOSE") == EQUAL)
  1572.     {
  1573.         return(OK) ;
  1574.     }
  1575.     else if (strcmp(resp, "XBADCMD") == EQUAL)
  1576.     {
  1577.         return(BADCMD) ;
  1578.     }
  1579.     else
  1580.         return(BAD) ;
  1581. }
  1582. long psgetmodtime()
  1583. {
  1584.     long pstime ;
  1585.     char tmp[100] ;
  1586.     if (debugcall >= 3)
  1587.     {
  1588.         fprintf(stderr, "CALL: psgetatts()\n") ;
  1589.         fflush(stderr) ;
  1590.     }
  1591.     pscommand ("ti") ;
  1592.     psresponse(tmp) ;
  1593.     
  1594.     if (strcmp("XBADPATH", tmp) == 0)
  1595.         return(-1) ;
  1596.     return(atoi(tmp+1)) ;
  1597. }
  1598.  
  1599. pssetro()
  1600. {
  1601.     char tmp[100] ;
  1602.     if (debugcall >= 3)
  1603.     {
  1604.         fprintf(stderr, "CALL:pssetro()\n") ;
  1605.         fflush(stderr) ;
  1606.     }
  1607.     pscommand("wn") ;
  1608.     psresponse(tmp) ;
  1609. }
  1610. pssetrw()
  1611. {
  1612.     char tmp[100] ;
  1613.     if (debugcall >= 3)
  1614.     {
  1615.         fprintf(stderr, "CALL:pssetrw()\n") ;
  1616.         fflush(stderr) ;
  1617.     }
  1618.     pscommand("wy") ;
  1619.     psresponse(tmp) ;
  1620. }
  1621.  
  1622. pstf(trunc_size)
  1623. int trunc_size ;
  1624. {
  1625.     char tmp [100] ;
  1626.     if (debugcall >= 3)
  1627.     {
  1628.         fprintf(stderr, "CALL:pstf(trunc_size = %d)\n", trunc_size) ;
  1629.         fflush(stderr) ;
  1630.     }
  1631.         sprintf(tmp, "tf %d") ;
  1632.         pscommand(tmp) ;
  1633.         psresponse(tmp) ;
  1634.  }
  1635.  
  1636. psfc(mode)
  1637. int mode ;
  1638. {
  1639.     /* tell the psion to start talking (or not) with file level checksumming */
  1640.     char tmp[100] ;
  1641.     if (debugcall >=3)
  1642.     {
  1643.         fprintf(stderr, "CALL:psfc(mode = %d)\n", mode) ;
  1644.         fflush(stderr) ;
  1645.     }
  1646.     if (mode == TRUE)
  1647.     {
  1648.         sprintf(tmp,"fc 1") ;
  1649.         filechksum = TRUE ;
  1650.     }
  1651.     else
  1652.     {
  1653.         sprintf(tmp,"fc 0") ;
  1654.         filechksum = FALSE ;
  1655.     }
  1656.     pscommand(tmp) ;
  1657.     if (!psquery("XOK"))
  1658.        printf("Error in command psfc\n") ;
  1659. }
  1660.  
  1661. /* process control functions. these are dangerous if misused */
  1662. pspo(mode)
  1663. int mode ;
  1664. {
  1665.     /* tell the psion to disallow or allow override of process checking */
  1666.         char tmp[100] ;
  1667.     if (debugcall >=3)
  1668.     {
  1669.         fprintf(stderr, "CALL:pspo(mode = %d)\n", mode) ;
  1670.         fflush(stderr) ;
  1671.     }
  1672.     if (mode == TRUE)
  1673.     {
  1674.         sprintf(tmp,"po 1") ;
  1675.         pscommand(tmp) ;
  1676.         psreply("XON") ;
  1677.     }
  1678.     else
  1679.     {
  1680.         sprintf(tmp,"po 0") ;
  1681.         pscommand(tmp) ;
  1682.         psreply("XOFF") ;
  1683.     }
  1684.     return(OK) ;
  1685. }
  1686.  
  1687. pspl(fd, pattern)
  1688. FILE *fd ;
  1689. char * pattern ;
  1690. {
  1691.     /* list the processes according to the pattern */
  1692.     char txt[255] ;
  1693.     char tmp[20] ;
  1694.     if (debugcall >= 3)
  1695.     {
  1696.         fprintf(stderr, "CALL: pspl(OMITED FD, pattern = %s)\n", pattern) ;
  1697.         fflush(stderr) ;
  1698.     }
  1699.     /* assemble the command */
  1700.     sprintf(tmp, "pl %s", pattern) ;
  1701.     pscommand(tmp) ;
  1702.     if (psquery("XBADPARAM"))
  1703.     {
  1704.         if (findvar(VAR_HELPFULL) != NULL)
  1705.         {
  1706.             printf("HELP: Error in listing processes using pattern %s, posibly the pattern is to long\n", pattern) ;
  1707.         }
  1708.         return(OK) ;
  1709.     }
  1710.     while(1)
  1711.     {
  1712.         psresponse(txt) ;
  1713.         if (strcmp (txt, "XENDLIST") == 0)
  1714.             break ;
  1715.         if (fd == NULL)
  1716.             printf("Process :%s\n", txt) ;
  1717.         else
  1718.             fprintf(fd, "%s\n", txt) ;
  1719.         }
  1720. }
  1721. pspk(pattern)
  1722. char * pattern ;
  1723. {
  1724.     /* kill processes according to the pattern */
  1725.     char txt[255] ;
  1726.     char tmp[20] ;
  1727.     int count ;
  1728.     if (debugcall >= 3)
  1729.     {
  1730.         fprintf(stderr, "CALL: pspk( pattern = %s)\n", pattern) ;
  1731.         fflush(stderr) ;
  1732.     }
  1733.     /* assemble the command */
  1734.     sprintf(tmp, "pk %s", pattern) ;
  1735.     pscommand(tmp) ;
  1736.     psresponse(tmp);
  1737.     if (strcmp(tmp, "XBADPARAM") == 0)
  1738.     {
  1739.         if (findvar(VAR_HELPFULL) != NULL)
  1740.         {
  1741.             printf("HELP: Error in killing processes using pattern %s, posibly the pattern is to long or was not supplied\n", pattern) ;
  1742.         }
  1743.         return(OK) ;
  1744.     }
  1745.     if (strcmp(tmp, "KILLNOPROC") == 0)
  1746.     {
  1747.         if (findvar(VAR_HELPFULL) != NULL)
  1748.         {
  1749.             printf("HELP: Error in killing processes, no processes found matching patterm %s\n", pattern) ;
  1750.         }
  1751.         return(OK) ;
  1752.     }
  1753.     if (strcmp(tmp, "KILLERRPROC") == 0)
  1754.     {
  1755.         if (findvar(VAR_HELPFULL) != NULL)
  1756.         {
  1757.             printf("HELP: Error in killing processes, suncom error\n") ;
  1758.         }
  1759.         return(OK) ;
  1760.     }
  1761.     count = atoi(tmp+1) ;
  1762.     if (findvar(VAR_VERBOSE) != NULL)
  1763.         printf("%d processes killed matching pattern %s\n", count, pattern) ;
  1764.     return(OK) ;
  1765. }
  1766. psps(pattern)
  1767. char * pattern ;
  1768. {
  1769.     /* shutdown processes according to the pattern */
  1770.     char txt[255] ;
  1771.     char tmp[20] ;
  1772.     int count ;
  1773.     if (debugcall >= 3)
  1774.     {
  1775.         fprintf(stderr, "CALL: psps( pattern = %s)\n", pattern) ;
  1776.         fflush(stderr) ;
  1777.     }
  1778.     /* assemble the command */
  1779.     sprintf(tmp, "ps %s", pattern) ;
  1780.     pscommand(tmp) ;
  1781.     psresponse(tmp);
  1782.     if (strcmp(tmp, "XBADPARAM") == 0)
  1783.     {
  1784.         if (findvar(VAR_HELPFULL) != NULL)
  1785.         {
  1786.             printf("HELP: Error in shutting down processes using pattern %s, posibly the pattern is to long or was not supplied\n", pattern) ;
  1787.         }
  1788.         return(OK) ;
  1789.     }
  1790.     if (strcmp(tmp, "SDNOPROC") == 0)
  1791.     {
  1792.         if (findvar(VAR_HELPFULL) != NULL)
  1793.         {
  1794.             printf("HELP: Error in shutting down processes, no processes found matching patterm %s\n", pattern) ;
  1795.         }
  1796.         return(OK) ;
  1797.     }
  1798.     if (strcmp(tmp, "SDERRPROC") == 0)
  1799.     {
  1800.         if (findvar(VAR_HELPFULL) != NULL)
  1801.         {
  1802.             printf("HELP: Error in shutting down processes, suncom error\n") ;
  1803.         }
  1804.         return(OK) ;
  1805.     }
  1806.     count = atoi(tmp+1) ;
  1807.     if (findvar(VAR_VERBOSE) != NULL)
  1808.         printf("%d processes shutdown matching pattern %s\n", count, pattern) ;
  1809.     return(OK) ;
  1810. }
  1811.