home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / CPI-C.ZIP / JQCPIC.C < prev    next >
Text File  |  1992-06-25  |  12KB  |  365 lines

  1. /*
  2.  *  PROGRAM:   JQCPIC -- John Q's Portable CPI-C Abuser
  3.  *
  4.  *  MODULE:    JQCPIC.C -- main procedures, both client and server side
  5.  *
  6.  *  COPYRIGHTS:
  7.  *             This module contains code made available by IBM
  8.  *             Corporation on an AS IS basis.  Any one receiving the
  9.  *             module is considered to be licensed under IBM copyrights
  10.  *             to use the IBM-provided source code in any way he or she
  11.  *             deems fit, including copying it, compiling it, modifying
  12.  *             it, and redistributing it, with or without
  13.  *             modifications.  No license under any IBM patents or
  14.  *             patent applications is to be implied from this copyright
  15.  *             license.
  16.  *
  17.  *             A user of the module should understand that IBM cannot
  18.  *             provide technical support for the module and will not be
  19.  *             responsible for any consequences of use of the program.
  20.  *
  21.  *             Any notices, including this one, are not to be removed
  22.  *             from the module without the prior written consent of
  23.  *             IBM.
  24.  *
  25.  *  AUTHOR:    Dr. John Q. Walker II
  26.  *             IBM VNET: JOHNQ at RALVM6          IBM tie line: 444-4414
  27.  *             Internet: johnq@vnet.ibm.com        phone: (919) 254-4414
  28.  *
  29.  *  RELATED FILES:
  30.  *             See file JQCPIC.DOC for detailed information.
  31.  *
  32.  *  CHANGE HISTORY:
  33.  *  Date       Description
  34.  *  05/12/92   Added prologue.
  35.  *  06/24/92   Converted all malloc() and printf() calls, for
  36.  *             future portability.
  37.  */
  38.  
  39. #include <conio.h>
  40. #include <signal.h>
  41. #include <stdio.h>
  42. #include <stdlib.h>
  43. #include <string.h>
  44. #include <time.h>
  45.  
  46. #include "jqcpic.h"
  47.  
  48. /* global variables */
  49. char *program_version = "1.04";
  50. char *program_name;
  51.  
  52. unsigned char sym_dest_name[MAX_SYM_DEST_NAME];
  53. time_t tStartTime;          /* start time of this run */
  54. time_t tEndTime;            /* completion time of this run */
  55.  
  56. static unsigned long total_call_count;
  57.  
  58. /* depending upon which side is being compiled, define what the reset
  59.  * conversation state should be.
  60.  */
  61. #ifdef SERVER_SIDE
  62. #define CM_RESET_STATE  CM_ACCP_STATE
  63. #else
  64. #define CM_RESET_STATE  CM_INIT_STATE
  65. #endif
  66.  
  67. /* local function prototypes */
  68. static void handler(int);
  69. static void set_up_control_block(CPIC_CONV_ATTRIB *);
  70.  
  71.  
  72. void main(int argc, char **argv)
  73. {
  74.     /*=========================================================================
  75.      * This is the main procedure.
  76.      *=======================================================================*/
  77.  
  78.     FILE *copyright_output = stderr;    /* send the header here */
  79.     int keystroke = 0;                  /* pressed key */
  80.  
  81.     CPIC_CONV_ATTRIB local;             /* one conversation instance */
  82.     CM_CONVERSATION_STATE conv_state;   /* current conversation state */
  83.  
  84.  
  85.     program_name = get_program_name(argv[0]);
  86.  
  87.     if ((1 < argc) &&
  88.         (QUESTION_MARK  == argv[1][0]) &&
  89.         (NULL_CHARACTER == argv[1][1]))
  90.         copyright_output = stdout;
  91.  
  92.     /* Print the title and copyright notices. */
  93.     write_error(
  94. #ifdef SERVER_SIDE
  95.        "%s: Portable CPI-C Abuser (Server side)  version %s\n"
  96. #else
  97.        "%s: Portable CPI-C Abuser (Client side)  version %s\n"
  98. #endif
  99.        "by Dr. John Q. Walker II (johnq@ralvm6.vnet.ibm.com)\n"
  100.        "Copyright (c) IBM Corporation 1992.\n\n"
  101.        "\tPress \"Q\" to quit this program\n\n",
  102.        program_name, program_version);
  103.  
  104.     if (copyright_output == stdout) {
  105.         usage();
  106.         exit(EXIT_SUCCESS);
  107.     }
  108.  
  109.     /* Save the start time.  Must be before the signal handler. */
  110.     time(&tStartTime);
  111.  
  112.     /* set up a signal handler, to clean up upon exit */
  113.     if (SIG_DFL == signal(SIGINT, SIG_IGN))
  114.         signal(SIGINT, handler);
  115.  
  116.     /* initialize to all ones, not zeros */
  117.     memset((void *)&local, (int)(-1), sizeof(local));
  118.  
  119.     /* set the initial values in the conversation control block */
  120.     set_up_control_block(&local);
  121.  
  122. #ifndef SERVER_SIDE
  123.     /* process command line arguments */
  124.     command_line(argc, argv);
  125.  
  126.     {
  127.     /* this is how the most important parm gets set! */
  128.     unsigned i;                     /* local loop counter */
  129.     for (i = 0; i < SYM_DEST_NAME_LENGTH; i++)
  130.         local.sym_dest_name[i] = sym_dest_name[i];
  131.     }
  132. #endif
  133.  
  134.     /* set the seed for all future random calls */
  135.     srand((unsigned)tStartTime);
  136.  
  137.     /*-------------------------------------------------------------------------
  138.      * Loop forever, until an unexpected CPI-C return code or the letter
  139.      * Q is pressed.
  140.      *-----------------------------------------------------------------------*/
  141.  
  142.     total_call_count = 0;
  143.     while (((int)'q' != keystroke) &&
  144.            ((int)'Q' != keystroke)) {
  145.         while (!kbhit()) {  /* keep going until any keystroke */
  146.             /* Given the local conversation state, make a random CPI-C
  147.              * call that is valid in that state -- returning the new
  148.              * conversation state.
  149.              */
  150.             conv_state = issue_cpic_call(&local);
  151.             total_call_count++;
  152.             if ((CM_CONVERSATION_STATE)(-1) == conv_state) {
  153.                 /* unexpected return code on Extract Conversation State */
  154.                 write_error("\n\tThe preceding return code is invalid for"
  155.                             " the verb and state!\n");
  156.                 all_done(EXIT_FAILURE); /* this does an exit() */
  157.             }
  158.         }
  159.  
  160.         keystroke = getch();  /* grab the keystroke */
  161.     }
  162.  
  163.     /* we get here only upon pressing the right key */
  164.     all_done(EXIT_SUCCESS);
  165. }
  166.  
  167.  
  168. void all_done(const int status)
  169. {
  170.     /*=========================================================================
  171.      * This procedure is called upon exit or when Ctrl+Break is invoked.
  172.      *=======================================================================*/
  173.  
  174.     time_t tTotalTime;
  175.  
  176.     flushall();
  177.  
  178.     time(&tEndTime);          /* save the end time */
  179.  
  180.     tTotalTime = tEndTime - tStartTime; /* calculate how long it took */
  181.  
  182.     /* output the elapsed time */
  183.     write_error("\n%s: %lu calls, %lu calls/second"
  184.                 "\n\telapsed time was ",
  185.                 program_name, total_call_count,
  186.                 (tTotalTime > 0) ? total_call_count/tTotalTime : 0);
  187.  
  188.     /* calculate the hours */
  189.     if ((time_t)0 < tTotalTime/3600) {
  190.         /* A non-zero number of minutes */
  191.         if ((time_t)1 == tTotalTime/3600)
  192.             (void)write_error("%ld hour, ", tTotalTime/3600);
  193.         else
  194.             (void)write_error("%ld hours, ", tTotalTime/3600);
  195.  
  196.         /* reduce to the minutes that are left */
  197.         tTotalTime = tTotalTime % 3600;
  198.     }
  199.  
  200.     /* calculate the minutes */
  201.     if ((time_t)0 < tTotalTime/60) {
  202.         /* A non-zero number of minutes */
  203.         if ((time_t)1 == tTotalTime/60)
  204.             (void)write_error("%ld minute, ", tTotalTime/60);
  205.         else
  206.             (void)write_error("%ld minutes, ", tTotalTime/60);
  207.  
  208.         /* reduce to the minutes that are left */
  209.         tTotalTime = tTotalTime % 60;
  210.     }
  211.  
  212.     /* calculate the seconds */
  213.     if ((time_t)1 == tTotalTime)
  214.         (void)write_error("%ld second\n", tTotalTime);
  215.     else
  216.         (void)write_error("%ld seconds\n", tTotalTime);
  217.  
  218.  
  219.     exit(status);
  220. }
  221.  
  222.  
  223. CM_CONVERSATION_STATE get_new_conversation_state(CPIC_CONV_ATTRIB *this)
  224. {
  225.     /*=========================================================================
  226.      * Given the current conversation status, return the current conversation
  227.      * state.
  228.      *=======================================================================*/
  229.  
  230.     /* Show the return code from the last call issued. */
  231.     show_return_code(this);
  232.  
  233.     fetch_conversation_state(this);
  234.  
  235.     switch (this->return_code) {
  236.         case CM_OK:
  237.             return this->conversation_state;
  238.             break;
  239.  
  240.         case CM_PROGRAM_PARAMETER_CHECK:
  241.             /* the conversation_ID is no good; it's time to reset */
  242. #ifdef SERVER_SIDE
  243.             /* exit when the conversation ID is no longer valid */
  244.             all_done(EXIT_SUCCESS);
  245. #else
  246.             /* on the client side, go back to issue CMINIT */
  247.             return CM_RESET_STATE;
  248. #endif
  249.             break;
  250.  
  251.         case CM_TAKE_BACKOUT:
  252.             /* what's this return code mean here?? */
  253.             return this->conversation_state;
  254.             break;
  255.  
  256.         case CM_PRODUCT_SPECIFIC_ERROR:
  257.             /* what's this return code mean here?? */
  258.             return this->conversation_state;
  259.             break;
  260.  
  261.         default:
  262. #ifdef NOCPIC
  263.             return this->conversation_state;
  264. #else
  265.             return unexpected_rc(this);
  266. #endif
  267.             break;
  268.     }
  269. }
  270.  
  271.  
  272. BOOL generate_valid_parm(void)
  273. {
  274.     /*=========================================================================
  275.      * Decide whether to generate a valid parameter.
  276.      * Constant VALID_PARM_PERCENTAGE should be a number from 0 to 100.
  277.      * Returns TRUE is the parameter should be valid,
  278.      * otherwise returns FALSE.
  279.      *=======================================================================*/
  280.  
  281.     if (VALID_PARM_PERCENTAGE > (rand() % 100))
  282.         return TRUE;
  283.     else
  284.         return FALSE;
  285. }
  286.  
  287.  
  288. void fill_field(char *name, size_t length)
  289. {
  290.     /*=========================================================================
  291.      * Fill the field with random characters (anything from 0 to 255).
  292.      *=======================================================================*/
  293.  
  294.     memset((void *)name, rand()%256, length);
  295. }
  296.  
  297.  
  298. CM_INT32 get_random_CM_INT32(void)
  299. {
  300.     /*=========================================================================
  301.      * Returns a random 32-bit integer.
  302.      * Usually large (32k Squared is its median value).
  303.      *=======================================================================*/
  304.  
  305.     return (CM_INT32)((CM_INT32)rand() * (CM_INT32)rand());
  306. }
  307.  
  308.  
  309. static
  310. void set_up_control_block(CPIC_CONV_ATTRIB *local_ptr)
  311. {
  312.     /*=========================================================================
  313.      * Set up the single control block.
  314.      *=======================================================================*/
  315.  
  316.     local_ptr->conversation_ID = (unsigned char CM_PTR)
  317.                                     get_memory(CONVERSATION_ID_LENGTH);
  318.     local_ptr->sym_dest_name   = (unsigned char CM_PTR)
  319.                                     get_memory(MAX_SYM_DEST_NAME);
  320.     local_ptr->mode_name       = (unsigned char CM_PTR)
  321.                                     get_memory(MAX_MODE_NAME);
  322.     local_ptr->partner_LU_name = (unsigned char CM_PTR)
  323.                                     get_memory(MAX_FQPLU_NAME);
  324.     local_ptr->TP_name         = (unsigned char CM_PTR)
  325.                                     get_memory(MAX_TP_NAME);
  326.  
  327. /* this is the trick I use to determine the initial state */
  328. #ifdef SERVER_SIDE
  329.     local_ptr->conversation_state = 1;   /* start with CMACCP */
  330. #else
  331.     local_ptr->conversation_state = 0;   /* start with CMINIT */
  332. #endif
  333. }
  334.  
  335.  
  336. void usage(void)
  337. {
  338.     /*=========================================================================
  339.      * Display usage information.
  340.      *=======================================================================*/
  341.  
  342. #ifdef SERVER_SIDE
  343.     write_error("Server side:\n"
  344.                 "\tShould be started by an incoming Attach.\n");
  345. #else
  346.     write_error("Usage:\n"
  347.                 "\t%s sym_dest_name\n\n"
  348.                 "\tRuns until the letter \"Q\" is pressed.\n"
  349.                 , program_name);
  350. #endif
  351. }
  352.  
  353.  
  354. static
  355. void handler(int sig)
  356. {
  357.     /*=========================================================================
  358.      * This is the signal handler.
  359.      * Input parameter "sig" is not used, but required by the
  360.      * function prototype for the signal() library call.
  361.      *=======================================================================*/
  362.     (void)signal(SIGINT, SIG_IGN);  /* ignore the signal */
  363.     all_done(EXIT_SUCCESS);
  364. }
  365.