Category : OS/2 Files
Archive   : OS2CMAPI.ZIP
Filename : FILECREQ.C

 
Output of file : FILECREQ.C contained in archive : OS2CMAPI.ZIP
/************************************************************************/
/* */
/* MODULE NAME: FILECREQ.C */
/* */
/* DESCRIPTIVE NAME: APPC FILE REQUESTER C SAMPLE PROGRAM FOR */
/* OPERATING SYSTEM/2 EXTENDED EDITION */
/* */
/* COPYRIGHT = (C) COPYRIGHT IBM CORP. 1987,1988 */
/* LICENSED MATERIAL - PROGRAM PROPERTY OF IBM */
/* ALL RIGHTS RESERVED */
/* */
/* STATUS = LPP Release 1 Modification 0 */
/* */
/* FUNCTION = Issues a request for a file to a server and */
/* transfers the file to the default local disk */
/* (current directory). All data transfer is to */
/* a peer server via APPC calls. The program is */
/* invoked: */
/* */
/* FILECREQ filename */
/* */
/* The filename is a valid DOS filename on the server */
/* system. Both the server and requester sample programs */
/* use this filename for DOSOPEN so any subdirectory */
/* specified must be valid on both systems. */
/* */
/* Uses the following APPC Verbs: */
/* */
/* TP_STARTED */
/* MC_ALLOCATE */
/* MC_SEND_DATA */
/* MC_RECEIVE_AND_WAIT */
/* MC_CONFIRMED */
/* TP_ENDED */
/* */
/* Uses the following General Services verbs: */
/* */
/* CONVERT */
/* */
/* MODULE TYPE: IBM Personal Computer C/2 Compiler Version 1.1 */
/* (Compiles with Small Memory Model) */
/* */
/* Requires message file "APX.MSG" at runtime. */
/* */
/************************************************************************/
#define LINT_ARGS

#include
#include
#include
#include
#include
#include
#include

#define TRUE 1
#define FALSE 0

/* Macro clear_vcb sets the APPC verb control block to zeros */
#define clear_vcb() memset(&vcb,(int)'\0',sizeof(vcb))

typedef unsigned int BOOL;

BOOL sys_err = FALSE; /* Fatal system error flag */
BOOL prog_done = FALSE; /* Program done flag */
BOOL eof_flag = FALSE; /* End of File flag */
BOOL bad_filename = FALSE; /* Bad file name flag */
BOOL first_time = TRUE; /* First time executed flag */

unsigned short dos_rc; /* Save area for return codes */
unsigned short appc_rc_p; /* APPC Primary return code */
unsigned long appc_rc_s; /* APPC Secondary return code */

unsigned long conv_id; /* APPC Conversation id */
char tp_id[8]; /* APPC TP Id */
unsigned short what_rcvd; /* APPC What_Received value */

char al_tp_name[64]; /* tp_name for MC_ALLOCATE */
char al_mode_name[8]; /* mode name for MC_ALLOCATE */
char tps_tp_name[64]; /* tp_name for TP_STARTED */

unsigned short length; /* length of received data */
char filename[100]; /* filename for DOSOPEN */

unsigned char far *anbptr; /* Pointer to AlphaNumeric */
/* Buffer (shared) */

unsigned short filehandle; /* Returned by DOSOPEN */
unsigned short action; /* Returned by DOSOPEN */
unsigned short bytes_written; /* Returned by DOSWRITE */
unsigned long byte_count; /* Tally total bytes written */

char msg_buff[100]; /* Buffer for message data */
char msg_filename[] = "apx.msg"; /* Message file filename */

/*--------------------------------------------------------------------------*/
/* Verb Control Block - Union of Structures */
/*--------------------------------------------------------------------------*/

union {
struct mc_allocate alloc;
struct mc_receive_and_wait rcv_wait;
struct mc_send_data send;
struct mc_confirmed confirmed;
struct tp_started tpstart;
struct tp_ended tpend;
struct convert cnvt; /* General Svcs. Convert */
} vcb;

unsigned far *vcbptr; /* Pointer to the vcb */

#ifdef LINT_ARGS
/*--------------------------------------------------------------------------*/
/* Function Prototypes */
/*--------------------------------------------------------------------------*/
void main(int, char **);
void INIT_SELF(void);
void SHOW_MSG(unsigned short);
void SHOW_ERR(void);
void SHOW_DOS_ERROR(void);
void PARSE_FILENAME(char *);

