[Next] [Up] [Previous] [Contents]
Next: Checking on a Specific Previous: Checking on a Specific

Searching for Parts Using a WWW Browser

#!/utils/perl
# perl is linked from /utils/perl on cae003
&init_socket;

$id = '$Id: search_family_parts.pl,v 1.8 1996/07/23 17:44:26 fparts Exp $';

# machine and port for the familyd generate server
$server = "cae016.ed.ray.com";
$server_port = 4000;

# last modified date (had to seperate $ from Date to keep RCS from
# expanding the Date in the replacement command)  
($last_mod = '$Date: 1996/07/23 17:44:26 $') =~ s/[\$]Date: (.*)[\$]/\1 GMT/;

# name of the file listing the family parts   
$family_file = "/usr2/std/fpts/family-list";

# this is the filename of the other script
$check_url = "check_family_parts.pl";

# username of person to receive error mail
$maintainer = "fparts@sudcv91.ed.ray.com";

print "Content-type: text/html\n".
      "\n".
      "<HTML>\n".
      "<HEAD>\n".
      "<TITLE>Family of Parts Search</TITLE>\n".
      "<LINK REV=made HREF=\"mailto:gmm7689@sudcv91.ed.ray.com\">\n".
      "<!-- $id -->\n".
      "</HEAD>\n".
      "<BODY BGCOLOR=\"#00af00\" TEXT=\"#060600\" LINK=\"#0000aa\" \n".
      "BACKGROUND=\"/graphics/webtiles/gifs64/paper1/ab____64.gif\">\n".
      "<H1>Family of Parts Search</H1>\n";  

# for first pass through script, REQUEST_METHOD is GET, the rest use POST
# the default for no method (shouldn't be able to happen, but just in case)
# is to assume GET.
if($ENV{'REQUEST_METHOD'} ne "POST") 
  {
    &master_search;
  }
else
  { 
    # method is post, so read in the right amount of data from standard 
    # input. 
    read(STDIN, $data, $ENV{'CONTENT_LENGTH'}); 

    # Use parseform to split the data into fields, store in %query
    %query = &parseform($data); 

    # find out which function should be called
    $function = $query{'function'};

    # call the proper function, pass the query variable
    if($function eq 'master_matches')
      {
        &master_matches(%query);
      }
    elsif($function eq 'family_search')
      {
        &family_search(%query);
      }
    elsif($function eq 'family_matches')
      {
        &family_matches(%query);
      }
    elsif($function eq 'find_parts')
      {
        &find_parts(%query);
      }
    elsif($function eq 'generate')
      {
        &generate_parts(%query);
      }
  }

# end the page and exit the program
print "<P>\n".
      "Last Modified: $last_mod\n".
      "</BODY>\n".
      "</HTML>\n";
exit 0;

