1 #!/local/bin/perl 2 ############################################## 3 # generic.cgi # 4 # Started by Steve Sowder on June 7, 2004 # 5 ############################################## 6 7 require "cgi-lib.pl"; 8 &ReadParse(*input); 9 10 print &PrintHeader; 11 12 &loadconfig; 13 &verifyconfig; 14 &makebackup; 15 16 17 ## Global Field Names 18 # $KEYLENGTH - length of the numeic primary key 19 # $DATABASE - The filename of the database (no path info) 20 # $HOMEBASE - the name of this program with absolute path name 21 # $SYSTEMSIP - IP address of the systems user 22 # $SYSTEMSUSER- equal "Y" if true 23 # $USERIP - Ip address of the library user 24 # @FIELDS - Names of the fields in the database 25 # @DISPLAY - Nmaes to use for displaying the field names of the database 26 # @SECURITY - Security level for each field 27 # @DATATYPE - Datatype for each field 28 # 29 30 31 &verifysecurity; 32 33 34 $action = $input{'action'}; 35 $field_count = @FIELDS; 36 $col_span = $field_count + 1; 37 $search_field = $input{'search_field'}; 38 $search_for = $input{'search_for'}; 39 @keys = $input{'key'}; 40 $key_matches = @keys; 41 42 43 if($action =~ /add record/i){ 44 # Add the record passed from the add record page 45 # $key = $keys[0]; 46 #print "
add record routine\n"; 47 &add_record; 48 $message="Record Added"; 49 &print_message($message); 50 } 51 elsif($action =~ /add/i){ 52 # Display the add record page 53 &print_add_screen; 54 } 55 56 57 elsif($action =~ /search/i) 58 { 59 # Search database and display the results 60 &search_database($search_for); 61 $count = @results; 62 if($count > 0) 63 { 64 $button_text = "Back to Database"; 65 $caption = "Search Results"; 66 &multiple_match; 67 } 68 else {&no_match; } 69 } 70 71 elsif($action =~ /modify record/i) 72 { 73 # Display the results of the search 74 75 &search_database($input{'key'}); 76 $count = @results; 77 &no_match if($count < 1); 78 &print_modify_page; 79 } 80 81 elsif($action =~ /modify this record/i) 82 { 83 # Modify the record that was passed 84 $key=$keys[0]; 85 &add_record; 86 $message="Record Modified"; 87 &print_message($message); 88 } 89 90 elsif($action =~ /modify/i) 91 { 92 # Search and display results for modification 93 &search_database($search_for); 94 $count = @results; 95 if($count < 1) {&no_match } 96 elsif($count == 1) {&print_modify_page } 97 else 98 { 99 $caption="Modify Which Record?"; 100 $button_text="Modify Record"; 101 &multiple_match("RADIO","modify"); 102 } 103 } 104 105 106 elsif($action =~ /delete record/i){ 107 # Delete the record(s) that were passed 108 $key = $keys[0]; 109 &delete_records; 110 $message="Record(s) Deleted"; 111 &print_message($message); 112 } 113 elsif($action =~ /delete/i){ 114 # Search and display results for modification 115 &search_database($search_for); 116 $count = @results; 117 &no_match if($count < 1); 118 $caption="Delete Which Record(s)?"; 119 $button_text="Delete Record(s)"; 120 &multiple_match("CHECKBOX","delete"); 121 122 } 123 elsif($action =~ /update/i){ 124 # update file 125 &update_database; 126 $message='File Updated'; 127 &print_message($message); 128 129 } 130 elsif($action =~ /publish/i){ 131 # update file 132 &update_database; 133 &publish; 134 $message='File Updated and Published'; 135 &print_message($message); 136 137 138 } 139 140 141 else {&print_default} 142 143 ########################################### 144 sub add_record { 145 $key = $input{'key'}; # key 0 146 147 if (length($key) != $KEYLENGTH) 148 { &get_highest_key; $key = $nextkey; } 149 $record = $key; 150 151 $timestamp = time(); # key 1 152 $record .= "\^$timestamp"; 153 154 for ($x = 2; $x <= $field_count; $x++) # remaining keys 155 { 156 $field = $input{"$FIELDS[$x]"}; 157 $field = filter($field); 158 if ($DATACASE[$x] =~ /U/i) {$field = uc $field } 159 $record .= "\^$field"; 160 } 161 162 open (DB, ">>$DATABASE") || die "Error opening database for add. $!\n"; 163 164 flock DB, $EXCLUSIVE; 165 # seek DB, 0, 2; 166 print DB "$record\n"; 167 flock DB, $UNLOCK; 168 close(DB); 169 170 } # End of add_record subroutine. 171 ########################################### 172 sub print_add_screen{ 173 print<Add a Record 175 176
177 Add a Record 178
179

