RSA BSAFE Cert-C

Certificate Components for C

Crypto-C 6.2.1 Developer's Guide
Search

inoutcl.c

Utilities to read input and write output either from the standard I/ O or from file

/* $Id: inoutcl.c,v 1.3 2004/03/02 05:18:34 gsingh Exp $ */
/* inoutcl.c
** Copyright (c) 1992-2002, RSA Security Inc.
**
** This file is used to demonstrate how to interface to an RSA Security
** licensed development product.  You have a royalty-free right to use,
** modify, reproduce and distribute this demonstration file (including
** any modified version), provided that you agree that RSA Security has
** no warranty, implied or otherwise, or liability for this demonstration
** file or any modified version.
*/

#include <stdio.h>
#include "aglobal.h"
#include "bcert.h" 
#include "demo.h"
#include "simpleio.h"
#include "inoutcl.h" 
#include "dutil.h"

/* Definitions are only accessed in this module.
 */
#define LINE_DELIMITER_CHAR '~'
#define IO_CTX_STDIN 1
#define IO_CTX_STRING 2
#define IO_CTX_FILE 3

static void UpdateInputSource PROTO_LIST ((IO_CTX_CL *));
static void CALL_CONV SimpleLogError PROTO_LIST ((char *, int, int, POINTER));

/* Initialize the IO_CTX_CL based on the command line arguments supplied.
   CloseIOContext should be called at the finish of the program.
   See UpdateInputSource() a description of the members of the IO_CTX_CL.
 */
void OpenIOContextCL (ioContextCL, argc, argv)
IO_CTX_CL *ioContextCL;
int argc;
char *argv[];
{
  ioContextCL->argc = argc;
  ioContextCL->argv = argv;

  /* Set inputSource to 0 to force update, and set argIndex to 0 so that it
       will be advanced by UpdateInputSource to the first argument. */
  ioContextCL->argIndex = 0;
  ioContextCL->inputSource = 0;
  UpdateInputSource (ioContextCL);
}

void CloseIOContextCL (ioContextCL)
IO_CTX_CL *ioContextCL;
{
  if (ioContextCL->inputSource == IO_CTX_FILE)
    fclose (ioContextCL->inFile);
}

/* If type is non-zero, print as a TIPEM error or warning as given
     by 'warning'.
   If type is IO_CTX_PROMPT, only print if the inputSource is IO_CTX_STDIN
     and treat the type as if it is supplied as zero.
 */
void PrintMessage (message, warning, type, ioContextCL)
char *message;
int warning;
int type;
IO_CTX_CL *ioContextCL;
{
  if (type == IO_CTX_PROMPT) {
    if (ioContextCL->inputSource != IO_CTX_STDIN)
      /* print only when getting input from stdin */
      return;
  
    /* set type to behave as if it wasn't supplied */
    type = 0;
  }

  if (type == 0)
    printf ("%s\n", message);
  else
    SimpleLogError (message, warning, type, NULL_PTR);

  fflush (stdout);
}

/* Print the prompt and read a line into commandLine up to maxLineSize - 1
     charaters.
   See UpdateInputSource() for a description of the IO_CTX_CL.
 */
void GetCommandLine (commandLine, maxLineSize, prompt, ioContextCL)
char *commandLine;
unsigned int maxLineSize;
char *prompt;
IO_CTX_CL *ioContextCL;
{
  char inputChar, *string;
  int done, status;
  unsigned int index;

  done = 0;
  
  /* Try reading from any of the input sources until successful.
   */
  while (!done) {
    if (ioContextCL->inputSource == IO_CTX_STDIN) {
      printf ("%s", prompt);
      printf ("\n");
      SimpleGetLine (commandLine, maxLineSize, (POINTER)stdin);
      done = 1;
    }
    else if (ioContextCL->inputSource == IO_CTX_FILE) {
      if ((status = SimpleGetLine
           (commandLine, maxLineSize, (POINTER)ioContextCL->inFile)) != 0) {
        /* If the error is not end of stream, close the stream;
             otherwise UpdateInputSource will catch the end of stream.
         */
        if (status != D_EOS) {
          PrintMessage
            ("ERROR: Cannot read from the following input file:", 0, 0,
             ioContextCL);
          PrintMessage
            (ioContextCL->argv[ioContextCL->argIndex], 0, 0, ioContextCL);
        
          /* Close the file and set inputSource to 0 to force
               UpdateInputSource to get the next input.
           */
          fclose (ioContextCL->inFile);
          ioContextCL->inputSource = 0;
        }
      }
      else
        done = 1;
    }
    else if (ioContextCL->inputSource == IO_CTX_STRING) {
      string = ioContextCL->argv[ioContextCL->argIndex];
      index = 0;

      while (((inputChar = string[ioContextCL->point]) != 0) &&
             inputChar != LINE_DELIMITER_CHAR) {
        if (index < maxLineSize)
          commandLine[index++] = inputChar;
        ioContextCL->point ++;
      }

      /* Put null-terminator on commandLine.
       */
      if (index >= maxLineSize)
        commandLine[maxLineSize-1] = '\0';
      else
        commandLine[index] = '\0';

      if (inputChar == LINE_DELIMITER_CHAR)
        ioContextCL->point ++;
      
      done = 1;
    }
  
    /* Update the input source so that PrintMessage will know
         whether or not to print prompts.
     */
    UpdateInputSource (ioContextCL);
  }
}