void DO_TP_STARTED(void);
void DO_MC_ALLOCATE(void);
void DO_MC_RECEIVE_AND_WAIT(void);
void DO_MC_CONFIRMED(void);
void DO_TP_ENDED(void);

void ALLOC_SHARED_BUFFER(void);
void OPEN_DOS_FILE(void);
void CLOSE_DOS_FILE(void);
void WRITE_DOS_DATA(void);
void SEND_DOS_FILENAME(void);
#endif
/****************************************************************************/
/* */
/* Main Program Section */
/* */
/****************************************************************************/

void
main (argc, argv) /* Need argc,argv to get */
/* Filename from command line. */
int argc;
char *argv[];

{
INIT_SELF(); /* Do initialization */
PARSE_FILENAME(argv[1]); /* Get filename ready to send */

while ((! sys_err) && (! prog_done)) {
DO_TP_STARTED(); /* Tell APPC a TP has started */
if (! sys_err) {
DO_MC_ALLOCATE(); /* Alloc. session & start conv */
SEND_DOS_FILENAME(); /* Send filename we requested */

while ((! eof_flag) && (! sys_err) && (! bad_filename)) {
/* MAIN LOOP TO RCV. FILE DATA */
DO_MC_RECEIVE_AND_WAIT(); /* Wait to hear from Server */
if ((appc_rc_p != AP_OK) && /* Check retcode */
(appc_rc_p != AP_PROG_ERROR_NO_TRUNC)) {
/* Should be "ok" or "prog_err" */
printf ("\n"); sys_err = TRUE; SHOW_ERR();
/* if not, set sys_err & */
/* show error */
}
else {
if (appc_rc_p == AP_PROG_ERROR_NO_TRUNC)
/* Prog_err = File not found */
{SHOW_MSG (14); eof_flag = TRUE; break;}
/* Show "Not Found" msg. & quit */
what_rcvd = (*(unsigned *)&vcb.rcv_wait.what_rcvd);

if (what_rcvd == AP_DATA_COMPLETE)
/* Write file if we rcvd data */
WRITE_DOS_DATA();
else
if (what_rcvd == AP_CONFIRM_DEALLOCATE)
/* Confirm_dealloc says EOF */
{eof_flag = TRUE; DO_MC_CONFIRMED();}
/* And confirm that we are done */
else
{SHOW_MSG(15); /* Else show Bad WHAT_RCVD msg. */
printf ("%04X\n",what_rcvd);
/* and quit */
sys_err = TRUE;
break; }
}
}
prog_done = TRUE;
}
}

if (! bad_filename) CLOSE_DOS_FILE(); /* Close output file (if open) */
DO_TP_ENDED(); /* Tell APPC tran pgm is done */

dos_rc = DOSFREESEG(FP_SEG(anbptr)); /* Free the shared segment */
if (dos_rc != 0) {SHOW_DOS_ERROR();} /* Display err. if unsuccessful */
printf ("\n"); /* Skip a line */
SHOW_MSG(3); /* Show function complete msg. */

}

/****************************************************************************/
/* */
/* UTILITY FUNCTIONS */
/* */
/****************************************************************************/

