home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************************
- * *
- * This is a complete working implementation of a plug. *
- * It transfers ascii files with delay. *
- * *
- * ------------------------------------------------------------------ *
- * *
- * No copyright by Markus Schmidt, 1993 *
- * *
- ***********************************************************************/
-
- #define INCL_WINSHELLDATA
- #define INCL_WINDIALOGS
- #define INCL_WINWINDOWMGR
- #define INCL_WINMESSAGEMGR
- #define INCL_WINSTDFILE
- #define INCL_WINBUTTONS
- #define INCL_WINENTRYFIELDS
-
- #define INCL_DOSPROCESS
- #define INCL_DOSFILEMGR
-
- #define INCL_NOCOMMON
- #include <os2.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- // pip include
- #define PIP_INCL_PLUG
- #include "pip.h"
-
- // our private includefile
- #include "pipascii.h"
-
- #define INI_KEY "Ascii by M.Schmidt" // Key for OS2.INI
-
- // declare a parameter struct for the transfer
- typedef struct _TRANSFER_PARM {
- int delay; // delay between characters
- BOOL show_echo; // strip LF from instream
- char entrybuf[3+1]; // buffer for entryfield
- } TRANSFER_PARM;
-
-
- // private functions (externs are declared in PIP.H)
- static MRESULT EXPENTRY OptsDlgProc(HWND , ULONG , MPARAM , MPARAM );
- static MRESULT EXPENTRY TransDlgProc(HWND , ULONG , MPARAM , MPARAM );
- static void Center(HWND hwndRef, HWND hwndCentr);
- static char * AskFilename(char *title, char *path);
-
-
- ////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////
- // PLUG PUBLIC PART //
- ////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////
-
-
- /***********************************************************************
- * Introduce ourselves to the socket *
- * *
- * *
- ***********************************************************************/
- int pipIntro(PIP_SOCKET const * const pps, PIP_PLUG * const ppp)
- {
- if (!PIP_COMPATIBLE(pps->PipVersion,PIP_VERSION))
- return (PIP_ERROR);
-
- // My name is UPLOAD, ASCII UPLOAD
- strcpy(ppp->PlugName, "ASCII");
- strcpy(ppp->PlugDescription, "Upload of ASCII files");
- // ... and I'm a file transfer protocol
- ppp->PlugType= PIP_TYPE_PROTOCOL;
-
- // We're capable of uploading single files and we can
- // do an options-dialog and filerequester under pm
- ppp->PlugBits= PIP_PBIT_SINGLEUPLOAD |
- PIP_PBIT_PM_OPTIONS |
- PIP_PBIT_PM_FILEREQUESTER |
- PIP_PBIT_DISABLE_DOWNLOAD ;
-
- // Tell him which version we use
- ppp->PlugPipVersion= PIP_VERSION;
-
- return (PIP_OK);
- }
-
-
- /***********************************************************************
- * Initialize things *
- * Allocate a nice parameter structure (nice guys don't use static *
- * in DLLs) and fetch default values from INI file *
- ***********************************************************************/
- int pipInit(PIP_SOCKET const * const pps, PIP_PLUG * const ppp)
- {
- int rc=PIP_ERROR;
- TRANSFER_PARM *ptp;
-
- if (PIP_COMPATIBLE(pps->PipVersion,PIP_VERSION)) {
-
- ppp->PlugPrivate= malloc(sizeof(TRANSFER_PARM));
-
- if (ppp->PlugPrivate!=NULL) {
- ULONG howmany;
-
- // preset values, in case no INI-Section there
- ptp= ppp->PlugPrivate;
- ptp->delay=20;
- ptp->show_echo= TRUE;
-
- // load init params from OS2.INI
- howmany= sizeof(TRANSFER_PARM);
- PrfQueryProfileData(HINI_USERPROFILE, PIP_INIAPPL, INI_KEY,
- ppp->PlugPrivate, &howmany);
-
- rc= PIP_OK;
- }
-
- }
-
- return (rc);
- }
-
-
- /***********************************************************************
- * Display a setup-window and store data to TRANSFER_PARM *
- * *
- * *
- ***********************************************************************/
- int pipSetup(PIP_SOCKET const * const pps, PIP_PLUG * const ppp)
- {
- HWND hwndDlg;
- int rc;
-
- if (!PIP_COMPATIBLE(pps->PipVersion,PIP_VERSION))
- return (PIP_ERROR);
-
- // this should not happen, but: never trust a socket
- if (ppp->PlugPrivate==NULL || pps->hab==0)
- return (PIP_ERROR); // err if init failed or not pm appl.
-
- // open and process modal dialog on the socket window
- hwndDlg= WinLoadDlg(HWND_DESKTOP, pps->dlgHwndFrame,
- OptsDlgProc, // our DlgProc
- ppp->hmPlugDll,IDD_DLG_OPTIONS, // get OPTIONS dialog from DLL
- ppp->PlugPrivate); // give the parameter block to the DlgProc
-
- Center(pps->dlgHwndFrame, hwndDlg);
-
- rc= WinProcessDlg(hwndDlg);
- WinDestroyWindow(hwndDlg);
-
- if (rc==DID_OK) {
- PrfWriteProfileData(HINI_USERPROFILE, PIP_INIAPPL, INI_KEY,
- ppp->PlugPrivate, sizeof(TRANSFER_PARM));
- }
-
- return (PIP_OK);
- }
-
-
- /***********************************************************************
- * Transfer a file *
- * *
- * *
- ***********************************************************************/
- int pipSend(PIP_SOCKET const * const pps, PIP_PLUG * const ppp,
- unsigned char *path, unsigned char **multipath)
- {
- char inpath[CCHMAXPATH]= "";
- HWND hwndTransfer;
- int rc= PIP_ERROR;
- TRANSFER_PARM *ptp= ppp->PlugPrivate;
-
- if (!PIP_COMPATIBLE(pps->PipVersion,PIP_VERSION))
- return (PIP_ERROR);
-
- // this should not happen, but: never trust a socket
- if (ppp->PlugPrivate==NULL || multipath!=NULL ||
- path==NULL && pps->hab==0) // we can't filereq. outside pm
- return (rc);
-
- // if no filename given, ask for one
- if (path==NULL) {
- // use default upload dir for the filerequester
- strcpy(inpath, pps->szUploadDir);
- // show filerequester
- path= AskFilename("File to send", inpath);
- }
-
- if (path!=NULL) { // could be NULL, if the user canceled
- char buf[80];
- FILE *f;
- int cnt= 0;
-
- // here we go to send our stuff
-
- // load the transferwindow from resource
- hwndTransfer= WinLoadDlg(HWND_DESKTOP, pps->dlgHwndFrame,
- TransDlgProc,
- ppp->hmPlugDll,IDD_DLG_TRANSFER,
- NULL);
-
- Center(pps->dlgHwndFrame, hwndTransfer);
-
- // show the filename
- WinSetDlgItemText(hwndTransfer, IDD_STAT_FILENAME, path);
-
- // read and send bytes
- f= pps->fopen(path, "r", 0L);
- if (f) {
- for (cnt=0; !feof(f); cnt++) {
- int c;
-
- // IMPORTANT!! IMPORTANT!! IMPORTANT!! IMPORTANT!!
- // IMPORTANT!! IMPORTANT!! IMPORTANT!! IMPORTANT!!
- // Since we control the application, we must ensure
- // that incoming messages are processed now and then!!
-
- pps->CoreLoop();
-
- // IMPORTANT!! IMPORTANT!! IMPORTANT!! IMPORTANT!!
- // IMPORTANT!! IMPORTANT!! IMPORTANT!! IMPORTANT!!
-
-
- // read character from file
- c= pps->fgetc(f);
-
- // break if end of file
- if (c==EOF)
- break;
-
- // break if our window is not longer accessible
- if (!WinIsWindow(pps->hab, hwndTransfer) ||
- WinWindowFromID(HWND_DESKTOP,IDD_DLG_TRANSFER)==0) {
- hwndTransfer= 0;
- break;
- }
-
- if (c=='\n')
- c= '\r';
-
- // send the character to the serial device
- pps->ioSerPutChar(c);
- DosSleep(ptp->delay);
-
- // show counter in the window
- sprintf(buf, "%d", cnt);
- WinSetDlgItemText(hwndTransfer, IDD_STAT_SENT, buf);
-
- // if echo wanted put incoming characters to the console
- if (ptp->show_echo) {
- // as long as bytes available
- while (pps->ioSerQueryAvail()>0) {
- // read one
- c= pps->ioSerGetChar();
- // print one
- if (c!=PIP_READ_NODATA)
- pps->ioConPutChar(c);
- }
- }
- }
-
- pps->fclose(f);
- rc= PIP_OK;
- }
-
- // if not already closed, destroy transfer window
- if (hwndTransfer!=0)
- WinDestroyWindow(hwndTransfer);
- }
-
- return (rc);
- }
-
-
- /***********************************************************************
- * ASCII download not supported. However: Function must exist *
- * *
- * *
- ***********************************************************************/
- int pipReceive(PIP_SOCKET const * const pps, PIP_PLUG * const ppp,
- unsigned char *path, unsigned char **multipath)
- {
- return (PIP_ERROR);
- }
-
-
- /***********************************************************************
- * Free the parameter block *
- * *
- * *
- ***********************************************************************/
- int pipCleanup(PIP_SOCKET const * const pps, PIP_PLUG * const ppp)
- {
- int rc= PIP_ERROR;
-
-
- if (PIP_COMPATIBLE(pps->PipVersion,PIP_VERSION)) {
-
- if (ppp->PlugPrivate!=NULL) {
- free(ppp->PlugPrivate);
- ppp->PlugPrivate= NULL;
- rc= PIP_OK;
- }
-
- }
-
- return (rc);
- }
-
-
-
- ////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////
- // PLUG PRIVATE PART //
- ////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////
-
-
- /***********************************************************************
- * Window procedure for the options dialog *
- * *
- * *
- ***********************************************************************/
- MRESULT EXPENTRY
- OptsDlgProc(HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2)
- {
- MRESULT rc= (MRESULT)FALSE;
- TRANSFER_PARM *ptp;
- char buf[3+1];
-
- switch (msg) {
-
- /*****************************************************
- * Dialog initialisation:
- * Get ASCII-Parameter pointer and fill dialog items
- ******************************************************/
- case WM_INITDLG:
- // save the init parameter (addr. of ascii parm)
- // in the user window word for later use
- WinSetWindowULong(hwndDlg, QWL_USER, LONGFROMMP(mp2));
-
- // get parameter address
- ptp= (TRANSFER_PARM*)WinQueryWindowULong(hwndDlg, QWL_USER);
-
- // fill entryfield "delay"
- sprintf(buf, "%3.3d", ptp->delay);
- WinSendDlgItemMsg(hwndDlg, IDD_ENTRY_DELAY, EM_SETTEXTLIMIT,
- MPFROMSHORT(sizeof(buf)-1), 0L);
- WinSetDlgItemText(hwndDlg, IDD_ENTRY_DELAY, buf);
-
- // fill entryfield "cr only"
- WinSendDlgItemMsg(hwndDlg, IDD_CHK_SHOWECHO, BM_SETCHECK,
- MPFROMSHORT(ptp->show_echo), 0L);
- break;
-
- /*****************************************************
- * COMMAND means OK or CANCEL button:
- * If OK, fetch actual values from dialog fields
- ******************************************************/
- case WM_COMMAND:
- switch(SHORT1FROMMP(mp1)) { /* Extract the command value */
- // The Enter pushbutton or key.
- case DID_OK:
- ptp= (TRANSFER_PARM*)WinQueryWindowULong(hwndDlg, QWL_USER);
-
- // query delay from entryfield
- WinQueryDlgItemText(hwndDlg, IDD_ENTRY_DELAY,
- sizeof(buf), buf);
- ptp->delay= atoi(buf);
-
- // query cr-only from check
- ptp->show_echo= (BOOL)WinSendDlgItemMsg(hwndDlg,
- IDD_CHK_SHOWECHO, BM_QUERYCHECK,
- 0L, 0L);
- break;
-
- // The Cancel pushbutton or key.
- case DID_CANCEL:
- break;
- }
- WinDismissDlg(hwndDlg, SHORT1FROMMP(mp1));
- break;
-
- /*************************
- * Default stuff go here *
- *************************/
- default:
- rc= WinDefDlgProc(hwndDlg, msg, mp1, mp2);
- }
-
- return (rc);
- }
-
-
-
-
- /***********************************************************************
- * Window procedure for the transfer window *
- * *
- * *
- ***********************************************************************/
- MRESULT EXPENTRY
- TransDlgProc(HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2)
- {
- MRESULT rc= (MRESULT)FALSE;
-
- switch (msg) {
-
- // Destroy window for CANCEL to indicate the end to main loop
- case WM_COMMAND:
- if (SHORT1FROMMP(mp1) == DID_CANCEL) {
- WinDestroyWindow(hwndDlg);
- rc= (MRESULT)TRUE;
- }
- else
- goto DefProc;
- break;
-
- // all else goes here
- DefProc:
- default:
- rc= WinDefDlgProc(hwndDlg, msg, mp1, mp2);
- }
-
- return (rc);
- }
-
-
-
-
- /***********************************************************************
- * Center a window over another *
- * *
- * *
- ***********************************************************************/
- void
- Center(HWND hwndRef, HWND hwndCentr)
- {
- RECTL rcl2;
- SWP swp;
-
- if (hwndRef==0)
- hwndRef=HWND_DESKTOP;
-
- WinQueryWindowPos(hwndRef, &swp);
- WinQueryWindowRect(hwndCentr,&rcl2);
-
- if (swp.cx > rcl2.xRight) // if screen < window
- rcl2.xLeft= (swp.cx-rcl2.xRight) /2; // center it
- else
- rcl2.xLeft= 0;
-
- if (swp.cy > rcl2.yTop) // if screen < window
- rcl2.yBottom= (swp.cy-rcl2.yTop) /2; // center it
- else
- rcl2.yBottom= swp.cy-rcl2.yTop;
-
- if (!WinIsChild(hwndCentr, hwndRef)) {
- rcl2.xLeft+= swp.x;
- rcl2.yBottom+= swp.y;
- }
-
- WinSetWindowPos(hwndCentr, 0,
- rcl2.xLeft, rcl2.yBottom,
- 0,0, SWP_MOVE | SWP_SHOW);
- }
-
-
-
-
- /***********************************************************************
- * Ask for a filename in a filerequester *
- * Path may be a directory or wildcard or default filename *
- * *
- ***********************************************************************/
- char *
- AskFilename(char *title, char *path)
- {
- static FILEDLG fdlg;
- FILESTATUS3 fs3;
- int rc;
-
- memset(&fdlg, 0, sizeof(fdlg));
- fdlg.cbSize= sizeof(fdlg);
- fdlg.fl= FDS_OPEN_DIALOG | FDS_CENTER;
- fdlg.pszTitle= title;
-
- if (path[0]=='\\' || path[1]==':') { // Full qualified name
- strcpy(fdlg.szFullFile, path);
- }
- else { // make full qualified name and append given path
- DosQueryPathInfo(".", FIL_QUERYFULLNAME,
- fdlg.szFullFile, sizeof(fdlg.szFullFile));
- strcat(fdlg.szFullFile, "\\");
- strcat(fdlg.szFullFile, path);
- }
-
-
- // If directory, append "\\*"
- rc= DosQueryPathInfo(fdlg.szFullFile, FIL_STANDARD, &fs3, sizeof(fs3));
- if (rc==0 && (fs3.attrFile & FILE_DIRECTORY)!=0) {
- strcat(fdlg.szFullFile, "\\*");
- }
-
- if (WinFileDlg(HWND_DESKTOP, HWND_DESKTOP, &fdlg)!=0 &&
- fdlg.lReturn==DID_OK) {
-
- // return full name
- return(fdlg.szFullFile);
- }
- else
- return(NULL);
- }
-