sub master_search 
  {
    local (%query) = @_;
 
    # directions for the user
    print "<H2>Family Selection</H2>\n".
          "<P>\n".
          "Enter string to match against family names and descriptions,\n".
	  "(e.g. 38999, T55164, connector).  The search is case-".
	  "insensitive and spaces match any character.".
          "or select the family from the list below.\n".
          "<HR>\n";

    # print the first form
    print "<P>\n".
          "Spaces match any character.  Search is case-insensitive.<BR>\n".
          "<FORM METHOD=POST>\n".
          "<INPUT TYPE=hidden NAME=function VALUE=\"master_matches\">\n".
          "<INPUT TYPE=text NAME=master>\n".
          "<INPUT TYPE=submit>\n".
          "<INPUT TYPE=reset VALUE=\"Reset Defaults\">\n".
	  "</FORM>\n".
	  "<HR>\n";

    # get family names for second form
    unless(open(FAMILIES, $family_file))
      {
        open(MAIL, "|/usr/ucb/mail -s 'Search_Family_Parts error' $maintainer");
        print MAIL "Unable to open family list.";
        close MAIL;
        &form_die("Search Error<P>Unable to open family list.\n"); 
      }

    # initialize the variables
    $directory = "";
    $partname = "";
    $comment = "";
    $image = "";
    
    # check each of the families for the string
    while(<FAMILIES>)
      {
        # remove the trailing newline
        chop;

        # skip blank lines
	next unless(/\w/);

        # deal with continuation lines
        while (s/\\$//) { $_ .= <FAMILIES>; chop; }

        # there should always be at least three colons in the line to 
        # split, add three just in case some are missing
        $_ .= ":::";

        # split line into its parts
        ($directory, $partname, $comment, $image) = split(':');

        # add the directory to the list of directories, the part name 
        # to the list of part names, and the image to the list of images
        push(@directories, $directory);
        push(@partnames, $partname);
        push(@comments, $comment);
        push(@images, $image);
      }

    # done with this file
    close(FAMILIES);

    # start the second form
    print "<FORM METHOD=POST>\n".
          "<INPUT TYPE=hidden NAME=function VALUE=\"family_search\">\n".
          "<SELECT NAME=\"selected_family\" SIZE=5>\n";

    # report the families
    for ($i = 0; $i < $#partnames + 1; $i++) 
      {
        print "<OPTION>".($i + 1).": $partnames[$i] : $comments[$i]\n";
      }

    # end the option list
    print "\n</SELECT>\n";

    # put the directory names in the file
    foreach (@directories)
      {
        print "<INPUT TYPE=hidden NAME=directories VALUE=\"$_\">\n";
      }

    # put the partnames in the file
    foreach (@partnames)
      {
        print "<INPUT TYPE=hidden NAME=partnames VALUE=\"$_\">\n";
      }

    # put the images in the file
    foreach (@images)
      {
        print "<INPUT TYPE=hidden NAME=images VALUE=\"$_\">\n";
      }

    # end the second form
    print "<P>\n".
          "<INPUT TYPE=submit>\n".
          "<INPUT TYPE=reset VALUE=\"Reset Defaults\">\n".
          "</FORM>\n";   
  }
 
sub master_matches 
  {
    local (%query) = @_;

    # the search string is stored under the index 'master'
    $pattern = $query{'master'};

    # print the instructions
    print "<H2>Matched Master Parts</H2>\n".
          "<P>\n".
          "Select the desired master part from the following list of parts.\n";

    # get family names 
    unless(open(FAMILIES, $family_file))
      {
        open(MAIL, "|/usr/ucb/mail -s 'Search_Family_Parts error' $maintainer");
        print MAIL "Unable to open family list.";
        close MAIL;
        &form_die("Search Error<P>Unable to open family list.\n"); 
      }

    # exit search if no characters were entered.
    ($pattern) || &form_die("No search string entered.\n");

    # quote all .'s so they match only .'s (as in 0.5)
    $pattern =~ s#\.#\\.#g;

    # change all spaces to .'s (space in input string will match
    # any character.)
    $pattern =~ s/ /./g;

    # found_a_match becomes 1 when an entry is found that matches
    # the search string
    $found_a_match = 0;

    # initialize the variables
    $directory = "";
    $partname = "";
    $comment = "";
    $image = "";
    
    # check each of the families for the string
    while(<FAMILIES>)
      {
        # remove the trailing newline
        chop;

        # deal with continuation lines
        while (s/\\$//) { $_ .= <FAMILIES>; chop; }

        # there should always be at least three colons in the line to 
        # split, add three just in case some are missing
        $_ .= ":::";

        # split line into its parts
        ($directory, $partname, $comment, $image) = split(':');

        # search in the pattern and comments
        if(($partname =~ /$pattern/i) || ($comment =~ /$pattern/i))
          {
	    # add the directory to the list of directories, the part
	    # name to the list of part names, comment to list of
	    # comments, image to list of images, and set the
	    # found_a_match flag.
            push(@directories, $directory);
            push(@partnames, $partname);
            push(@comments, $comment);
            push(@images, $image);
            $found_a_match = 1;
          }
      }

    # done with this file
    close(FAMILIES);

    # if no matches were found, exit the search
    ($found_a_match == 1) || &form_die("No matches found.");

    print "<FORM METHOD=POST>\n".
          "<INPUT TYPE=hidden NAME=function VALUE=\"family_search\">\n";

    # report the matches, giving each a radiobox.
    for ($i = 0; $i < $#partnames + 1; $i++)
      {
        $buttons[$i] = "<INPUT TYPE=radio NAME=\"selected_family\" VALUE=". 
                       ($i+1).">";
      }

    # print the buttons, master part names and comments
    for ($i = 0; $i < $#partnames + 1; $i++) 
      {
        print "<DT>$buttons[$i]$partnames[$i]\n".
              "<DD>$comments[$i]\n";
      }

    print "</DL>\n".
          "<HR>\n";

    # put directory names in the file
    foreach (@directories)
      {
        print "<INPUT TYPE=hidden NAME=directories VALUE=\"$_\">\n";
      }

    # put part names in the file
    foreach (@partnames)
      {
        print "<INPUT TYPE=hidden NAME=partnames VALUE=\"$_\">\n";
      }

    # put image names in the file
    foreach (@images)
      {
        print "<INPUT TYPE=hidden NAME=images VALUE=\"$_\">\n";
      }

    # add the submit and reset buttons, end the form
    print "<P>\n".
          "<INPUT TYPE=submit>\n".
          "<INPUT TYPE=reset VALUE=\"Reset Defaults\">\n".
          "</FORM>\n";
  }

sub family_search
  {
    local (%query) = @_;

    print "<H2>Searching Family Variables</H2>\n";

    # recover the arrays of directories, images and partnames
    @directories = split(/\n/, $query{'directories'});
    @images = split(/\n/, $query{'images'});
    @partnames = split(/\n/, $query{'partnames'});

    # get the selected partname, directory, and image
    $partno = $query{'selected_family'} - 1;
    $partname = @partnames[$partno];
    $directory = @directories[$partno];
    $image = @images[$partno];
       
    # open the family of parts table
    unless(open(TABLE, "$directory/_tbl"))
      {
        open(MAIL, "|/usr/ucb/mail -s 'Search_Family_Parts error' $maintainer");
        print MAIL "Unable to open $directory/_tbl.";
        close MAIL;
        &form_die("Search Error<P>Unable to open _tbl file.\n");
      }

    print "<PRE>\n";

    # skip the header lines, but print lines beginning with #!, 
    # they're comments for the users.
    while(($_ = <TABLE>) =~ /^\#/) 
      {
        print if (s/^#!//);
      }

    print "</PRE>\n";

    # the first non-header line contains the variable names
    (@fields) = split;

    close(TABLE);

    # inline the image (/usr2/std is not accessable via
    # http://cae003..., and people have to be able to access /usr2/std
    # to use these, so file://localhost/ should be fine.
    if ($image =~ /\w/)
      {
        print "<P>\n".
              "<IMG SRC=\"file://localhost$image\" ".
              "ALT=\"[Picture of Part]\">\n";
      }

    # print instructions
    print "<H3>Enter your search strings in the appropriate fields.</H3>\n";

    print "<P>\n".
	  "This is a string comparison.  Spaces match any character.\n".
	  "Search is case-insensitive.<BR>\n".
          "Examples: given the values 8.0, 18.0, 28.0, 8.125 and 1.825,<BR>\n".
          "8 will match 8.0, 18.0, 28.0, 8.125 and 1.825<BR>\n".
	  "8. will match 8.0, 18.0, 28.0, and 8.125, but not 1.825<BR>\n".
	  "8.0 will match 8.0, 18.0, 28.0, but not 8.125 or 1.825.<BR>\n".
	  "^8. will match 8.0, and 8.125 but not 18.0, 28.0, or 1.825.\n";
 
    # start the form
    print "<P>\n".
          "<FORM METHOD=POST>\n".
          "<INPUT TYPE=hidden NAME=function VALUE=\"family_matches\">\n".
          "<HR>\n".
          "<PRE>\n";

    # print the fields
    foreach (@fields)
      {
        printf("%-20s <INPUT TYPE=text NAME=$_>\n", $_);
      }

    # add directory and part name, end the form
    print "</PRE>\n".
          "<HR>\n".
          "<P>\n".
          "<INPUT TYPE=hidden NAME=directory VALUE=\"$directory\">\n".
          "<INPUT TYPE=hidden NAME=partname VALUE=\"$partname\">\n".
          "<INPUT TYPE=submit>\n".
          "<INPUT TYPE=reset VALUE=\"Reset Defaults\">\n".
          "</FORM>\n";
  }

sub family_matches
  {
    local (%query) = @_;

    # get part and directory names
    $partname = $query{'partname'};
    $directory = $query{'directory'};

    print "<H2>Matched entries</H2>\n";

    # open the family of parts table
    unless(open(TABLE, "$directory/_tbl"))
      {
        open(MAIL, "|/usr/ucb/mail -s 'Search_Family_Parts error' $maintainer");
        print MAIL "Unable to open $directory/_tbl.";
        close MAIL;
        &form_die("Search Error<P>Unable to open _tbl file.\n"); 
      }

    # skip the header lines.
    while(<TABLE>){ last unless /^\#/; }

    # the first non-header line contains the variable names
    @fields = split;

    # keep track of last pattern entered, to reduce search time
    $last_pattern = -1;

    for($i = 0; $i < $#fields; $i++)
      {	
	# if no pattern was entered, use "." as the pattern
	if($_ = $query{$fields[$i]})
	  {
	    $pattern[$i] = $_;
	    $last_pattern = $i;
          }
        else
          {
	    $pattern[$i] = ".";
          }
      }

    # end the search if no patterns were entered
    ($last_pattern > -1) || &form_die("No patterns entered.\n");

    # found_a_match becomes 1 when an entry is found that matches all of
    # the search strings
    $found_a_match = 0;

    # skip the master_part entry in the table
    <TABLE>;
   
    # step through each of the entries, and compare the 
    # entered search strings to the fields
    WHILE: while(<TABLE>)
      {  
        (@entry) = split;

        # check each of the textfields, up to last pattern entered
        for ($i = 0; $i <= $last_pattern; $i++)
          {
            # if one string doesn't match, the entry doesn't match
            (($entry[$i]) =~ /$pattern[$i]/i) || next WHILE ;
          }

        # add it to the list of matches and set the found_a_match flag.
        push(@matches, $_);
        push(@matched_names, $entry[0]);
        $found_a_match = 1;
      }

    # done with the file
    close(TABLE);

    # stop here if nothing matched.
    ($found_a_match == 1) || &form_die("No matches found.\n");

    # create the list of checkboxes
    for ($i = 1; $i <= $#matches+1; $i++)
      {
        $checkboxes[$i] = 
            "<INPUT TYPE=checkbox NAME=\"selected_matches\" VALUE=$i>\n"
      }

    # display instructions
    print "<P>\n".
          "Select the checkboxes above the entries you want to find.\n".
          "<P>\n".
          "Select linked partnames to look for that part.\n";

    # start form
    print "<FORM METHOD=POST>\n".
          "<INPUT TYPE=hidden NAME=function VALUE=\"find_parts\">\n".
          "<HR>\n";

    # print checkboxes and entries
    $i = 1;
    foreach (@matches)
      { 
        print "<PRE>\n".
              "$checkboxes[$i++]\n";

        @entry = split;

        # display each field of the entry
        $j = 0;
        foreach (@fields) 
          { 
            # If the field name contains "Filename" but the entry isn't 
            # "N/A", change entry to a link to the other script around the
            # original text of the entry
            if((/Filename/) && (!($entry[$j] =~ m#^N/A#i)))
              {
		$entry[$j] = "<A HREF=\"$check_url?$entry[$j]\">$entry[$j]</A>";
              }

            # print the entry
            printf("%-20s: %s\n", $_, $entry[$j++]);
          }

        # end this part
        print "</PRE>\n".
              "<HR>\n";
      }

    # save the Member_name for each matched part.
    foreach (@matched_names)
      {
        print "<INPUT TYPE=hidden NAME=\"matched_names\" VALUE=\"$_\">\n";
      }

    # save the directory and master-part name, end the form
    print "<INPUT TYPE=hidden NAME=directory VALUE=$query{'directory'}>\n".
          "<INPUT TYPE=hidden NAME=partname VALUE=$query{'partname'}>\n".
          "<P>\n".
          "<INPUT TYPE=submit>\n".
          "<INPUT TYPE=reset VALUE=\"Reset Defaults\">\n".
          "</FORM>\n";
  }

sub find_parts {
  local (%query) = @_;
  # get the member_name of each of the member parts that matched
  @matches = split(/\n/, $query{'matched_names'});
  # get the numbers of the parts that the user selected
  @selected = split(/\n/, $query{'selected_matches'});
  # get the name of the master part
  $partname = $query{'partname'};
  # get the directory of the master part
  $directory = $query{'directory'};
   
  print "<H2>Final Part Results</H2>\n".
        "<P>\n".
        "If you generate new parts, it will take a few minutes.\n".
        "Please be patient while the parts are being generated.\n".
        "<HR>\n";

  foreach (@selected) {
    $member = $matches[$_ - 1];
    # build the filename of each selected member part
    $filename = "$directory-family/$member";
	
    # make the filename all lowercase
    $filename =~ s/(.*)/\L$1\E/;

    # if the part doesn't exist, create a form to generate it.
    unless(-e $filename) {
      print "<P>\n".
            "Member $member has not been generated.\n";

      print "<FORM METHOD=POST>\n".
            "<INPUT TYPE=hidden NAME=\"function\" VALUE=\"generate\">\n".
            "<INPUT TYPE=hidden NAME=\"partname\" VALUE=\"$partname\">\n".
            "<INPUT TYPE=hidden NAME=\"member\" VALUE=\"$member\">\n".
            "<INPUT TYPE=hidden NAME=\"directory\" VALUE=\"$directory\">\n".
            "<INPUT TYPE=submit VALUE=\"Generate This Part\">\n".
            "</FORM>";
          }
        else
          {
             print "<P>\n".
                   "Member $member has been generated.\n";
          }
        
	# make the member name lowercase for the activate part command
        $member =~ s/(.*)/\L$1\E/;
	
	# give command to activate the part
	print "<P>\nTo activate the part, use the command<BR>\n".
              "<TT>activate part $partname-family.$member</TT>".
              "<HR>";
      }

    # provide a button to start a new search.  Note METHOD=GET is required
    # to get the first stage of the search.
    print "<FORM METHOD=GET>\n".
          "<INPUT TYPE=submit VALUE=\"Start a new search\">\n".
          "</FORM>\n";
  } 

sub generate_parts {
  local (%query) = @_;
  $partname = $query{'partname'};
  $member = $query{'member'};
  $directory = $query{'directory'};

  # print the header
  print "<H2>Generation Results</H2>\n";

  # for browsers that display the page as it is received.
  print "<P>\n".
        "Part generation in progress, do not cancel.\n".
        "<P>\n";

  # networking setup
  chop($hostname = `hostname`);
  ($name, $aliases, $proto) = getprotobyname('tcp');
  ($name, $aliases, $type, $len, $thataddr) = gethostbyname($server);

  $sockaddr = 'S n a4 x8';
  $thatport = pack($sockaddr, &AF_INET, $server_port, $thataddr);

  unless(socket(S, &PF_INET, &SOCK_STREAM, $proto))
    {
      open(MAIL, "|/usr/ucb/mail -s 'Search_Family_Parts error' $maintainer");
      print MAIL "Unable to establish socket from `hostname`.";
      close MAIL;
      &form_die("Generate Error<P>Unable to connect to parts server.");
    }

  unless(connect(S, $thatport))
    {
      open(MAIL, "|/usr/ucb/mail -s 'Search_Family_Parts error' $maintainer");
      print MAIL "Unable to connect to server from `hostname`.";
      close MAIL;
      &form_die("Generate Error<P>Unable to connect to parts server.");
    }

  select(S); $| = 1; select(STDOUT);
  # end networking setup

  # send part information
  print S "$partname $member $directory\n";

  # get result code
  $_ = <S>;

  # determine proper response based on result code
  if($_ == 0)
    {
      # generate succeeded
      print "<P>\n".
            "Member $member was generated successfully.\n";

      # make the member name lowercase for the activate part command
      $member =~ s/(.*)/\L$1\E/;
	
      # give command to activate the part
      print "<P>\n".
            "To activate the part, use the command<BR>\n".
            "<TT>activate part $partname-family.$member</TT>\n".
            "<HR>\n";
    }
  elsif ($_ == 2)
    {
      # part may exist
      print "<P>\n".
            "Unable to generate member $member because the part directory\n".
            "already exists.  The part may already have been generated.\n".
            "<A HREF=\"mailto:$maintainer\">Send mail</A> to $maintainer\n".
            "with the name of the family and member you were trying to\n".
            "generate.  You will be contacted when the problem has been\n".
            "corrected.\n";            
   
      # make the member name lowercase for the activate part command
      $member =~ s/(.*)/\L$1\E/;
	
      # give command to activate the part
      print "<P>\n".
            "You may also try to activate the part using the command<BR>\n".
            "<TT>activate part ${partname}-family.$member</TT>\n".
            "<HR>\n";
    }
  else  
    {
      # generate failed
      print "<P>\n".
            "Member $member failed to generate.\n".
            "<A HREF=\"mailto:$maintainer\">Send mail</A> to $maintainer\n".
            "with the name of the family and member you were trying to\n".
            "generate.  You will be contacted when the problem has been\n".
            "corrected.\n";
    }

  print "<P>\n".
        "To generate other matched parts, press the back button on your\n".
        "browser and select another part.\n";

  # provide a button to start a new search.  Note METHOD=GET is required
  # to get the first stage of the search.  (This is default for a form)
  print "<P>\n".
        "<FORM>\n".
        "<INPUT TYPE=submit VALUE=\"Start a new search\">\n".
        "</FORM>\n";
  }

# used instead of die to exit the program.  Prints the error to the
# page and then ends the page.
sub form_die {
  local ($error) = @_;

  print "<P>\n".
        "$error\n".
        "<P>Last Modified: $last_mod".
        "</BODY>\n".
        "</HTML>\n";

  exit 0;
}

# File: parseform.pl 
# This subroutine takes a url-encoded string and 
# turns it into an associative array. 
sub parseform 
{ 
  local($formthing) = @_; 
   
  # Expects something like: 
  # foo=wow%21&bar=hello&baz=blah 
   
  # Split the string into each of the key-value pairs 
  (@fields) = split('&', $formthing); 
   
  # For each of these key-value pairs, decode the value 
  for $field (@fields) 
    { 
      # Split the key-value pair on the equal sign. 
      ($name, $value) = split('=', $field); 
   
      # Change all plus signs to spaces. This is an 
      # remnant of ISINDEX 
      $value =~ y/\+/ /; 
   
      # Decode the value & removes % escapes. 
      $value =~ s/%([\da-f]{1,2})/pack(C,hex($1))/eig; 
   
      # Create the appropriate entry in the 
      # associative array lookup 
      if(defined $lookup{$name}) 
        { 
          # If there are multiple values, separate 
          # them by newlines 
          $lookup{$name} .= "\n".$value; 
        } 
      else 
        { 
          $lookup{$name} = $value; 
        } 
    }
   
  # Return the associative array 
  %lookup; 
} 

sub init_socket
{
  # to replace sys/socket.ph
  if (!defined &_sys_socket_h){
    eval 'sub _sys_socket_h {1;}';
    eval 'sub SOCK_STREAM {1;}';
    eval 'sub SOCK_DGRAM {2;}';
    eval 'sub SOCK_RAW {3;}';
    eval 'sub SOCK_RDM {4;}';
    eval 'sub SOCK_SEQPACKET {5;}';
    eval 'sub SO_DEBUG {0x0001;}';
    eval 'sub SO_ACCEPTCONN {0x0002;}';
    eval 'sub SO_REUSEADDR {0x0004;}';
    eval 'sub SO_KEEPALIVE {0x0008;}';
    eval 'sub SO_DONTROUTE {0x0010;}';
    eval 'sub SO_BROADCAST {0x0020;}';
    eval 'sub SO_USELOOPBACK {0x0040;}';
    eval 'sub SO_LINGER {0x0080;}';
    eval 'sub SO_OOBINLINE {0x0100;}';
    eval 'sub SO_DONTLINGER {(~ &SO_LINGER);}';
    eval 'sub SO_SNDBUF {0x1001;}';
    eval 'sub SO_RCVBUF {0x1002;}';
    eval 'sub SO_SNDLOWAT {0x1003;}';
    eval 'sub SO_RCVLOWAT {0x1004;}';
    eval 'sub SO_SNDTIMEO {0x1005;}';
    eval 'sub SO_RCVTIMEO {0x1006;}';
    eval 'sub SO_ERROR {0x1007;}';
    eval 'sub SO_TYPE {0x1008;}';
    eval 'sub SOL_SOCKET {0xffff;}';
    eval 'sub AF_UNSPEC {0;}';
    eval 'sub AF_UNIX {1;}';
    eval 'sub AF_INET {2;}';
    eval 'sub AF_IMPLINK {3;}';
    eval 'sub AF_PUP {4;}';
    eval 'sub AF_CHAOS {5;}';
    eval 'sub AF_NS {6;}';
    eval 'sub AF_NBS {7;}';
    eval 'sub AF_ECMA {8;}';
    eval 'sub AF_DATAKIT {9;}';
    eval 'sub AF_CCITT {10;}';
    eval 'sub AF_SNA {11;}';
    eval 'sub AF_DECnet {12;}';
    eval 'sub AF_DLI {13;}';
    eval 'sub AF_LAT {14;}';
    eval 'sub AF_HYLINK {15;}';
    eval 'sub AF_APPLETALK {16;}';
    eval 'sub AF_NIT {17;}';
    eval 'sub AF_802 {18;}';
    eval 'sub AF_OSI {19;}';
    eval 'sub AF_X25 {20;}';
    eval 'sub AF_OSINET {21;}';
    eval 'sub AF_GOSIP {22;}';
    eval 'sub AF_MAX {21;}';
    eval 'sub PF_UNSPEC { &AF_UNSPEC;}';
    eval 'sub PF_UNIX { &AF_UNIX;}';
    eval 'sub PF_INET { &AF_INET;}';
    eval 'sub PF_IMPLINK { &AF_IMPLINK;}';
    eval 'sub PF_PUP { &AF_PUP;}';
    eval 'sub PF_CHAOS { &AF_CHAOS;}';
    eval 'sub PF_NS { &AF_NS;}';
    eval 'sub PF_NBS { &AF_NBS;}';
    eval 'sub PF_ECMA { &AF_ECMA;}';
    eval 'sub PF_DATAKIT { &AF_DATAKIT;}';
    eval 'sub PF_CCITT { &AF_CCITT;}';
    eval 'sub PF_SNA { &AF_SNA;}';
    eval 'sub PF_DECnet { &AF_DECnet;}';
    eval 'sub PF_DLI { &AF_DLI;}';
    eval 'sub PF_LAT { &AF_LAT;}';
    eval 'sub PF_HYLINK { &AF_HYLINK;}';
    eval 'sub PF_APPLETALK { &AF_APPLETALK;}';
    eval 'sub PF_NIT { &AF_NIT;}';
    eval 'sub PF_802 { &AF_802;}';
    eval 'sub PF_OSI { &AF_OSI;}';
    eval 'sub PF_X25 { &AF_X25;}';
    eval 'sub PF_OSINET { &AF_OSINET;}';
    eval 'sub PF_GOSIP { &AF_GOSIP;}';
    eval 'sub PF_MAX { &AF_MAX;}';
    eval 'sub SOMAXCONN {5;}';
    eval 'sub MSG_OOB {0x1;}';
    eval 'sub MSG_PEEK {0x2;}';
    eval 'sub MSG_DONTROUTE {0x4;}';
    eval 'sub MSG_MAXIOVLEN {16;}';
  }
}

Last Modified: Wed Aug 28 14:41:29 EDT 1996

Gregory Marr <gregm@alum.wpi.edu>