/* If inputSource is zero, or the current input source is finished, advance
     the argIndex, read the command line argument and set the inputSource
     appropriately.
   When there are no more arguments in argv, inputSource is set to
     IO_CTX_STDIN.
   If inputSource is IO_CTX_STDIN, then read commands from stdin and
     outputs to stdout.
   If inputSource is IO_CTX_STRING, then read commands from argv[argIndex],
     and point indexes the current read position in the string.
   If inputSource is IO_CTX_FILE, then read commands from inFile.
   If there is trouble opening the inFile, print and error and move on.
 */
static void UpdateInputSource (ioContextCL)
IO_CTX_CL *ioContextCL;
{
  int tempChar;

  while (1) {
    /* Check if the input source does not need to be updated.
       If it does not need to be updated, then return, otherwise
         move on past the switch statement which will get the
         next input source. 
     */
    switch (ioContextCL->inputSource) {
      
    case IO_CTX_STDIN:
      /* update is never needed for IO_CTX_STDIN */
      return;
      
    case IO_CTX_FILE:
      if ((tempChar = getc (ioContextCL->inFile)) != EOF) {
        /* un-get the character and return */
        ungetc (tempChar, ioContextCL->inFile);
        return;
      }
        
      /* There isn't any more data in this file, so move on to next
           input source.  The file will be closed below.
       */
      break;  
    
    case IO_CTX_STRING:
      if (ioContextCL->argv[ioContextCL->argIndex][ioContextCL->point])
        /* string is not pointing to '\0' so there is more to read */
        return;
      break;
    }
    
    /* The input source does need updating,
     */
    if (ioContextCL->inputSource == IO_CTX_FILE)
      /* close this file before moving on */
      fclose (ioContextCL->inFile);

    /* Set inputSource to 0 to force the loop to continue until
         an input source is opened with information to read. */
    ioContextCL->inputSource = 0;
    
    /* point to next argument */
    ioContextCL->argIndex ++;
    
    if (ioContextCL->argIndex >= ioContextCL->argc)
      /* ran out of arguments, so switch to stdin */
      ioContextCL->inputSource = IO_CTX_STDIN;
    else if (!T_memcmp ((POINTER)ioContextCL->argv[ioContextCL->argIndex],
                        (POINTER)"-f", 2) ||
             !T_memcmp ((POINTER)ioContextCL->argv[ioContextCL->argIndex],
                        (POINTER)"-F", 2)) {
      /* The first 2 characters of this argument are "-f" so read from the
           file name in the next arg.
       */
      ioContextCL->argIndex ++;
      
      if (ioContextCL->argIndex > ioContextCL->argc) {
        /* ran out of arguments so print error */
        PrintMessage
          ("ERROR: Input file name not specified.", 0, 0, ioContextCL);
      }
      else {
        if ((ioContextCL->inFile = fopen
             (ioContextCL->argv[ioContextCL->argIndex], "r")) == NULL) {
          /* Couldn't open file, will automatically loop back and try again.
           */
          PrintMessage
            ("ERROR: Cannot open the following file for input:", 0, 0,
             ioContextCL);
          PrintMessage
            (ioContextCL->argv[ioContextCL->argIndex], 0, 0, ioContextCL);
        }
        else
          /* file opened successfully */
          ioContextCL->inputSource = IO_CTX_FILE;
      }
    }
    else {
      /* Default: Interpret the argument as a string of command lines
           separated by LINE_DELIMITER_CHAR.
       */
      ioContextCL->inputSource = IO_CTX_STRING;
      ioContextCL->point = 0;
    }
  }
}


/* handle is ignored.
 */
static void CALL_CONV SimpleLogError (task, warning, type, handle)
char *task;
int warning;
int type;
POINTER handle;
{
  char *typeString, buf[80];
  
UNUSED_ARG (task)
UNUSED_ARG (handle)
  
  if ((typeString = GetErrorMessage (type)) == (char *)NULL_PTR) {
    /* Type is not recognized, so print as hex.
     */
    sprintf (buf, "Code 0x%04x", type);
    typeString = buf;
  }

  if (warning)
    printf ("WARNING: %s\n", typeString);
  else
    printf ("ERROR: %s\n", typeString);
  
  fflush (stdout);
}


Copyright (c) 1999-2005 RSA Security Inc. All rights reserved. 067-001001-2720-001-000 - 2.7.2