void
INIT_SELF()
/* Do initialization housekeeping */
{
SHOW_MSG(2); /* Show the REQUESTER message */
vcbptr = (unsigned far *)&vcb; /* Get pointer to the vcb */
ALLOC_SHARED_BUFFER(); /* DOSALLOCSEG for APPC */
/* data buffer */

/* Translate ASCII to EBCDIC as required by APPC for names */

memset (al_tp_name, (int)' ',sizeof(al_tp_name));
/* all blanks */
memcpy (al_tp_name,"FILEMSVR",8); /* Set the tp_name for allocate */
clear_vcb(); /* Zero out the control block */
vcb.cnvt.opcode = SV_CONVERT; /* Do a CONVERT general service */
vcb.cnvt.direction = SV_ASCII_TO_EBCDIC; /* Cnvt ASCII to EBCDIC */
vcb.cnvt.char_set = SV_AE; /* AE conversion type */
vcb.cnvt.len = sizeof(al_tp_name); /* Convert 64 bytes */
vcb.cnvt.source = vcb.cnvt.target = (unsigned char far *)al_tp_name;
/* Addr. (Convert in place) */
ACSSVC_C ((long) vcbptr); /* Go convert it to EBCDIC */

memcpy (al_mode_name, "MODE1 ", 8); /* Set the mode name allocate */
clear_vcb(); /* Convert the MODE name next */
vcb.cnvt.opcode = SV_CONVERT;
vcb.cnvt.direction = SV_ASCII_TO_EBCDIC;
vcb.cnvt.char_set = SV_A; /* Conversion type A */
vcb.cnvt.len = sizeof(al_mode_name);
vcb.cnvt.source = vcb.cnvt.target = (unsigned char far *)al_mode_name;

ACSSVC_C ((long) vcbptr);

memset (tps_tp_name, (int)' ',sizeof(tps_tp_name));
/* all blanks */
memcpy (tps_tp_name,"FILEMREQ",8); /* Set tp_name for start_tp */
clear_vcb(); /* Convert the TP_ID to EBCDIC */
vcb.cnvt.opcode = SV_CONVERT;
vcb.cnvt.direction = SV_ASCII_TO_EBCDIC;
vcb.cnvt.char_set = SV_AE;
vcb.cnvt.len = sizeof(tps_tp_name);
vcb.cnvt.source = vcb.cnvt.target = (unsigned char far *)tps_tp_name;

ACSSVC_C ((long) vcbptr);
}

void
SHOW_MSG (msgno)
/* Displays the requested message number from the file SAM.MSG */

unsigned short msgno;
{
unsigned short msg_rc;
unsigned short msg_len;

msg_rc = DOSGETMESSAGE ((char far *)0,0,(char far *)msg_buff,
sizeof(msg_buff),msgno,(char far *)msg_filename,
(unsigned far *)&msg_len);
/* Read requested message */
/* from message file */
if (msg_rc != 0) {
printf("APPC Sample Program Error - Unable to process message file\n");
printf("Return code = %04d Message number = %04d \n",msg_rc,msgno);
return;
}
msg_buff[msg_len] = 0x00; /* Set msg. to a ASCIIZ string */
printf("%s",msg_buff); /* Display it */
}

void
SHOW_ERR ()
/* Displays the APPC Primary and Secondary return codes + the verb */

{
SHOW_MSG (10); /* APPC Error Primary RC = msg. */
printf ("%04X\n",appc_rc_p); /* Show Primary rc in hex */
SHOW_MSG (11); /* Secondary RC = msg. */
printf ("%08lX\n",appc_rc_s); /* Show Secondary rc in hex */
SHOW_MSG (18); /* APPC verb in error */
printf ("%04X\n",vcb.send.opcode); /* Show verb in hex */
}

void
SHOW_DOS_ERROR ()
/* Displays the most recent OS/2 non-zero return code. */

{
SHOW_MSG (12); /* OS/2 Error, RC = msg. */
printf ("%04d\n",dos_rc); /* Show the OS/2 rc in decimal */
}

void
PARSE_FILENAME (argv)
/* Convert requested filename (from the command line) into an ASCIIZ */
/* string that is headed by a LL (binary string length) byte. This */
/* allows the C and Pascal sample SERVER/REQUESTERS to be mixed. */
/* Place this string in the APPC data buffer in shared unnamed storage */

char *argv;
{

register unsigned filename_len; /* Includes the null byte */
strcpy (filename, argv); /* Save for DOSOPEN */
filename_len = strlen(filename);

anbptr[0] = (unsigned char)(++filename_len + 1);
/* Put length byte in string */
/* Add 1 for length byte itself */
/* and 1 for null byte on end. */

for (;filename_len; ) { /* Move filename, starting at */
filename_len--; /* end and working down to zero */
/* this includes the null byte */
anbptr[filename_len + 1] = filename[filename_len];
}
}

/****************************************************************************/
/* */
/* APPC RELATED FUNCTIONS */

/* */
/****************************************************************************/