180

183 184 185
186 HTML 187 188 $x=0; 189 foreach $field (@FIELDS) 190 { 191 print< 193 HTML 194 if ($SYSTEMSUSER =~ /Y/ and $SECURITY[$x] =~ /S/) {$SECURITY[$x] = 'O'} 195 if ($SYSTEMSUSER !~ /Y/ and $SECURITY[$x] =~ /S/) {$SECURITY[$x] = 'D'} 196 197 if ($SECURITY[$x] =~ /D/i) # display - display only no changes 198 { 199 print <$fs\u$DISPLAY[$x]:$fc 201 202 203 DISPLAY 204 } 205 206 if ($SECURITY[$x] =~ /O/i) # open - display and allow changes 207 { 208 if ($DATATYPE[$x] =~ /T/i) 209 { 210 print <$fs\u$DISPLAY[$x]:$fc 212 213 214 OPENTEXT 215 } # end type T 216 else 217 { 218 print < 220 223 OPENAREA 224 } # end else not type T (eg type A) 225 } 226 227 228 ##--------- 229 # if ($x < 8) 230 # { 231 # print ""; 232 # if ($x <= 1) {print ''; } 233 # else 234 # { 235 # print < 238 # 239 #HTML2 240 # } 241 # } 242 # elsif ($x == 8) 243 # { 244 # print < 246 # 249 #DESCR 250 251 252 # } 253 # else 254 # { 255 # print ""; 256 # } 257 # print ''; 258 259 $x++; 260 } # End of foreach. 261 print< 263 268 269
$field_vals[$x]
$fs\u$DISPLAY[$x]:$fc 222 $fs\u$field:$fc
$fs\u$field:$fc 248 #
264
265 266
267
270

271 272 273 HTML 274 } # End of print_add_screen subroutine. 275 276 277 ########################################### 278 sub get_highest_key 279 { 280 open (DB, "$DATABASE") || die "Error opening database for get_key $!\n"; 281 282 flock DB, $EXCLUSIVE; 283 # seek DB, 0, 2; 284 $nextkey = ' '; 285 $didthis = 'yes'; 286 while ($getkey = ) 287 { 288 $thiskey = substr($getkey,0,$KEYLENGTH); 289 if ($thiskey gt $nextkey and $thiskey lt '9900') {$nextkey = $thiskey;} 290 } 291 flock DB, $UNLOCK; 292 close(DB); 293 $nextkey = $nextkey + 1; 294 while (length($nextkey) < $KEYLENGTH) {$nextkey = '0' . $nextkey; } 295 296 } # end of get_highest_key 297 298 ########################################### 299 sub delete_records 300 { 301 # $record = $key; 302 $record = $input{'key'}; 303 $record = substr($record,0,$KEYLENGTH); # get only number part of key 304 $timestamp = time(); 305 $record .= "\^$timestamp"; 306 307 $record .= "\^**KILLED**"; # in name field 308 309 for ($x = 4; $x < $field_count; $x++) {$record .= "\^"; } 310 311 open (DB, ">>$DATABASE") || die "Error opening database for del. $!\n"; 312 313 flock DB, $EXCLUSIVE; 314 print DB "$record\n"; 315 flock DB, $UNLOCK; 316 close(DB); 317 318 } # End of delete subroutine. 319 320 321 ########################################### 322 sub filter{ 323 my $temp = $_[0]; 324 $temp =~ s/\^//; # Remove pipe symbols in text. 325 $temp =~ s/\r//; # Remove carriage return in text. 326 $temp =~ s/\s+$//; # remove trailing blanks 327 328 return ($temp); 329 } 330 331 332 333 ########################################### 334 sub print_modify_page{ 335 336 (@field_vals) = split(/\^/, $results[0]); 337 $key = $field_vals[0]; 338 $fs=""; 339 $fc=""; 340 341 print<

