#!/usr/bin/perl
use strict;
use warnings;
use FindBin;

if (@ARGV != 2) {
    HELP_MESSAGE();
    exit(1);
}

my $str = $ARGV[0];
my $file = $ARGV[1];
open(my $fd, $file) or die "Fail to open $file\n";

my $BUF_LEN = 4096;
if (length($str) > $BUF_LEN) {
    print "string is too long\n";
}
my $buf;
my $match_buf;
my $find_eol;
while (1) {
    my $ok = read($fd, $buf, $BUF_LEN);
    if ($ok) {
        $match_buf = $match_buf . $buf;
        if (length($match_buf) < length($str)) {
            print "Not found\n";
            last;
        }
        my $id = index($match_buf, $str);
        if ($id == -1) {
            $match_buf = substr($buf, $BUF_LEN, length($str) -1);
        } else {
            my $eol = index($match_buf, "\0", $id);
            if ($eol != -1) {
                print substr($match_buf, $id, ($eol - $id))
            } else {
                print substr($match_buf, $id);
            }
            while (1) {
                $ok = read($fd, $buf, $BUF_LEN);
                if ($ok) {
                    $id = index($buf, '\0');
                    if ($id == -1) {
                        print $buf;
                    } else {
                        print substr($buf, 0, $id);
                        last;
                    }
                } else {
                    last;
                }
            }
            last;
        }
    } else {
        print("Not found\n");
        last;
    }
}

sub HELP_MESSAGE {
    print <<EOF;
Find a C string in FILE begins with STRING, output to STDOUT.

Usage: $FindBin::Script STRING FILE
EOF
}
