Category : OS/2 Files
Archive   : ZOCDEV.ZIP
Filename : PIPASCII.C

 
Output of file : PIPASCII.C contained in archive : ZOCDEV.ZIP
/***********************************************************************
* *
* 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
#include
#include
#include

// 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);
}


  3 Responses to “Category : OS/2 Files
Archive   : ZOCDEV.ZIP
Filename : PIPASCII.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/