343 Modify Record 344 345 346 347
348 Modify Record 349
350
351 352
353 354 HTML 355 356 $x=0; 357 foreach $field (@FIELDS) 358 { 359 print< 361 HTML 362 if ($SYSTEMSUSER =~ /Y/ and $SECURITY[$x] =~ /S/) {$SECURITY[$x] = 'O'} 363 if ($SYSTEMSUSER !~ /Y/ and $SECURITY[$x] =~ /S/) {$SECURITY[$x] = 'D'} 364 365 if ($SECURITY[$x] =~ /D/i) # display - display only no changes 366 { 367 print <$fs\u$DISPLAY[$x]:$fc 369 370 371 DISPLAY 372 } 373 374 if ($SECURITY[$x] =~ /O/i) # open - display and allow changes 375 { 376 if ($DATATYPE[$x] =~ /T/i) 377 { 378 print <$fs\u$DISPLAY[$x]:$fc 380 381 382 OPENTEXT 383 } # end type T 384 else 385 { 386 print < 388 391 OPENAREA 392 } # end else not type T (eg type A) 393 } 394 395 # elsif ($x == 8) 396 # { 397 # print < 399 # 402 #DESCR 403 404 $data =~ s/\s+//; 405 $num = substr($data,1,4); 406 407 $DES[$num] = $data; 408 409 410 # } 411 $x++; 412 } # End of foreach. 413 414 415 print< 417 422 423
$field_vals[$x]
$fs\u$DISPLAY[$x]:$fc 390 $fs\u$field:$fc 401 # 418
419 420
421
424
425


426 427 HTML 428 } 429 430 431 432 433 ########################################### 434 sub search_database 435 { 436 $search_for = $_[0]; 437 open(DB, $DATABASE) or die "Error opening file: $!\n"; 438 while() 439 { 440 if (length($search_for) == $KEYLENGTH+10) # search_for has number & timestamp 441 { 442 $search_for = substr($_[0],0,$KEYLENGTH) . "\^" . substr($_[0],$KEYLENGTH); 443 $search_field = 'all'; 444 } 445 if($search_field =~ /all/i) 446 { 447 if (length($search_for) != $KEYLENGTH+11) 448 {if(/$search_for/oi){push @results, $_}; } 449 if (length($search_for) == $KEYLENGTH+11) 450 { 451 $temp = substr($_,0,$KEYLENGTH+11); 452 if ($temp eq $search_for) {push @results, $_ ;} 453 } 454 } 455 else 456 { 457 (@field_vals) = split(/\^/, $_); # delimiter changed Sowder 458 if($field_vals[$search_field] =~ /$search_for/oi){push @results, $_}; 459 } # End of else. 460 } # End of while. 461 close (DB); 462 } # End of search_database subroutine. 463 464 ########################################### 465 sub multiple_match{ 466 print "
\n"; 467 print "'Match Results'\n"; 468 print "\n"; 469 print< 471
$caption
472 473 474
There were $count matches
475
476 477
478

479

480 481 HTML 482 483 if($_[1] =~ /(modify|delete)/) # and not search 484 { 485 print "\n"; 487 } 488 489 foreach $field (@FIELDS) # print field titles 490 { 491 print "\n"; 493 } # End of foreach 494 495 print ""; 496 497 foreach $record (@results) # print field contents 498 { 499 (@field_vals) = split(/\^/, $record); 500 501 print ""; 502 503 if($_[1] =~ /(modify|delete)/) # and not search 504 { 505 print "\n"; 508 } # End of if. 509 510 for($x=0;$x<$field_count;$x++) # display each field contents 511 { 512 $item = &check_empty($field_vals[$x]); 513 print "\n"; 514 } 515 print ""; 516 } # End of foreach loop. 517 518 print< 520 523 524
"; 486 print "Select"; 492 print "\u$field
"; 506 print ""; 507 print "$item
521 522
525 526 HTML 527 } # End of multiple_match subroutine. 528 529 530 ########################################### 531 sub no_match{ 532 print <
534 No Match 535 536

There was no match for $search_for 537 please hit back and try again.

538 539 HTML 540 exit; 541 } # End of no_match subroutine. 542 543 ########################################### 544 sub print_message { 545 print< 547
$_[0]

548

549

