Back to index

lightning-sunbird  0.9+nobinonly
pk11util.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 
00038 #include <stdio.h>
00039 #include <string.h>
00040 
00041 #if defined(WIN32)
00042 #undef __STDC__
00043 #include "fcntl.h"
00044 #include "io.h"
00045 #include <fcntl.h>
00046 #else
00047 #include <unistd.h>
00048 #include <sys/fcntl.h>
00049 #endif
00050 
00051 #include "secutil.h"
00052 
00053 
00054 #include "nspr.h"
00055 #include "prtypes.h"
00056 #include "prtime.h"
00057 #include "prlong.h"
00058 #include "prinrval.h"
00059 
00060 #include "pkcs11.h"
00061 
00062 #include "pk11util.h"
00063 
00064 #ifndef O_BINARY
00065 #define O_BINARY 0
00066 #endif
00067 
00068 CK_ULONG systemFlags;
00069 #define FLAG_NEGATE 0x80000000
00070 #define FLAG_Verify 0x00000001
00071 #define FLAG_VerifyFile 0x00000002
00072 #define CKR_QUIT 0x80000000
00073 
00074 int ArgSize(ArgType type);
00075 const char *constLookup(const char *bp, CK_ULONG *value, ConstType *type);
00076 
00077 int
00078 isNum(char c)
00079 {
00080     return (c >= '0' && c <= '9');
00081 }
00082 
00083 int
00084 isConst(const char *c)
00085 {
00086     CK_ULONG value;
00087     ConstType type;
00088 
00089     constLookup(c, &value, &type);
00090     return type != ConstNone;
00091 }
00092 
00093 /*
00094  * see if the variable is really a 'size' function. This
00095  * function may modify var if it is a size function.
00096  */
00097 char *
00098 isSize(char *var, int *isArray)
00099 {
00100     char *ptr = NULL;
00101     char *end;
00102     int array = 0;
00103 
00104     if (PL_strncasecmp(var,"sizeof(",/*)*/ 7) == 0) {
00105        ptr = var + 7;
00106     } else if (PL_strncasecmp(var,"size(",/*)*/ 5) == 0) {
00107        ptr = var + 5;
00108     } else if (PL_strncasecmp(var,"sizeofarray(",/*)*/ 12) == 0) {
00109        ptr = var + 12;
00110        array = 1;
00111     } else if (PL_strncasecmp(var,"sizea(",/*)*/ 6) == 0) {
00112        ptr = var + 6;
00113        array = 1;
00114     } else {
00115        return NULL;
00116     }
00117     end = strchr(ptr,/*(*/ ')') ;
00118     if (end == NULL) {
00119        return NULL;
00120     }
00121     if (isArray) *isArray = array;
00122     *end = 0;
00123     return ptr;
00124 }
00125  
00126 void
00127 printConst(CK_ULONG value, ConstType type, int newLine)
00128 {
00129     int i;
00130 
00131     for (i=0; i < constCount; i++) {
00132        if (consts[i].type == type && consts[i].value == value) {
00133            printf("%s",consts[i].name);
00134            break;
00135        }
00136        if (type == ConstNone && consts[i].value == value) {
00137            printf("%s",consts[i].name);
00138            break;
00139        }
00140     }
00141     if (i == constCount) {
00142        if ((type == ConstAvailableSizes) || (type == ConstCurrentSize)) {
00143            printf("%lu",value);
00144        } else {
00145            printf("Unknown %s (%lu:0x%lx)",constTypeString[type],value,value);
00146        }
00147     }
00148     if (newLine) {
00149        printf("\n");
00150     }
00151 }
00152 
00153 ConstType
00154 getConstFromAttribute(CK_ATTRIBUTE_TYPE type)
00155 {
00156     int i;
00157 
00158     for (i=0; i < constCount; i++) {
00159        if (consts[i].type == ConstAttribute && consts[i].value == type) {
00160            return consts[i].attrType;
00161        }
00162     }
00163     return ConstNone;
00164 }
00165 
00166 void
00167 printChars(const char *name, CK_ULONG size)
00168 {
00169     CK_ULONG i;
00170     for (i=0; i < size; i++) {
00171        if (name[i] == 0) {
00172               break;
00173        }
00174        printf("%c",name[i]);
00175     }
00176     printf("\n");
00177 }
00178 
00179 #define DUMP_LEN 16
00180 void printDump(const unsigned char *buf, int size)
00181 {
00182     int i,j;
00183 
00184     for(i=0; i < size; i+= DUMP_LEN) {
00185        printf(" ");
00186        for (j=0; j< DUMP_LEN; j++) {
00187            if (i+j < size) {
00188               printf("%02x ",buf[i+j]);
00189            } else {
00190               printf("   ");
00191            }
00192        } 
00193        for (j=0; j< DUMP_LEN; j++) {
00194            if (i+j < size) {
00195               if (buf[i+j] < ' ' || buf[i+j] >= 0x7f) {
00196                   printf(".");
00197               } else {
00198                   printf("%c",buf[i+j]);
00199               }
00200            } else {
00201               printf(" ");
00202            }
00203        } 
00204        printf("\n");
00205     }
00206 }
00207 
00208 /*
00209  * free an argument structure
00210  */
00211 void
00212 argFreeData(Value *arg)
00213 {
00214     if (arg->data && ((arg->type & ArgStatic) == 0)) {
00215        if ((arg->type & ArgMask) == ArgAttribute) {
00216            int i;
00217            CK_ATTRIBUTE *template = (CK_ATTRIBUTE *)arg->data;
00218 
00219            for (i=0; i < arg->arraySize; i++) {
00220               free(template[i].pValue);
00221            }
00222        }
00223        if ((arg->type & ArgMask) == ArgInitializeArgs) {
00224            CK_C_INITIALIZE_ARGS *init = (CK_C_INITIALIZE_ARGS *)arg->data;
00225             if (init->LibraryParameters) {
00226               free(init->LibraryParameters);
00227            }
00228        }
00229        free(arg->data);
00230     }
00231     arg->type &= ~ArgStatic;
00232     arg->data = NULL;
00233 }
00234 
00235 void
00236 argFree(Value *arg)
00237 {
00238     if (arg == NULL) return;
00239 
00240     arg->reference--;
00241     if (arg->reference == 0) {
00242        if (arg->type & ArgFile) {
00243            free(arg->filename);
00244        }
00245        argFreeData(arg);
00246        free (arg);
00247     }
00248 }
00249 
00250 /*
00251  * free and argument list
00252  */
00253 void
00254 parseFree(Value **ap)
00255 {
00256     int i;
00257     for (i=0 ; i < MAX_ARGS; i++) {
00258        argFree(ap[i]);
00259     }
00260 }
00261 
00262 /*
00263  * getEnd: how for to the end of this argmument list?
00264  */
00265 int
00266 getEnd(const char *bp)
00267 {
00268     int count = 0;
00269 
00270     while (*bp) {
00271         if (*bp == ' ' || *bp == '\t' || *bp == '\n') return count;
00272        count++;
00273        bp++;
00274     }
00275     return (count);
00276 }
00277 
00278 
00279 /*
00280  * strip: return the first none white space character
00281  */
00282 const char *
00283 strip(const char *bp)
00284 {
00285     while (*bp && (*bp == ' ' || *bp == '\t' || *bp == '\n')) bp++;
00286     return bp;
00287 }
00288 
00289 /*
00290  * read in the next argument into dp ... don't overflow
00291  */
00292 const char *
00293 readChars(const char *bp, char *dp, int max )
00294 {
00295     int count = 1;
00296     while (*bp) {
00297         if (*bp == ' ' || *bp == '\t' || *bp == '\n' ) {
00298            *dp = 0;
00299            return bp;
00300        }
00301        *dp++ = *bp++;
00302        if (++count == max) break;
00303     }
00304     while (*bp && (*bp != ' ' && *bp != '\t' && *bp != '\n')) bp++;
00305     *dp = 0;
00306     return (bp);
00307 }
00308 
00309 Value * varLookup(const char *bp, char *vname, int max, int *error);
00310 
00311 CK_ULONG
00312 getValue(const char *v, int *error)
00313 {
00314     Value * varVal = NULL;
00315     CK_ULONG retVal = 0;
00316     ConstType type;
00317     char tvar[512];
00318 
00319     *error = 0;
00320 
00321     varVal = varLookup( v, tvar, sizeof(tvar), error);
00322 
00323     if (varVal) {
00324        if ((varVal->type & ArgMask) == ArgULong) {
00325            retVal = *(CK_ULONG *)varVal->data;
00326        } else {
00327            fprintf(stderr,"%s: is not a ulong\n", v);
00328            *error = 1;
00329        }
00330        argFree(varVal);
00331        return retVal;
00332     }
00333     constLookup(v, &retVal, &type);
00334     return retVal;
00335 }
00336 
00337 Value *
00338 NewValue(ArgType type, CK_ULONG arraySize)
00339 {
00340     Value *value;
00341 
00342     value = (Value *)malloc(sizeof(Value));
00343     if (!value) return NULL;
00344     value->size = ArgSize(type)*arraySize;
00345     value->type = type;
00346     value->filename = NULL;
00347     value->constType = ConstNone;
00348     value->data = (void *)malloc(value->size);
00349     if (!value->data) {
00350        free(value);
00351        return NULL;
00352     }
00353     value->reference = 1;
00354     value->arraySize = (type == ArgChar) ? 1: arraySize;
00355 
00356     memset(value->data, 0, value->size);
00357     return value;
00358 }
00359 
00360 #define INVALID_INDEX 0xffffffff
00361 
00362 CK_ULONG
00363 handleArray(char *vname, int *error)
00364 {
00365     char *bracket;
00366     CK_ULONG index = INVALID_INDEX;
00367 
00368     if ((bracket = strchr(vname,'[')) != 0) {
00369        char *tmpv = bracket+1;
00370        *bracket = 0;
00371        bracket = strchr(tmpv,']');
00372 
00373        if (bracket == 0) {
00374            fprintf(stderr,"%s: missing closing brace\n", vname);
00375            return INVALID_INDEX;
00376        }
00377        *bracket = 0;
00378 
00379        index = getValue(tmpv, error);
00380        if (*error == 1) {
00381            return INVALID_INDEX;
00382        } else if (index == INVALID_INDEX) {
00383            fprintf(stderr, "%s: 0x%x is an invalid index\n",vname,index);
00384            *error = 1;
00385        }
00386     }
00387     return index;
00388 }
00389 
00390 void *
00391 makeArrayTarget(const char *vname, const Value *value, CK_ULONG index)
00392 {
00393     char * target;
00394     CK_ULONG elementSize;
00395 
00396     if (index >= (CK_ULONG)value->arraySize) {
00397        fprintf(stderr, "%s[%d]: index larger than array size (%d)\n",
00398               vname, index, value->arraySize);
00399        return NULL;
00400     }
00401 
00402     target = (char *)value->data;
00403     elementSize = value->size/value->arraySize;
00404     target += index * elementSize;
00405     return target;
00406 }
00407 
00408 /*
00409  * look up a variable from the variable chain
00410  */
00411 static Variable *varHead = NULL;
00412 Value *
00413 varLookup(const char *bp, char *vname, int max, int *error)
00414 {
00415     Variable *current;
00416     CK_ULONG index = INVALID_INDEX;
00417     int isArray = 0;
00418     char *ptr;
00419     *error = 0;
00420 
00421     if (bp != NULL) {
00422        readChars(bp, vname, max);
00423     } 
00424 
00425     /* don't make numbers into variables */
00426     if (isNum(vname[0])) {
00427        return NULL;
00428     }
00429     /* nor consts */
00430     if (isConst(vname)) {
00431        return NULL;
00432     }
00433     /* handle sizeof() */
00434     if ((ptr = isSize(vname, &isArray)) != NULL) {
00435        CK_ULONG size;
00436        Value  *targetValue = NULL;
00437        Value  *sourceValue = varLookup(NULL, ptr, 0, error);
00438        if (!sourceValue) {
00439           if (*error == 0) {
00440               /* just didn't find it */
00441               *error = 1;
00442               fprintf(stderr,"Couldn't find variable %s to take size of\n",
00443                      ptr);
00444               return NULL;
00445           }
00446        }
00447        size = isArray ? sourceValue->arraySize : sourceValue->size;
00448        targetValue = NewValue(ArgULong,1);
00449        memcpy(targetValue->data, &size, sizeof(size));
00450 
00451        return targetValue;
00452     }
00453 
00454     /* modifies vname */
00455     index = handleArray(vname, error);
00456     if (*error == 1) {
00457        return NULL;
00458     }
00459 
00460     for (current = varHead; current; current = current->next) {
00461        if (PL_strcasecmp(current->vname, vname) == 0) {
00462            char *target;
00463            if (index == INVALID_INDEX) {
00464               (current->value->reference)++;
00465               return current->value;
00466            }
00467            target = makeArrayTarget(vname, current->value, index);
00468            if (target) {
00469               Value *element = NewValue(current->value->type, 1);
00470               if (!element) {
00471                   fprintf(stderr, "MEMORY ERROR!\n");
00472                   *error = 1;
00473               }
00474               argFreeData(element);
00475               element->data = target;
00476               element->type |= ArgStatic;
00477               return element;
00478            }
00479            *error = 1;
00480            return NULL;
00481        }
00482     }
00483     return NULL;
00484 }
00485 
00486 static CK_RV 
00487 list(void)
00488 {
00489     Variable *current;
00490 
00491     if (varHead) {
00492        printf(" %10s\t%16s\t%8s\tSize\tElements\n","Name","Type","Const");
00493     } else {
00494        printf(" no variables set\n");
00495     }
00496 
00497     for (current = varHead; current; current = current->next) {
00498        printf(" %10s\t%16s\t%8s\t%d\t%d\n", current->vname,
00499            valueString[current->value->type&ArgMask],
00500            constTypeString[current->value->constType],
00501            current->value->size, current->value->arraySize);
00502     }
00503     return CKR_OK;
00504 }
00505 
00506 CK_RV
00507 printFlags(const char *s, CK_ULONG flags, ConstType type)
00508 {
00509     CK_ULONG i;
00510     int needComma = 0;
00511 
00512     printf("%s",s);
00513     for (i=1; i ; i=i << 1) {
00514        if (flags & i) {
00515           printf("%s",needComma?",":"");
00516           printConst(i, type, 0);
00517           needComma=1;
00518        }
00519     }
00520     if (!needComma) {
00521        printf("Empty");
00522     }
00523     printf("\n");
00524     return CKR_OK;
00525 }
00526 
00527 /*
00528  * add a new variable to the chain
00529  */
00530 const char *
00531 AddVariable(const char *bp, Value **ptr)
00532 {
00533     char vname[512];
00534     Variable *current;
00535     int index = INVALID_INDEX;
00536     int size;
00537     int error = 0;
00538 
00539     bp = readChars(bp,vname,sizeof(vname));
00540 
00541     /* don't make numbers into variables */
00542     if (isNum(vname[0])) {
00543        return bp;
00544     }
00545     /* or consts */
00546     if (isConst(vname)) {
00547        return bp;
00548     }
00549     /* or NULLs */
00550     if (vname[0] == 0) {
00551        return bp;
00552     }
00553     /* or sizeof */
00554     if (isSize(vname, NULL)) {
00555        return bp;
00556     }
00557     /* arrays values should be written back to the original */
00558     index = handleArray(vname, &error);
00559     if (error == 1) {
00560        return bp;
00561     }
00562 
00563 
00564     for (current = varHead; current; current = current->next) {
00565        if (PL_strcasecmp(current->vname,vname) == 0) {
00566            char *target;
00567            /* found a complete object, return the found one */
00568            if (index == INVALID_INDEX) {
00569               argFree(*ptr);
00570               *ptr = current->value;
00571               return bp;
00572            }
00573            /* found an array, update the array element */
00574            target = makeArrayTarget(vname, current->value, index);
00575            if (target) {
00576               memcpy(target, (*ptr)->data, (*ptr)->size);
00577               argFreeData(*ptr);
00578               (*ptr)->data = target;
00579               (*ptr)->type |= ArgStatic;
00580            }
00581            return bp;
00582        }
00583     }
00584 
00585     /* we are looking for an array and didn't find one */
00586     if (index != INVALID_INDEX) {
00587        return bp;
00588     }
00589 
00590 
00591     current = (Variable *)malloc(sizeof(Variable));
00592     size = strlen(vname);
00593     current->vname = (char *)malloc(size+1);
00594     strcpy(current->vname,vname);
00595     current->value = *ptr;
00596     (*ptr)->reference++;
00597 
00598     current->next = varHead;
00599     varHead = current;
00600     return bp;
00601 }
00602 
00603 ArgType
00604 FindTypeByName(const char *typeName)
00605 {
00606     int i;
00607 
00608     for (i=0; i < valueCount; i++) {
00609        if (PL_strcasecmp(typeName,valueString[i]) == 0) {
00610            return (ArgType) i;
00611        }
00612        if (valueString[i][0] == 'C' && valueString[i][1] == 'K' &&
00613           valueString[i][2] == '_' && 
00614                      (PL_strcasecmp(typeName,&valueString[i][3]) == 0)) {
00615            return (ArgType) i;
00616        }
00617     }
00618     return ArgNone;
00619 }
00620 
00621 CK_RV 
00622 ArrayVariable(const char *bp, const char *typeName, CK_ULONG count)
00623 {
00624     ArgType type;
00625     Value *value; /* new Value */
00626 
00627     type = FindTypeByName(typeName);
00628     if (type == ArgNone) {
00629        fprintf(stderr,"Invalid type (%s)\n", typeName);
00630        return CKR_FUNCTION_FAILED;
00631     }
00632     value = NewValue(type, count);
00633     (void) AddVariable(bp, &value);
00634     return CKR_OK;
00635 }
00636 
00637 #define MAX_TEMPLATE 25
00638 
00639 CK_RV 
00640 ArrayTemplate(const char *bp, char *attributes)
00641 {
00642     char aname[512];
00643     CK_ULONG attributeTypes[MAX_TEMPLATE];
00644     CK_ATTRIBUTE *template;
00645     Value *value; /* new Value */
00646     char *ap;
00647     int i, count = 0;
00648 
00649     memcpy(aname,attributes,strlen(attributes)+1);
00650 
00651     for (ap = aname, count = 0; ap && *ap && count < MAX_TEMPLATE; count++) {
00652        char *cur = ap;
00653        ConstType type;
00654 
00655        ap = strchr(ap,',');
00656        if (ap) {
00657            *ap++ = 0;
00658        }
00659 
00660        (void)constLookup(cur, &attributeTypes[count], &type);
00661        if ((type != ConstAttribute) && (type != ConstNone)) {
00662           fprintf(stderr, "Unknown Attribute %s\n", cur);
00663           return CKR_FUNCTION_FAILED;
00664        }
00665     }
00666 
00667     value = NewValue(ArgAttribute, count);
00668 
00669     template = (CK_ATTRIBUTE *)value->data;
00670     for (i=0; i < count ; i++) {
00671        template[i].type = attributeTypes[i];
00672     }
00673     (void) AddVariable(bp, &value);
00674     return CKR_OK;
00675 }
00676 
00677 CK_RV
00678 BuildTemplate(Value *vp)
00679 {
00680     CK_ATTRIBUTE *template = (CK_ATTRIBUTE *)vp->data;
00681     int i;
00682 
00683     for (i=0; i < vp->arraySize; i++) {
00684        if (((signed long)template[i].ulValueLen) > 0) {
00685            if (template[i].pValue) free(template[i].pValue);
00686            template[i].pValue = malloc(template[i].ulValueLen);
00687        }
00688     }
00689     return CKR_OK;
00690 }
00691 
00692 CK_RV
00693 SetTemplate(Value *vp, CK_ULONG index, CK_ULONG value)
00694 {
00695     CK_ATTRIBUTE *template = (CK_ATTRIBUTE *)vp->data;
00696     int isbool = 0;
00697     CK_ULONG len;
00698     ConstType attrType;
00699 
00700     if (index >= (CK_ULONG) vp->arraySize) {
00701        fprintf(stderr,"index (%lu) greater than array (%d)\n", 
00702                                           index, vp->arraySize);
00703        return CKR_ARGUMENTS_BAD;
00704     }
00705     attrType =  getConstFromAttribute(template[index].type);
00706 
00707     if (attrType == ConstNone) {
00708        fprintf(stderr,"can't set index (%lu) because ", index);
00709        printConst(template[index].type,ConstAttribute, 0);
00710        fprintf(stderr, " is not a CK_BBOOL or CK_ULONG\n");
00711        return CKR_ARGUMENTS_BAD;
00712     }
00713     isbool = (attrType == ConstBool);
00714     len = isbool ? sizeof (CK_BBOOL) : sizeof(CK_ULONG);
00715     if ((template[index].ulValueLen != len) || (template[index].pValue)) {
00716        free(template[index].pValue);
00717        template[index].pValue = malloc(len);
00718        template[index].ulValueLen = len;
00719     }
00720     if (isbool) {
00721        *(CK_BBOOL *)template[index].pValue = (CK_BBOOL) value;
00722     } else {
00723        *(CK_ULONG *)template[index].pValue = (CK_ULONG) value;
00724     }
00725     return CKR_OK;
00726 
00727 }
00728 
00729 CK_RV
00730 NewMechanism(const char *bp, CK_ULONG mechType)
00731 {
00732     Value *value; /* new Value */
00733     CK_MECHANISM *mechanism;
00734 
00735     value = NewValue(ArgMechanism, 1);
00736     mechanism = (CK_MECHANISM *)value->data;
00737     mechanism->mechanism = mechType;
00738     mechanism->pParameter = NULL;
00739     mechanism->ulParameterLen = 0;
00740     (void) AddVariable(bp, &value);
00741     return CKR_OK;
00742 }
00743 
00744 CK_RV
00745 NewInitializeArgs(const char *bp, CK_ULONG flags, const char *param)
00746 {
00747     Value *value; /* new Value */
00748     CK_C_INITIALIZE_ARGS *init;
00749 
00750     value = NewValue(ArgInitializeArgs, 1);
00751     init = (CK_C_INITIALIZE_ARGS *)value->data;
00752     init->flags = flags;
00753     if (strcmp(param, "null") != 0) {
00754         init->LibraryParameters = (CK_CHAR_PTR *)strdup(param);
00755     }
00756     (void) AddVariable(bp, &value);
00757     return CKR_OK;
00758 }
00759 
00760 /*
00761  * add a new variable to the chain
00762  */
00763 CK_RV
00764 DeleteVariable(const char *bp)
00765 {
00766     char vname[512];
00767     Variable **current;
00768 
00769     bp = readChars(bp,vname,sizeof(vname));
00770 
00771     for (current = &varHead; *current; current = &(*current)->next) {
00772        if (PL_strcasecmp((*current)->vname,vname) == 0) {
00773                argFree((*current)->value);
00774               *current = (*current)->next;
00775               break;
00776        }
00777     }
00778     return CKR_OK;
00779 }
00780 
00781 /*
00782  * convert an octal value to integer
00783  */   
00784 CK_ULONG
00785 otoi(const char *o)
00786 {
00787     CK_ULONG value = 0;
00788 
00789     while (*o) {
00790        if ((*o >= '0') && (*o <= '7')) {
00791            value = (value << 3) | (unsigned)(*o - '0');
00792        } else {
00793            break;
00794        }
00795     }
00796     return value;
00797 }
00798 
00799 /*
00800  * convert a hex value to integer
00801  */   
00802 CK_ULONG
00803 htoi(const char *x)
00804 {
00805     CK_ULONG value = 0;
00806 
00807     while (*x) {
00808        if ((*x >= '0') && (*x <= '9')) {
00809            value = (value << 4) | (unsigned)(*x - '0');
00810        } else if ((*x >= 'a') && (*x <= 'f')) {
00811            value = (value << 4) | (unsigned)(*x - 'a');
00812        } else if ((*x >= 'A') && (*x <= 'F')) {
00813            value = (value << 4) | (unsigned)(*x - 'A');
00814        } else {
00815            break;
00816        }
00817     }
00818     return value;
00819 }
00820 
00821 
00822 /*
00823  * look up or decode a constant value
00824  */
00825 const char *
00826 constLookup(const char *bp, CK_ULONG *value, ConstType *type)
00827 {
00828     char vname[512];
00829     int i;
00830 
00831     bp = readChars(bp,vname,sizeof(vname));
00832 
00833     for (i=0; i < constCount; i++) {
00834        if ((PL_strcasecmp(consts[i].name,vname) == 0) ||
00835               PL_strcasecmp(consts[i].name+5,vname) == 0) {
00836            *value = consts[i].value;
00837            *type = consts[i].type;
00838            return bp;
00839        }
00840     }
00841 
00842     *type = ConstNone;
00843     if (vname[0] == '0' && vname[1] == 'X') {
00844        *value = htoi(&vname[2]);
00845     } else if (vname[0] == '0') {
00846        *value = otoi(&vname[1]);
00847     } else {
00848        *value = atoi(vname);
00849     }
00850     return bp;
00851 }
00852 
00853 int
00854 ArgSize(ArgType type)
00855 {
00856        int size=0;
00857        type &= ArgMask;
00858 
00859        switch (type) {
00860        case ArgNone:
00861            size = 0;
00862            break;
00863        case ArgULong:
00864            size = sizeof(CK_ULONG);
00865            break;
00866        case ArgVar:
00867            size = 1; /* get's changed later */
00868            break;
00869        case ArgChar:
00870        case ArgUTF8:
00871            size = 1;
00872            break;
00873        case ArgInfo:
00874            size = sizeof(CK_INFO);
00875            break;
00876        case ArgSlotInfo:
00877            size = sizeof(CK_SLOT_INFO);
00878            break;
00879        case ArgTokenInfo:
00880            size = sizeof(CK_TOKEN_INFO);
00881            break;
00882        case ArgSessionInfo:
00883            size = sizeof(CK_SESSION_INFO);
00884            break;
00885        case ArgAttribute:
00886            size = sizeof(CK_ATTRIBUTE);
00887            break;
00888        case ArgMechanism:
00889            size = sizeof(CK_MECHANISM);
00890            break;
00891        case ArgMechanismInfo:
00892            size = sizeof(CK_MECHANISM_INFO);
00893            break;
00894        case ArgInitializeArgs:
00895            size = sizeof(CK_C_INITIALIZE_ARGS);
00896            break;
00897        case ArgFunctionList:
00898            size = sizeof(CK_FUNCTION_LIST);
00899            break;
00900        default:
00901            break;
00902        }
00903 
00904        return (size);
00905 }
00906 
00907 CK_RV
00908 restore(const char *filename,Value *ptr)
00909 {
00910     int fd,size;
00911 
00912     fd = open(filename,O_RDONLY|O_BINARY);
00913     if (fd < 0) {
00914        perror(filename);
00915        return CKR_FUNCTION_FAILED;
00916     }
00917 
00918     size = read(fd,ptr->data,ptr->size);
00919     if (systemFlags & FLAG_VerifyFile) {
00920        printDump(ptr->data,ptr->size);
00921     }
00922     if (size < 0) {
00923        perror(filename);
00924        return CKR_FUNCTION_FAILED;
00925     } else if (size != ptr->size) {
00926        fprintf(stderr,"%s: only read %d bytes, needed to read %d bytes\n",
00927                      filename,size,ptr->size);
00928        return CKR_FUNCTION_FAILED;
00929     }
00930     close(fd);
00931     return CKR_OK;
00932 }
00933 
00934 CK_RV
00935 save(const char *filename,Value *ptr)
00936 {
00937     int fd,size;
00938 
00939     fd = open(filename,O_WRONLY|O_BINARY|O_CREAT,0666);
00940     if (fd < 0) {
00941        perror(filename);
00942        return CKR_FUNCTION_FAILED;
00943     }
00944 
00945     size = write(fd,ptr->data,ptr->size);
00946     if (size < 0) {
00947        perror(filename);
00948        return CKR_FUNCTION_FAILED;
00949     } else if (size != ptr->size) {
00950        fprintf(stderr,"%s: only wrote %d bytes, need to write %d bytes\n",
00951                      filename,size,ptr->size);
00952        return CKR_FUNCTION_FAILED;
00953     }
00954     close(fd);
00955     return CKR_OK;
00956 }
00957 
00958 static CK_RV
00959 increment(Value *ptr, CK_ULONG value)
00960 {
00961     if ((ptr->type & ArgMask) != ArgULong) {
00962        return CKR_ARGUMENTS_BAD;
00963     }
00964     *(CK_ULONG *)ptr->data += value;
00965     return CKR_OK;
00966 }
00967 
00968 static CK_RV
00969 decrement(Value *ptr, CK_ULONG value)
00970 {
00971     if ((ptr->type & ArgMask) != ArgULong) {
00972        return CKR_ARGUMENTS_BAD;
00973     }
00974     *(CK_ULONG *)ptr->data -= value;
00975     return CKR_OK;
00976 }
00977 
00978 CK_RV
00979 printArg(Value *ptr,int arg_number)
00980 {
00981     ArgType type = ptr->type & ArgMask;
00982     CK_INFO *info;
00983     CK_SLOT_INFO    *slotInfo;
00984     CK_TOKEN_INFO   *tokenInfo;
00985     CK_SESSION_INFO *sessionInfo;
00986     CK_ATTRIBUTE    *attribute;
00987     CK_MECHANISM    *mechanism;
00988     CK_MECHANISM_INFO    *mechanismInfo;
00989     CK_C_INITIALIZE_ARGS *initArgs;
00990     CK_FUNCTION_LIST *functionList;
00991     CK_RV ckrv = CKR_OK;
00992     ConstType constType;
00993 
00994     if (arg_number) {
00995        printf("Arg %d: \n",arg_number);
00996     }
00997     if (ptr->arraySize > 1) {
00998        Value element;
00999        int i;
01000        int elementSize = ptr->size/ptr->arraySize;
01001        char *dp = (char *)ptr->data;
01002 
01003        /* build a temporary Value to hold a single element */
01004        element.type = type;
01005        element.constType = ptr->constType;
01006        element.size = elementSize;
01007        element.filename = ptr->filename;
01008        element.reference = 1;
01009        element.arraySize = 1;
01010        for (i=0; i < ptr->arraySize; i++) {
01011            printf(" -----[ %d ] -----\n", i);
01012            element.data = (void *) &dp[i*elementSize];
01013            (void) printArg(&element, 0);
01014        }
01015        return ckrv;
01016     }
01017     if (ptr->data == NULL) {
01018        printf(" NULL ptr to a %s\n", valueString[type]);
01019        return ckrv;
01020     }
01021     switch (type) {
01022     case ArgNone:
01023        printf(" None\n");
01024        break;
01025     case ArgULong:
01026        printf(" %lu (0x%lx)\n", *((CK_ULONG *)ptr->data),
01027                      *((CK_ULONG *)ptr->data));
01028        if (ptr->constType != ConstNone) {
01029            printf(" ");
01030            printConst(*(CK_ULONG *)ptr->data,ptr->constType,1);
01031        }
01032        break;
01033     case ArgVar:
01034        printf(" %s\n",(char *)ptr->data);
01035        break;
01036     case ArgUTF8:
01037        printf(" %s\n",(char *)ptr->data);
01038        break;
01039     case ArgChar:
01040        printDump(ptr->data,ptr->size);
01041        break;
01042     case ArgInfo:
01043 #define VERSION(x) (x).major, (x).minor
01044        info = (CK_INFO *)ptr->data;
01045        printf(" Cryptoki Version: %d.%02d\n",
01046               VERSION(info->cryptokiVersion));
01047        printf(" Manufacturer ID: ");
01048        printChars(info->manufacturerID,sizeof(info->manufacturerID));
01049        printFlags(" Flags: ", info->flags, ConstInfoFlags);
01050        printf(" Library Description: ");
01051        printChars(info->libraryDescription,sizeof(info->libraryDescription));
01052        printf(" Library Version: %d.%02d\n",
01053               VERSION(info->libraryVersion));
01054        break;
01055     case ArgSlotInfo:
01056        slotInfo = (CK_SLOT_INFO *)ptr->data;
01057        printf(" Slot Description: ");
01058        printChars(slotInfo->slotDescription,sizeof(slotInfo->slotDescription));
01059        printf(" Manufacturer ID: ");
01060        printChars(slotInfo->manufacturerID,sizeof(slotInfo->manufacturerID));
01061        printFlags(" Flags: ", slotInfo->flags, ConstSlotFlags);
01062        printf(" Hardware Version: %d.%02d\n",
01063               VERSION(slotInfo->hardwareVersion));
01064        printf(" Firmware Version: %d.%02d\n",
01065               VERSION(slotInfo->firmwareVersion));
01066        break;
01067     case ArgTokenInfo:
01068        tokenInfo = (CK_TOKEN_INFO *)ptr->data;
01069        printf(" Label: ");
01070        printChars(tokenInfo->label,sizeof(tokenInfo->label));
01071        printf(" Manufacturer ID: ");
01072        printChars(tokenInfo->manufacturerID,sizeof(tokenInfo->manufacturerID));
01073        printf(" Model: ");
01074        printChars(tokenInfo->model,sizeof(tokenInfo->model));
01075        printf(" Serial Number: ");
01076        printChars(tokenInfo->serialNumber,sizeof(tokenInfo->serialNumber));
01077        printFlags(" Flags: ", tokenInfo->flags, ConstTokenFlags);
01078        printf(" Max Session Count: ");
01079        printConst(tokenInfo->ulMaxSessionCount, ConstAvailableSizes, 1);
01080        printf(" Session Count: ");
01081        printConst(tokenInfo->ulSessionCount, ConstCurrentSize, 1);
01082        printf(" RW Session Count: ");
01083        printConst(tokenInfo->ulMaxRwSessionCount, ConstAvailableSizes, 1);
01084        printf(" Max Pin Length : ");
01085        printConst(tokenInfo->ulMaxPinLen, ConstCurrentSize, 1);
01086        printf(" Min Pin Length : ");
01087        printConst(tokenInfo->ulMinPinLen, ConstCurrentSize, 1);
01088        printf(" Total Public Memory: ");
01089        printConst(tokenInfo->ulTotalPublicMemory, ConstAvailableSizes, 1);
01090        printf(" Free Public Memory: ");
01091        printConst(tokenInfo->ulFreePublicMemory, ConstCurrentSize, 1);
01092        printf(" Total Private Memory: ");
01093        printConst(tokenInfo->ulTotalPrivateMemory, ConstAvailableSizes, 1);
01094        printf(" Free Private Memory: ");
01095        printConst(tokenInfo->ulFreePrivateMemory, ConstCurrentSize, 1);
01096        printf(" Hardware Version: %d.%02d\n",
01097               VERSION(tokenInfo->hardwareVersion));
01098        printf(" Firmware Version: %d.%02d\n",
01099               VERSION(tokenInfo->firmwareVersion));
01100        printf(" UTC Time: ");
01101        printChars(tokenInfo->utcTime,sizeof(tokenInfo->utcTime));
01102        break;
01103     case ArgSessionInfo:
01104        sessionInfo = (CK_SESSION_INFO *)ptr->data;
01105        printf(" SlotID: 0x%08lx\n", sessionInfo->slotID);
01106        printf(" State: ");
01107        printConst(sessionInfo->state, ConstSessionState, 1);
01108        printFlags(" Flags: ", sessionInfo->flags, ConstSessionFlags);
01109        printf(" Device error: %lu 0x%08lx\n",sessionInfo->ulDeviceError,
01110                      sessionInfo->ulDeviceError);
01111        break;
01112     case ArgAttribute:
01113        attribute = (CK_ATTRIBUTE *)ptr->data;
01114        printf(" Attribute Type: ");
01115        printConst(attribute->type, ConstAttribute, 1);
01116        printf(" Attribute Data: ");
01117        if (attribute->pValue == NULL) {
01118            printf("NULL\n");
01119            printf("Attribute Len: %lu\n",attribute->ulValueLen);
01120        } else {
01121            constType = getConstFromAttribute(attribute->type);
01122            if (constType != ConstNone) {
01123               CK_ULONG value = (constType == ConstBool) ?
01124                   *(CK_BBOOL *)attribute->pValue :
01125                   *(CK_ULONG *)attribute->pValue;
01126               printConst(value, constType, 1);
01127            } else {
01128               printf("\n");
01129               printDump(attribute->pValue, attribute->ulValueLen);
01130            }
01131        }
01132        break;
01133     case ArgMechanism:
01134        mechanism = (CK_MECHANISM *)ptr->data;
01135        printf(" Mechanism Type: ");
01136        printConst(mechanism->mechanism, ConstMechanism, 1);
01137        printf(" Mechanism Data:\n");
01138        printDump(mechanism->pParameter, mechanism->ulParameterLen);
01139        break;
01140     case ArgMechanismInfo:
01141        mechanismInfo = (CK_MECHANISM_INFO *)ptr->data;
01142        printf(" Minimum Key Size: %ld\n",mechanismInfo->ulMinKeySize);
01143        printf(" Maximum Key Size: %ld\n",mechanismInfo->ulMaxKeySize);
01144        printFlags(" Flags: ", mechanismInfo->flags, ConstMechanismFlags);
01145        break;
01146     case ArgInitializeArgs:
01147        initArgs = (CK_C_INITIALIZE_ARGS *)ptr->data;
01148        printFlags(" Flags: ", initArgs->flags, ConstInitializeFlags);
01149         if (initArgs->LibraryParameters) {
01150            printf("Params: %s\n",initArgs->LibraryParameters);
01151        }
01152     case ArgFunctionList:
01153        functionList = (CK_FUNCTION_LIST *)ptr->data;
01154        printf(" Version: %d.%02d\n", VERSION(functionList->version));
01155 #ifdef notdef
01156 #undef CK_NEED_ARG_LIST
01157 #define CK_PKCS11_FUNCTION_INFO(func) \
01158        printf(" %s: 0x%08lx\n", #func, (unsigned long) functionList->func );
01159 #include "pkcs11f.h"
01160 #undef CK_NEED_ARG_LIST
01161 #undef CK_PKCS11_FUNCTION_INFO
01162 #endif
01163     default:
01164        ckrv = CKR_ARGUMENTS_BAD;
01165        break;
01166     }
01167 
01168     return ckrv;
01169 }
01170 
01171 
01172 /*
01173  * Feeling ambitious? turn this whole thing into lexx yacc parser
01174  * with full expressions.
01175  */
01176 Value **
01177 parseArgs(int index, const char * bp)
01178 {
01179     const Commands *cp = &commands[index];
01180     int size = strlen(cp->fname);
01181     int i;
01182     CK_ULONG value;
01183     char vname[512];
01184     Value **argList,*possible;
01185     ConstType constType;
01186 
01187     /*
01188      * skip pass the command
01189      */
01190     if ((cp->fname[0] == 'C') && (cp->fname[1] == '_') && (bp[1] != '_')) {
01191        size -= 2;
01192     }
01193     bp += size;
01194 
01195     /*
01196      * Initialize our argument list
01197      */
01198     argList = (Value **)malloc(sizeof(Value*)*MAX_ARGS);
01199     for (i=0; i < MAX_ARGS; i++) { argList[i] = NULL; }
01200 
01201     /*
01202      * Walk the argument list parsing it...
01203      */
01204     for (i=0 ;i < MAX_ARGS; i++) {
01205        ArgType type = cp->args[i] & ArgMask;
01206        int error;
01207 
01208         /* strip blanks */
01209         bp = strip(bp);
01210 
01211        /* if we hit ArgNone, we've nabbed all the arguments we need */
01212        if (type == ArgNone) {
01213            break;
01214        }
01215 
01216        /* if we run out of space in the line, we weren't given enough
01217         * arguments... */
01218        if (*bp == '\0') {
01219            /* we're into optional arguments, ok to quit now */
01220            if (cp->args[i] & ArgOpt) {
01221               break;
01222            }
01223            fprintf(stderr,"%s: only %d args found,\n",cp->fname,i);
01224            parseFree(argList);
01225            return NULL;
01226        }
01227 
01228        /* collect all the rest of the command line and send
01229         * it as a single argument */
01230        if (cp->args[i] & ArgFull) {
01231            int size = strlen(bp)+1;
01232            argList[i] = NewValue(type, size);
01233            memcpy(argList[i]->data, bp, size);
01234            break;
01235        }
01236 
01237        /*
01238         * look up the argument in our variable list first... only 
01239         * exception is the new argument type for set...
01240         */
01241        error = 0;
01242        if ((cp->args[i] != (ArgVar|ArgNew)) && 
01243                      (possible = varLookup(bp,vname,sizeof(vname),&error))) {
01244           /* ints are only compatible with other ints... all other types
01245            * are interchangeable... */
01246           if (type != ArgVar) { /* ArgVar's match anyone */
01247               if ((type == ArgULong) ^ 
01248                             ((possible->type & ArgMask) == ArgULong)) {
01249                   fprintf(stderr,"%s: Arg %d incompatible type with <%s>\n",
01250                             cp->fname,i+1,vname);
01251                   argFree(possible);
01252                   parseFree(argList);
01253                   return NULL;
01254               }
01255               /*
01256                * ... that is as long as they are big enough...
01257                */
01258               if (ArgSize(type) > possible->size) {
01259                   fprintf(stderr,
01260                "%s: Arg %d %s is too small (%d bytes needs to be %d bytes)\n",
01261                      cp->fname,i+1,vname,possible->size,ArgSize(type));
01262                   argFree(possible);
01263                   parseFree(argList);
01264                   return NULL;
01265               }
01266           }
01267        
01268           /* everything looks kosher here, use it */    
01269           argList[i] = possible;
01270 
01271           bp = readChars(bp,vname,sizeof(vname));
01272           if (cp->args[i] & ArgOut) {
01273               possible->type |= ArgOut;
01274           }
01275           continue;
01276        }
01277 
01278        if (error == 1) {
01279            parseFree(argList);
01280            return NULL;
01281        }
01282 
01283        /* create space for our argument */
01284        argList[i] = NewValue(type, 1);
01285 
01286         if ((PL_strncasecmp(bp, "null", 4) == 0)  && ((bp[4] == 0) 
01287               || (bp[4] == ' ') || (bp[4] =='\t') || (bp[4] =='\n'))) {
01288            if (cp->args[i] == ArgULong) {
01289               fprintf(stderr, "%s: Arg %d CK_ULONG can't be NULL\n",
01290                                                         cp->fname,i+1);
01291               parseFree(argList);
01292               return NULL;
01293            }
01294            argFreeData(argList[i]);
01295            argList[i]->data = NULL;
01296            argList[i]->size = 0;
01297            bp += 4;
01298            if (*bp) bp++;
01299            continue;
01300         }
01301 
01302        /* if we're an output variable, we need to add it */
01303        if (cp->args[i] & ArgOut) {
01304             if (PL_strncasecmp(bp,"file(",5) == 0 /* ) */ ) {
01305                char filename[512];
01306               bp = readChars(bp+5,filename,sizeof(filename));
01307               size = PL_strlen(filename);
01308               if ((size > 0) && (/* ( */filename[size-1] == ')')) {
01309                   filename[size-1] = 0; 
01310               }
01311               filename[size] = 0; 
01312               argList[i]->filename = (char *)malloc(size+1);
01313 
01314               PL_strcpy(argList[i]->filename,filename);
01315 
01316               argList[i]->type |= ArgOut|ArgFile;
01317               break;
01318            }
01319            bp = AddVariable(bp,&argList[i]);
01320            argList[i]->type |= ArgOut;
01321            continue;
01322        } 
01323 
01324         if (PL_strncasecmp(bp, "file(", 5) == 0 /* ) */ ) {
01325            char filename[512];
01326 
01327            bp = readChars(bp+5,filename,sizeof(filename));
01328            size = PL_strlen(filename);
01329            if ((size > 0) && ( /* ( */ filename[size-1] == ')')) {
01330               filename[size-1] = 0; 
01331            }
01332 
01333            if (restore(filename,argList[i]) != CKR_OK) {
01334               parseFree(argList);
01335               return NULL;
01336            }
01337            continue;
01338        }
01339 
01340        switch (type) {
01341        case ArgULong:
01342             bp = constLookup(bp, &value, &constType);
01343             *(int *)argList[i]->data = value;
01344             argList[i]->constType = constType;
01345             break;
01346        case ArgVar:
01347             argFreeData(argList[i]);
01348             size = getEnd(bp)+1;
01349             argList[i]->data = (void *)malloc(size);
01350             argList[i]->size = size;
01351             /* fall through */
01352        case ArgInfo:
01353        case ArgSlotInfo:
01354        case ArgTokenInfo:
01355        case ArgSessionInfo:
01356        case ArgAttribute:
01357        case ArgMechanism:
01358        case ArgMechanismInfo:
01359        case ArgInitializeArgs:
01360        case ArgUTF8:
01361        case ArgChar:
01362             bp = readChars(bp,(char *)argList[i]->data,argList[i]->size);
01363        case ArgNone:
01364        default:
01365             break;
01366        }
01367     }
01368 
01369     return argList;
01370 }
01371 
01372 /* lookup the command in the array */
01373 int
01374 lookup(const char *buf)
01375 {
01376     int size,i;
01377     int buflen;
01378 
01379     buflen = PL_strlen(buf);
01380 
01381     for ( i = 0; i < commandCount; i++) {
01382        size = PL_strlen(commands[i].fname);
01383 
01384        if (size <= buflen) {
01385            if (PL_strncasecmp(buf,commands[i].fname,size) == 0) {
01386               return i;
01387            }
01388        }
01389        if (size-2 <= buflen) {
01390            if (commands[i].fname[0] == 'C' && commands[i].fname[1] == '_' &&
01391               (PL_strncasecmp(buf,&commands[i].fname[2],size-2) == 0)) {
01392               return i;
01393            }
01394        }
01395     }
01396     fprintf(stderr,"Can't find command %s\n",buf);
01397     return -1;
01398 }
01399 
01400 void
01401 putOutput(Value **ptr)
01402 {
01403     int i;
01404 
01405     for (i=0; i < MAX_ARGS; i++) {
01406        ArgType type;
01407 
01408        if (ptr[i] == NULL) break;
01409 
01410        type  = ptr[i]->type;
01411 
01412        ptr[i]->type &= ~ArgOut;
01413        if (type == ArgNone) {
01414            break;
01415        }
01416        if (type & ArgOut) {
01417            (void) printArg(ptr[i],i+1);
01418        }
01419        if (type & ArgFile) {
01420            save(ptr[i]->filename,ptr[i]);
01421            free(ptr[i]->filename);
01422            ptr[i]->filename= NULL; /* paranoia */
01423        }
01424     }
01425 }
01426           
01427 CK_RV
01428 unloadModule(Module *module)
01429 {
01430    
01431    if (module->library) {
01432        PR_UnloadLibrary(module->library);
01433    }
01434 
01435    module->library = NULL;
01436    module->functionList = NULL;
01437 
01438    return CKR_OK;
01439 }
01440 
01441 CK_RV
01442 loadModule(Module *module, char *library)
01443 {
01444    PRLibrary *newLibrary;
01445    CK_C_GetFunctionList getFunctionList;
01446    CK_FUNCTION_LIST *functionList;
01447    CK_RV ckrv;
01448 
01449    newLibrary = PR_LoadLibrary(library);
01450    if (!newLibrary) {
01451        fprintf(stderr,"Couldn't load library %s\n",library);
01452        return CKR_FUNCTION_FAILED;
01453    }
01454    getFunctionList = (CK_C_GetFunctionList) 
01455                      PR_FindSymbol(newLibrary,"C_GetFunctionList");
01456    if (!getFunctionList) {
01457        fprintf(stderr,"Couldn't find \"C_GetFunctionList\" in %s\n",library);
01458        return CKR_FUNCTION_FAILED;
01459    }
01460 
01461    ckrv = (*getFunctionList)(&functionList);
01462    if (ckrv != CKR_OK) {
01463        return ckrv;
01464    }
01465    
01466    if (module->library) {
01467        PR_UnloadLibrary(module->library);
01468    }
01469 
01470    module->library = newLibrary;
01471    module->functionList = functionList;
01472 
01473    return CKR_OK;
01474 }
01475 
01476 static void
01477 printHelp(int index, int full)
01478 {
01479     int j;
01480     printf(" %s", commands[index].fname);
01481     for (j=0; j < MAX_ARGS; j++) {
01482        ArgType type = commands[index].args[j] & ArgMask;
01483        if (type == ArgNone) {
01484            break;
01485        }
01486        printf(" %s", valueString[type]);
01487     }
01488     printf("\n");
01489     printf(" %s\n",commands[index].helpString);
01490 }
01491 
01492 /* add Topical help here ! */
01493 static CK_RV
01494 printTopicHelp(char *topic)
01495 {
01496     int size,i;
01497     int topicLen;
01498 
01499     topicLen = PL_strlen(topic);
01500 
01501     for ( i = 0; i < topicCount; i++) {
01502        size = PL_strlen(topics[i].name);
01503 
01504        if (size <= topicLen) {
01505            if (PL_strncasecmp(topic,topics[i].name,size) == 0) {
01506               break;
01507            }
01508        }
01509     }
01510 
01511     if (i == topicCount) {
01512        fprintf(stderr,"Can't find topic '%s'\n", topic);
01513        return CKR_DATA_INVALID;
01514     }
01515 
01516     printf(" %s", topic);
01517     printf("\n");
01518     printf(" %s\n",topics[i].helpString);
01519     return CKR_OK;
01520 }
01521 
01522 static CK_RV
01523 printGeneralHelp(void)
01524 {
01525     int i;
01526     printf(" To get help on commands, select from the list below:");
01527     for ( i = 0; i < commandCount; i++) {
01528        if (i % 5 == 0) printf("\n");
01529        printf("%s,", commands[i].fname);
01530     }
01531     printf("\n");
01532     /* print help topics */
01533     printf(" To get help on a topic, select from the list below:");
01534     for ( i = 0; i < topicCount; i++) {
01535        if (i % 5 == 0) printf("\n");
01536        printf("%s,", topics[i].name);
01537     }
01538     printf("\n");
01539    return CKR_OK;
01540 }
01541 
01542 static CK_RV
01543 quitIf(CK_ULONG a, const char *cmp, CK_ULONG b)
01544 {
01545     if (strcmp(cmp, "<") == 0) {
01546        return (a < b) ? CKR_QUIT : CKR_OK;
01547     } else if (strcmp(cmp, ">") == 0) {
01548        return (a > b) ? CKR_QUIT : CKR_OK;
01549     } else if (strcmp(cmp, "<=") == 0) {
01550        return (a <= b) ? CKR_QUIT : CKR_OK;
01551     } else if (strcmp(cmp, ">=") == 0) {
01552        return (a >= b) ? CKR_QUIT : CKR_OK;
01553     } else if (strcmp(cmp, "=") == 0) {
01554        return (a == b) ? CKR_QUIT : CKR_OK;
01555     } else if (strcmp(cmp, "!=") == 0) {
01556        return (a != b) ? CKR_QUIT : CKR_OK;
01557     }
01558     printf("Unkown integer comparator: '%s'\n", cmp);
01559     return CKR_ARGUMENTS_BAD;
01560 }
01561 
01562 static CK_RV
01563 quitIfString(const char *a, const char *cmp, const char *b)
01564 {
01565 
01566     if (strcmp(cmp, "=") == 0) {
01567        return (strcmp(a,b) == 0) ? CKR_QUIT : CKR_OK;
01568     } else if (strcmp(cmp, "!=") == 0) {
01569        return (strcmp(a,b) != 0) ? CKR_QUIT : CKR_OK;
01570     }
01571     printf("Unkown string comparator: '%s'\n", cmp);
01572     return CKR_ARGUMENTS_BAD;
01573 }
01574 
01575 CK_RV run(const char *); 
01576 CK_RV timeCommand(const char *); 
01577 CK_RV loop(const char *filename, const char *var, 
01578             CK_ULONG start, CK_ULONG end, CK_ULONG step) ;
01579 
01580 /*
01581  * Actually dispatch the function... Bad things happen
01582  * if these don't match the commands array.
01583  */
01584 CK_RV
01585 do_func(int index, Value **a)
01586 {
01587     int value, helpIndex;
01588     static Module module = { NULL, NULL} ;
01589     CK_FUNCTION_LIST *func = module.functionList;
01590 
01591     switch (commands[index].fType) {
01592     case F_C_Initialize:
01593        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01594        return func->C_Initialize((void *)a[0]->data);
01595     case F_C_Finalize:
01596        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01597        return func->C_Finalize((void *)a[0]->data);
01598     case F_C_GetInfo:
01599        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01600        return func->C_GetInfo((CK_INFO *)a[0]->data);
01601     case F_C_GetFunctionList:
01602        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01603        return func->C_GetFunctionList((CK_FUNCTION_LIST **)a[0]->data);
01604     case F_C_GetSlotList:
01605        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01606        return func->C_GetSlotList((CK_BBOOL)*(CK_ULONG *)a[0]->data,
01607                                    (CK_SLOT_ID *)a[1]->data,
01608                                    (CK_LONG *)a[2]->data);
01609     case F_C_GetSlotInfo:
01610        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01611        return func->C_GetSlotInfo(*(CK_ULONG *)a[0]->data,
01612                                    (CK_SLOT_INFO *)a[1]->data);
01613     case F_C_GetTokenInfo:
01614        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01615        return func->C_GetTokenInfo(*(CK_ULONG *)a[0]->data,
01616                                    (CK_TOKEN_INFO *)a[1]->data);
01617     case F_C_GetMechanismList:
01618        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01619        if (a[1]->data) {
01620            a[1]->constType = ConstMechanism;
01621        }
01622        return func->C_GetMechanismList(*(CK_ULONG *)a[0]->data,
01623                                    (CK_MECHANISM_TYPE*)a[1]->data,
01624                                    (CK_ULONG *)a[2]->data);
01625     case F_C_GetMechanismInfo:
01626        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01627        return func->C_GetMechanismInfo(*(CK_ULONG *)a[0]->data,
01628                                    *(CK_ULONG *)a[1]->data,
01629                                    (CK_MECHANISM_INFO *)a[2]->data);
01630     case F_C_InitToken:
01631        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01632        return func->C_InitToken(*(CK_ULONG *)a[0]->data,
01633                                    (CK_CHAR *)a[1]->data,
01634                                    *(CK_ULONG *)a[2]->data,
01635                                    (CK_CHAR *)a[3]->data);
01636     case F_C_InitPIN:
01637        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01638        return func->C_InitPIN(*(CK_ULONG *)a[0]->data,
01639                                    (CK_CHAR *)a[1]->data,
01640                                    *(CK_ULONG *)a[2]->data);
01641     case F_C_SetPIN:
01642        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01643        return func->C_SetPIN(*(CK_ULONG *)a[0]->data,
01644                                    (CK_CHAR *)a[1]->data,
01645                                    *(CK_ULONG *)a[2]->data,
01646                                    (CK_CHAR *)a[3]->data,
01647                                    *(CK_ULONG *)a[4]->data);
01648     case F_C_OpenSession:
01649        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01650        return func->C_OpenSession(*(CK_ULONG *)a[0]->data,
01651                                    *(CK_ULONG *)a[1]->data,
01652                                    (void *)NULL,
01653                                    (CK_NOTIFY) NULL,
01654                                    (CK_ULONG *)a[2]->data);
01655     case F_C_CloseSession:
01656        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01657        return func->C_CloseSession(*(CK_ULONG *)a[0]->data);
01658     case F_C_CloseAllSessions:
01659        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01660        return func->C_CloseAllSessions(*(CK_ULONG *)a[0]->data);
01661     case F_C_GetSessionInfo:
01662        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01663        return func->C_GetSessionInfo(*(CK_ULONG *)a[0]->data,
01664                                    (CK_SESSION_INFO *)a[1]->data);
01665     case F_C_GetOperationState:
01666        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01667        return func->C_GetOperationState(*(CK_ULONG *)a[0]->data,
01668                                    (CK_BYTE *)a[1]->data,
01669                                    (CK_ULONG *)a[2]->data);
01670     case F_C_SetOperationState:
01671        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01672        return func->C_SetOperationState(*(CK_ULONG *)a[0]->data,
01673                                    (CK_CHAR *)a[1]->data,
01674                                    *(CK_ULONG *)a[2]->data,
01675                                    *(CK_ULONG *)a[3]->data,
01676                                    *(CK_ULONG *)a[4]->data);
01677     case F_C_Login:
01678        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01679        return func->C_Login(*(CK_ULONG *)a[0]->data,
01680                                    *(CK_ULONG *)a[1]->data,
01681                                    (CK_CHAR *)a[2]->data,
01682                                    *(CK_ULONG *)a[3]->data);
01683     case F_C_Logout:
01684        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01685        return func->C_Logout(*(CK_ULONG *)a[0]->data);
01686     case F_C_CreateObject:
01687        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01688        return func->C_CreateObject(*(CK_ULONG *)a[0]->data,
01689                                    (CK_ATTRIBUTE *)a[1]->data,
01690                                    *(CK_ULONG *)a[2]->data,
01691                                    (CK_ULONG *)a[3]->data);
01692     case F_C_CopyObject:
01693        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01694        return func->C_CopyObject(*(CK_ULONG *)a[0]->data,
01695                                    *(CK_ULONG *)a[0]->data,
01696                                    (CK_ATTRIBUTE *)a[1]->data,
01697                                    *(CK_ULONG *)a[2]->data,
01698                                    (CK_ULONG *)a[3]->data);
01699     case F_C_DestroyObject:
01700        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01701        return func->C_DestroyObject(*(CK_ULONG *)a[0]->data,
01702                                    *(CK_ULONG *)a[1]->data);
01703     case F_C_GetObjectSize:
01704        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01705        return func->C_GetObjectSize(*(CK_ULONG *)a[0]->data,
01706                                    *(CK_ULONG *)a[1]->data,
01707                                    (CK_ULONG *)a[2]->data);
01708     case F_C_GetAttributeValue:
01709        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01710        return func->C_GetAttributeValue(*(CK_ULONG *)a[0]->data,
01711                                    *(CK_ULONG *)a[1]->data,
01712                                    (CK_ATTRIBUTE *)a[2]->data,
01713                                    *(CK_ULONG *)a[3]->data);
01714     case F_C_SetAttributeValue:
01715        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01716        return func->C_SetAttributeValue(*(CK_ULONG *)a[0]->data,
01717                                    *(CK_ULONG *)a[1]->data,
01718                                    (CK_ATTRIBUTE *)a[2]->data,
01719                                    *(CK_ULONG *)a[3]->data);
01720     case F_C_FindObjectsInit:
01721        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01722        return func->C_FindObjectsInit(*(CK_ULONG *)a[0]->data,
01723                                    (CK_ATTRIBUTE *)a[1]->data,
01724                                    *(CK_ULONG *)a[2]->data);
01725     case F_C_FindObjects:
01726        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01727        return func->C_FindObjects(*(CK_ULONG *)a[0]->data,
01728                                    (CK_ULONG *)a[1]->data,
01729                                    *(CK_ULONG *)a[2]->data,
01730                                    (CK_ULONG *)a[3]->data);
01731     case F_C_FindObjectsFinal:
01732        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01733        return func->C_FindObjectsFinal(*(CK_ULONG *)a[0]->data);
01734     case F_C_EncryptInit:
01735        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01736        return func->C_EncryptInit(*(CK_ULONG *)a[0]->data,
01737                                    (CK_MECHANISM *)a[1]->data,
01738                                    *(CK_ULONG *)a[2]->data);
01739     case F_C_Encrypt:
01740        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01741        return func->C_Encrypt(*(CK_ULONG *)a[0]->data,
01742                                    (CK_CHAR *)a[1]->data,
01743                                    *(CK_ULONG *)a[2]->data,
01744                                    (CK_CHAR *)a[3]->data,
01745                                    (CK_ULONG *)a[4]->data);
01746     case F_C_EncryptUpdate:
01747        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01748        return func->C_EncryptUpdate(*(CK_ULONG *)a[0]->data,
01749                                    (CK_CHAR *)a[1]->data,
01750                                    *(CK_ULONG *)a[2]->data,
01751                                    (CK_CHAR *)a[3]->data,
01752                                    (CK_ULONG *)a[4]->data);
01753     case F_C_EncryptFinal:
01754        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01755        return func->C_EncryptFinal(*(CK_ULONG *)a[0]->data,
01756                                    (CK_CHAR *)a[1]->data,
01757                                    (CK_ULONG *)a[2]->data);
01758     case F_C_DecryptInit:
01759        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01760        return func->C_DecryptInit(*(CK_ULONG *)a[0]->data,
01761                                    (CK_MECHANISM *)a[1]->data,
01762                                    *(CK_ULONG *)a[2]->data);
01763     case F_C_Decrypt:
01764        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01765        return func->C_Decrypt(*(CK_ULONG *)a[0]->data,
01766                                    (CK_CHAR *)a[1]->data,
01767                                    *(CK_ULONG *)a[2]->data,
01768                                    (CK_CHAR *)a[3]->data,
01769                                    (CK_ULONG *)a[4]->data);
01770     case F_C_DecryptUpdate:
01771        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01772        return func->C_DecryptUpdate(*(CK_ULONG *)a[0]->data,
01773                                    (CK_CHAR *)a[1]->data,
01774                                    *(CK_ULONG *)a[2]->data,
01775                                    (CK_CHAR *)a[3]->data,
01776                                    (CK_ULONG *)a[4]->data);
01777     case F_C_DecryptFinal:
01778        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01779        return func->C_DecryptFinal(*(CK_ULONG *)a[0]->data,
01780                                    (CK_CHAR *)a[1]->data,
01781                                    (CK_ULONG *)a[2]->data);
01782     case F_C_DigestInit:
01783        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01784        return func->C_DigestInit(*(CK_ULONG *)a[0]->data,
01785                                    (CK_MECHANISM *)a[1]->data);
01786     case F_C_Digest:
01787        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01788        return func->C_Digest(*(CK_ULONG *)a[0]->data,
01789                                    (CK_CHAR *)a[1]->data,
01790                                    *(CK_ULONG *)a[2]->data,
01791                                    (CK_CHAR *)a[3]->data,
01792                                    (CK_ULONG *)a[4]->data);
01793     case F_C_DigestUpdate:
01794        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01795        return func->C_DigestUpdate(*(CK_ULONG *)a[0]->data,
01796                                    (CK_CHAR *)a[1]->data,
01797                                    *(CK_ULONG *)a[2]->data);
01798     case F_C_DigestKey:
01799        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01800        return func->C_DigestKey(*(CK_ULONG *)a[0]->data,
01801                                    *(CK_ULONG *)a[1]->data);
01802     case F_C_DigestFinal:
01803        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01804        return func->C_DigestFinal(*(CK_ULONG *)a[0]->data,
01805                                    (CK_CHAR *)a[1]->data,
01806                                    (CK_ULONG *)a[2]->data);
01807     case F_C_SignInit:
01808        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01809        return func->C_SignInit(*(CK_ULONG *)a[0]->data,
01810                                    (CK_MECHANISM *)a[1]->data,
01811                                    *(CK_ULONG *)a[2]->data);
01812     case F_C_Sign:
01813        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01814        return func->C_Sign(*(CK_ULONG *)a[0]->data,
01815                                    (CK_CHAR *)a[1]->data,
01816                                    *(CK_ULONG *)a[2]->data,
01817                                    (CK_CHAR *)a[3]->data,
01818                                    (CK_ULONG *)a[4]->data);
01819     case F_C_SignUpdate:
01820        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01821        return func->C_SignUpdate(*(CK_ULONG *)a[0]->data,
01822                                    (CK_CHAR *)a[1]->data,
01823                                    *(CK_ULONG *)a[2]->data);
01824     case F_C_SignFinal:
01825        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01826        return func->C_SignFinal(*(CK_ULONG *)a[0]->data,
01827                                    (CK_CHAR *)a[1]->data,
01828                                    (CK_ULONG *)a[2]->data);
01829 
01830     case F_C_SignRecoverInit:
01831        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01832        return func->C_SignRecoverInit(*(CK_ULONG *)a[0]->data,
01833                                    (CK_MECHANISM *)a[1]->data,
01834                                    *(CK_ULONG *)a[2]->data);
01835     case F_C_SignRecover:
01836        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01837        return func->C_SignRecover(*(CK_ULONG *)a[0]->data,
01838                                    (CK_CHAR *)a[1]->data,
01839                                    *(CK_ULONG *)a[2]->data,
01840                                    (CK_CHAR *)a[3]->data,
01841                                    (CK_ULONG *)a[4]->data);
01842     case F_C_VerifyInit:
01843        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01844        return func->C_VerifyInit(*(CK_ULONG *)a[0]->data,
01845                                    (CK_MECHANISM *)a[1]->data,
01846                                    *(CK_ULONG *)a[2]->data);
01847     case F_C_Verify:
01848        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01849        return func->C_Verify(*(CK_ULONG *)a[0]->data,
01850                                    (CK_CHAR *)a[1]->data,
01851                                    *(CK_ULONG *)a[2]->data,
01852                                    (CK_CHAR *)a[3]->data,
01853                                    *(CK_ULONG *)a[4]->data);
01854     case F_C_VerifyUpdate:
01855        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01856        return func->C_VerifyUpdate(*(CK_ULONG *)a[0]->data,
01857                                    (CK_CHAR *)a[1]->data,
01858                                    *(CK_ULONG *)a[2]->data);
01859     case F_C_VerifyFinal:
01860        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01861        return func->C_VerifyFinal(*(CK_ULONG *)a[0]->data,
01862                                    (CK_CHAR *)a[1]->data,
01863                                    *(CK_ULONG *)a[2]->data);
01864 
01865     case F_C_VerifyRecoverInit:
01866        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01867        return func->C_VerifyRecoverInit(*(CK_ULONG *)a[0]->data,
01868                                    (CK_MECHANISM *)a[1]->data,
01869                                    *(CK_ULONG *)a[2]->data);
01870     case F_C_VerifyRecover:
01871        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01872        return func->C_VerifyRecover(*(CK_ULONG *)a[0]->data,
01873                                    (CK_CHAR *)a[1]->data,
01874                                    *(CK_ULONG *)a[2]->data,
01875                                    (CK_CHAR *)a[3]->data,
01876                                    (CK_ULONG *)a[4]->data);
01877     case F_C_DigestEncryptUpdate:
01878        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01879        return func->C_DigestEncryptUpdate(*(CK_ULONG *)a[0]->data,
01880                                    (CK_CHAR *)a[1]->data,
01881                                    *(CK_ULONG *)a[2]->data,
01882                                    (CK_CHAR *)a[3]->data,
01883                                    (CK_ULONG *)a[4]->data);
01884     case F_C_DecryptDigestUpdate:
01885        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01886        return func->C_DecryptDigestUpdate(*(CK_ULONG *)a[0]->data,
01887                                    (CK_CHAR *)a[1]->data,
01888                                    *(CK_ULONG *)a[2]->data,
01889                                    (CK_CHAR *)a[3]->data,
01890                                    (CK_ULONG *)a[4]->data);
01891     case F_C_SignEncryptUpdate:
01892        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01893        return func->C_SignEncryptUpdate(*(CK_ULONG *)a[0]->data,
01894                                    (CK_CHAR *)a[1]->data,
01895                                    *(CK_ULONG *)a[2]->data,
01896                                    (CK_CHAR *)a[3]->data,
01897                                    (CK_ULONG *)a[4]->data);
01898     case F_C_DecryptVerifyUpdate:
01899        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01900        return func->C_DecryptVerifyUpdate(*(CK_ULONG *)a[0]->data,
01901                                    (CK_CHAR *)a[1]->data,
01902                                    *(CK_ULONG *)a[2]->data,
01903                                    (CK_CHAR *)a[3]->data,
01904                                    (CK_ULONG *)a[4]->data);
01905     case F_C_GenerateKey:
01906        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01907        return func->C_GenerateKey(*(CK_ULONG *)a[0]->data,
01908                                    (CK_MECHANISM *)a[1]->data,
01909                                    (CK_ATTRIBUTE *)a[2]->data,
01910                                    *(CK_ULONG *)a[3]->data,
01911                                    (CK_ULONG *)a[4]->data);
01912     case F_C_GenerateKeyPair:
01913        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01914        return func->C_GenerateKeyPair(*(CK_ULONG *)a[0]->data,
01915                                    (CK_MECHANISM *)a[1]->data,
01916                                    (CK_ATTRIBUTE *)a[2]->data,
01917                                    *(CK_ULONG *)a[3]->data,
01918                                    (CK_ATTRIBUTE *)a[4]->data,
01919                                    *(CK_ULONG *)a[5]->data,
01920                                    (CK_ULONG *)a[6]->data,
01921                                    (CK_ULONG *)a[7]->data);
01922     case F_C_WrapKey:
01923        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01924        return func->C_WrapKey(*(CK_ULONG *)a[0]->data,
01925                                    (CK_MECHANISM *)a[1]->data,
01926                                    *(CK_ULONG *)a[2]->data,
01927                                    *(CK_ULONG *)a[3]->data,
01928                                    (CK_CHAR *)a[5]->data,
01929                                    (CK_ULONG *)a[6]->data);
01930     case F_C_UnwrapKey:
01931        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01932        return func->C_UnwrapKey(*(CK_ULONG *)a[0]->data,
01933                                    (CK_MECHANISM *)a[1]->data,
01934                                    *(CK_ULONG *)a[2]->data,
01935                                    (CK_CHAR *)a[3]->data,
01936                                    *(CK_ULONG *)a[4]->data,
01937                                    (CK_ATTRIBUTE *)a[5]->data,
01938                                    *(CK_ULONG *)a[6]->data,
01939                                    (CK_ULONG *)a[7]->data);
01940     case F_C_DeriveKey:
01941        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01942        return func->C_DeriveKey (*(CK_ULONG *)a[0]->data,
01943                                    (CK_MECHANISM *)a[1]->data,
01944                                    *(CK_ULONG *)a[2]->data,
01945                                    (CK_ATTRIBUTE *)a[3]->data,
01946                                    *(CK_ULONG *)a[4]->data,
01947                                    (CK_ULONG *)a[5]->data);
01948     case F_C_SeedRandom:
01949        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01950        return func->C_SeedRandom(*(CK_ULONG *)a[0]->data,
01951                                    (CK_CHAR *)a[1]->data,
01952                                    *(CK_ULONG *)a[2]->data);
01953     case F_C_GenerateRandom:
01954        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01955        return func->C_GenerateRandom(*(CK_ULONG *)a[0]->data,
01956                                    (CK_CHAR *)a[1]->data,
01957                                    *(CK_ULONG *)a[2]->data);
01958     case F_C_GetFunctionStatus:
01959        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01960        return func->C_GetFunctionStatus(*(CK_ULONG *)a[0]->data);
01961     case F_C_CancelFunction:
01962        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01963        return func->C_CancelFunction(*(CK_ULONG *)a[0]->data);
01964     case F_C_WaitForSlotEvent:
01965        if (!func) return CKR_CRYPTOKI_NOT_INITIALIZED;
01966        return func->C_WaitForSlotEvent(*(CK_ULONG *)a[0]->data,
01967                                    (CK_ULONG *)a[1]->data,
01968                                    (void *)a[2]->data);
01969     /* set a variable */
01970     case F_SetVar:   
01971     case F_SetStringVar:    
01972        (void) DeleteVariable(a[0]->data);
01973        (void) AddVariable(a[0]->data,&a[1]);
01974        return CKR_OK;
01975     /* print a value */
01976     case F_Print:
01977        return printArg(a[0],0);
01978     case F_SaveVar:
01979        return save(a[0]->data,a[1]);
01980     case F_RestoreVar:
01981        return restore(a[0]->data,a[1]);
01982     case F_Delete:
01983        return DeleteVariable(a[0]->data);
01984     case F_Increment:
01985        return increment(a[0], *(CK_ULONG *)a[1]->data);
01986     case F_Decrement:
01987        return decrement(a[0], *(CK_ULONG *)a[1]->data);
01988     case F_List:
01989        return list();
01990     case F_Run:
01991        return run(a[0]->data);
01992     case F_Time:
01993        return timeCommand(a[0]->data);
01994     case F_Load:
01995        return loadModule(&module,a[0]->data);
01996     case F_Unload:
01997        return unloadModule(&module);
01998     case F_NewArray:
01999        (void) DeleteVariable(a[0]->data);
02000        return ArrayVariable(a[0]->data,a[1]->data,*(CK_ULONG *)a[2]->data);
02001     case F_NewTemplate:
02002        (void) DeleteVariable(a[0]->data);
02003        return ArrayTemplate(a[0]->data,a[1]->data);
02004     case F_BuildTemplate:
02005        return BuildTemplate(a[0]);
02006     case F_SetTemplate:
02007        return SetTemplate(a[0],
02008               *(CK_ULONG *)a[1]->data,
02009               *(CK_ULONG *)a[2]->data);
02010     case F_NewMechanism:
02011        (void) DeleteVariable(a[0]->data);
02012        return NewMechanism(a[0]->data,*(CK_ULONG *)a[1]->data);
02013     case F_NewInitializeArgs:
02014        (void) DeleteVariable(a[0]->data);
02015        return NewInitializeArgs(a[0]->data,*(CK_ULONG *)a[1]->data,a[2]->data);
02016     case F_System:
02017         value = *(int *)a[0]->data;
02018        if (value & 0x80000000) {
02019            systemFlags &= ~value;
02020        } else {
02021            systemFlags |= value;
02022        }
02023        return CKR_OK;
02024     case F_Loop:
02025        return loop(a[0]->data,a[1]->data,*(CK_ULONG *)a[2]->data,
02026               *(CK_ULONG *)a[3]->data,*(CK_ULONG *)a[4]->data);
02027     case F_Help:
02028        if (a[0]) {
02029            helpIndex = lookup(a[0]->data);
02030            if (helpIndex < 0) {
02031               return printTopicHelp(a[0]->data);
02032            }
02033            printHelp(helpIndex, 1);
02034            return CKR_OK;
02035        }
02036        return printGeneralHelp();
02037     case F_QuitIfString:
02038        return quitIfString(a[0]->data,a[1]->data,a[2]->data);
02039     case F_QuitIf:
02040        return quitIf(*(CK_ULONG *)a[0]->data,a[1]->data,*(CK_ULONG *)a[2]->data);
02041     case F_Quit:
02042        return CKR_QUIT;
02043     default:
02044        fprintf(stderr,
02045               "Function %s not yet supported\n",commands[index].fname );
02046        return CKR_OK;
02047     }
02048     /* Not Reached */
02049     return CKR_OK;
02050 }
02051 
02052 CK_RV
02053 processCommand(const char * buf)
02054 {
02055     CK_RV error = CKR_OK;
02056     int index;
02057     const char *bp;
02058     Value **arglist;
02059 
02060     bp = strip(buf);
02061     /* allow comments and blank lines in scripts */
02062     if ((*bp == '#') || (*bp == 0) || (*bp == '\n')){
02063        return CKR_OK;
02064     }
02065 
02066     index = lookup(bp);
02067 
02068     if (index < 0) {
02069        return CKR_OK;
02070     }
02071 
02072     arglist = parseArgs(index,bp);
02073     if (arglist == NULL) {
02074        return CKR_OK;
02075     }
02076 
02077     error = do_func(index,arglist);
02078     if (error == CKR_OK) {
02079        putOutput(arglist);
02080     } else if (error != CKR_QUIT) {
02081        printf(">> Error : ");
02082        printConst(error, ConstResult, 1);
02083     }
02084 
02085     parseFree(arglist);
02086     return error;
02087 }
02088 
02089 CK_RV
02090 timeCommand(const char *command) 
02091 {
02092     CK_RV ckrv;
02093     PRIntervalTime startTime = PR_IntervalNow();
02094     PRIntervalTime endTime;
02095     PRIntervalTime elapsedTime;
02096 
02097     ckrv = processCommand(command);
02098 
02099     endTime = PR_IntervalNow();
02100     elapsedTime = endTime - startTime;
02101     printf("Time -- %d msec \n", 
02102        PR_IntervalToMilliseconds(elapsedTime));
02103     
02104     return ckrv;
02105 }
02106 
02107 
02108 
02109 CK_RV
02110 process(FILE *inFile,int user)
02111 {
02112     char buf[2048];
02113     CK_RV error;
02114     CK_RV ckrv = CKR_OK;
02115 
02116     if (user) { printf("pkcs11> "); fflush(stdout); }
02117 
02118     while (fgets(buf,2048,inFile) != NULL) {
02119 
02120        if (!user) printf("* %s",buf);
02121        error = processCommand(buf);
02122        if (error == CKR_QUIT) {
02123            break;
02124        } else if (error != CKR_OK) {
02125            ckrv = error;
02126        }
02127        if (user) { 
02128            printf("pkcs11> "); fflush(stdout); 
02129        }
02130     }
02131     return ckrv;
02132 }
02133 
02134 CK_RV
02135 run(const char *filename) 
02136 {
02137     FILE *infile;
02138     CK_RV ckrv;
02139 
02140     infile = fopen(filename,"r");
02141 
02142     if (infile == NULL) {
02143        perror(filename);
02144        return CKR_FUNCTION_FAILED;
02145     }
02146 
02147     ckrv = process(infile, 0);
02148 
02149     fclose(infile);
02150     return ckrv;
02151 }
02152 
02153 CK_RV
02154 loop(const char *filename, const char *var, 
02155      CK_ULONG start, CK_ULONG end, CK_ULONG step) 
02156 {
02157     CK_ULONG i = 0;
02158     Value *value = 0;
02159     CK_RV ckrv;
02160 
02161     for (i=start; i < end; i += step)
02162     {
02163         value = NewValue(ArgULong, 1);
02164        *(CK_ULONG *)value->data = i;
02165        DeleteVariable(var);
02166        AddVariable(var, &value);
02167        ckrv = run(filename);
02168        argFree(value);
02169        if (ckrv == CKR_QUIT) {
02170            break;
02171        }
02172     }
02173     return ckrv;
02174 }
02175 
02176 int
02177 main(int argc, char **argv)
02178 {
02179     /* I suppose that some day we could parse some arguments */
02180     (void) process(stdin, 1);
02181     return 0;
02182 }