/* This is part of ODS2 written by Paul Nankervis, * email address: Paulnank@au1.ibm.com * * ODS2 is distributed freely for all members of the * VMS community to use. However all derived works * must maintain comments in their source to acknowledge * the contributions of the original author and * subsequent contributors. This is free software; no * warranty is offered, and while we believe it to be useful, * you use it at your own risk. */ #if !defined( DEBUG ) && defined( DEBUG_DIFFCMD ) #define DEBUG DEBUG_DIFFCMD #else #ifndef DEBUG #define DEBUG 0 #endif #endif #include "cmddef.h" #include "phyio.h" /******************************************************************* dodiff() */ /* dodiff: a simple file difference routine */ static uint32_t maxdiffs; #define diff_maxdiff OPT_GENERIC_1 #define diff_binary OPT_GENERIC_2 qual_t diffquals[] = {{"maximum_differences", diff_maxdiff, 0, DV(&maxdiffs), "commands difference qual_maxdiff"}, {"nomaximum_differences", 0, diff_maxdiff, NV, NULL }, {"binary", diff_binary, 0, NV, "commands difference qual_binary"}, { NULL, 0, 0, NV, NULL } }; param_t diffpars[] = { {"Files-11_filespec", REQ, FSPEC, NOPA, "commands difference Files-11_spec"}, {"local_filespec", REQ, FSPEC, NOPA, "commands difference local_spec"}, { NULL, 0, 0, NOPA, NULL } }; DECL_CMD(diff) { vmscond_t sts; options_t options; uint32_t records, diffs = 0; char *rec, *cpy = NULL, *buf = NULL; size_t bufsize = 80; char *name; FILE *tof; struct FAB fab = cc$rms_fab; struct RAB rab = cc$rms_rab; struct NAM nam = cc$rms_nam; char rsname[NAM$C_MAXRSS+1]; UNUSED(argc); if( $FAILS(sts = checkquals( &options, 0, diffquals, qualc, qualv )) ) return sts; name = get_realpath( argv[2] ); records = 0; nam.nam$l_rsa = rsname; nam.nam$b_rss = (uint8_t)(sizeof( rsname) - 1); fab.fab$l_nam = &nam; fab.fab$l_fna = argv[1]; fab.fab$b_fns = (uint8_t)strlen( fab.fab$l_fna ); if ( (tof = openf( name? name: argv[2], "r" )) == NULL ) { int err; err = errno; printmsg( DIFF_OPENIN, 0, name? name: argv[2] ); sts = printmsg( ODS2_OSERROR, MSG_CONTINUE, DIFF_OPENIN, strerror(err) ); free( name ); return sts; } if( $SUCCESSFUL(sts = sys_open( &fab )) ) { rab.rab$l_fab = &fab; nam.nam$l_rsa[nam.nam$b_rsl] = '\0'; if( $SUCCESSFUL(sts = sys_connect( &rab )) ) { if( (rec = malloc( MAXREC + 2 )) == NULL ) { int err; err = errno; sts = SS$_INSFMEM; printmsg( sts, 0 ); sts = printmsg( ODS2_OSERROR, MSG_CONTINUE, sts, strerror(err) ); } else { rab.rab$l_ubf = rec; rab.rab$w_usz = MAXREC; while( $SUCCESSFUL(sts = sys_get( &rab )) ) { rec[rab.rab$w_rsz] = '\0'; ++records; cpy = fgetline( tof, FALSE, &buf, &bufsize ); if( cpy == NULL || rab.rab$w_rsz != strlen( cpy ) || memcmp( rec, cpy, rab.rab$w_rsz ) != 0 ) { if( options & diff_binary ) sts = printmsg( DIFF_DIFFER, 0, records ); else printf( "************\n" "File %s\n" "%5u %.*s\n" "******\n" "File %s\n" "%5u %s\n" "************\n", rsname, records, rab.rab$w_rsz, rec, name, records, cpy? cpy: "" ); if( (++diffs > maxdiffs && (options & diff_maxdiff)) || cpy == NULL ) break; } cpy = NULL; } free( rec ); rec = cpy = NULL; } sys_disconnect(&rab); } sys_close(&fab); } else { printmsg( DIFF_OPENIN, 0, argv[1] ); sts = printmsg( sts, MSG_CONTINUE, DIFF_OPENIN ); } if( sts == RMS$_EOF ) { if( (cpy = fgetline( tof, FALSE, &buf, &bufsize )) == NULL ) sts = SS$_NORMAL; else { if( diffs < maxdiffs ) sts = printmsg( DIFF_DIFFER, 0, records ); } } if( buf != NULL ) free( buf ); fclose(tof); if( $SUCCESSFUL(sts) ) { sts = printmsg( DIFF_COMPARED, 0, records ); } else if( !$MATCHCOND(sts, DIFF_DIFFER) ) { sts = printmsg( sts, 0, rab.rab$l_stv ); } free( name ); return sts; }