550 Back To 552 Main Database Screen 553
554 555 HTML 556 } 557 558 ########################################### 559 sub check_empty{ 560 $r_val = $_[0]; 561 if($r_val =~ /^\s*$/){$r_val=" "} 562 563 return($r_val); 564 } 565 566 ################################################# 567 sub update_database { 568 569 ## sort the database file to update database 570 571 my $backupfile = $DATABASE . '.scr'; 572 573 print "UPDATING THE DATABASE...\n"; 574 open INFILE, "$DATABASE" or die "no joy in\n"; 575 open OUTFILE, ">$backupfile" or die "no joy out\n"; 576 577 print OUTFILE sort (); 578 579 close INFILE; 580 close OUTFILE; 581 582 open (INFILE, "$backupfile") or die "no joy in\n"; 583 open (OUTFILE, ">$DATABASE") or die "no joy out\n"; 584 my $lastrecord = ''; 585 586 while ($line = ) 587 { 588 chomp($line); 589 590 if (length($lastrecord) > 0 591 and substr($line,0,$KEYLENGTH) ne substr($lastrecord,0,$KEYLENGTH)) 592 { 593 if (index($lastrecord,'**KILLED**') < 0) 594 {print OUTFILE "$lastrecord\n"; } 595 } 596 $lastrecord = $line; 597 } 598 599 my $x; 600 my $keyt; 601 602 for ($x = 1; $x <= $KEYLENGTH; $x++) {$keyt = $keyt . '9'} 603 604 print OUTFILE "$keyt\^999999999\^999\^\^\^\^\^\^\n"; 605 606 close INFILE; 607 close OUTFILE; 608 609 } # end of update_database 610 611 612 ########################## 613 sub print_default { 614 print < 616 $DATANAME SCREEN 617 618
619
620 $DATANAME SCREEN 621

622 623

624 625 626 634 635 636 637 638 639 644 645 656 657
627
628 To add a record, click on the Add button. 629 To search/modify/delete records, enter the text in 630 the box below and choose the field to search on. Then 631 click to appropriate button. 632
633
Search For:
Search On: 640 All 641 Number 642 Name 643
646
647 648 649 650 651 652 653 654
655
658 HTML 659 660 } 661 ############################# 662 sub publish { 663 664 &staff directory; 665 &phonedirectory; 666 &emaildirectory; 667 668 669 # FLASH USER 670 print < 672

Publish Routine Completed

673
674
675 676 HTML 677 678 679 680 } # end publish 681 682 ############################# 683 sub staffdirectory { 684 my @temp; 685 686 open INFILE, "$DATABASE"; 687 688 while ($line = ) 689 { 690 chomp $line; 691 @f = split /\^/, $line; 692 693 if ($f[11] !~ /Y/i and $f[0] ne '999') {push @temp, "$f[2]^$line" } 694 695 } 696 close INFILE; 697 @temp = sort @temp; 698 open OUTFILE, '>newstaff.html'; 699 700 &printtemplate; 701 702 #---- 703 # 704 # 705 #

706 # 707 # 708 # 709 # Sallie Alger 710 # 711 # 712 #

713 # 714 # 715 # 716 # 717 # Head 719 # of Bibliographic Services
720 # Assistant Professor of Library Science
721 # M.L.S., Indiana University
722 # M.S.A., Andrews University
723 # Room 252, Main Floor, James White Library
724 # Phone: (269) 471-6215
725 # 726 # Email: salger@andrews.edu
727 # Interests: Reading, Travel, Aerobics, Music, Grandbaby
728 #

730 # 731 # 732 #---- 733 734 foreach $line (@temp) 735 { 736 @f = split /\^/, $line; 737 # $phone =~ s!\(269\) 471-!!g; 738 ($last,$first) = split /\,/, $f[3]; 739 $last =~ s/\s+$//; 740 $first =~ s/^\s+//; 741 $first =~ s/^\s+$//; 742 $anchor = lc ($last . substr($first,0,1)); 743 print OUTFILE <$first $last 745 $f[4] 746
$f[5] 747
$f[6] 748 749 DATALINE 750 } 751 752 &gettime; 753 print OUTFILE <

