home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / wps / com / zocdev / pip / pipascii.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-02  |  15.8 KB  |  521 lines

  1. /***********************************************************************
  2. *                                                                      *
  3. *   This is a complete working implementation of a plug.               *
  4. *   It transfers ascii files with delay.                               *
  5. *                                                                      *
  6. *   ------------------------------------------------------------------ *
  7. *                                                                      *
  8. *   No copyright by Markus Schmidt, 1993                               *
  9. *                                                                      *
  10. ***********************************************************************/
  11.  
  12. #define INCL_WINSHELLDATA
  13. #define INCL_WINDIALOGS
  14. #define INCL_WINWINDOWMGR
  15. #define INCL_WINMESSAGEMGR
  16. #define INCL_WINSTDFILE
  17. #define INCL_WINBUTTONS
  18. #define INCL_WINENTRYFIELDS
  19.  
  20. #define INCL_DOSPROCESS
  21. #define INCL_DOSFILEMGR
  22.  
  23. #define INCL_NOCOMMON
  24. #include <os2.h>
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28.  
  29. // pip include
  30. #define PIP_INCL_PLUG
  31. #include "pip.h"
  32.  
  33. // our private includefile
  34. #include "pipascii.h"
  35.  
  36. #define INI_KEY     "Ascii by M.Schmidt"            // Key for OS2.INI 
  37.  
  38. // declare a parameter struct for the transfer
  39. typedef struct _TRANSFER_PARM {
  40.     int delay;        // delay between characters
  41.     BOOL show_echo;    // strip LF from instream
  42.     char entrybuf[3+1];    // buffer for entryfield
  43. } TRANSFER_PARM;
  44.  
  45.  
  46. // private functions (externs are declared in PIP.H)
  47. static MRESULT EXPENTRY OptsDlgProc(HWND , ULONG , MPARAM , MPARAM );
  48. static MRESULT EXPENTRY TransDlgProc(HWND , ULONG , MPARAM , MPARAM );
  49. static void Center(HWND hwndRef, HWND hwndCentr);
  50. static char * AskFilename(char *title, char *path);
  51.  
  52.  
  53. ////////////////////////////////////////////////////////////////////////
  54. ////////////////////////////////////////////////////////////////////////
  55. ////////////////////////////////////////////////////////////////////////
  56. //  PLUG PUBLIC PART                                                  //
  57. ////////////////////////////////////////////////////////////////////////
  58. ////////////////////////////////////////////////////////////////////////
  59. ////////////////////////////////////////////////////////////////////////
  60.  
  61.  
  62. /***********************************************************************
  63. *   Introduce ourselves to the socket                                  *
  64. *                                                                      *
  65. *                                                                      *
  66. ***********************************************************************/
  67. int pipIntro(PIP_SOCKET const * const pps, PIP_PLUG * const ppp)
  68. {
  69.     if (!PIP_COMPATIBLE(pps->PipVersion,PIP_VERSION))
  70.         return (PIP_ERROR);
  71.  
  72.     // My name is UPLOAD, ASCII UPLOAD
  73.     strcpy(ppp->PlugName, "ASCII");
  74.     strcpy(ppp->PlugDescription, "Upload of ASCII files");
  75.     // ... and I'm a file transfer protocol
  76.     ppp->PlugType= PIP_TYPE_PROTOCOL;
  77.  
  78.     // We're capable of uploading single files and we can
  79.     // do an options-dialog and filerequester under pm 
  80.     ppp->PlugBits=    PIP_PBIT_SINGLEUPLOAD |
  81.                     PIP_PBIT_PM_OPTIONS |
  82.                     PIP_PBIT_PM_FILEREQUESTER |
  83.                     PIP_PBIT_DISABLE_DOWNLOAD ;
  84.  
  85.     // Tell him which version we use
  86.     ppp->PlugPipVersion= PIP_VERSION;
  87.  
  88.     return (PIP_OK);
  89. }
  90.  
  91.  
  92. /***********************************************************************
  93. *   Initialize things                                                  *
  94. *   Allocate a nice parameter structure (nice guys don't use static    *
  95. *   in DLLs) and fetch default values from INI file                    *
  96. ***********************************************************************/
  97. int pipInit(PIP_SOCKET const * const pps, PIP_PLUG * const ppp)
  98. {
  99.     int rc=PIP_ERROR;
  100.     TRANSFER_PARM *ptp;
  101.  
  102.     if (PIP_COMPATIBLE(pps->PipVersion,PIP_VERSION)) {
  103.  
  104.         ppp->PlugPrivate= malloc(sizeof(TRANSFER_PARM));
  105.  
  106.         if (ppp->PlugPrivate!=NULL) {
  107.             ULONG howmany;
  108.  
  109.             // preset values, in case no INI-Section there
  110.             ptp= ppp->PlugPrivate;
  111.             ptp->delay=20;
  112.             ptp->show_echo= TRUE;
  113.  
  114.             // load init params from OS2.INI
  115.             howmany= sizeof(TRANSFER_PARM);
  116.             PrfQueryProfileData(HINI_USERPROFILE, PIP_INIAPPL, INI_KEY,
  117.                                 ppp->PlugPrivate, &howmany);
  118.  
  119.             rc= PIP_OK;
  120.         }
  121.  
  122.     }
  123.  
  124.     return (rc);
  125. }
  126.  
  127.  
  128. /***********************************************************************
  129. *   Display a setup-window and store data to TRANSFER_PARM             *
  130. *                                                                      *
  131. *                                                                      *
  132. ***********************************************************************/
  133. int pipSetup(PIP_SOCKET const * const pps, PIP_PLUG * const ppp)
  134. {
  135.     HWND hwndDlg;
  136.     int rc; 
  137.  
  138.     if (!PIP_COMPATIBLE(pps->PipVersion,PIP_VERSION))
  139.         return (PIP_ERROR);
  140.  
  141.     // this should not happen, but: never trust a socket
  142.     if (ppp->PlugPrivate==NULL || pps->hab==0)
  143.         return (PIP_ERROR);    // err if init failed or not pm appl.
  144.  
  145.      // open and process modal dialog on the socket window
  146.     hwndDlg= WinLoadDlg(HWND_DESKTOP, pps->dlgHwndFrame,
  147.             OptsDlgProc,         // our DlgProc
  148.             ppp->hmPlugDll,IDD_DLG_OPTIONS, // get OPTIONS dialog from DLL
  149.             ppp->PlugPrivate);    // give the parameter block to the DlgProc
  150.  
  151.     Center(pps->dlgHwndFrame, hwndDlg);
  152.  
  153.     rc= WinProcessDlg(hwndDlg);
  154.     WinDestroyWindow(hwndDlg);
  155.  
  156.     if (rc==DID_OK) {
  157.         PrfWriteProfileData(HINI_USERPROFILE, PIP_INIAPPL, INI_KEY, 
  158.                     ppp->PlugPrivate, sizeof(TRANSFER_PARM));
  159.     }
  160.  
  161.     return (PIP_OK);
  162. }
  163.  
  164.  
  165. /***********************************************************************
  166. *   Transfer a file                                                    *
  167. *                                                                      *
  168. *                                                                      *
  169. ***********************************************************************/
  170. int pipSend(PIP_SOCKET const * const pps, PIP_PLUG * const ppp,
  171.             unsigned char *path, unsigned char **multipath)
  172. {
  173.     char inpath[CCHMAXPATH]= "";
  174.     HWND hwndTransfer;
  175.     int rc= PIP_ERROR;
  176.     TRANSFER_PARM *ptp= ppp->PlugPrivate;
  177.  
  178.     if (!PIP_COMPATIBLE(pps->PipVersion,PIP_VERSION))
  179.         return (PIP_ERROR);
  180.  
  181.     // this should not happen, but: never trust a socket
  182.     if (ppp->PlugPrivate==NULL || multipath!=NULL ||
  183.         path==NULL && pps->hab==0)    // we can't filereq. outside pm
  184.         return (rc);
  185.  
  186.     // if no filename given, ask for one
  187.     if (path==NULL) {
  188.         // use default upload dir for the filerequester
  189.         strcpy(inpath, pps->szUploadDir);
  190.         // show filerequester
  191.         path= AskFilename("File to send", inpath);
  192.     }
  193.  
  194.     if (path!=NULL) {    // could be NULL, if the user canceled
  195.         char buf[80];
  196.         FILE *f;
  197.         int cnt= 0;
  198.  
  199.         // here we go to send our stuff
  200.  
  201.         // load the transferwindow from resource
  202.         hwndTransfer= WinLoadDlg(HWND_DESKTOP,  pps->dlgHwndFrame,
  203.                         TransDlgProc, 
  204.                         ppp->hmPlugDll,IDD_DLG_TRANSFER,
  205.                         NULL); 
  206.  
  207.         Center(pps->dlgHwndFrame, hwndTransfer);
  208.  
  209.         // show the filename
  210.         WinSetDlgItemText(hwndTransfer, IDD_STAT_FILENAME, path);
  211.  
  212.         // read and send bytes
  213.         f= pps->fopen(path, "r", 0L);
  214.         if (f) {
  215.             for (cnt=0; !feof(f); cnt++) {
  216.                 int c;
  217.  
  218.                 // IMPORTANT!! IMPORTANT!! IMPORTANT!! IMPORTANT!!
  219.                 // IMPORTANT!! IMPORTANT!! IMPORTANT!! IMPORTANT!!
  220.                 // Since we control the application, we must ensure
  221.                 // that incoming messages are processed now and then!!
  222.  
  223.                 pps->CoreLoop();
  224.  
  225.                 // IMPORTANT!! IMPORTANT!! IMPORTANT!! IMPORTANT!!
  226.                 // IMPORTANT!! IMPORTANT!! IMPORTANT!! IMPORTANT!!
  227.  
  228.  
  229.                 // read character from file
  230.                 c= pps->fgetc(f);
  231.  
  232.                 // break if end of file
  233.                 if (c==EOF)
  234.                     break;
  235.  
  236.                 // break if our window is not longer accessible
  237.                 if (!WinIsWindow(pps->hab, hwndTransfer) ||
  238.                     WinWindowFromID(HWND_DESKTOP,IDD_DLG_TRANSFER)==0) {
  239.                     hwndTransfer= 0;
  240.                     break;
  241.                 }
  242.  
  243.                 if (c=='\n')
  244.                     c= '\r';
  245.  
  246.                 // send the character to the serial device
  247.                 pps->ioSerPutChar(c);
  248.                 DosSleep(ptp->delay);
  249.  
  250.                 // show counter in the window
  251.                 sprintf(buf, "%d", cnt);
  252.                 WinSetDlgItemText(hwndTransfer, IDD_STAT_SENT, buf);
  253.  
  254.                 // if echo wanted put incoming characters to the console
  255.                 if (ptp->show_echo) {
  256.                     // as long as bytes available
  257.                     while (pps->ioSerQueryAvail()>0) {
  258.                         // read one
  259.                         c= pps->ioSerGetChar();
  260.                         // print one
  261.                         if (c!=PIP_READ_NODATA)
  262.                             pps->ioConPutChar(c);
  263.                     }
  264.                 }
  265.             }
  266.  
  267.             pps->fclose(f);
  268.             rc= PIP_OK;
  269.         }
  270.  
  271.         // if not already closed, destroy transfer window
  272.         if (hwndTransfer!=0)
  273.             WinDestroyWindow(hwndTransfer);
  274.     }
  275.  
  276.     return (rc);
  277. }
  278.  
  279.  
  280. /***********************************************************************
  281. *   ASCII download not supported. However: Function must exist         *
  282. *                                                                      *
  283. *                                                                      *
  284. ***********************************************************************/
  285. int pipReceive(PIP_SOCKET const * const pps, PIP_PLUG * const ppp,
  286.                 unsigned char *path, unsigned char **multipath)
  287. {
  288.     return (PIP_ERROR);
  289. }
  290.  
  291.  
  292. /***********************************************************************
  293. *   Free the parameter block                                           *
  294. *                                                                      *
  295. *                                                                      *
  296. ***********************************************************************/
  297. int pipCleanup(PIP_SOCKET const * const pps, PIP_PLUG * const ppp)
  298. {
  299.     int rc= PIP_ERROR; 
  300.  
  301.  
  302.     if (PIP_COMPATIBLE(pps->PipVersion,PIP_VERSION)) {
  303.  
  304.         if (ppp->PlugPrivate!=NULL) {
  305.             free(ppp->PlugPrivate);
  306.             ppp->PlugPrivate= NULL;
  307.             rc= PIP_OK;
  308.         }
  309.  
  310.     }
  311.  
  312.     return (rc);
  313. }
  314.  
  315.  
  316.  
  317. ////////////////////////////////////////////////////////////////////////
  318. ////////////////////////////////////////////////////////////////////////
  319. ////////////////////////////////////////////////////////////////////////
  320. //  PLUG PRIVATE PART                                                 //
  321. ////////////////////////////////////////////////////////////////////////
  322. ////////////////////////////////////////////////////////////////////////
  323. ////////////////////////////////////////////////////////////////////////
  324.  
  325.  
  326. /***********************************************************************
  327. *    Window procedure for the options dialog                           *
  328. *                                                                      *
  329. *                                                                      *
  330. ***********************************************************************/
  331. MRESULT EXPENTRY 
  332. OptsDlgProc(HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2)
  333. {
  334.     MRESULT rc= (MRESULT)FALSE;
  335.     TRANSFER_PARM *ptp;
  336.     char buf[3+1];
  337.  
  338.     switch (msg) {
  339.  
  340.         /*****************************************************
  341.         * Dialog initialisation: 
  342.         * Get ASCII-Parameter pointer and fill dialog items
  343.         ******************************************************/
  344.         case WM_INITDLG:
  345.             // save the init parameter (addr. of ascii parm) 
  346.             // in the user window word for later use
  347.             WinSetWindowULong(hwndDlg, QWL_USER, LONGFROMMP(mp2));
  348.  
  349.             // get parameter address
  350.             ptp= (TRANSFER_PARM*)WinQueryWindowULong(hwndDlg, QWL_USER);
  351.  
  352.             // fill entryfield "delay" 
  353.             sprintf(buf, "%3.3d", ptp->delay);
  354.             WinSendDlgItemMsg(hwndDlg, IDD_ENTRY_DELAY, EM_SETTEXTLIMIT,
  355.                                     MPFROMSHORT(sizeof(buf)-1), 0L);
  356.             WinSetDlgItemText(hwndDlg, IDD_ENTRY_DELAY, buf);
  357.  
  358.             // fill entryfield "cr only" 
  359.             WinSendDlgItemMsg(hwndDlg, IDD_CHK_SHOWECHO, BM_SETCHECK, 
  360.                                     MPFROMSHORT(ptp->show_echo), 0L);
  361.             break;
  362.  
  363.         /*****************************************************
  364.         * COMMAND means OK or CANCEL button:
  365.         * If OK, fetch actual values from dialog fields
  366.         ******************************************************/
  367.         case WM_COMMAND: 
  368.             switch(SHORT1FROMMP(mp1)) { /* Extract the command value */
  369.                 // The Enter pushbutton or key. 
  370.                 case DID_OK:
  371.                     ptp= (TRANSFER_PARM*)WinQueryWindowULong(hwndDlg, QWL_USER);
  372.  
  373.                     // query delay from entryfield
  374.                     WinQueryDlgItemText(hwndDlg, IDD_ENTRY_DELAY, 
  375.                                         sizeof(buf), buf);
  376.                     ptp->delay= atoi(buf);
  377.  
  378.                     // query cr-only from check 
  379.                     ptp->show_echo= (BOOL)WinSendDlgItemMsg(hwndDlg,
  380.                                             IDD_CHK_SHOWECHO, BM_QUERYCHECK,
  381.                                             0L, 0L);
  382.                     break;
  383.  
  384.                 // The Cancel pushbutton or key. 
  385.                 case DID_CANCEL:
  386.                     break;
  387.             }
  388.             WinDismissDlg(hwndDlg, SHORT1FROMMP(mp1));
  389.             break;
  390.  
  391.         /*************************
  392.         * Default stuff go here  *
  393.         *************************/
  394.         default:
  395.             rc= WinDefDlgProc(hwndDlg, msg, mp1, mp2);
  396.     }
  397.  
  398.     return (rc);
  399. }
  400.  
  401.  
  402.  
  403.  
  404. /***********************************************************************
  405. *    Window procedure for the transfer window                          *
  406. *                                                                      *
  407. *                                                                      *
  408. ***********************************************************************/
  409. MRESULT EXPENTRY 
  410. TransDlgProc(HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2)
  411. {
  412.     MRESULT rc= (MRESULT)FALSE;
  413.  
  414.     switch (msg) {
  415.  
  416.         // Destroy window for CANCEL to indicate the end to main loop
  417.         case WM_COMMAND: 
  418.             if (SHORT1FROMMP(mp1) == DID_CANCEL) { 
  419.                 WinDestroyWindow(hwndDlg);
  420.                 rc= (MRESULT)TRUE;
  421.             }
  422.             else 
  423.                 goto DefProc;
  424.             break;
  425.  
  426.         // all else goes here
  427.         DefProc:
  428.         default:
  429.             rc= WinDefDlgProc(hwndDlg, msg, mp1, mp2);
  430.     }
  431.  
  432.     return (rc);
  433. }
  434.  
  435.  
  436.  
  437.  
  438. /***********************************************************************
  439. *    Center a window over another                                      *
  440. *                                                                      *
  441. *                                                                      *
  442. ***********************************************************************/
  443. void 
  444. Center(HWND hwndRef, HWND hwndCentr)
  445. {
  446.     RECTL rcl2;
  447.     SWP swp;
  448.  
  449.     if (hwndRef==0)
  450.         hwndRef=HWND_DESKTOP;
  451.  
  452.     WinQueryWindowPos(hwndRef, &swp);
  453.     WinQueryWindowRect(hwndCentr,&rcl2);
  454.  
  455.     if (swp.cx > rcl2.xRight)    // if screen < window 
  456.         rcl2.xLeft= (swp.cx-rcl2.xRight) /2;    // center it
  457.     else
  458.         rcl2.xLeft= 0;
  459.  
  460.     if (swp.cy > rcl2.yTop)    // if screen < window 
  461.         rcl2.yBottom= (swp.cy-rcl2.yTop) /2;    // center it
  462.     else
  463.         rcl2.yBottom= swp.cy-rcl2.yTop;
  464.  
  465.     if (!WinIsChild(hwndCentr, hwndRef)) {
  466.         rcl2.xLeft+= swp.x;
  467.         rcl2.yBottom+= swp.y;
  468.     }
  469.  
  470.     WinSetWindowPos(hwndCentr, 0,
  471.                   rcl2.xLeft, rcl2.yBottom,
  472.                   0,0, SWP_MOVE | SWP_SHOW);
  473. }
  474.  
  475.  
  476.  
  477.  
  478. /***********************************************************************
  479. *   Ask for a filename in a filerequester                              *
  480. *   Path may be a directory or wildcard or default filename            *
  481. *                                                                      *
  482. ***********************************************************************/
  483. char *
  484. AskFilename(char *title, char *path)
  485. {
  486.     static FILEDLG fdlg;
  487.     FILESTATUS3 fs3;
  488.     int rc;
  489.  
  490.     memset(&fdlg, 0, sizeof(fdlg));
  491.     fdlg.cbSize= sizeof(fdlg);
  492.     fdlg.fl= FDS_OPEN_DIALOG | FDS_CENTER;
  493.     fdlg.pszTitle= title;
  494.  
  495.     if (path[0]=='\\' || path[1]==':') {  // Full qualified name
  496.         strcpy(fdlg.szFullFile, path);
  497.     }
  498.     else {    // make full qualified name and append given path
  499.         DosQueryPathInfo(".", FIL_QUERYFULLNAME, 
  500.                 fdlg.szFullFile, sizeof(fdlg.szFullFile));
  501.         strcat(fdlg.szFullFile, "\\");
  502.         strcat(fdlg.szFullFile, path);
  503.     }
  504.  
  505.  
  506.     // If directory, append "\\*"
  507.     rc= DosQueryPathInfo(fdlg.szFullFile, FIL_STANDARD, &fs3, sizeof(fs3));
  508.     if (rc==0  && (fs3.attrFile & FILE_DIRECTORY)!=0) {
  509.         strcat(fdlg.szFullFile, "\\*");
  510.     }
  511.  
  512.     if (WinFileDlg(HWND_DESKTOP, HWND_DESKTOP, &fdlg)!=0 &&
  513.         fdlg.lReturn==DID_OK) {
  514.  
  515.         // return full name
  516.         return(fdlg.szFullFile);
  517.     }
  518.     else
  519.         return(NULL);
  520. }
  521.