/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */ /* The copyright notice above does not evidence any */ /* actual or intended publication of such source code. */ #ident "@(#)TLtest.c 1.4 92/07/14 SMI" /* SVr4.0 1.4 */ #include #include #include #include #include #include #define BSIZE 512 #define MAXIDS 10 #define NENTRIES 10 #define SKIPWS(p) if( p ) while( *p == ' ' || *p == '\t' ) p++ #define SEEKWS(p) if( p ) while( *p && *p != ' ' && *p != '\t' && *p != '\n' )\ p++ struct errmsg { int value; char *name; } errtable[] = { TLSUBSTITUTION, "TLSUBSTITUTION", TLBADFIELD, "TLBADFIELD", TLNOMEMORY, "TLNOMEMORY", TLBADENTRY, "TLBADENTRY", TLBADFORMAT, "TLBADFORMAT", TLBADID, "TLBADID", TLTOOMANY, "TLTOOMANY", TLDESCRIPTION, "TLDESCRIPTION", TLTOOLONG, "TLTOOLONG", TLARGS, "TLARGS", TLFAILED, "TLFAILED", TLOK, "TLOK", TLBADFS, "TLBADFS", TLDIFFFORMAT, "TLDIFFFORMAT" }; int errsize = (sizeof( errtable ) / sizeof( struct errmsg ) ); char buffer[ BSIZE ], *myfgets(), *ptr; FILE *sfptr = 0; ENTRY entries[ NENTRIES ]; int echo = 0; TLsearch_t sarray[NENTRIES]; unsigned char fieldnames[NENTRIES][80]; unsigned char patterns[NENTRIES][80]; char *errmap(); main( argc, argv ) char *argv[]; { register rc; register entryno_t entryno, first, last; int c, mode, tid, entry, how_to_match; TLdesc_t desc; unsigned char *filename, *fieldname, *value, *pattern, *replacement; extern char *optarg; extern int optind; strncpy( entries, "", NENTRIES * sizeof( ENTRY ) ); while( (c = getopt( argc, argv, "s:e") ) != -1 ) switch( c ) { case 'e': /* echo input to output */ echo = 1; break; case 's': /* Tee output into optarg */ if( !(sfptr = fopen( optarg, "w" ) ) ) fprintf( stderr, "%s: cannot open %s for writing, errno %d\n", argv[0], optarg, errno ); break; default: fprintf( stderr, "synopsis: %s [-s shadowfile ]\n", argv[0] ); break; } strncpy( &desc, "", sizeof( TLdesc_t ) ); fprintf( stdout, "> " ); while( myfgets( buffer, BSIZE, stdin ) == buffer ) { ptr = buffer; SKIPWS(ptr); switch( *ptr ) { case 'a': ptr++; if( *ptr == 'f' ) { /* ASSIGN FIELD */ ptr++; SKIPWS(ptr); tid = getinteger(); SKIPWS(ptr); entry = getentry( tid ); SKIPWS(ptr); fieldname = (unsigned char *)ptr; SEEKWS(ptr); *ptr = '\0'; ptr++; SKIPWS(ptr); value = (unsigned char *)ptr; while( *ptr && *ptr != '\n' ) ptr++; *ptr = '\0'; rc = TLassign( tid, entries[ entry ], fieldname, value ); fprintf( stdout, "--TLassign returns %s\n", errmap( rc ) ); break; } /* APPEND ENTRY */ SKIPWS(ptr); tid = getinteger(); entryno = getentryno(); entry = getentry( tid ); rc = TLappend( tid, entryno, entries[ entry ] ); if( rc == TLFAILED ) fprintf( stdout, "--TLappend returns TLFAILED errno %d\n", errno ); else fprintf( stdout, "--TLappend returns %s\n", errmap( rc ) ); break; case 'c': /* CLOSE */ ptr++; SKIPWS(ptr); tid = getinteger(); rc = TLclose( tid ); fprintf( stdout, "--close: %s\n", errmap( rc ) ); break; case 'd': /* DELETE ENTRY */ ptr++; SKIPWS(ptr); tid = getinteger(); entryno = getentryno(); rc = TLdelete( tid, entryno ); if( rc == TLFAILED ) fprintf( stdout, "--TLdelete returns TLFAILED, errno %d\n", errno ); else fprintf( stdout, "--TLdelete returns %s\n", errmap( rc ) ); break; case 'D': /* DESCRIPTION */ if( !getcresp( "comment char: ", &(desc.td_comment) ) ) break; if( !getcresp( "field sep char: ", &(desc.td_fs) ) ) break; if( !getcresp( "end of entry char: ", &(desc.td_eoe) ) ) break; break; case 'f': /* FREE AN ENTRY */ ptr++; SKIPWS(ptr); tid = getinteger(); entry = getentry(tid); if( entry == -1 ) break; TLfreeentry( tid, entries[ entry ] ); strncpy( entries[ entry ], "", sizeof( ENTRY ) ); break; case 'F': /* FORMAT */ ptr++; SKIPWS(ptr); if( desc.td_format ) Free( desc.td_format ); if( !(desc.td_format = (unsigned char *)Malloc( Strlen( ptr ) ) )) fprintf( stdout, "--malloc fails\n" ); else strncpy( desc.td_format, ptr, Strlen(ptr) - 1 ); break; case 'g': /* GETFIELD and GETENTRY */ ptr++; switch( *ptr ) { case 'e': ptr++; SKIPWS(ptr); tid = getinteger(); if( (entry = getentry( tid ) ) == -1 ) break; if( entries[ entry ] ) TLfreeentry( tid, entries[ entry ] ); entries[ entry ] = TLgetentry( tid ); fprintf( stdout, "--TLgetentry() returns %s\n", (entries[ entry ])? "SUCCESS": "NULL" ); break; case 'f': ptr++; SKIPWS(ptr); tid = getinteger(); if( (entry = getentry( tid ) ) == -1 ) break; SKIPWS(ptr); fieldname = (unsigned char *)ptr; SEEKWS(ptr); *ptr++ = '\0'; if( !Strcmp( (char *)fieldname, "comment" ) ) fieldname = TLCOMMENT; else if( !Strcmp( (char *)fieldname, "trailing" ) ) fieldname = TLTRAILING; ptr = (char *)TLgetfield( tid, entries[ entry ], fieldname ); fprintf( stdout, "--TLgetfield() returns >%s<\n", ( ptr? ptr: "NULL" ) ); break; default: goto error; } break; case 'o': /* OPEN */ ptr++; SKIPWS(ptr); /* Get filename */ filename = (unsigned char *)ptr; SEEKWS(ptr); *ptr++ = '\0'; SKIPWS(ptr); mode = getoctal(); rc = TLopen( &tid, filename, &desc, (mode? (O_RDWR|O_CREAT): O_RDWR), mode ); if( rc == TLFAILED ) fprintf( stdout, "--TLopen of %s returns TLFAILED, errno %d, tid %d\n", filename, errno, tid ); else fprintf( stdout, "--TLopen of %s returns %s, tid %d\n", filename, errmap( rc ), tid ); break; case 'q': /* QUIT */ #ifdef MONITOR monitor( (int (*)())0, 0, 0, 0, 0 ); #endif exit( 0 ); break; case 'r': /* READ */ ptr++; SKIPWS(ptr); tid = getinteger(); entryno = getentryno(); if( (entry = getentry(tid)) == -1 ) break; rc = TLread( tid, entryno, entries[ entry ] ); if( rc == TLFAILED ) fprintf( stdout, "--TLread returns TLFAILED, errno %d\n", errno ); else fprintf( stdout, "--TLread returns %s\n", errmap( rc ) ); if( rc == TLOK ) pr_entry( entries[ entry ] ); break; case 's': /* SEARCH, SUBST, SYNC */ ptr++; switch( *ptr ) { case 'e': ptr++; SKIPWS(ptr); tid = getinteger(); SKIPWS(ptr); first = getentryno(); last = getentryno(); getsearches( sarray ); how_to_match = gethow_to_match(); rc = TLsearch1( tid, sarray, first, last, how_to_match ); if( rc < 0 ) fprintf( stdout, "--TLsearch1() returns %s\n", errmap( rc ) ); else fprintf( stdout, "--TLsearch1() returns %d\n", rc ); break; case 'u': ptr++; SKIPWS(ptr); tid = getinteger(); SKIPWS(ptr); entry = getentry( tid ); SKIPWS(ptr); fieldname = (unsigned char *)ptr; SEEKWS(ptr); *ptr = '\0'; ptr++; SKIPWS(ptr); pattern = (unsigned char *)ptr; SEEKWS(ptr); *ptr = '\0'; ptr++; replacement = (unsigned char *)ptr; while( *ptr != '\n' ) ptr++; *ptr = '\0'; rc = TLsubst( tid, entries[entry], fieldname, pattern, replacement ); fprintf( stdout, "--TLsubst() returns %s\n", errmap( rc ) ); break; case 'y': ptr++; SKIPWS(ptr); tid = getinteger(); rc = TLsync( tid ); if( rc == TLFAILED ) fprintf( stdout, "--TLsync returns TLFAILED, errno %d\n", errno ); else fprintf( stdout, "--TLsync returns %s\n", errmap( rc ) ); break; } break; case 'w': /* WRITE ENTRY */ ptr++; SKIPWS(ptr); tid = getinteger(); entryno = getentryno(); if( (entry = getentry(tid)) == -1 ) break; rc = TLwrite( tid, entryno, entries[ entry ] ); if( rc == TLFAILED ) fprintf( stdout, "--TLwrite returns TLFAILED, errno %d\n", errno ); else fprintf( stdout, "--TLwrite returns %s\n", errmap( rc ) ); break; case '!': /* SYSTEM */ ptr++; system( ptr ); break; case '#': /* Comment */ break; case '?': default: error: fprintf( stdout, "Commands:\n" ); fprintf( stdout, "\ta - append an entry\n" ); fprintf( stdout, "\taf - assign field value\n" ); fprintf( stdout, "\tc - close\n" ); fprintf( stdout, "\td - delete an entry\n" ); fprintf( stdout, "\tD - fill in description structure\n" ); fprintf( stdout, "\tf - free an entry\n" ); fprintf( stdout, "\tF - format\n" ); fprintf( stdout, "\tge - get an entry\n" ); fprintf( stdout, "\tgf - get a fieldvalue\n" ); fprintf( stdout, "\to - open a table\n" ); fprintf( stdout, "\tq - quit\n" ); fprintf( stdout, "\tr - read an entry\n" ); fprintf( stdout, "\tse - search for an entry\n" ); fprintf( stdout, "\tsu - substitute in a field\n" ); fprintf( stdout, "\tsy - sync\n" ); fprintf( stdout, "\tw - write an entry\n" ); fprintf( stdout, "\tentryno: B(begin) E(end) \n"); fprintf( stdout, "\t\t where B = begin + and E = end - \n" ); fprintf( stdout, "\tentry: in array of ENTRYs\n" ); } fprintf( stdout, "> " ); } #ifdef MONITOR monitor( (int (*))0, 0, 0, 0, 0 ); #endif exit( 0 ); } getoctal() { register i, n, c = 0; for( i = 0; i < 3; i++, ptr++ ) if( *ptr && isdigit( (int)*ptr) && (n = *ptr - '0') < 8 ) c = c*8 + n; else break; return( c ); } char getcharacter() { if( !ptr || !*ptr ) return( '\0' ); if( *ptr == '\\' ) { if( *(++ptr) == '\\' ) return( '\\' ); return( (char)getoctal( ptr ) ); } else return( *ptr ); } getcresp( prompt, ptr ) unsigned char *prompt, *ptr; { unsigned char *tmp; fprintf( stdout, "%s", prompt ); if( myfgets( buffer, BSIZE, stdin ) == buffer ) { tmp = (unsigned char *)buffer; SKIPWS(tmp); return( *ptr = getcharacter( tmp ) ); } else return( 0 ); } getentryno() { SKIPWS(ptr); switch( *ptr ) { case 'B': case 'b': ptr++; return( TLBEGIN + getinteger() ); case 'E': case 'e': ptr++; return( TLEND - getinteger() ); default: return( getinteger() ); } } getinteger() { int n = 0; while( isdigit(*ptr) ) { n = n * 10 + *ptr - '0'; ptr++; } return( n ); } getentry( tid ) int tid; { int n; SKIPWS(ptr); n = getinteger(); if( n > 0 && n <= NENTRIES ) return( n - 1 ); return( -1 ); } pr_entry( entry ) entry_t *entry; { fprintf( stdout, "ENTRY:\n\tstatus 0x%x\n\tseekaddr %d\n", entry->status, entry->seekaddr ); pr_fields( &(entry->fields), "\t" ); if( entry->comment ) fprintf( stdout, "\tComment: %s\n", entry->comment ); } pr_fields( fields, prolog ) field_t *fields; char *prolog; { register i; for( i = 0; i < fields->count; i++ ) fprintf( stdout, "%s%d: %s\n", prolog, i + 1, fields->values[ i ] ); } char * myfgets( buffer, size, fptr ) char *buffer; int size; FILE *fptr; { register char *tmp; if( (tmp = fgets( buffer, size, fptr )) && sfptr ) fprintf( sfptr, "%s", buffer ); if( tmp && echo ) fprintf( stdout, "%s", buffer ); return( tmp ); } int i_decide( fieldname, fieldvalue, pattern ) unsigned char *fieldname, *fieldvalue, *pattern; { unsigned char *ptr; fprintf( stdout, "Fieldname: %s\n", fieldname ); fprintf( stdout, "Fieldvalue: %s\n", fieldvalue ); fprintf( stdout, "Pattern: %s\n", pattern ); fprintf( stdout, "Y or N: " ); if( myfgets( buffer, BSIZE, stdin ) == buffer ) { ptr = (unsigned char *)buffer; SKIPWS(ptr); return( *ptr == 'y' || *ptr == 'Y' ); } return( FALSE ); } getsearches( sarray ) TLsearch_t *sarray; { int i; unsigned char *ptr; for( i = 0; i < NENTRIES; i++ ) { fprintf( stdout, "Fieldname: " ); if( (unsigned char *)myfgets( fieldnames[i], 80, stdin ) != fieldnames[i] ) { sarray[i].ts_fieldname = NULL; return; } if( !(ptr = (unsigned char *)strchr( fieldnames[i], '\n' )) ) { sarray[i].ts_fieldname = NULL; return; } *ptr = '\0'; if( !Strlen( fieldnames[i] ) ) { sarray[i].ts_fieldname = NULL; return; } sarray[i].ts_fieldname = fieldnames[i]; fprintf( stdout, "Pattern: " ); if( (unsigned char *)myfgets( patterns[i], 80, stdin ) != patterns[i] ) { sarray[i].ts_fieldname = NULL; return; } else if( !(ptr = (unsigned char *)strchr( patterns[i], '\n' )) ) { sarray[i].ts_fieldname = NULL; return; } *ptr = '\0'; if( !Strlen( patterns[i] ) ) { sarray[i].ts_fieldname = NULL; return; } sarray[i].ts_pattern = patterns[i]; if( !getoperation( sarray + i ) ) { sarray[i].ts_fieldname = NULL; return; } } } gethow_to_match( ) { unsigned char *ptr; fprintf( stdout, "HOW_TO_MATCH: (TL_AND (default), TL_NAND, TL_OR, or TLNOR) ? " ); if( myfgets( buffer, BSIZE, stdin ) != buffer ) { return( TL_AND ); } else { buffer[ Strlen(buffer) - 1 ] = '\0'; ptr = (unsigned char *)buffer; SKIPWS(ptr); if( !Strcmp( ptr, "TL_NAND" ) ) return( TL_NAND ); else if( !Strcmp( ptr, "TL_OR" ) ) return( TL_OR ); else if( !Strcmp( ptr, "TL_NOR" ) ) return( TL_NOR ); else return( TL_AND ); } } getoperation( sptr ) TLsearch_t *sptr; { int i_decide(), addr = 0; unsigned char *ptr; fprintf( stdout, "Choose match operation:\n" ); fprintf( stdout, "\tTLEQ, TLNE, TLLT, TLGT, TLLE, TLGE, TLMATCH, TLNMATCH, TLNUMEQ\n" ); fprintf( stdout, "\tTLNUMNE, TLNUMLT, TLNUMGT, TLNUMLE, TLNUMGE, i_decide (default)\n" ); fprintf( stdout, "operation: " ); if( myfgets( buffer, BSIZE, stdin ) != buffer ) return( FALSE ); buffer[ Strlen(buffer) - 1] = '\0'; ptr = (unsigned char *)buffer; SKIPWS(ptr); if( !Strcmp( ptr, "TLEQ" ) ) addr = TLEQ; else if( !Strcmp( ptr, "TLNE" ) ) addr = TLNE; else if( !Strcmp( ptr, "TLLT" ) ) addr = TLLT; else if( !Strcmp( ptr, "TLGT" ) ) addr = TLGT; else if( !Strcmp( ptr, "TLLE" ) ) addr = TLLE; else if( !Strcmp( ptr, "TLGE" ) ) addr = TLGE; else if( !Strcmp( ptr, "TLMATCH" ) ) addr = TLMATCH; else if( !Strcmp( ptr, "TLNMATCH" ) ) addr = TLNMATCH; else if( !Strcmp( ptr, "TLNUMEQ" ) ) addr = TLNUMEQ; else if( !Strcmp( ptr, "TLNUMNE" ) ) addr = TLNUMNE; else if( !Strcmp( ptr, "TLNUMLT" ) ) addr = TLNUMLT; else if( !Strcmp( ptr, "TLNUMGT" ) ) addr = TLNUMGT; else if( !Strcmp( ptr, "TLNUMLE" ) ) addr = TLNUMLE; else if( !Strcmp( ptr, "TLNUMGE" ) ) addr = TLNUMGE; if( addr ) sptr->ts_operation = (int (*)())addr; else sptr->ts_operation = i_decide; return( TRUE ); } char * errmap( errcode ) int errcode; { register i; static char errbuf[40]; for( i = 0; i < errsize; i++ ) if( errtable[ i ].value == errcode ) return( errtable[ i ].name ); sprintf( errbuf, "%d", errcode ); return( errbuf ); }