Updated $MONTH/$DAY/$YEAR 755 756 HTML 757 758 close OUTFILE; 759 760 761 762 } # end staffdirectory 763 764 ############################# 765 sub printtemplate { 766 767 print OUTFILE < 769 770 Staff Directory, James White Library 771 772 773 774 775 776 777 780 781 784 785 786 787 837 838 839
JWL homepage. Andrews University homepage.
788 James White Library Information Gateway.About JWL. 793 MyLibrary
796
797 798 799 805 810 818 824 ="49"> 830 833 834 835
800 803 804 806 809 811 816 817 819 823 825 828 829
836
840 841 842 843 850 851 TEMPLATE 852 } # end printtemplate 853 854 ############################# 855 # make telephone directory 856 # 857 sub phonedirectory { 858 859 my @temp; 860 861 open INFILE, "$DATABASE"; 862 863 while ($line = ) 864 { 865 chomp $line; 866 @f = split /\^/, $line; 867 868 if ($f[0] ne '999') {push @temp, "$f[2]^$f[6]";} 869 870 } 871 close INFILE; 872 @temp = sort @temp; 873 open OUTFILE, '>phone.html'; 874 875 print OUTFILE <James White Library Telephone Directory 877 878

Library Phone Directory

879
844
845 846 Staff Directory 847 848
849
880 HTML 881 882 foreach $line (@temp) 883 { 884 ($name,$phone) = split /\^/, $line; 885 $phone =~ s!\(269\) 471-!!g; 886 887 print OUTFILE < 889 DATALINE 890 } 891 892 &gettime; 893 print OUTFILE <

Updated $MONTH/$DAY/$YEAR 895 896 HTML 897 898 close OUTFILE; 899 900 } # end phonedirectory 901 902 ############################# 903 sub emaildirectory { 904 905 my @temp; 906 907 open INFILE, "$DATABASE"; 908 909 while ($line = ) 910 { 911 chomp $line; 912 @f = split /\^/, $line; 913 914 if ($f[11] !~ /Y/i and $f[0] ne '999') {push @temp, "$f[2]^$f[6]^$f[7]";} 915 916 } 917 close INFILE; 918 @temp = sort @temp; 919 open OUTFILE, '>emails.html'; 920 921 print OUTFILE <James White Library Email Directory 923 924

Library Email Directory

925
$namex$phone
926 HTML 927 928 929 foreach $line (@temp) 930 { 931 ($name,$phone,$email) = split /\^/, $line; 932 $phone =~ s!\(269\) 471-!!g; 933 934 print OUTFILE < 936 DATALINE 937 } 938 939 &gettime; 940 print OUTFILE <

Updated $MONTH/$DAY/$YEAR 942 943 HTML 944 945 close OUTFILE; 946 947 948 } # end emaildirectory 949 950 951 ############################# 952 # make backup if necessary 953 sub makebackup { 954 955 ($DAY, $MONTH, $YEAR) = (localtime)[3,4,5]; 956 957 #print "finis local time1\n"; 958 959 $M=$MONTH; #bidwell fix 960 961 $MONTH++; 962 $YEAR = $YEAR + 1900; 963 964 if (length($MONTH) < 2) {$MONTH = '0' . $MONTH} 965 if (length($DAY) < 2) {$DAY = '0' . $DAY} 966 967 $backupfile = "$DATABASE." . $YEAR . $MONTH . $DAY; 968 969 open BACKUPFILE, "$backupfile"; 970 $getit = ; 971 close BACKUPFILE; 972 973 chomp $getit; 974 975 if ($backupfile =~ /(.+)/) {$backupfile = $1; } # to untaint file name 976 977 978 if (length($getit) == 0) 979 { 980 open INFILE, "$DATABASE"; 981 open BACKUP, ">$backupfile"; 982 while ($line = ) {print BACKUP "$line"} 983 close INFILE; 984 close BACKUP; 985 # system "cp sailtitles.dat $backupfile"; # even untainted this doesn't work 986 } 987 988 989 } # end make back up 990 ################################# 991 sub gettime { 992 993 ($DAY, $MONTH, $YEAR) = (localtime)[3,4,5]; 994 995 #print "finis local time1\n"; 996 997 $M=$MONTH; #bidwell fix 998 999 $MONTH++; 1000 $YEAR = $YEAR + 1900; 1001 1002 if (length($MONTH) < 2) {$MONTH = '0' . $MONTH} 1003 if (length($DAY) < 2) {$DAY = '0' . $DAY} 1004 1005 1006 } 1007 1008 ######################################################## 1009 # badkarma 1010 sub badkarma { 1011 1012 print < 1014

1015

Sorry 1016
According to our files 1017
you are not allowed to run 1018
this screen 1019

