Annotation of coherent/d/bin/strings.c, revision 1.1.1.1

1.1       root        1: /**
                      2:  *     strings -- prints out all the character strings in an executable file.
                      3:  *
                      4:  *     Usage: strings [-xaop] [-nnn] [file ...]
                      5:  *
                      6:  *     Options:
                      7:  *              -x     print offset of each string in the file in hex
                      8:  *              -a     print offset of each string in the file in ASCII
                      9:  *              -o     print offset of each string in the file in octal
                     10:  *              -p     mask out the parity bit
                     11:  */
                     12: 
                     13: #include       <sys/stat.h>
                     14: #include       <l.out.h>
                     15: #include       <stdio.h>
                     16: #include       <canon.h>
                     17: #include       <ctype.h>
                     18: 
                     19: /* The lamentable <rico.h>... */
                     20: #define        bool    char
                     21: #define        TRUE    (0 == 0)
                     22: #define        FALSE   (!TRUE)
                     23: 
                     24: int    nchars  = 4;    /* minimum character string length */
                     25: 
                     26: bool   flag;           /* input condition: FALSE for redirection, else TRUE */
                     27: bool   aflag;          /* option flags:        ascii line numbering */
                     28: bool   xflag;          /*                      hex   line numbering */
                     29: bool   oflag;          /*                      octal line numbering */
                     30: 
                     31: int    pbit;           /* parity bit mask */
                     32: long   addr;           /* current seek position in data space segment */
                     33: long   count;          /* size of data space segment */
                     34: char  * buff;          /* string to store beginning NCHARS
                     35:                                        characters in character string */
                     36: bool   printstr();
                     37: bool   lookfor();
                     38: 
                     39: extern FILE    * freopen();
                     40: extern char    * malloc();
                     41: 
                     42: 
                     43: main( argc, argv )
                     44: 
                     45: int    argc;
                     46: char  * argv[];
                     47: 
                     48: {
                     49:        char    * malloc();
                     50:        char    * s;
                     51: 
                     52:        while( (--argc > 0) && ((*++argv)[0] == '-') ) {
                     53: 
                     54:                /*
                     55:                 * Read options declared.
                     56:                 */
                     57:                for( s = argv[0] + 1 ; *s != '\0'; s++ ) {
                     58: 
                     59:                        /*
                     60:                         * Set minimum string length for recognizing
                     61:                         * character strings.
                     62:                         */
                     63:                        if( isdigit( *s ) ) {
                     64:                                if( (nchars = atoi( s )) <= 0 )
                     65:                                        fatal( "string length must be greater than 0" );
                     66: 
                     67:                                break;
                     68:                        }
                     69: 
                     70:                        /*
                     71:                         * Set appropriate flags or bit mask according to
                     72:                         * option declared.
                     73:                         */
                     74:                        switch( *s ) {
                     75: 
                     76:                        case 'x':
                     77:                                if( aflag | oflag | xflag )
                     78:                                        usage();
                     79: 
                     80:                                xflag = TRUE;
                     81:                                break;
                     82: 
                     83:                        case 'a':
                     84:                                if( aflag | oflag | xflag )
                     85:                                        usage();
                     86: 
                     87:                                aflag = TRUE;
                     88:                                break;
                     89: 
                     90:                        case 'o':
                     91:                                if( aflag | oflag | xflag )
                     92:                                        usage();
                     93: 
                     94:                                oflag = TRUE;
                     95:                                break;
                     96: 
                     97:                        case 'p':
                     98:                                pbit = 0200;
                     99:                                break;
                    100: 
                    101:                        default:
                    102:                                usage();
                    103:                        }
                    104:                }
                    105:        }
                    106: 
                    107:        /*
                    108:         * Get memory for string buffer.
                    109:         */
                    110:        if( (buff = malloc( nchars )) == NULL )
                    111:                fatal( "not enough memory" );
                    112: 
                    113:        /*
                    114:         * Set input condition:
                    115:         *      FALSE if input is through indirection, else TRUE.
                    116:         */
                    117:        if( argc > 0 )
                    118:                flag = TRUE;
                    119:        else {
                    120:                argc++;
                    121:                flag = FALSE;
                    122:        }
                    123: 
                    124:        /*
                    125:         * Examine each file for strings of the required length.
                    126:         */
                    127:        while( argc-- ) {
                    128: 
                    129:                /*
                    130:                 * Test for read permission in file.
                    131:                 */
                    132:                if( flag  &&  freopen( *argv, "r", stdin ) == NULL )
                    133:                        fatal( "can't open %s", argv[0] );
                    134: 
                    135:                /*
                    136:                 * Test if file is an executable file.
                    137:                 */
                    138:                if( checklout( stdin ) < 0 ) {
                    139:                        if( flag ) {
                    140:                                fprintf( stderr, "strings: '%s' not executable\n", *argv);
                    141:                                ++argv;
                    142:                                continue;
                    143:                        }
                    144:                        else {
                    145:                                fprintf( stderr, "strings: not executable\n" );
                    146:                                exit( 1 );
                    147:                        }
                    148:                }
                    149: 
                    150:                /*
                    151:                 * Display file name if available.
                    152:                 */
                    153:                if( flag )
                    154:                        fprintf( stderr, "%s:\n", *argv );
                    155: 
                    156:                /*
                    157:                 * Display all character strings in file.
                    158:                 */
                    159:                while( printstr() )
                    160:                        ;
                    161: 
                    162:                ++argv;
                    163:        }
                    164: 
                    165:        free( buff );
                    166:        exit( 0 );
                    167: }
                    168: 
                    169: /**
                    170:  * bool
                    171:  * printstr()
                    172:  *
                    173:  *     Input:  None.
                    174:  *
                    175:  *     Action: Display character strings in file.
                    176:  *
                    177:  *     Return: FALSE on error or no character strings available,
                    178:  *             otherwise TRUE.
                    179:  *
                    180:  *     Note:   None.
                    181:  *
                    182:  */
                    183: 
                    184: bool
                    185: printstr()
                    186: 
                    187: {
                    188:        char    c;
                    189:        char  * p;
                    190:        char  * q;
                    191: 
                    192:        p = buff;
                    193:        q = p + nchars;
                    194: 
                    195:        /*
                    196:         * Check if character strings are available in file.
                    197:         */
                    198:        if( ! lookfor() )
                    199:                return( FALSE );
                    200: 
                    201:        /*
                    202:         * Display line number according to the format option specified.
                    203:         * Ignore if no format option is set.
                    204:         */
                    205:        if( aflag )
                    206:                printf( "%-6D: ", addr-nchars );
                    207: 
                    208:        else if( oflag )
                    209:                printf( "0%-6O: ", addr-nchars );
                    210: 
                    211:        else if( xflag )
                    212:                printf( "0x%-6X: ", addr-nchars );
                    213: 
                    214:        /*
                    215:         * Display printable characters found.
                    216:         */
                    217:        do {
                    218:                putchar( *p++ );
                    219:        } while( p < q );
                    220: 
                    221:        /*
                    222:         * Display remaining printable characters in file.
                    223:         */
                    224:        for ( ;; ) {
                    225:                if( --count <= 0L )
                    226:                        return( FALSE );
                    227: 
                    228:                ++addr;
                    229:                c = getchar();
                    230: 
                    231:                if( c == EOF )
                    232:                        return( FALSE );
                    233: 
                    234:                if( ! (isascii( (c) & ~pbit ) &&  isprint( (c) & ~pbit )) )
                    235:                        break;
                    236: 
                    237:                putchar( c );
                    238:        }
                    239: 
                    240:        putchar( '\n' );
                    241:        return( TRUE );
                    242: }
                    243: 
                    244: /**
                    245:  * bool
                    246:  * lookfor()
                    247:  *
                    248:  *     Input:  None.
                    249:  *
                    250:  *     Action: Look for the first character string in file.
                    251:  *
                    252:  *     Return: TRUE if a character string is found, else FALSE.
                    253:  *
                    254:  *     Note:   None.
                    255:  *
                    256:  */
                    257: 
                    258: bool
                    259: lookfor()
                    260: 
                    261: {
                    262:        char    c;
                    263:        char  * p;
                    264:        char  * q;
                    265: 
                    266:        q = buff + nchars;
                    267: 
                    268:        for( ;; ) {
                    269: 
                    270:                /*
                    271:                 * Seek in data space segment of file until a printable
                    272:                 * character is encountered.
                    273:                 */
                    274:                do {
                    275:                        if( --count <= 0L )
                    276:                                return( FALSE );
                    277: 
                    278:                        ++addr;
                    279:                        c = getchar();
                    280: 
                    281:                        if( c == EOF )
                    282:                                return( FALSE );
                    283: 
                    284:                } while( ! (isascii( (c) & ~pbit ) && isprint( (c) & ~pbit )) );
                    285: 
                    286:                p = buff;
                    287: 
                    288:                /*
                    289:                 * Check for valid character string.
                    290:                 */
                    291:                do {
                    292:                        *p++ = c;
                    293: 
                    294:                        if( p >= q )
                    295:                                return( TRUE );
                    296: 
                    297:                        if( --count <= 0L )
                    298:                                return( FALSE );
                    299: 
                    300:                        ++addr;
                    301:                        c = getchar();
                    302: 
                    303:                        if( c == EOF )
                    304:                                return( FALSE );
                    305: 
                    306:                } while( isascii( (c) & ~pbit ) && isprint( (c) & ~pbit ) );
                    307:        }
                    308: }
                    309: 
                    310: 
                    311: /**
                    312:  * int
                    313:  * checklout( f )
                    314:  *
                    315:  * register FILE * f;
                    316:  *
                    317:  *     Input:  f       - file pointer to stdin.
                    318:  *
                    319:  *     Action: Check if executable (l.out) file.
                    320:  *
                    321:  *     Return: Returns -1 on error or file is not executable, otherwise 0.
                    322:  *
                    323:  *     Note:   None.
                    324:  *
                    325:  */
                    326: 
                    327: int
                    328: checklout( f )
                    329: 
                    330: register FILE  * f;
                    331: 
                    332: {
                    333:        register int      i;            /* counter variable */
                    334:        int               ret = -1;     /* returning error value */
                    335:        struct   stat     s;            /* file attributes */
                    336:        struct   ldheader l;            /* file header information */
                    337: 
                    338:        if( fstat( fileno( f ), &s ) == -1 )
                    339:                return( ret );
                    340: 
                    341:        /*
                    342:         * File type check. Return unless regular file.
                    343:         */
                    344:        if( (s.st_mode & S_IFMT) != S_IFREG )
                    345:                return( ret );
                    346: 
                    347:        /*
                    348:         * Get file header information.
                    349:         */
                    350:        if( fread( &l, sizeof( l ), 1, f ) != 1 ) {
                    351:                rewind( f );
                    352:                return( ret );
                    353:        }
                    354: 
                    355:        rewind( f );
                    356: 
                    357:        if( l.l_magic != L_MAGIC )
                    358:                return( ret );
                    359: 
                    360:        /*
                    361:         * Correct canonical effect on file format information.
                    362:         */
                    363:        for( i = 0 ; i < NLSEG ; ++i )
                    364:                canlong(l.l_ssize[i]);
                    365: 
                    366:        /*
                    367:         * Get seek position to the beginning memory location of the
                    368:         * data space segment in the executable file.
                    369:         */
                    370:        fseek( f, (long)sizeof(l) + l.l_ssize[L_SHRI] + l.l_ssize[L_PRVI], 0 );
                    371:        addr = ftell( f );
                    372: 
                    373:        /*
                    374:         * Get size of data space segment of file.
                    375:         */
                    376:        count = l.l_ssize[L_SHRD] + l.l_ssize[L_PRVD];
                    377: 
                    378:        if( count == 0L ) {
                    379:                fatal( "zero-length data segments" );
                    380:                /* NOTREACHED */
                    381:        }
                    382: 
                    383:        ++count;
                    384:        return( 0 );
                    385: }
                    386: 
                    387: /**
                    388:  * void
                    389:  * fatal( arg0 )
                    390:  *
                    391:  * char        * arg0;
                    392:  *
                    393:  *     Input:  arg0    - pointer to string containing the error message.
                    394:  *
                    395:  *     Action: Display fatal error message and exit.
                    396:  *
                    397:  *     Return: Never return, always exit.
                    398:  *
                    399:  *     Note:   None.
                    400:  *
                    401:  */
                    402: 
                    403: fatal( arg0 )
                    404: 
                    405: char   * arg0;
                    406: 
                    407: {
                    408:        fflush( stdout );
                    409:        fprintf( stderr, "strings: %r\n", &arg0 );
                    410:        exit( 1 );
                    411: }
                    412: 
                    413: /**
                    414:  * void
                    415:  * usage()
                    416:  *
                    417:  *     Input:  None.
                    418:  *
                    419:  *     Action: Display command usage format.
                    420:  *
                    421:  *     Return: Never return, always exit.
                    422:  *
                    423:  *     Note:   None.
                    424:  *
                    425:  */
                    426: 
                    427: usage()
                    428: 
                    429: {
                    430:        fprintf( stderr, "Usage: strings [-xaop] [-nnn] [file ...]\n" );
                    431:        exit( 1 );
                    432: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.