From d6f2ac21803616a6173e584b455aeb849faea594 Mon Sep 17 00:00:00 2001 From: Daniel Markstedt Date: Sat, 7 Oct 2023 09:14:38 +0900 Subject: [PATCH 1/5] Use glibtoolize on macOS --- autogen.sh | 8 +++++++- test/{postmark-1_5.c => postmark.c} | 0 2 files changed, 7 insertions(+), 1 deletion(-) rename test/{postmark-1_5.c => postmark.c} (100%) diff --git a/autogen.sh b/autogen.sh index 70900b1..a57827e 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,7 +1,13 @@ #!/bin/sh +LIBTOOLIZE=libtoolize +SYSNAME=`uname` +if [ "x$SYSNAME" = "xDarwin" ] ; then + LIBTOOLIZE=glibtoolize +fi + # build it all. -libtoolize --copy --force && \ +$LIBTOOLIZE --copy --force && \ aclocal -I macros $ACLOCAL_FLAGS && \ autoheader && \ automake --include-deps --add-missing --foreign && \ diff --git a/test/postmark-1_5.c b/test/postmark.c similarity index 100% rename from test/postmark-1_5.c rename to test/postmark.c From 2816983108077976c24d61c7415065776b84c01a Mon Sep 17 00:00:00 2001 From: Daniel Markstedt Date: Sat, 7 Oct 2023 09:15:57 +0900 Subject: [PATCH 2/5] Upgrade to postmark v1.53 and rename the source file to postmark.c Source: http://www.slac.stanford.edu/~alfw/postmark-1.53.c.gz --- test/Makefile.am | 2 +- test/postmark.c | 2104 ++++++++++++++++++++++------------------------ 2 files changed, 1007 insertions(+), 1099 deletions(-) diff --git a/test/Makefile.am b/test/Makefile.am index 627f0ae..d943f5c 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -11,7 +11,7 @@ libafptest_la_SOURCES = afpcli.c afpcmd.c afphelper.c adoublehelper.c extattr.c afparg_SOURCES = afparg.c afparg_FPfuncs.c afparg_LDADD = libafptest.la -postmark_SOURCES = postmark-1_5.c +postmark_SOURCES = postmark.c postmark_LDFLAGS = -export-dynamic postmark_LDADD = libafptest.la diff --git a/test/postmark.c b/test/postmark.c index f12b463..3fbbddc 100644 --- a/test/postmark.c +++ b/test/postmark.c @@ -1,62 +1,66 @@ /* - Written by Jeffrey Katcher under contract to Network Appliance. - Copyright (C) 1997-2001 - Network Appliance, Inc. - - This code has been successfully compiled and run by Network - Appliance on various platforms, including Solaris 2 on an Ultra-170, - and Windows NT on a Compaq ProLiant. However, this PostMark source - code is distributed under the Artistic License appended to the end - of this file. As such, no support is provided. However, please report - any errors to the author, Jeffrey Katcher , or to - Andy Watson . - - For AFP - need to: - set buffering false - - Versions: - 1.00 - Original release - 8/17/97 - - 1.01 - Fixed endless loop on EOF, - Divide by zero when file_size_high=file_size_low - 10/29/97 - (Thanks to Chuck Murnane) - - 1.1 - Added new commands to distribute work across multiple directories - and/or file systems and multiple work subdirectories. - - Changed set location command (+,-) to allow file systems & weights - Added set subdirectories command and code to distribute work across - multiple subdirectories - Added file redirect to show and run commands - Improved help system - 4/8/98 - - 1.11 - Fixed unfortunate problem where read_file opens in append mode thus - avoiding actual reads. (Thanks to Kent Peacock) - - 1.12 - Changed bytes read and written to float. Hopefully this will avoid - overflow when very large file sizes are used. - - 1.13 - Added terse report option allowing results to be easily included in - other things. (Thanks to Walter Wong) - Also tweaked help code to allow partial matches - - 1.14 - Automatically stop run if work files are depleted - - 1.5 - It was pointed out by many (most recently Michael Flaster) that the - pseudo-random number generator was more pseudo than random. After - a review of the literature and extensive benchmarking, I've replaced - the previous PRNG with the Mersenne Twister. While an excellent PRNG, - it retains much of the performance of the previous implementation. - URL: http://www.math.keio.ac.jp/~matumoto/emt.html - Also changed MB definition to 1024KB, tweaked show command +Written by Jeffrey Katcher under contract to Network Appliance. +Copyright (C) 1997-2001 +Network Appliance, Inc. + +This code has been successfully compiled and run by Network +Appliance on various platforms, including Solaris 2 on an Ultra-170, +and Windows NT on a Compaq ProLiant. However, this PostMark source +code is distributed under the Artistic License appended to the end +of this file. As such, no support is provided. However, please report +any errors to the author, Jeffrey Katcher , or to +Andy Watson . + +Versions: +1.00 - Original release - 8/17/97 + +1.01 - Fixed endless loop on EOF, + Divide by zero when file_size_high=file_size_low - 10/29/97 + (Thanks to Chuck Murnane) + +1.1 - Added new commands to distribute work across multiple directories + and/or file systems and multiple work subdirectories. + + Changed set location command (+,-) to allow file systems & weights + Added set subdirectories command and code to distribute work across + multiple subdirectories + Added file redirect to show and run commands + Improved help system - 4/8/98 + +1.11 - Fixed unfortunate problem where read_file opens in append mode thus + avoiding actual reads. (Thanks to Kent Peacock) + +1.12 - Changed bytes read and written to float. Hopefully this will avoid + overflow when very large file sizes are used. + +1.13 - Added terse report option allowing results to be easily included in + other things. (Thanks to Walter Wong) + Also tweaked help code to allow partial matches + +1.14 - Automatically stop run if work files are depleted + +1.5 - Many people (most recently Michael Flaster) have emphasized that the + pseudo-random number generator was more pseudo than random. After + a review of the literature and extensive benchmarking, I've replaced + the previous PRNG with the Mersenne Twister. While an excellent PRNG, + it retains much of the performance of the previous implementation. + URL: http://www.math.keio.ac.jp/~matumoto/emt.html + Also changed MB definition to 1024KB, tweaked show command + +1.51 - Added command to load config file from CLI + +1.52 - Fixed error in time base for terse report. (Thanks to Collin Park) + +1.53 - Fixed error in report of deleted files (Thanks to Alf Wachsmann) */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ +#include +#include +#include +#include +#include -#include "afpclient.h" +#define PM_VERSION "v1.51 : 8/14/01" #ifdef _WIN32 #include @@ -82,9 +86,9 @@ extern char *getwd(); #define PROMPT "pm>" typedef struct { /* ADT for table of CLI commands */ - char *name; /* name of command */ - int (*func)(); /* pointer to callback function */ - char *help; /* descriptive help string */ + char *name; /* name of command */ + int (*func)(); /* pointer to callback function */ + char *help; /* descriptive help string */ } cmd; extern int cli_set_size(); @@ -95,45 +99,44 @@ extern int cli_set_location(); extern int cli_set_subdirs(); extern int cli_set_read(); extern int cli_set_write(); +extern int cli_set_buffering(); extern int cli_set_bias_read(); extern int cli_set_bias_create(); extern int cli_set_report(); extern int cli_run(); +extern int cli_load(); extern int cli_show(); extern int cli_help(); extern int cli_quit(); cmd command_list[]={ /* table of CLI commands */ - {"set size",cli_set_size,"Sets low and high bounds of files"}, - {"set number",cli_set_number,"Sets number of simultaneous files"}, - {"set seed",cli_set_seed,"Sets seed for random number generator"}, - {"set transactions",cli_set_transactions,"Sets number of transactions"}, - {"set location",cli_set_location,"Sets location of working files"}, - {"set subdirectories",cli_set_subdirs,"Sets number of subdirectories"}, - {"set read",cli_set_read,"Sets read block size"}, - {"set write",cli_set_write,"Sets write block size"}, - {"set bias read",cli_set_bias_read, - "Sets the chance of choosing read over append"}, - {"set bias create",cli_set_bias_create, - "Sets the chance of choosing create over delete"}, - {"set report",cli_set_report,"Choose verbose or terse report format"}, - {"run",cli_run,"Runs one iteration of benchmark"}, - {"show",cli_show,"Displays current configuration"}, - {"help",cli_help,"Prints out available commands"}, - {"quit",cli_quit,"Exit program"}, - NULL + {"set size",cli_set_size,"Sets low and high bounds of files"}, + {"set number",cli_set_number,"Sets number of simultaneous files"}, + {"set seed",cli_set_seed,"Sets seed for random number generator"}, + {"set transactions",cli_set_transactions,"Sets number of transactions"}, + {"set location",cli_set_location,"Sets location of working files"}, + {"set subdirectories",cli_set_subdirs,"Sets number of subdirectories"}, + {"set read",cli_set_read,"Sets read block size"}, + {"set write",cli_set_write,"Sets write block size"}, + {"set buffering",cli_set_buffering,"Sets usage of buffered I/O"}, + {"set bias read",cli_set_bias_read, + "Sets the chance of choosing read over append"}, + {"set bias create",cli_set_bias_create, + "Sets the chance of choosing create over delete"}, + {"set report",cli_set_report,"Choose verbose or terse report format"}, + {"run",cli_run,"Runs one iteration of benchmark"}, + {"load",cli_load,"Read configuration file"}, + {"show",cli_show,"Displays current configuration"}, + {"help",cli_help,"Prints out available commands"}, + {"quit",cli_quit,"Exit program"}, + NULL }; extern void verbose_report(); extern void terse_report(); void (*reports[])()={verbose_report,terse_report}; -u_int16_t Vol; -DSI *Dsi; -CONN *Conn; -int Verbose; - /* Counters */ int files_created; /* number of files created */ int files_deleted; /* number of files deleted */ @@ -148,35 +151,29 @@ int file_size_high=10000; /* file size: fixed or random within range */ int simultaneous=500; /* simultaneous files */ int seed=42; /* random number generator seed */ int transactions=500; /* number of transactions */ -int subdirectories=0; /* Number of subdirectories */ +int subdirectories=0; /* Number of subdirectories */ int read_block_size=512; /* I/O block sizes */ int write_block_size=512; int bias_read=5; /* chance of picking read over append */ int bias_create=5; /* chance of picking create over delete */ +int buffered_io=1; /* use C library buffered I/O */ int report=0; /* 0=verbose, 1=terse report format */ -char *vers = "AFP3.2"; -char *uam = "Cleartxt Passwrd"; -char *usr; -char *pwd; -char *server; -char *Volume; - /* Working Storage */ char *file_source; /* pointer to buffer of random text */ typedef struct { - char name[MAX_FILENAME+1]; /* name of individual file */ - int size; /* current size of file, 0 = unused file slot */ + char name[MAX_FILENAME+1]; /* name of individual file */ + int size; /* current size of file, 0 = unused file slot */ } file_entry; file_entry *file_table; /* table of files in use */ int file_allocated; /* pointer to last allocated slot in file_table */ typedef struct file_system_struct { - file_entry system; - struct file_system_struct *next,*prev; -} file_system; + file_entry system; + struct file_system_struct *next,*prev; +} file_system; file_system *file_systems; /* table of file systems/directories to use */ int file_system_weight; /* sum of weights for all file systems */ @@ -191,419 +188,404 @@ extern void sgenrand(); /* converts integer values to byte/kilobyte/megabyte strings */ char *scale(i) - int i; +int i; { - static char buffer[MAX_LINE]; /* storage for current conversion */ + static char buffer[MAX_LINE]; /* storage for current conversion */ - if (i/MEGABYTE) - sprintf(buffer,"%.2f megabytes",(float)i/MEGABYTE); - else - if (i/KILOBYTE) - sprintf(buffer,"%.2f kilobytes",(float)i/KILOBYTE); - else - sprintf(buffer,"%d bytes",i); + if (i/MEGABYTE) + sprintf(buffer,"%.2f megabytes",(float)i/MEGABYTE); + else + if (i/KILOBYTE) + sprintf(buffer,"%.2f kilobytes",(float)i/KILOBYTE); + else + sprintf(buffer,"%d bytes",i); - return(buffer); + return(buffer); } /* converts float values to byte/kilobyte/megabyte strings */ char *scalef(i) - float i; +float i; { - static char buffer[MAX_LINE]; /* storage for current conversion */ + static char buffer[MAX_LINE]; /* storage for current conversion */ - if (i/(float)MEGABYTE>1) - sprintf(buffer,"%.2f megabytes",i/(float)MEGABYTE); - else - if (i/(float)KILOBYTE) - sprintf(buffer,"%.2f kilobytes",i/(float)KILOBYTE); - else - sprintf(buffer,"%f bytes",i); + if (i/(float)MEGABYTE>1) + sprintf(buffer,"%.2f megabytes",i/(float)MEGABYTE); + else + if (i/(float)KILOBYTE) + sprintf(buffer,"%.2f kilobytes",i/(float)KILOBYTE); + else + sprintf(buffer,"%f bytes",i); - return(buffer); + return(buffer); } /* UI callback for 'set size' command - sets range of file sizes */ int cli_set_size(param) - char *param; /* remainder of command line */ +char *param; /* remainder of command line */ { - char *token; - int size; - - if (param && (size=atoi(param))>0) - { - file_size_low=size; - if ((token=strchr(param,' ')) && (size=atoi(token))>0 && - size>=file_size_low) - file_size_high=size; - else - file_size_high=file_size_low; - } - else - fprintf(stdout,"Error: no file size low or high bounds specified\n"); + char *token; + int size; + + if (param && (size=atoi(param))>0) + { + file_size_low=size; + if ((token=strchr(param,' ')) && (size=atoi(token))>0 && + size>=file_size_low) + file_size_high=size; + else + file_size_high=file_size_low; + } + else + fprintf(stderr,"Error: no file size low or high bounds specified\n"); + + return(1); +} + +int cli_generic_int(var,param,error) +int *var; /* pointer to variable to set */ +char *param; /* remainder of command line */ +char *error; /* error message */ +{ + int value; + + if (param && (value=atoi(param))>0) + *var=value; + else + fprintf(stderr,"Error: %s\n",error); - return(1); + return(1); } /* UI callback for 'set number' command - sets number of files to create */ int cli_set_number(param) - char *param; /* remainder of command line */ +char *param; /* remainder of command line */ { - int size; - - if (param && (size=atoi(param))>0) - simultaneous=size; - else - fprintf(stdout,"Error: no file number specified\n"); - - return(1); + return(cli_generic_int(&simultaneous,param,"invalid number of files")); } /* UI callback for 'set seed' command - initial value for random number gen */ int cli_set_seed(param) - char *param; /* remainder of command line */ +char *param; /* remainder of command line */ { - int size; - - if (param && (size=atoi(param))>0) - seed=size; - else - fprintf(stdout,"Error: no random number seed specified\n"); - - return(1); + return(cli_generic_int(&seed,param,"invalid seed for random numbers")); } /* UI callback for 'set transactions' - configure number of transactions */ int cli_set_transactions(param) - char *param; /* remainder of command line */ +char *param; /* remainder of command line */ { - int size; - - if (param && (size=atoi(param))>0) - transactions=size; - else - fprintf(stdout,"Error: no transactions specified\n"); - - return(1); + return(cli_generic_int(&transactions,param,"no transactions specified")); } int parse_weight(params) - char *params; +char *params; { - int weight=1; - char *split; - - if (split=strrchr(params,' ')) - { - *split='\0'; - if ((weight=atoi(split+1))<=0) - { - fprintf(stdout,"Error: ignoring invalid weight '%s'\n",split+1); - weight=1; - } - } - - return(weight); + int weight=1; + char *split; + + if (split=strrchr(params,' ')) + { + *split='\0'; + if ((weight=atoi(split+1))<=0) + { + fprintf(stderr,"Error: ignoring invalid weight '%s'\n",split+1); + weight=1; + } + } + + return(weight); } void add_location(params,weight) - char *params; - int weight; +char *params; +int weight; { - file_system *new_file_system; - - if (new_file_system=(file_system *)calloc(1,sizeof(file_system))) - { - strcpy(new_file_system->system.name,params); - new_file_system->system.size=weight; - - if (file_systems) - { - new_file_system->prev=file_systems->prev; - file_systems->prev->next=new_file_system; - file_systems->prev=new_file_system; - } - else - { - new_file_system->prev=new_file_system; - file_systems=new_file_system; - } - - file_system_weight+=weight; - file_system_count++; - } + file_system *new_file_system; + + if (new_file_system=(file_system *)calloc(1,sizeof(file_system))) + { + strcpy(new_file_system->system.name,params); + new_file_system->system.size=weight; + + if (file_systems) + { + new_file_system->prev=file_systems->prev; + file_systems->prev->next=new_file_system; + file_systems->prev=new_file_system; + } + else + { + new_file_system->prev=new_file_system; + file_systems=new_file_system; + } + + file_system_weight+=weight; + file_system_count++; + } } void delete_location(loc_name) - char *loc_name; +char *loc_name; { - file_system *traverse; + file_system *traverse; - for (traverse=file_systems; traverse; traverse=traverse->next) - if (!strcmp(traverse->system.name,loc_name)) - { - file_system_weight-=traverse->system.size; - file_system_count--; + for (traverse=file_systems; traverse; traverse=traverse->next) + if (!strcmp(traverse->system.name,loc_name)) + { + file_system_weight-=traverse->system.size; + file_system_count--; - if (file_systems->prev==file_systems) + if (file_systems->prev==file_systems) { - free(file_systems); - file_systems=NULL; + free(file_systems); + file_systems=NULL; } - else + else { - if (file_systems->prev==traverse) - file_systems->prev=traverse->prev; + if (file_systems->prev==traverse) + file_systems->prev=traverse->prev; - if (traverse==file_systems) - file_systems=file_systems->next; - else - traverse->prev->next=traverse->next; + if (traverse==file_systems) + file_systems=file_systems->next; + else + traverse->prev->next=traverse->next; - if (traverse->next) - traverse->next->prev=traverse->prev; + if (traverse->next) + traverse->next->prev=traverse->prev; - free(traverse); + free(traverse); } - break; - } + break; + } - if (!traverse) - fprintf(stdout,"Error: cannot find location '%s'\n",loc_name); + if (!traverse) + fprintf(stderr,"Error: cannot find location '%s'\n",loc_name); } void delete_locations() { - file_system *next; + file_system *next; - while (file_systems) - { - next=file_systems->next; - free(file_systems); - file_systems=next; - } + while (file_systems) + { + next=file_systems->next; + free(file_systems); + file_systems=next; + } - file_system_weight=0; - file_system_count=0; + file_system_weight=0; + file_system_count=0; } /* UI callback for 'set location' - configure current working directory */ int cli_set_location(param) - char *param; /* remainder of command line */ +char *param; /* remainder of command line */ { - if (param) - { - switch (*param) - { - case '+': /* add location to list */ + if (param) + { + switch (*param) + { + case '+': /* add location to list */ add_location(param+1,parse_weight(param+1)); break; - case '-': /* remove location from list */ + case '-': /* remove location from list */ delete_location(param+1); break; - default: + default: delete_locations(); add_location(param,parse_weight(param)); - } - } - else - fprintf(stdout,"Error: no directory name specified\n"); + } + } + else + fprintf(stderr,"Error: no directory name specified\n"); - return(1); + return(1); } /* UI callback for 'set subdirectories' - configure number of subdirectories */ int cli_set_subdirs(param) - char *param; /* remainder of command line */ +char *param; /* remainder of command line */ { - int subdirs; - - if (param && (subdirs=atoi(param))>=0) - subdirectories=subdirs; - else - fprintf(stdout,"Error: invalid number of subdirectories specified\n"); - - return(1); + return(cli_generic_int(&subdirectories,param, + "invalid number of subdirectories")); } /* UI callback for 'set read' - configure read block size (integer) */ int cli_set_read(param) - char *param; /* remainder of command line */ +char *param; /* remainder of command line */ { - int size; - - if (param && (size=atoi(param))>0) - read_block_size=size; - else - fprintf(stdout,"Error: no block size specified\n"); - - return(1); + return(cli_generic_int(&read_block_size,param,"invalid read block size")); } /* UI callback for 'set write' - configure write block size (integer) */ int cli_set_write(param) - char *param; /* remainder of command line */ +char *param; /* remainder of command line */ { - int size; - - if (param && (size=atoi(param))>0) - write_block_size=size; - else - fprintf(stdout,"Error: no block size specified\n"); + return(cli_generic_int(&write_block_size,param,"invalid write block size")); +} - return(1); +/* UI callback for 'set buffering' - sets buffering mode on or off + - true = buffered I/O (default), false = raw I/O */ +int cli_set_buffering(param) +char *param; /* remainder of command line */ +{ + if (param && (!strcmp(param,"true") || !strcmp(param,"false"))) + buffered_io=(!strcmp(param,"true"))?1:0; + else + fprintf(stderr,"Error: no buffering mode (true/false) specified\n"); + + return(1); } /* UI callback for 'set bias read' - sets probability of read vs. append */ int cli_set_bias_read(param) - char *param; /* remainder of command line */ +char *param; /* remainder of command line */ { - int value; + int value; - if (param && (value=atoi(param))>=-1 && value<=10) - bias_read=value; - else - fprintf(stdout, - "Error: no bias specified (0-10 for greater chance,-1 to disable)\n"); + if (param && (value=atoi(param))>=-1 && value<=10) + bias_read=value; + else + fprintf(stderr, + "Error: no bias specified (0-10 for greater chance,-1 to disable)\n"); - return(1); + return(1); } /* UI callback for 'set bias create' - sets probability of create vs. delete */ int cli_set_bias_create(param) - char *param; /* remainder of command line */ +char *param; /* remainder of command line */ { - int value; + int value; - if (param && (value=atoi(param))>=-1 && value<=10) - bias_create=value; - else - fprintf(stdout, - "Error: no bias specified (0-10 for greater chance,-1 to disable)\n"); + if (param && (value=atoi(param))>=-1 && value<=10) + bias_create=value; + else + fprintf(stderr, + "Error: no bias specified (0-10 for greater chance,-1 to disable)\n"); - return(1); + return(1); } /* UI callback for 'set report' - chooses verbose or terse report formats */ int cli_set_report(param) - char *param; /* remainder of command line */ +char *param; /* remainder of command line */ { - int match=0; - - if (param) - { - if (!strcmp(param,"verbose")) - report=0; - else - if (!strcmp(param,"terse")) - report=1; - else - match=-1; - } - - if (!param || match==-1) - fprintf(stdout,"Error: either 'verbose' or 'terse' required\n"); - - return(1); + int match=0; + + if (param) + { + if (!strcmp(param,"verbose")) + report=0; + else + if (!strcmp(param,"terse")) + report=1; + else + match=-1; + } + + if (!param || match==-1) + fprintf(stderr,"Error: either 'verbose' or 'terse' required\n"); + + return(1); } /* populate file source buffer with 'size' bytes of readable randomness */ char *initialize_file_source(size) - int size; /* number of bytes of junk to create */ +int size; /* number of bytes of junk to create */ { - char *new_source; - int i; + char *new_source; + int i; - if ((new_source=(char *)malloc(size))==NULL) /* allocate buffer */ - fprintf(stdout,"Error: failed to allocate source file of size %d\n",size); - else - for (i=0; i=write_block_size; - i-=write_block_size,offset+=write_block_size) - { - AFPWrite(Conn, fd, 0, write_block_size , file_source+offset, 0x80 ); -// write(fd,file_source+offset,write_block_size); - } -// write(fd,file_source+offset,i); /* write remainder */ - AFPWrite(Conn, fd, 0, i , file_source+offset, 0x80 ); + /* write even blocks */ + for (i=size; i>=write_block_size; + i-=write_block_size,offset+=write_block_size) + write(fd,file_source+offset,write_block_size); + + write(fd,file_source+offset,i); /* write remainder */ - bytes_written+=size; /* update counter */ + bytes_written+=size; /* update counter */ + + close(fd); } -/* write 'size' bytes to file 'fp' using buffered I/O */ +/* write 'size' bytes to file 'fp' using buffered I/O and close file */ void fwrite_blocks(fp,size) - FILE *fp; - int size; /* bytes to write to file */ +FILE *fp; +int size; /* bytes to write to file */ { - int offset=0; /* offset into file */ - int i; + int offset=0; /* offset into file */ + int i; - /* write even blocks */ - for (i=size; i>=write_block_size; - i-=write_block_size,offset+=write_block_size) - fwrite(file_source+offset,write_block_size,1,fp); + /* write even blocks */ + for (i=size; i>=write_block_size; + i-=write_block_size,offset+=write_block_size) + fwrite(file_source+offset,write_block_size,1,fp); - fwrite(file_source+offset,i,1,fp); /* write remainder */ + fwrite(file_source+offset,i,1,fp); /* write remainder */ + + bytes_written+=size; /* update counter */ - bytes_written+=size; /* update counter */ + fclose(fp); } void create_file_name(dest) - char *dest; +char *dest; { - char conversion[MAX_LINE+1]; - - *dest='\0'; - if (file_system_count) - { - strcat(dest, - location_index[(file_system_count==1)?0:RND(file_system_weight)]); - strcat(dest,SEPARATOR); - } - - if (subdirectories>1) - { - sprintf(conversion,"s%d%s",RND(subdirectories),SEPARATOR); - strcat(dest,conversion); - } - - sprintf(conversion,"%d",++files_created); - strcat(dest,conversion); + char conversion[MAX_LINE+1]; + + *dest='\0'; + if (file_system_count) + { + strcat(dest, + location_index[(file_system_count==1)?0:RND(file_system_weight)]); + strcat(dest,SEPARATOR); + } + + if (subdirectories>1) + { + sprintf(conversion,"s%d%s",RND(subdirectories),SEPARATOR); + strcat(dest,conversion); + } + + sprintf(conversion,"%d",++files_created); + strcat(dest,conversion); } /* creates new file of specified length and fills it with data */ void create_file(buffered) - int buffered; /* 1=buffered I/O (default), 0=unbuffered I/O */ +int buffered; /* 1=buffered I/O (default), 0=unbuffered I/O */ { - FILE *fp=NULL; - int fd=-1; - int ac = OPENACC_WR | OPENACC_RD; - int free_file; /* file_table slot for new file */ - - if ((free_file=find_free_file())!=-1) /* if file space is available */ - { /* decide on name and initial length */ - create_file_name(file_table[free_file].name); - - file_table[free_file].size= - file_size_low+RND(file_size_high-file_size_low); - - if (buffered) - fp=fopen(file_table[free_file].name,"w"); - else { - u_int16_t bitmap = 0; - - AFPCreateFile(Conn, Vol, 0, DIRDID_ROOT , file_table[free_file].name); - fd = AFPOpenFork(Conn, Vol, OPENFORK_DATA , bitmap ,DIRDID_ROOT, file_table[free_file].name,ac); - if (!fd) fd = -1; - // fd=open(file_table[free_file].name,O_RDWR|O_CREAT,0644); - } - if (fp || fd!=-1) - { - if (buffered) - { - fwrite_blocks(fp,file_table[free_file].size); - fclose(fp); - } - else - { - write_blocks(fd,file_table[free_file].size); - // close(fd); - AFPFlushFork(Conn, fd); - AFPCloseFork(Conn, fd); - } - } - else - fprintf(stdout,"Error: cannot open '%s' for writing\n", - file_table[free_file].name); - } + FILE *fp=NULL; + int fd=-1; + int free_file; /* file_table slot for new file */ + + if ((free_file=find_free_file())!=-1) /* if file space is available */ + { /* decide on name and initial length */ + create_file_name(file_table[free_file].name); + + file_table[free_file].size= + file_size_low+RND(file_size_high-file_size_low); + + if (buffered) + fp=fopen(file_table[free_file].name,"w"); + else + fd=open(file_table[free_file].name,O_RDWR|O_CREAT,0644); + + if (fp || fd!=-1) + { + if (buffered) + fwrite_blocks(fp,file_table[free_file].size); + else + write_blocks(fd,file_table[free_file].size); + } + else + fprintf(stderr,"Error: cannot open '%s' for writing\n", + file_table[free_file].name); + } } /* deletes specified file from disk and file_table */ void delete_file(number) - int number; +int number; { - if (file_table[number].size) - { -// if (remove(file_table[number].name)) - if (AFPDelete(Conn, Vol, DIRDID_ROOT , file_table[number].name)) - fprintf(stdout,"Error: Cannot delete '%s'\n",file_table[number].name); - else - { /* reset entry in file_table and update counter */ - file_table[number].size=0; - files_deleted++; - } - } + if (file_table[number].size) + { + if (remove(file_table[number].name)) + fprintf(stderr,"Error: Cannot delete '%s'\n",file_table[number].name); + else + { /* reset entry in file_table and update counter */ + file_table[number].size=0; + files_deleted++; + } + } } /* reads entire specified file into temporary buffer */ void read_file(number,buffered) - int number; /* number of file to read (from file_table) */ - int buffered; /* 1=buffered I/O (default), 0=unbuffered I/O */ +int number; /* number of file to read (from file_table) */ +int buffered; /* 1=buffered I/O (default), 0=unbuffered I/O */ { - FILE *fp=NULL; - int fd=-1; - int i; - int ac = OPENACC_WR | OPENACC_RD; - - if (buffered) - fp=fopen(file_table[number].name,"r"); - else { - fd = AFPOpenFork(Conn, Vol, OPENFORK_DATA , 0 ,DIRDID_ROOT, file_table[number].name,ac); - if (!fd) fd = -1; - // fd =open(file_table[number].name,O_RDONLY,0644); - } - if (fp || fd!=-1) - { /* read as many blocks as possible then read the remainder */ - if (buffered) - { - for (i=file_table[number].size; i>=read_block_size; i-=read_block_size) - fread(read_buffer,read_block_size,1,fp); - - fread(read_buffer,i,1,fp); - - fclose(fp); - } - else - { - for (i=file_table[number].size; i>=read_block_size; i-=read_block_size) - { - AFPRead(Conn, fd, 0, read_block_size, read_buffer); - - //read(fd,read_buffer,read_block_size); - } - AFPRead(Conn, fd, 0, i, read_buffer); - AFPCloseFork(Conn, fd); - - // read(fd,read_buffer,i); - // close(fd); - - } - - /* increment counters to record transaction */ - bytes_read+=file_table[number].size; - files_read++; - } - else - fprintf(stdout,"Error: cannot open '%s' for reading\n", - file_table[number].name); + FILE *fp=NULL; + int fd=-1; + int i; + + if (buffered) + fp=fopen(file_table[number].name,"r"); + else + fd=open(file_table[number].name,O_RDONLY,0644); + + if (fp || fd!=-1) + { /* read as many blocks as possible then read the remainder */ + if (buffered) + { + for (i=file_table[number].size; i>=read_block_size; i-=read_block_size) + fread(read_buffer,read_block_size,1,fp); + + fread(read_buffer,i,1,fp); + + fclose(fp); + } + else + { + for (i=file_table[number].size; i>=read_block_size; i-=read_block_size) + read(fd,read_buffer,read_block_size); + + read(fd,read_buffer,i); + + close(fd); + } + + /* increment counters to record transaction */ + bytes_read+=file_table[number].size; + files_read++; + } + else + fprintf(stderr,"Error: cannot open '%s' for reading\n", + file_table[number].name); } /* appends random data to a chosen file up to the maximum configured length */ void append_file(number,buffered) - int number; /* number of file (from file_table) to append date to */ - int buffered; /* 1=buffered I/O (default), 0=unbuffered I/O */ +int number; /* number of file (from file_table) to append date to */ +int buffered; /* 1=buffered I/O (default), 0=unbuffered I/O */ { - FILE *fp=NULL; - int fd=-1; - int block; /* size of data to append */ - int ac = OPENACC_WR | OPENACC_RD; - - if (file_table[number].sizenext) - for (count=0; countsystem.size; count++) - index[i++]=list->system.name; - - return(index); + char **index; + int count; + int i=0; + + if ((index=(char **)calloc(1,weight*sizeof(char *)))==NULL) + fprintf(stderr,"Error: cannot build weighted index of locations\n"); + else + for (; list; list=list->next) + for (count=0; countsystem.size; count++) + index[i++]=list->system.name; + + return(index); } -/* --------------------------------- */ void create_subdirectories(dir_list,base_dir,subdirs) - file_system *dir_list; - char *base_dir; - int subdirs; +file_system *dir_list; +char *base_dir; +int subdirs; { - char dir_name[MAX_LINE+1]; /* buffer holding subdirectory names */ - char save_dir[MAX_LINE+1]; - int i; - - if (dir_list) - { - for (; dir_list; dir_list=dir_list->next) - create_subdirectories(NULL,dir_list->system.name,subdirs); - } - else - { - if (base_dir) - sprintf(save_dir,"%s%s",base_dir,SEPARATOR); - else - *save_dir='\0'; - - for (i=0; inext) + create_subdirectories(NULL,dir_list->system.name,subdirs); + } + else + { + if (base_dir) + sprintf(save_dir,"%s%s",base_dir,SEPARATOR); + else + *save_dir='\0'; + + for (i=0; inext) - delete_subdirectories(NULL,dir_list->system.name,subdirs); - } - else - { - if (base_dir) - sprintf(save_dir,"%s%s",base_dir,SEPARATOR); - else - *save_dir='\0'; - - for (i=0; inext) + delete_subdirectories(NULL,dir_list->system.name,subdirs); + } + else + { + if (base_dir) + sprintf(save_dir,"%s%s",base_dir,SEPARATOR); + else + *save_dir='\0'; + + for (i=0; i0) - location_index=build_location_index(file_systems,file_system_weight); - - /* create files in specified directory until simultaneous number */ - - if ((Conn = (CONN *)calloc(1, sizeof(CONN))) == NULL) { - return 0; - } - Dsi = &Conn->dsi; - Dsi->socket = OpenClientSocket(server, 548); /* FIXME */ - if ( Dsi->socket < 0) { - return 0; - } - Dsi->protocol = DSI_TCPIP; - - if (FPopenLoginExt(Conn, vers, uam, usr, pwd) != AFP_OK) { - return 0; - } - Conn->afp_version = 33; - - Vol = FPOpenVol(Conn, Volume); - if (Vol == 0xffff) { - return 0; - } - - /* create subdirectories if necessary */ - if (subdirectories>1) - { - printf("Creating subdirectories..."); - fflush(stdout); - create_subdirectories(file_systems,NULL,subdirectories); - printf("Done\n"); - } + time_t start_time,t_start_time,t_end_time,end_time; /* elapsed timers */ + int delete_base; /* snapshot of deleted files counter */ + FILE *fp=NULL; /* file descriptor for directing output */ + int incomplete; + int i; /* generic iterator */ + + reset_counters(); /* reset counters before each run */ + + sgenrand(seed); /* initialize random number generator */ + + /* allocate file space and fill with junk */ + file_source=initialize_file_source(file_size_high<<1); + + /* allocate read buffer */ + read_buffer=(char *)malloc(read_block_size); + + /* allocate table of files at 2 x simultaneous files */ + file_allocated=0; + if ((file_table=(file_entry *)calloc(simultaneous<<1,sizeof(file_entry)))== + NULL) + fprintf(stderr,"Error: Failed to allocate table for %d files\n", + simultaneous<<1); + + if (file_system_count>0) + location_index=build_location_index(file_systems,file_system_weight); + + /* create subdirectories if necessary */ + if (subdirectories>1) + { + printf("Creating subdirectories..."); + fflush(stdout); + create_subdirectories(file_systems,NULL,subdirectories); + printf("Done\n"); + } + + time(&start_time); /* store start time */ + + /* create files in specified directory until simultaneous number */ + printf("Creating files..."); + fflush(stdout); + for (i=0; i1) + { + printf("Deleting subdirectories..."); + fflush(stdout); + delete_subdirectories(file_systems,NULL,subdirectories); + printf("Done\n"); + } + + if (location_index) + { + free(location_index); + location_index=NULL; + } + + if (param) + if ((fp=fopen(param,"a"))==NULL) + fprintf(stderr,"Error: Cannot direct output to file '%s'\n",param); + + if (!fp) + fp=stdout; + + if (!incomplete) + reports[report](fp,end_time,start_time,t_end_time,t_start_time, + files_deleted-delete_base); + + if (param && fp!=stdout) + fclose(fp); + + /* free resources allocated for this run */ + free(file_table); + free(read_buffer); + free(file_source); + + return(1); /* return 1 unless exit requested, then return 0 */ +} - time(&start_time); /* store start time */ - - - printf("Creating files..."); - fflush(stdout); - for (i=0; i1) - { - printf("Deleting subdirectories..."); - fflush(stdout); - delete_subdirectories(file_systems,NULL,subdirectories); - printf("Done\n"); - } +/* CLI callback for 'load' - read configuration file */ +int cli_load(param) +char *param; +{ + char buffer[MAX_LINE+1]; /* storage for input command line */ - if (location_index) - { - free(location_index); - location_index=NULL; - } + if (param) + read_config_file(param,buffer,0); + else + fprintf(stderr,"Error: no configuration file specified\n"); - if (param) - if ((fp=fopen(param,"a"))==NULL) - fprintf(stdout,"Error: Cannot direct output to file '%s'\n",param); - - if (!fp) - fp=stdout; - - if (!incomplete) - reports[report](fp,end_time,start_time,t_end_time,t_start_time, - files_deleted-delete_base); - - if (param && fp!=stdout) - fclose(fp); - - /* free resources allocated for this run */ - free(file_table); - free(read_buffer); - free(file_source); -fin: - AFPFlush(Conn, Vol); - AFPCloseVol(Conn,Vol); - AFPLogOut(Conn); - free(Dsi); - return(1); /* return 1 unless exit requested, then return 0 */ + return(1); /* return 1 unless exit requested, then return 0 */ } /* CLI callback for 'show' - print values of configuration variables */ -int cli_show(param) - char *param; /* optional: name of output file */ +int cli_show(param) +char *param; /* optional: name of output file */ { - char current_dir[MAX_LINE+1]; /* buffer containing working directory */ - file_system *traverse; - FILE *fp=NULL; /* file descriptor for directing output */ + char current_dir[MAX_LINE+1]; /* buffer containing working directory */ + file_system *traverse; + FILE *fp=NULL; /* file descriptor for directing output */ - if (param) - if ((fp=fopen(param,"a"))==NULL) - fprintf(stdout,"Error: Cannot direct output to file '%s'\n",param); + if (param) + if ((fp=fopen(param,"a"))==NULL) + fprintf(stderr,"Error: Cannot direct output to file '%s'\n",param); - if (!fp) - fp=stdout; + if (!fp) + fp=stdout; - fprintf(fp,"Current configuration is:\n"); - fprintf(fp,"The base number of files is %d\n",simultaneous); - fprintf(fp,"Transactions: %d\n",transactions); + fprintf(fp,"Current configuration is:\n"); + fprintf(fp,"The base number of files is %d\n",simultaneous); + fprintf(fp,"Transactions: %d\n",transactions); - if (file_size_low!=file_size_high) - { - fprintf(fp,"Files range between %s ",scale(file_size_low)); - fprintf(fp,"and %s in size\n",scale(file_size_high)); - } - else - fprintf(fp,"Files are %s in size\n",scale(file_size_low)); + if (file_size_low!=file_size_high) + { + fprintf(fp,"Files range between %s ",scale(file_size_low)); + fprintf(fp,"and %s in size\n",scale(file_size_high)); + } + else + fprintf(fp,"Files are %s in size\n",scale(file_size_low)); - fprintf(fp,"Working director%s: %s\n",(file_system_count>1)?"ies":"y", - (file_system_count==0)?GETWD(current_dir):""); + fprintf(fp,"Working director%s: %s\n",(file_system_count>1)?"ies":"y", + (file_system_count==0)?GETWD(current_dir):""); - for (traverse=file_systems; traverse; traverse=traverse->next) - printf("\t%s (weight=%d)\n",traverse->system.name,traverse->system.size); + for (traverse=file_systems; traverse; traverse=traverse->next) + printf("\t%s (weight=%d)\n",traverse->system.name,traverse->system.size); - if (subdirectories>0) - fprintf(fp,"%d subdirector%s will be used\n",subdirectories, - (subdirectories==1)?"y":"ies"); + if (subdirectories>0) + fprintf(fp,"%d subdirector%s will be used\n",subdirectories, + (subdirectories==1)?"y":"ies"); - fprintf(fp,"Block sizes are: read=%s, ",scale(read_block_size)); - fprintf(fp,"write=%s\n",scale(write_block_size)); - fprintf(fp,"Biases are: read/append=%d, create/delete=%d\n",bias_read, - bias_create); - fprintf(fp,"Random number generator seed is %d\n",seed); + fprintf(fp,"Block sizes are: read=%s, ",scale(read_block_size)); + fprintf(fp,"write=%s\n",scale(write_block_size)); + fprintf(fp,"Biases are: read/append=%d, create/delete=%d\n",bias_read, + bias_create); + fprintf(fp,"%ssing Unix buffered file I/O\n",buffered_io?"U":"Not u"); + fprintf(fp,"Random number generator seed is %d\n",seed); - fprintf(fp,"Report format is %s.\n",report?"terse":"verbose"); + fprintf(fp,"Report format is %s.\n",report?"terse":"verbose"); - if (param && fp!=stdout) - fclose(fp); + if (param && fp!=stdout) + fclose(fp); - return(1); /* return 1 unless exit requested, then return 0 */ + return(1); /* return 1 unless exit requested, then return 0 */ } /* CLI callback for 'quit' - returns 0 causing UI to exit */ int cli_quit(param) /* none */ - char *param; /* unused */ +char *param; /* unused */ { - return(0); /* return 1 unless exit requested, then return 0 */ + return(0); /* return 1 unless exit requested, then return 0 */ } /* CLI callback for 'help' - prints help strings from command_list */ -int cli_help(param) - char *param; /* optional: specific command to get help for */ +int cli_help(param) +char *param; /* optional: specific command to get help for */ { - int n=0; /* number of matching items */ - int i; /* traversal variable for command table */ - int len; + int n=0; /* number of matching items */ + int i; /* traversal variable for command table */ + int len; - if (param && (len=strlen(param))>0) /* if a command is specified... */ - for (i=0; command_list[i].name; i++) /* walk command table */ - if (!strncmp(command_list[i].name,param,len)) + if (param && (len=strlen(param))>0) /* if a command is specified... */ + for (i=0; command_list[i].name; i++) /* walk command table */ + if (!strncmp(command_list[i].name,param,len)) { - printf("%s - %s\n",command_list[i].name,command_list[i].help); - n++; + printf("%s - %s\n",command_list[i].name,command_list[i].help); + n++; } - if (!param || !n) - for (i=0; command_list[i].name; i++) /* traverse command table */ - printf("%s - %s\n",command_list[i].name,command_list[i].help); + if (!param || !n) + for (i=0; command_list[i].name; i++) /* traverse command table */ + printf("%s - %s\n",command_list[i].name,command_list[i].help); - return(1); /* return 1 unless exit requested, then return 0 */ + return(1); /* return 1 unless exit requested, then return 0 */ } /* read CLI line from user, translate aliases if any, return fgets status */ char *cli_read_line(buffer,size) - char *buffer; /* empty input line */ - int size; +char *buffer; /* empty input line */ +int size; { - char *result; - - printf("%s",PROMPT); /* print prompt */ - fflush(stdout); /* force prompt to print */ - if (result=fgets(buffer,size,stdin)) /* read line safely */ - { - buffer[strlen(buffer)-1]='\0'; /* delete final CR */ - if (!strcmp(buffer,"?")) /* translate aliases */ - strcpy(buffer,"help"); - if (!strcmp(buffer,"exit")) - strcpy(buffer,"quit"); - } - - return(result); /* return success of fgets */ + char *result; + + printf("%s",PROMPT); /* print prompt */ + fflush(stdout); /* force prompt to print */ + if (result=fgets(buffer,size,stdin)) /* read line safely */ + { + buffer[strlen(buffer)-1]='\0'; /* delete final CR */ + if (!strcmp(buffer,"?")) /* translate aliases */ + strcpy(buffer,"help"); + if (!strcmp(buffer,"exit")) + strcpy(buffer,"quit"); + } + + return(result); /* return success of fgets */ } /* parse CLI input line */ int cli_parse_line(buffer) - char *buffer; /* line of user input */ +char *buffer; /* line of user input */ { - int result=1; /* default return status */ - int len; /* length of parsed command */ - int i; /* traversal variable for command table */ - - if (*buffer=='!') /* check for shell escape */ - system((strlen(buffer)>1)?buffer+1:getenv("SHELL")); - else - { - for (i=0; command_list[i].name; i++) /* walk command table */ - if (!strncmp(command_list[i].name,buffer, - len=strlen(command_list[i].name))) + int result=1; /* default return status */ + int len; /* length of parsed command */ + int i; /* traversal variable for command table */ + + if (*buffer=='!') /* check for shell escape */ + system((strlen(buffer)>1)?buffer+1:getenv("SHELL")); + else + { + for (i=0; command_list[i].name; i++) /* walk command table */ + if (!strncmp(command_list[i].name,buffer, + len=strlen(command_list[i].name))) { /* if command matches... */ - result=(command_list[i].func) - (((int)strlen(buffer)>len)?buffer+len+1:NULL); - break; /* call function and pass remainder of line as parameter */ + result=(command_list[i].func) + (((int)strlen(buffer)>len)?buffer+len+1:NULL); + break; /* call function and pass remainder of line as parameter */ } - if (!command_list[i].name) /* if no commands were called... */ - printf("Eh?\n"); /* tribute to Canadian diction */ - } + if (!command_list[i].name) /* if no commands were called... */ + printf("Eh?\n"); /* tribute to Canadian diction */ + } - return(result); /* return 1 unless exit requested, then return 0 */ + return(result); /* return 1 unless exit requested, then return 0 */ } /* read config file if present and process it line by line - if 'quit' is in file then function returns 0 */ -int read_config_file(filename,buffer) - char *filename; /* file name of config file */ - char *buffer; /* temp storage for each line read from file */ -{ - int result=1; /* default exit value - proceed with UI */ - FILE *fp; - - if (fp=fopen(filename,"r")) /* open config file */ - { - printf("Reading configuration from file '%s'\n",filename); - while (fgets(buffer,MAX_LINE,fp) && result) /* read lines until 'quit' */ - { - buffer[strlen(buffer)-1]='\0'; /* delete final CR */ - result=cli_parse_line(buffer); /* process line as typed in */ - } - - fclose(fp); - } - - return(result); -} - -static void usage(char *n) +int read_config_file(filename,buffer,ignore) +char *filename; /* file name of config file */ +char *buffer; /* temp storage for each line read from file */ +int ignore; /* ignore file not found */ { - printf("usage: %s -s SERVERADDRESS -v VOLUME -u USER -p PASSWORD\n", n); - - exit(1); + int result=1; /* default exit value - proceed with UI */ + FILE *fp; + + if (fp=fopen(filename,"r")) /* open config file */ + { + printf("Reading configuration from file '%s'\n",filename); + while (fgets(buffer,MAX_LINE,fp) && result) /* read lines until 'quit' */ + { + buffer[strlen(buffer)-1]='\0'; /* delete final CR */ + result=cli_parse_line(buffer); /* process line as typed in */ + } + + fclose(fp); + } + else + if (!ignore) + fprintf(stderr,"Error: cannot read configuration file '%s'\n", + filename); + + return(result); } /* main function - reads config files then enters get line/parse line loop */ -int main(int argc, char **argv) +main(argc,argv) +int argc; +char *argv[]; { - char buffer[MAX_LINE+1]; /* storage for input command line */ - int c; - - while ((c = getopt(argc, argv, ":u:p:s:v:" )) != EOF) { - switch (c) { - case 's': - server = strdup(optarg); - break; - case 'u': - usr = strdup(optarg); - break; - case 'p': - pwd = strdup(optarg); - break; - case 'v': - Volume = strdup(optarg); - break; - default: - usage(argv[0]); - } - } + char buffer[MAX_LINE+1]; /* storage for input command line */ - if (!server || !usr || !pwd || !Volume) - usage(argv[0]); - - if (read_config_file((argc==2)?argv[1]:".pmrc",buffer)) - while (cli_read_line(buffer,MAX_LINE) && cli_parse_line(buffer)) - ; + printf("PostMark %s\n",PM_VERSION); + if (read_config_file((argc==2)?argv[1]:".pmrc",buffer,1)) + while (cli_read_line(buffer,MAX_LINE) && cli_parse_line(buffer)) + ; } /* - The "Artistic License" - - Preamble - - The intent of this document is to state the conditions under which a - Package may be copied, such that the Copyright Holder maintains some - semblance of artistic control over the development of the package, - while giving the users of the package the right to use and distribute - the Package in a more-or-less customary fashion, plus the right to make - reasonable modifications. - - Definitions: - - "Package" refers to the collection of files distributed by the - Copyright Holder, and derivatives of that collection of files - created through textual modification. - - "Standard Version" refers to such a Package if it has not been - modified, or has been modified in accordance with the wishes - of the Copyright Holder as specified below. - - "Copyright Holder" is whoever is named in the copyright or - copyrights for the package. - - "You" is you, if you're thinking about copying or distributing - this Package. - - "Reasonable copying fee" is whatever you can justify on the - basis of media cost, duplication charges, time of people involved, - and so on. (You will not be required to justify it to the - Copyright Holder, but only to the computing community at large - as a market that must bear the fee.) - - "Freely Available" means that no fee is charged for the item - itself, though there may be fees involved in handling the item. - It also means that recipients of the item may redistribute it - under the same conditions they received it. - - 1. You may make and give away verbatim copies of the source form of the - Standard Version of this Package without restriction, provided that you - duplicate all of the original copyright notices and associated disclaimers. - - 2. You may apply bug fixes, portability fixes and other modifications - derived from the Public Domain or from the Copyright Holder. A Package - modified in such a way shall still be considered the Standard Version. - - 3. You may otherwise modify your copy of this Package in any way, provided - that you insert a prominent notice in each changed file stating how and - when you changed that file, and provided that you do at least ONE of the - following: - - a) place your modifications in the Public Domain or otherwise make them - Freely Available, such as by posting said modifications to Usenet or - an equivalent medium, or placing the modifications on a major archive - site such as uunet.uu.net, or by allowing the Copyright Holder to include - your modifications in the Standard Version of the Package. - - b) use the modified Package only within your corporation or organization. - - c) rename any non-standard executables so the names do not conflict - with standard executables, which must also be provided, and provide - a separate manual page for each non-standard executable that clearly - documents how it differs from the Standard Version. - - d) make other distribution arrangements with the Copyright Holder. - - 4. You may distribute the programs of this Package in object code or - executable form, provided that you do at least ONE of the following: - - a) distribute a Standard Version of the executables and library files, - together with instructions (in the manual page or equivalent) on where - to get the Standard Version. - - b) accompany the distribution with the machine-readable source of - the Package with your modifications. - - c) give non-standard executables non-standard names, and clearly - document the differences in manual pages (or equivalent), together - with instructions on where to get the Standard Version. - - d) make other distribution arrangements with the Copyright Holder. - - 5. You may charge a reasonable copying fee for any distribution of this - Package. You may charge any fee you choose for support of this - Package. You may not charge a fee for this Package itself. However, - you may distribute this Package in aggregate with other (possibly - commercial) programs as part of a larger (possibly commercial) software - distribution provided that you do not advertise this Package as a - product of your own. You may embed this Package's interpreter within - an executable of yours (by linking); this shall be construed as a mere - form of aggregation, provided that the complete Standard Version of the - interpreter is so embedded. - - 6. The scripts and library files supplied as input to or produced as - output from the programs of this Package do not automatically fall - under the copyright of this Package, but belong to whomever generated - them, and may be sold commercially, and may be aggregated with this - Package. If such scripts or library files are aggregated with this - Package via the so-called "undump" or "unexec" methods of producing a - binary executable image, then distribution of such an image shall - neither be construed as a distribution of this Package nor shall it - fall under the restrictions of Paragraphs 3 and 4, provided that you do - not represent such an executable image as a Standard Version of this - Package. - - 7. C subroutines (or comparably compiled subroutines in other - languages) supplied by you and linked into this Package in order to - emulate subroutines and variables of the language defined by this - Package shall not be considered part of this Package, but are the - equivalent of input as in Paragraph 6, provided these subroutines do - not change the language in any way that would cause it to fail the - regression tests for the language. - - 8. Aggregation of this Package with a commercial distribution is always - permitted provided that the use of this Package is embedded; that is, - when no overt attempt is made to make this Package's interfaces visible - to the end user of the commercial distribution. Such use shall not be - construed as a distribution of this Package. - - 9. The name of the Copyright Holder may not be used to endorse or promote - products derived from this software without specific prior written permission. - - 10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - - The End + The "Artistic License" + + Preamble + +The intent of this document is to state the conditions under which a +Package may be copied, such that the Copyright Holder maintains some +semblance of artistic control over the development of the package, +while giving the users of the package the right to use and distribute +the Package in a more-or-less customary fashion, plus the right to make +reasonable modifications. + +Definitions: + + "Package" refers to the collection of files distributed by the + Copyright Holder, and derivatives of that collection of files + created through textual modification. + + "Standard Version" refers to such a Package if it has not been + modified, or has been modified in accordance with the wishes + of the Copyright Holder as specified below. + + "Copyright Holder" is whoever is named in the copyright or + copyrights for the package. + + "You" is you, if you're thinking about copying or distributing + this Package. + + "Reasonable copying fee" is whatever you can justify on the + basis of media cost, duplication charges, time of people involved, + and so on. (You will not be required to justify it to the + Copyright Holder, but only to the computing community at large + as a market that must bear the fee.) + + "Freely Available" means that no fee is charged for the item + itself, though there may be fees involved in handling the item. + It also means that recipients of the item may redistribute it + under the same conditions they received it. + +1. You may make and give away verbatim copies of the source form of the +Standard Version of this Package without restriction, provided that you +duplicate all of the original copyright notices and associated disclaimers. + +2. You may apply bug fixes, portability fixes and other modifications +derived from the Public Domain or from the Copyright Holder. A Package +modified in such a way shall still be considered the Standard Version. + +3. You may otherwise modify your copy of this Package in any way, provided +that you insert a prominent notice in each changed file stating how and +when you changed that file, and provided that you do at least ONE of the +following: + + a) place your modifications in the Public Domain or otherwise make them + Freely Available, such as by posting said modifications to Usenet or + an equivalent medium, or placing the modifications on a major archive + site such as uunet.uu.net, or by allowing the Copyright Holder to include + your modifications in the Standard Version of the Package. + + b) use the modified Package only within your corporation or organization. + + c) rename any non-standard executables so the names do not conflict + with standard executables, which must also be provided, and provide + a separate manual page for each non-standard executable that clearly + documents how it differs from the Standard Version. + + d) make other distribution arrangements with the Copyright Holder. + +4. You may distribute the programs of this Package in object code or +executable form, provided that you do at least ONE of the following: + + a) distribute a Standard Version of the executables and library files, + together with instructions (in the manual page or equivalent) on where + to get the Standard Version. + + b) accompany the distribution with the machine-readable source of + the Package with your modifications. + + c) give non-standard executables non-standard names, and clearly + document the differences in manual pages (or equivalent), together + with instructions on where to get the Standard Version. + + d) make other distribution arrangements with the Copyright Holder. + +5. You may charge a reasonable copying fee for any distribution of this +Package. You may charge any fee you choose for support of this +Package. You may not charge a fee for this Package itself. However, +you may distribute this Package in aggregate with other (possibly +commercial) programs as part of a larger (possibly commercial) software +distribution provided that you do not advertise this Package as a +product of your own. You may embed this Package's interpreter within +an executable of yours (by linking); this shall be construed as a mere +form of aggregation, provided that the complete Standard Version of the +interpreter is so embedded. + +6. The scripts and library files supplied as input to or produced as +output from the programs of this Package do not automatically fall +under the copyright of this Package, but belong to whomever generated +them, and may be sold commercially, and may be aggregated with this +Package. If such scripts or library files are aggregated with this +Package via the so-called "undump" or "unexec" methods of producing a +binary executable image, then distribution of such an image shall +neither be construed as a distribution of this Package nor shall it +fall under the restrictions of Paragraphs 3 and 4, provided that you do +not represent such an executable image as a Standard Version of this +Package. + +7. C subroutines (or comparably compiled subroutines in other +languages) supplied by you and linked into this Package in order to +emulate subroutines and variables of the language defined by this +Package shall not be considered part of this Package, but are the +equivalent of input as in Paragraph 6, provided these subroutines do +not change the language in any way that would cause it to fail the +regression tests for the language. + +8. Aggregation of this Package with a commercial distribution is always +permitted provided that the use of this Package is embedded; that is, +when no overt attempt is made to make this Package's interfaces visible +to the end user of the commercial distribution. Such use shall not be +construed as a distribution of this Package. + +9. The name of the Copyright Holder may not be used to endorse or promote +products derived from this software without specific prior written permission. + +10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + + The End */ @@ -1478,7 +1386,7 @@ int main(int argc, char **argv) /* See the GNU Library General Public License for more details. */ /* You should have received a copy of the GNU Library General */ /* Public License along with this library; if not, write to the */ -/* Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA */ +/* Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA */ /* 02111-1307 USA */ /* Copyright (C) 1997, 1999 Makoto Matsumoto and Takuji Nishimura. */ @@ -1493,14 +1401,14 @@ int main(int argc, char **argv) /* ACM Transactions on Modeling and Computer Simulation, */ /* Vol. 8, No. 1, January 1998, pp 3--30. */ -/* Period parameters */ +/* Period parameters */ #define N 624 #define M 397 #define MATRIX_A 0x9908b0df /* constant vector a */ #define UPPER_MASK 0x80000000 /* most significant w-r bits */ #define LOWER_MASK 0x7fffffff /* least significant r bits */ -/* Tempering parameters */ +/* Tempering parameters */ #define TEMPERING_MASK_B 0x9d2c5680 #define TEMPERING_MASK_C 0xefc60000 #define TEMPERING_SHIFT_U(y) (y >> 11) @@ -1514,15 +1422,15 @@ static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */ /* Initializing the array with a seed */ void sgenrand(seed) - unsigned long seed; + unsigned long seed; { int i; for (i=0;i> 16; - seed = 69069 * seed + 1; + mt[i] = seed & 0xffff0000; + seed = 69069 * seed + 1; + mt[i] |= (seed & 0xffff0000) >> 16; + seed = 69069 * seed + 1; } mti = N; } @@ -1532,23 +1440,23 @@ sgenrand(seed) /* This function allows to choose any of 2^19937-1 ones. */ /* Essential bits in "seed_array[]" is following 19937 bits: */ /* (seed_array[0]&UPPER_MASK), seed_array[1], ..., seed_array[N-1]. */ -/* (seed_array[0]&LOWER_MASK) is discarded. */ +/* (seed_array[0]&LOWER_MASK) is discarded. */ /* Theoretically, */ /* (seed_array[0]&UPPER_MASK), seed_array[1], ..., seed_array[N-1] */ /* can take any values except all zeros. */ void lsgenrand(seed_array) - unsigned long seed_array[]; + unsigned long seed_array[]; /* the length of seed_array[] must be at least N */ { int i; - for (i=0;i Date: Sat, 7 Oct 2023 09:31:30 +0900 Subject: [PATCH 3/5] Explicitly import standard headers for file operations --- test/postmark.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/postmark.c b/test/postmark.c index 3fbbddc..e9eb1cd 100644 --- a/test/postmark.c +++ b/test/postmark.c @@ -59,6 +59,8 @@ Andy Watson . #include #include #include +#include +#include #define PM_VERSION "v1.51 : 8/14/01" From 9c81e6ff55fa1e182a055d869f44f12d28fc4c10 Mon Sep 17 00:00:00 2001 From: Daniel Markstedt Date: Sat, 7 Oct 2023 09:37:10 +0900 Subject: [PATCH 4/5] Move function declarations before the first usage --- test/postmark.c | 114 ++++++++++++++++++++++++------------------------ 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/test/postmark.c b/test/postmark.c index e9eb1cd..1281153 100644 --- a/test/postmark.c +++ b/test/postmark.c @@ -944,6 +944,63 @@ int subdirs; } } +/* parse CLI input line */ +int cli_parse_line(buffer) +char *buffer; /* line of user input */ +{ + int result=1; /* default return status */ + int len; /* length of parsed command */ + int i; /* traversal variable for command table */ + + if (*buffer=='!') /* check for shell escape */ + system((strlen(buffer)>1)?buffer+1:getenv("SHELL")); + else + { + for (i=0; command_list[i].name; i++) /* walk command table */ + if (!strncmp(command_list[i].name,buffer, + len=strlen(command_list[i].name))) + { /* if command matches... */ + result=(command_list[i].func) + (((int)strlen(buffer)>len)?buffer+len+1:NULL); + break; /* call function and pass remainder of line as parameter */ + } + + if (!command_list[i].name) /* if no commands were called... */ + printf("Eh?\n"); /* tribute to Canadian diction */ + } + + return(result); /* return 1 unless exit requested, then return 0 */ +} + +/* read config file if present and process it line by line + - if 'quit' is in file then function returns 0 */ +int read_config_file(filename,buffer,ignore) +char *filename; /* file name of config file */ +char *buffer; /* temp storage for each line read from file */ +int ignore; /* ignore file not found */ +{ + int result=1; /* default exit value - proceed with UI */ + FILE *fp; + + if (fp=fopen(filename,"r")) /* open config file */ + { + printf("Reading configuration from file '%s'\n",filename); + while (fgets(buffer,MAX_LINE,fp) && result) /* read lines until 'quit' */ + { + buffer[strlen(buffer)-1]='\0'; /* delete final CR */ + result=cli_parse_line(buffer); /* process line as typed in */ + } + + fclose(fp); + } + else + if (!ignore) + fprintf(stderr,"Error: cannot read configuration file '%s'\n", + filename); + + return(result); +} + /* CLI callback for 'run' - benchmark execution loop */ int cli_run(param) /* none */ char *param; /* unused */ @@ -1165,63 +1222,6 @@ int size; return(result); /* return success of fgets */ } -/* parse CLI input line */ -int cli_parse_line(buffer) -char *buffer; /* line of user input */ -{ - int result=1; /* default return status */ - int len; /* length of parsed command */ - int i; /* traversal variable for command table */ - - if (*buffer=='!') /* check for shell escape */ - system((strlen(buffer)>1)?buffer+1:getenv("SHELL")); - else - { - for (i=0; command_list[i].name; i++) /* walk command table */ - if (!strncmp(command_list[i].name,buffer, - len=strlen(command_list[i].name))) - { /* if command matches... */ - result=(command_list[i].func) - (((int)strlen(buffer)>len)?buffer+len+1:NULL); - break; /* call function and pass remainder of line as parameter */ - } - - if (!command_list[i].name) /* if no commands were called... */ - printf("Eh?\n"); /* tribute to Canadian diction */ - } - - return(result); /* return 1 unless exit requested, then return 0 */ -} - -/* read config file if present and process it line by line - - if 'quit' is in file then function returns 0 */ -int read_config_file(filename,buffer,ignore) -char *filename; /* file name of config file */ -char *buffer; /* temp storage for each line read from file */ -int ignore; /* ignore file not found */ -{ - int result=1; /* default exit value - proceed with UI */ - FILE *fp; - - if (fp=fopen(filename,"r")) /* open config file */ - { - printf("Reading configuration from file '%s'\n",filename); - while (fgets(buffer,MAX_LINE,fp) && result) /* read lines until 'quit' */ - { - buffer[strlen(buffer)-1]='\0'; /* delete final CR */ - result=cli_parse_line(buffer); /* process line as typed in */ - } - - fclose(fp); - } - else - if (!ignore) - fprintf(stderr,"Error: cannot read configuration file '%s'\n", - filename); - - return(result); -} - /* main function - reads config files then enters get line/parse line loop */ main(argc,argv) int argc; From bbcb33c455fe91de99e0b16540a895e908951c78 Mon Sep 17 00:00:00 2001 From: Daniel Markstedt Date: Sat, 7 Oct 2023 09:42:11 +0900 Subject: [PATCH 5/5] Explicitly import adoublehelper.h header --- test/T2_FPRead.c | 1 + 1 file changed, 1 insertion(+) diff --git a/test/T2_FPRead.c b/test/T2_FPRead.c index 08b132c..3b29894 100644 --- a/test/T2_FPRead.c +++ b/test/T2_FPRead.c @@ -1,5 +1,6 @@ #include "specs.h" #include "ea.h" +#include "adoublehelper.h" /* ------------------------- */ STATIC void test109()