home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / old / ckermit4e / ckmsfp.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  15KB  |  444 lines

  1. /* Version 0.8(35) - Jim Noble at Planning Research Corporation, June 1987. */
  2. /* Ported to Megamax native Macintosh C compiler. */
  3. /* Edit by Bill on Wed May 15, 15:48 */
  4. /* change name of rtol to sfprtol, make it the common file rtol rtn */
  5. /* either use RSRC & BINA if .RSRC extension, or use current defaults */
  6. /* Edit by Bill on Wed May 15, 15:48 */
  7. /* in initfilerecv make sure kermit flag binary is set */
  8.  
  9. /*
  10.  * file ckmsfp.c
  11.  *
  12.  * Module of MacKermit containing standard file package calls:
  13.  *
  14.  *    dosenddialog() - Send file...
  15.  *    dorecvdialog() - Receive file...
  16.  *    dogetfdialog() - Get file from server...
  17.  *
  18.  * Bill Schilit, May, 1984
  19.  *
  20.  * Copyright (C) 1985, Trustees of Columbia University in the City of
  21.  * New York.  Permission is granted to any individual or institution to
  22.  * use, copy, or redistribute this software so long as it is not sold
  23.  * for profit, provided this copyright notice is retained.
  24.  *
  25.  */
  26.  
  27. #include "ckcdeb.h"
  28. #include "ckcker.h"        /* Kermit definitions */
  29.  
  30. #define    __SEG__ ckmsfp
  31. #include <ctype.h>
  32.  
  33. #include <files.h>
  34. #include <errors.h>
  35. #include <controls.h>
  36. #include <dialogs.h>
  37. #include <packages.h>
  38. #include <events.h>
  39.  
  40. #include "ckmdef.h"        /* Common Mac module definitions */
  41. #include "ckmres.h"        /* resource defs */
  42.  
  43. FILINF filargs;            /* is global */
  44.  
  45. int radflgs[] = {FIL_DATA, FIL_RSRC, FIL_TEXT, FIL_BINA};
  46. int radnotflgs[] = {FIL_RSRC, FIL_DATA, FIL_BINA, FIL_TEXT};
  47.  
  48. /* Globals used by SEND dialog */
  49.  
  50. SFReply sfr;            /* holds file info */
  51. Boolean sendselflg;        /* TRUE means file was selected */
  52. Boolean sendasflg;        /* TRUE means AS field is active */
  53.  
  54.  
  55.  
  56. /****************************************************************************/
  57. /* gethdl - return a control handle given a resource ID */
  58. /****************************************************************************/
  59. Handle
  60. gethdl (item, dp)
  61. DialogPtr dp;
  62. {
  63.     short itype;
  64.     Rect ibox;
  65.     Handle ihdl;
  66.  
  67.     GetDItem (dp, item, &itype, &ihdl, &ibox);
  68.     return (ihdl);
  69. }                /* gethdl */
  70.  
  71.  
  72.  
  73. /****************************************************************************/
  74. /* setfilflgs - Manage the filflg word and radio controls.
  75.  *
  76.  * Flags will be changed when the resource ID of item hit (passed to
  77.  * this routine) is one of the radio items, or alternately routines can
  78.  * modify the filflg word itself and the radio items will be updated
  79.  * accordingly.
  80.  *
  81.  * N.B. Each dialog using these flags has them defined with the same
  82.  * DITL item numbers.
  83.  *
  84.  */
  85. /****************************************************************************/
  86. setfilflgs (item, dlg)
  87. DialogPtr dlg;
  88. {
  89.     ControlHandle ctlhdl;
  90.     int i;
  91.  
  92.     if (item >= RADITM_FIRST &&    /* check for item... is it  */
  93.     item <= RADITM_LAST) {    /* a radio item for us? */
  94.     filargs.filflg |= radflgs[item - RADITM_FIRST];    /* yes... set flag */
  95.     filargs.filflg &= ~radnotflgs[item - RADITM_FIRST];    /* clear opposite */
  96.     }
  97.     for (i = RADITM_FIRST; i <= RADITM_LAST; i++) {    /* update all */
  98.     ctlhdl = getctlhdl (i, dlg);    /* get a handle on his radio item */
  99.     SetCtlValue (ctlhdl,
  100.          (filargs.filflg & radflgs[i - RADITM_FIRST]) ? btnOn : btnOff);
  101.     }
  102. }                /* setfilflgs */
  103.  
  104.  
  105.  
  106. /****************************************************************************/
  107. /****************************************************************************/
  108. setfilnams (remfid, dlg)
  109. DialogPtr dlg;
  110. {
  111.     filargs.filrem[0] = 0;    /* no remote file */
  112.  
  113.     strcpy (filargs.fillcl, &sfr.fName);    /* copy sfr into local name
  114.                          * stg */
  115.  
  116.     if (remfid != 0)        /* fetch remote name if present */
  117.     GetIText (gethdl (remfid, dlg), filargs.filrem);    /* in an edittext field */
  118.  
  119.     binary = (filargs.filflg & FIL_BINA);    /* selected binary mode? */
  120. }                /* setfilnams */
  121.  
  122.  
  123.  
  124. Boolean isfolder;
  125.  
  126. /****************************************************************************/
  127. /* sendmydlg - SFPGetFIle item hit filter for "send file" dialog.
  128.  *
  129.  * This filter is called by SFPGetFile to let the programmer handle hits
  130.  * on his custom items.  Our items are 2 sets of buttons for selecting
  131.  * the fork (data or resource) and the transfer mode (binary or text).
  132.  * Also we have an EditText item for filling in the AS name.
  133.  *
  134.  * The buttons are set when the user clicks, but they also are given
  135.  * values depending on the selection of a file.  If the file's type is
  136.  * "APPL" then controls "Resource" and "Binary" are automaticlly set,
  137.  * otherwise the controls "Data" and "Text" are set.  SF-File keeps the
  138.  * SFReply upto date when a file name is selected, but...  unfortunately
  139.  * we are called before the SFReply is updated and so when we notice
  140.  * "getNmList" is hit we defer our update for one cycle.
  141.  *
  142.  * Our other item, the TextEdit item to set the "AS" file name, can be
  143.  * enabled or disabled to allow the selection of a file name by typing a
  144.  * character (standard SFGetFile stuff).  By using the global flag
  145.  * sendasflg and an event filter we switch between sending the chars to
  146.  * SF-File for filename selection and to ModalDialog for TextEdit of our
  147.  * AS name.  Since it would be nice to get rid of that blinking cursor
  148.  * in the TextEdit item our DITL has an invisible EditText item which
  149.  * becomes active for this purpose.
  150.  *
  151.  * At startup the AS field is disabled (the invisible EditText is
  152.  * current and sndasflg is FALSE).  The user can make AS active by
  153.  * clicking in it.  The user can toggle by clicking on the StatText
  154.  * "AS" -- though I won't tell anybody if you don't.
  155.  *
  156.  */
  157. /****************************************************************************/
  158. pascal short
  159. sendmydlg (ITEM, DLG)
  160. short ITEM;
  161. DialogPtr DLG;
  162. {
  163.     Boolean isappl;        /* file is an application */
  164.     short RSLT;
  165.  
  166.     p2cstr (&sfr.fName);    /* convert filename to C form */
  167.     if (sendselflg) {        /* file name selection occured? */
  168.     sendselflg = FALSE;    /* yes, don't do this again */
  169.  
  170.     zltor (&sfr.fName, filargs.filrem);    /* convert to remote form */
  171.     SetIText (gethdl (SEND_ASFN, DLG),    /* display converted name */
  172.           filargs.filrem);    /* in "As" field */
  173.     setfilnams (SEND_ASFN, DLG);    /* set file names since double */
  174.     /* clicking fouls us */
  175.  
  176.     filargs.filflg &= ~FIL_RBDT;    /* turn off all of our flags */
  177.     isappl = (sfr.fType == 'APPL');    /* application? */
  178.     if ((sfr.fName.length == 0) && !isfolder) {    /* check for folder */
  179.         /* change the button if necessary */
  180.         SetCTitle (getctlhdl (getOpen, DLG), "Open");
  181.         isfolder = TRUE;
  182.     } else if ((sfr.fName.length != 0) && isfolder) {
  183.         SetCTitle (getctlhdl (getOpen, DLG), "Send");
  184.         isfolder = FALSE;
  185.     }
  186.     filargs.filflg |= (isappl) ?    /* update flags */
  187.         (FIL_RSRC | FIL_BINA) :    /* application */
  188.         (FIL_DATA | FIL_TEXT);    /* not application */
  189.     }
  190.     switch (ITEM) {        /* according to the item */
  191.       case getNmList:        /* user hit file name */
  192.     if (sendasflg) {    /* "As" active? */
  193.         sendasflg = FALSE;    /* yes -> deactivate "As" name */
  194.         SelIText (DLG, SEND_INVT, 0, 256);    /* activate invisible
  195.                          * editText  */
  196.     }
  197.     sendselflg = TRUE;    /* next time around set buttons */
  198.     break;            /* nothing more to do in this pass */
  199.  
  200.       case SEND_ASFN:        /* hit EditText for "AS" */
  201.     sendasflg = TRUE;    /* let modal filter pass to us */
  202.     break;
  203.  
  204.       case getOpen:        /* done? */
  205.     setfilnams (SEND_ASFN, DLG);    /* set file names */
  206.     break;            /* done... */
  207.  
  208.       case SEND_ALL:        /* hit send all check box */
  209.     filargs.filflg ^= FIL_ALLFL;    /* toggle send all flag */
  210.  
  211.  
  212.     SetCtlValue (getctlhdl (SEND_ALL, DLG),    /* set the ctl value
  213.                          * according to the flag */
  214.              (filargs.filflg & FIL_ALLFL) ? btnOn : btnOff);
  215.     break;
  216.     }
  217.  
  218.     setfilflgs (ITEM, DLG);    /* check for and handle radio items */
  219.     c2pstr (&sfr.fName);    /* convert back to pascal form */
  220.     RSLT = ITEM;        /* pass item back */
  221.     return RSLT;
  222. }                /* sendmydlg */
  223.  
  224.  
  225.  
  226. /****************************************************************************/
  227. /* sendfilter - SFPGetFile event filter for "send file" dialog.
  228.  *
  229.  * This filter is the same form as a ModalDialog filter, it is used
  230.  * internally by SFPGetFile's ModalDialog call.  Our filter allows the
  231.  * user to select a file by typing the first character, which is a
  232.  * normal function of SFGetFile but is broken when we use EditText in
  233.  * our customized SFGetFile box.  Return 0x1000+char in itemhit to
  234.  * SFGetFile instead of letting ModalDialog handle it with a call to
  235.  * TextEdit.  Using a global flag "sendasflg" we decide to send the
  236.  * character to TextEdit via ModalDialog, or to SFGetFile.
  237.  *
  238.  */
  239. /****************************************************************************/
  240. pascal Boolean
  241. sendfilter (THEDIALOG, THEEVENT, ITEMHIT)
  242. DialogPtr THEDIALOG;
  243. EventRecord *THEEVENT;
  244. short *ITEMHIT;
  245. {
  246.     Boolean RETVAL;        /* returned value */
  247.  
  248.     RETVAL = FALSE;        /* default is to left Modal handle */
  249.  
  250.     if (THEEVENT->what == keyDown)    /* key down? */
  251.     if (!sendasflg) {    /* and the text isn't selected? */
  252.         /* then use as file name selector */
  253.         /* return char+0x1000 to SFPGetfile... */
  254.         *ITEMHIT = 0x1000 + (THEEVENT->message & 0x7f);
  255.         RETVAL = TRUE;    /* let SFP handle it, not modal */
  256.     }
  257.     return RETVAL;
  258. }                /* sendfilter */
  259.  
  260.  
  261.  
  262. /****************************************************************************/
  263. /* recvmydlg - SFPPutFile item filter for "receive file" dialog. */
  264. /****************************************************************************/
  265. pascal short
  266. recvmydlg (ITEM, DLG)
  267. short ITEM;
  268. DialogPtr DLG;
  269. {
  270.     short RSLT;
  271.  
  272.     RSLT = ITEM;
  273.  
  274.     switch (ITEM) {
  275.       case RECV_PROC:
  276.     filargs.filflg &= ~FIL_DODLG;    /* no more dialogs for me! */
  277.     RSLT = RECV_RBTN;    /* did "OK" */
  278.  
  279.       case RECV_RBTN:
  280.     p2cstr (&sfr.fName);    /* convert filename to C form */
  281.     setfilnams (0, DLG);    /* set names */
  282.     c2pstr (&sfr.fName);    /* convert back to pascal form */
  283.     break;
  284.     }
  285.     setfilflgs (ITEM, DLG);    /* check for and handle radios */
  286.     return RSLT;
  287. }                /* recvmydlg */
  288.  
  289.  
  290.  
  291. short recvpt[] = {75, 100};    /* Used as Point */
  292. short sendpt[] = {75, 80};    /* Used as Point */
  293.  
  294. /****************************************************************************/
  295. /* dosenddialog - Use SFPGetFile to fetch a file to send. */
  296. /* lclf: local file name;  remf: remote file name */
  297. /****************************************************************************/
  298. dosenddialog (lclf, remf)
  299. char *lclf[], *remf[];
  300. {
  301.     filargs.filflg = 0;
  302.     sendasflg = FALSE;        /* "AS" starts off inactive */
  303.     sendselflg = TRUE;        /* need to update file buttons */
  304.  
  305.     isfolder = FALSE;
  306.     SFPGetFile ((Point *) sendpt, "", NILPROC, -1,    /* all file types, 2
  307.                              * filters */
  308.         NILPTR, sendmydlg, &sfr, DLG_SEND, sendfilter);
  309.     *lclf = filargs.fillcl;
  310.     *remf = filargs.filrem;
  311.     filargs.filvol = sfr.vRefNum;    /* remember volume number */
  312.     return (sfr.good);        /* pass back return */
  313. }                /* dosenddialog */
  314.  
  315.  
  316.  
  317. /****************************************************************************/
  318. /****************************************************************************/
  319. dorecvdialog (fn, lclf)
  320. char *lclf[], *fn;
  321. {
  322.     int err;
  323.  
  324.     if (!(filargs.filflg & FIL_DODLG)) { /* don't want to do dialogs? */
  325.     *lclf = "";        /* then use a null string */
  326.     return;            /* and return now */
  327.     }
  328.     for (;;) {            /* keep trying */
  329.     filargs.filflg &= ~(FIL_RBDT);    /* clear file modes */
  330.     filargs.filflg |= sfprtol (fn);    /* convert fn and set modes */
  331.     SFPPutFile ((Point *) recvpt, "Receive as:", fn,
  332.             recvmydlg, &sfr, DLG_RECV, NILPROC);
  333.     *lclf = filargs.fillcl;
  334.     filargs.filvol = sfr.vRefNum;    /* remember volume number */
  335.  
  336.     if (!sfr.good) {    /* CANCEL */
  337.         cxseen = TRUE;    /* indicate cancel */
  338.         return;
  339.     } else {
  340.         /* delete if there */
  341.         err = FSDelete (filargs.fillcl, filargs.filvol);
  342.         if (err == fnfErr)    /* everything ok? */
  343.         return;        /* yes, return now */
  344.     }
  345.  
  346.     if (ioutil (err))
  347.         return;        /* until no error */
  348.     }
  349. }                /* dorecvdialog */
  350.  
  351.  
  352.  
  353. /****************************************************************************/
  354. /****************************************************************************/
  355. initfilrecv ()
  356. {
  357.     filargs.filflg = filargs.fildflg;    /* default flags are active */
  358.     warn = !(filargs.filflg & FIL_OKILL);    /* set kermit flag */
  359.     binary = (filargs.filflg & FIL_BINA);    /* selected binary mode? */
  360.     filargs.filsiz = 0;        /* no known size */
  361. }                /* initfilrecv */
  362.  
  363.  
  364.  
  365. /****************************************************************************/
  366. /****************************************************************************/
  367. initfilset ()
  368. {
  369.     filargs.filvol = 0;        /* default volume is always default */
  370.     filargs.fildflg = FIL_DATA | FIL_TEXT;    /* default file setting */
  371.     /* if no settings file */
  372. }                /* initfilset */
  373.  
  374.  
  375.  
  376. /****************************************************************************/
  377. /****************************************************************************/
  378. int
  379. dogetfdialog (remf)
  380. char *remf[];
  381. {
  382.     DialogPtr getfdlg;
  383.     ControlHandle getbhdl;
  384.     Handle remfhdl;
  385.     short item;
  386.  
  387.     getfdlg = GetNewDialog (DLG_GETF, NILPTR, (WindowPtr) - 1);
  388.     circleOK(getfdlg);
  389.     
  390.     remfhdl = gethdl (GETF_REMF, getfdlg);
  391.     getbhdl = getctlhdl (GETF_GETB, getfdlg);
  392.     HiliteControl (getbhdl, 255);    /* start with deactive Get button */
  393.  
  394.     for (;;) {
  395.     ModalDialog (NILPROC, &item);
  396.     switch (item) {
  397.       case ok:
  398.         if (filargs.filrem[0] == '\0')    /* no file name? */
  399.         break;        /* then they hit CR, don't allow */
  400.         *remf = filargs.filrem;    /* fill in for return */
  401.         initfilrecv ();    /* init recv flags */
  402.       case cancel:
  403.         DisposDialog (getfdlg);
  404.         return (item == ok);
  405.       case GETF_REMF:
  406.         GetIText (remfhdl, filargs.filrem);
  407.         HiliteControl (getbhdl, (filargs.filrem[0] == 0) ? 255 : 0);
  408.         break;
  409.     }
  410.     }
  411. }                /* dogetfdialog */
  412.  
  413.  
  414.  
  415. #define RSXLEN 5        /* ".rsrc" length */
  416.  
  417. /****************************************************************************/
  418. /* sfprtol - translate remote file name to a local file name and */
  419. /*          and figure out the flags as well. */
  420. /****************************************************************************/
  421. int
  422. sfprtol (fn)
  423. char *fn;
  424. {
  425.     int l;
  426.     register char *cp;
  427.     
  428.     for (cp = fn; *cp; cp++) {        /* convert to lower case */
  429.     if (isupper(*cp))
  430.         *cp = tolower(*cp);
  431.     if (*cp == ':')            /* nuke colons (for Mac) */
  432.         *cp = '_';
  433.     }
  434.     
  435.     if ((l = strlen (fn)) > RSXLEN &&    /* big enough? */
  436.     (strcmp (&fn[l - RSXLEN], ".rsrc") == 0 ||    /* and matches
  437.                              * extension? */
  438.      strcmp (&fn[l - RSXLEN], ".RSRC") == 0)) {    /* either way? */
  439.     fn[l - RSXLEN] = '\0';    /* so remove the extension */
  440.     return (FIL_BINA | FIL_RSRC);    /* want rsrc and binary */
  441.     }
  442.     return (filargs.fildflg & FIL_RBDT);    /* else return default */
  443. }                /* sfprtol */
  444.