If you believe this is in error 1020
please contact the 1021
system librarian 1022

1023
1024 $ra 1025 1026 KILLME 1027 } # end of badkarma (we hope!) 1028 1029 1030 1031 ########################## 1032 sub loadconfig { 1033 1034 while (my $data = ) 1035 { 1036 if ($data !~ /^\#/) 1037 { 1038 chomp $data; 1039 #print "
lc: $data\n"; 1040 if ($data =~ /dataname/i) {$DATANAME = substr($data,9) } 1041 if ($data =~ /homebase/i) {&splitonblank ($data, $HOMEBASE) } 1042 if ($data =~ /database/i) {&splitonblank ($data, $DATABASE) } 1043 if ($data =~ /keylength/i) {&splitonblank ($data, $KEYLENGTH) } 1044 if ($data =~ /systemsip/i) {&splitonblank ($data, $SYSTEMSIP) } 1045 if ($data =~ /userip/i) {&splitonblank ($data, $USERIP) } # multiple users? 1046 if ($data =~ /layout/i) 1047 { 1048 while ($data !~ /endlayout/i) 1049 { 1050 $data = ; 1051 chomp $data; 1052 #print "
lc: $data\n"; 1053 1054 my @f = split /\^/, $data; 1055 1056 push @FIELDS, $f[1]; 1057 push @DISPLAY, $f[2]; 1058 push @SECURITY, $f[3]; 1059 push @DATATYPE, $f[4]; 1060 push @DATACASE, $f[5]; 1061 1062 # $FIELDS[$f[0]] = $f[1]; 1063 # $DISPLAY[$f[0]] = $f[2]; 1064 # $SECURITY[$f[0]] = $f[3]; # O - open; D - no changes; S- open to systems only 1065 } 1066 } 1067 } 1068 } 1069 1070 } 1071 ################ 1072 sub verifyconfig { 1073 1074 my $knt = 0; 1075 if (length($HOMEBASE) < 1) {print "no homebase\n"; $knt++ } 1076 if (length($KEYLENGTH) < 1) {print "keylength zero\n"; $knt++ } 1077 if (length($DATABASE) < 1) {print "no databased named\n"; $knt++ } 1078 if (length($SECURITY[1]) < 1) {print "no security fields\n"; $knt++} 1079 my $dknt = @FIELDS; 1080 if ($dknt < 3) {print "no data layout\n"; $knt++} 1081 1082 if ($knt > 0) {die} 1083 1084 } 1085 ################ 1086 sub splitonblank { 1087 1088 $_[0] =~ tr/ / /s; # remove multiple blanks 1089 1090 my @f = split /\s/, $_[0]; 1091 @_[1] = $f[1]; 1092 1093 #print "dbsub: $_[0]<->$_[1]\n"; 1094 1095 return 0; 1096 1097 } 1098 ######################### 1099 sub verifysecurity { 1100 $ra = $ENV{'REMOTE_ADDR'}; 1101 1102 $host=$ENV{'REMOTE_ADDR'}; 1103 if ($ENV{'HTTP_X_FORWARDED_FOR'} ne ""){ 1104 (@list)=split(/,/,$ENV{'HTTP_X_FORWARDED_FOR'}); 1105 $host = @list[$#list]; 1106 $ra=@list[0]; 1107 } 1108 1109 my $badkarma = 'bad news'; 1110 1111 $SYSTEMSUSER = 'N'; 1112 if ($ra eq $SYSTEMSIP) {$badkarma = 'good'; $SYSTEMSUSER = 'Y' } 1113 if ($ra eq $USERIP) {$badkarma = 'good'; } 1114 1115 ### TYPE OF ACCESS <<<<<<<<<<<<<<<<<<<<<<^^^^^ 1138 layout: 1139 0^number^Number^D^T^ 1140 1^date^Date^D^T^ 1141 2^name^Name^O^T^ 1142 3^title^Title^O^T^ 1143 4^rank^Rank^O^T^ 1144 5^room^Room^O^T^ 1145 6^phone^Phone^O^T^ 1146 7^email^Email^O^T^ 1147 8^home^HomePage^O^T^ 1148 9^interest^Interests^O^T^ 1149 10^pic^Photo^O^T^ 1150 11^phonedir^Phone Dir Only?^O^T 1151 endlayout 1152 __END__ 1153
$name$phone$email