void
DO_TP_STARTED()
{
clear_vcb(); /* Zero the vcb */
vcb.tpstart.opcode = AP_TP_STARTED; /* APPC verb - TP_STARTED */
memcpy (vcb.tpstart.lu_alias, "FILEREQ ", 8);
/* Set LU_ALIAS */
memcpy (vcb.tpstart.tp_name,tps_tp_name,sizeof(tps_tp_name));
/* Set TP_NAME */

APPC_C ((long) vcbptr); /* Call APPC */

appc_rc_p = vcb.tpstart.primary_rc;
appc_rc_s = vcb.tpstart.secondary_rc; /* Save the return codes */
if (appc_rc_p != AP_OK) {SHOW_ERR(); sys_err = TRUE; return;}
/* Handle any error */

memcpy (tp_id,vcb.tpstart.tp_id,sizeof(tp_id));
/* Save the TP_ID */
}

void
DO_MC_ALLOCATE ()
{
clear_vcb(); /* Zero out the vcb */
vcb.alloc.opcode = AP_M_ALLOCATE; /* Verb - MC_ALLOCATE */
vcb.alloc.opext = AP_MAPPED_CONVERSATION; /* Mapped Conversation type */
memcpy (vcb.alloc.tp_id, tp_id, sizeof(tp_id));
/* Set the TP_ID */
vcb.alloc.sync_level = AP_CONFIRM_SYNC_LEVEL;
/* Sync level-confirm */
vcb.alloc.rtn_ctl = AP_WHEN_SESSION_ALLOCATED;
/* Return when ses. allocated */
vcb.alloc.security = AP_NONE; /* No security */
memcpy (vcb.alloc.plu_alias, "FILESVR ", 8);
/* Set PLU_ALIAS */
memcpy (vcb.alloc.tp_name,al_tp_name,sizeof(al_tp_name));
/* Set TP_NAME */
memcpy (vcb.alloc.mode_name,al_mode_name,sizeof(al_mode_name));
/* Set MODE_NAME */

APPC_C((long) vcbptr); /* Call APPC */

appc_rc_p = vcb.alloc.primary_rc;
appc_rc_s = vcb.alloc.secondary_rc; /* Save the return codes */

if (appc_rc_p != AP_OK) {SHOW_ERR(); sys_err = TRUE; return;}
/* Handle any errors */

conv_id = vcb.alloc.conv_id; /* Save the CONVERSATION_ID */
}

void
SEND_DOS_FILENAME ()
{
clear_vcb(); /* Zero out the vcb */
vcb.send.opcode = AP_M_SEND_DATA; /* APPC Verb - MC_SEND_DATA */
vcb.send.opext = AP_MAPPED_CONVERSATION; /* Mapped Conservation type */
vcb.send.conv_id = conv_id; /* Set conversation_id */
memcpy (vcb.send.tp_id, tp_id, sizeof(tp_id));
/* Set TP_id */
vcb.send.dlen = 100; /* Filename - 100 bytes max. */
vcb.send.dptr = anbptr; /* Set data pointer to buffer */

APPC_C((long) vcbptr); /* Call APPC to send filename */

appc_rc_p = vcb.send.primary_rc;
appc_rc_s = vcb.send.secondary_rc; /* Save return codes */
if (appc_rc_p != AP_OK) {SHOW_ERR(); sys_err = TRUE; return;}
/* Handle any error */
}

void
DO_MC_RECEIVE_AND_WAIT ()
{
clear_vcb(); /* Zero the vcb */
vcb.rcv_wait.opcode = AP_M_RECEIVE_AND_WAIT;
/* Verb - MC_RECEIVE_AND_WAIT */
vcb.rcv_wait.opext = AP_MAPPED_CONVERSATION;
/* Mapped Conversation type */
vcb.rcv_wait.conv_id = conv_id; /* Set conversation_id */
memcpy (vcb.rcv_wait.tp_id, tp_id, sizeof(tp_id));
/* Set tp_id */
vcb.rcv_wait.max_len = 4096; /* Receive file data in 4096 */
/* byte blocks */
vcb.rcv_wait.dptr = anbptr; /* Point to my buffer */

APPC_C((long) vcbptr); /* Call APPC */

length = vcb.rcv_wait.dlen; /* Get length we actually rcvd */
appc_rc_p = vcb.rcv_wait.primary_rc;
appc_rc_s = vcb.rcv_wait.secondary_rc; /* Save return codes */
if (appc_rc_p != AP_OK) {SHOW_ERR(); sys_err = TRUE; return; }
/* Handle any error */
}

void
DO_MC_CONFIRMED ()
{
clear_vcb(); /* Zero out the vcb */
vcb.confirmed.opcode = AP_M_CONFIRMED; /* Verb - MC_CONFIRMED */
vcb.confirmed.opext = AP_MAPPED_CONVERSATION;
/* Mapped Conversation type */
vcb.confirmed.conv_id = conv_id; /* Set conversation_id */
memcpy (vcb.confirmed.tp_id, tp_id, sizeof(tp_id));
/* Set tp_id */

APPC_C ((long) vcbptr); /* Do MC_CONFIRMED */

appc_rc_p = vcb.confirmed.primary_rc;
appc_rc_s = vcb.confirmed.secondary_rc; /* Save return codes */
if (appc_rc_p != AP_OK) {SHOW_ERR(); sys_err = TRUE; return; }
/* Handle any error */
}

void
DO_TP_ENDED ()
{
clear_vcb(); /* Zero the vcb */
vcb.tpend.opcode = AP_TP_ENDED; /* Verb - TP_ENDED */
memcpy (vcb.tpend.tp_id, tp_id, sizeof(tp_id));
/* Set tp_id */

APPC_C((long) vcbptr); /* Do the TP_ENDED */

appc_rc_p = vcb.tpend.primary_rc;
appc_rc_s = vcb.tpend.secondary_rc; /* Save return codes */
if (appc_rc_p != AP_OK) {SHOW_ERR(); sys_err = TRUE; return;}
/* Handle any error */
}

/****************************************************************************/
/* */
/* OS/2 RELATED FUNCTIONS */
/* */
/****************************************************************************/

void
ALLOC_SHARED_BUFFER()
/* APPC requires a data buffer in a shared unnamed segment */
{
unsigned short selector; /* Selector from DOSALLOCSEG */

dos_rc = DOSALLOCSEG (4096, (unsigned far *)&selector, 1);

if (dos_rc == 0) { /* If there is no error */
FP_OFF(anbptr) = 0; /* set the offset to zero */
FP_SEG(anbptr) = selector; /* address = Selector:0 */
}
else { /* Else show dos error */
SHOW_DOS_ERROR(); /* set system to true, */
sys_err = TRUE; /* zero out the pointer */
anbptr = (unsigned char far *)0;
}
}

void
OPEN_DOS_FILE()
{
eof_flag = FALSE;
dos_rc = DOSOPEN ((char far *)filename, /* addr. of file & path name */
(unsigned far *)&filehandle,
/* addr. of filehandle - */
/* returned by dos */
(unsigned far *)&action,
/* addr. of action taken by dos */
(long)0, /* file primary allocation */
0, /* file attribute */
0x0012, /* type of function to be done */
0x0022, /* Open mode of the file */
(long)0); /* Reserved double word */
/* Dos call to open the file */
if (dos_rc == 0) bad_filename = FALSE; /* Filename ok if good return */
else { SHOW_DOS_ERROR(); /* Show any error on DOSOPEN */
bad_filename = TRUE; /* Indicate the name is bad */
return; }
}

void
CLOSE_DOS_FILE ()
{
dos_rc = DOSCLOSE(filehandle); /* Close the file */
if (dos_rc != 0) {SHOW_DOS_ERROR(); sys_err = TRUE; return;}
}

void
WRITE_DOS_DATA ()
{
if (first_time == TRUE) { /* Open the file on first */
OPEN_DOS_FILE(); /* attempt to Write to it */
first_time = FALSE; /* Toggle first_time flag */
if (bad_filename == TRUE) { /* Show messages if bad open */
SHOW_MSG (13);
printf ("\n");
sys_err = TRUE;
return;
}
}

dos_rc = DOSWRITE (filehandle, anbptr, length,
(unsigned far *)&bytes_written);
/* Write the data */
if (dos_rc != 0) { /* Show message if bad DOSWRITE */
printf ("\n");
SHOW_DOS_ERROR();
sys_err = TRUE;
return;
}
byte_count = byte_count + (long) bytes_written;
SHOW_MSG(7); /* Display byte count */
/* progress msg */
printf ("%-10.lu\r",byte_count); /* Do a CR without a linefeed */
}

/* EOF - FILECREQ.C */


  3 Responses to “Category : OS/2 Files
Archive   : OS2CMAPI.ZIP
Filename : FILECREQ.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/