home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 May / W2KPRK.iso / apps / MigrationWizard / IISv5MigrationUtility-ApacheSource.TAR / source.pl
Perl Script  |  1999-04-12  |  99KB  |  3,446 lines

  1. #!/usr/bin/perl
  2.  
  3. # -------------------------------------------------------------
  4. # Microsoft IIS v.5 Migration Utility (Apache source component)
  5. # Copyright (c) 1999. All rights reserved.
  6. # -------------------------------------------------------------
  7. package topmain;
  8.  
  9.  
  10. # Configuration constants
  11.  
  12. # When true, script will cleanup after itself
  13. $myCleanup = 0;
  14.  
  15. # The name of this web server
  16. $myServerName = $ENV{'SERVER_NAME'};
  17.  
  18. # Figure out the script directory
  19. $myScriptDir = $0;
  20. $myScriptDir =~ s/Source.PL$//i;
  21.  
  22. # Temp directory
  23. $myTempDir = $myScriptDir;
  24.  
  25. # Log file location
  26. $myLogFilepath = $myScriptDir . 'iismu.log';
  27.  
  28. # Logging types
  29. $myLogNOTICE = 1;               # Used with LogMessage SUB, for logging general info
  30. $myLogWARNING = 2;              # Used with LogMessage SUB, for important warnings
  31. $myLogERROR = 3;                # Used with LogMessage SUB, for fatal stop
  32. $myLogCONONLY = 4;              # Used with LogMessage SUB, for output to console only
  33.  
  34. # Commands for iismu.data file
  35. $myCmdIISCOMPUTER =      'IISCOMPUTER      ';               # Command for creating new IIsComputer object
  36. $myCmdIISWEBSERVICE =    'IISWEBSERVICE    ';               # Command for creating new IIsWebService object
  37. $myCmdIISWEBINFO =       'IISWEBINFO       ';               # Command for creating new IIsWebInfo object
  38. $myCmdIISFILTERS =       'IISFILTERS       ';               # Command for creating new IIsFilters object
  39. $myCmdIISFILTER =        'IISFILTER        ';               # Command for creating new IIsFilter object
  40. $myCmdIISWEBSERVER =     'IISWEBSERVER     ';               # Command for creating new IIsWebServer object
  41. $myCmdIISCERTMAPPER =    'IISCERTMAPPER    ';               # Command for creating new IIsCertMapper object
  42. $myCmdIISWEBVIRTUALDIR = 'IISWEBVIRTUALDIR ';               # Command for creating new IIsWebVirtualDir object
  43. $myCmdIISWEBDIRECTORY =  'IISWEBDIRECTORY  ';               # Command for creating new IIsWebDirectory object
  44. $myCmdIISWEBFILE =       'IISWEBFILE       ';               # Command for creating new IIsWebFile object
  45. $myCmdPROPERTY =         'PROPERTY         ';               # Command for setting
  46.  
  47. # Command/operand separator
  48. $myCmdSep = chr(127);
  49.  
  50.  
  51. # Config files
  52. $myHttpdConf = 'httpd.conf';
  53. $mySrmConf = 'srm.conf';
  54.  
  55. # Output files
  56. $myIismuData = 'iismu.data';
  57. $myIismuFiles = 'iismu.files';
  58.  
  59. # Migration flag bitmasks
  60. $myMIGRATE_CONTENT = 0x1;       # Migrating content for the vserver
  61. $myMIGRATE_SETTINGS = 0x2;      # Migrate settings for the vserver
  62. $myMIGRATE_MIME = 0x4;          # Migrate MIME for the vserver
  63.  
  64.  
  65. # Array of server migration settings
  66. %myServerSettings = null;
  67.  
  68. # Location of /iismu doc directory
  69. $myDocDir = '';
  70.  
  71.  
  72. # Get parameters
  73.  
  74. $theForm = $ENV{'QUERY_STRING'};
  75.  
  76. if('POST' eq $ENV{'REQUEST_METHOD'})
  77. {
  78.   $theForm = $theForm . '&' . <STDIN>;
  79. }
  80.  
  81. @theFormPairs = split('&', $theForm);
  82.  
  83. for($i = 0; $i < scalar(@theFormPairs); $i++)
  84. {
  85.   ($theFieldName, $theFieldValue) = split('=', $theFormPairs[$i]);
  86.   $myForm{$theFieldName} = urlDecode($theFieldValue);
  87. }
  88.  
  89. # Get misc. form variables
  90. $myBackURL = $myForm{'backurl'};
  91.  
  92.  
  93.  
  94. # Verify password
  95.  
  96. if(! checkPassword($myForm{'password'}))
  97. {
  98.   print STDOUT "Content-type: text/html\n\n";
  99.   print STDOUT 'ERROR';
  100.   exit(0);
  101. }
  102.  
  103.  
  104.  
  105. # Handle page modes
  106.  
  107. $myMode =$myForm{'mode'};
  108.  
  109. if('getservers' eq $myMode)
  110. {
  111.   handleGetServers($myForm{'rootdir'}, $myForm{'configdirs'});
  112. }
  113. elsif('migrate' eq $myMode)
  114. {
  115.   handleMigrate($myForm{'rootdir'}, $myForm{'configdirs'}, $myForm{'servers'});
  116. }
  117. elsif(('getfile' eq $myMode) || ('getindexfile' eq $myMode))
  118. {
  119.   if('getfile' eq $myMode)
  120.   {
  121.     $theFile = $myForm{'file'};
  122.   }
  123.   else
  124.   {
  125.     $theFile = $myTempDir . 'iismu.files';
  126.   }
  127.   
  128.   if(-e $theFile)
  129.   {
  130.     if(open(THEFILE, $theFile))
  131.     {
  132.       print STDOUT "Content-type: application/octet-stream\n\n";
  133.  
  134.       binmode(THEFILE);
  135.       binmode(STDOUT);
  136.  
  137.       while(<THEFILE>)
  138.       {
  139.         print STDOUT $_;
  140.       }
  141.       
  142.       close(THEFILE);
  143.     }    
  144.   }
  145.  
  146.   exit(0);
  147. }
  148. else
  149. {
  150.   print STDOUT "Content-type: text/html\n\n";
  151.   print STDOUT "OK,TYPE=APACHE,CABBING=FALSE\n";
  152. }
  153.  
  154.  
  155.  
  156. # Begin supporting functions
  157.  
  158. sub dbgOut {
  159.     print( "<!--@_-->\n" ) ;
  160. }
  161.  
  162. # --------------------------------------------------------------------------------
  163. # Procedure to convert base 36 "meganum" string to base 10 integer
  164. #
  165. sub base36to10
  166. {
  167.   my $inMegaNum = ucase(trim($_[0]));
  168.   my $theValue = 0;
  169.   my $thePower = 0;
  170.   my $theDigitASC;
  171.   my $theDigitVal;
  172.  
  173.   for(my $i = length($inMegaNum) - 1; $i >= 0; $i--)
  174.   {
  175.     $theDigitASC = ord(substr($inMegaNum, $i, 1));
  176.   
  177.     if($theDigitASC >= 65)
  178.     {
  179.       # A=10, A=ASCII65, 65-55=10
  180.       $theDigitVal = $theDigitASC - 55;
  181.     }
  182.     else
  183.     {
  184.       # 0=ASCII48, 48-48=0
  185.       $theDigitVal = $theDigitASC - 48;
  186.     }
  187.   
  188.      $theValue += ($theDigitVal * (36**$thePower));
  189.      $thePower++;
  190.   }
  191.     
  192.   return $theValue;
  193. }
  194. # --------------------------------------------------------------------------------
  195.  
  196.  
  197. # --------------------------------------------------------------------------------
  198. # Procedure to check for execution password and return true if correct
  199. #
  200. sub checkPassword
  201. {  
  202.   my $inPassword = $_[0];
  203.  
  204.   if(open(THEFILE, $myScriptDir . "password.txt"))
  205.   {
  206.     my $theLine;
  207.     my $thePassword = '';
  208.     
  209.     while(<THEFILE>)
  210.     {
  211.       $theLine = $_;
  212.  
  213.       # Skip blank and comment lines
  214.       next if /^\s*$/;
  215.       next if /^;/;
  216.  
  217.       if($theLine =~ /^password=/i)
  218.       {
  219.         $theLine =~ s/password=//i;
  220.         $thePassword = trim($theLine);
  221.         last;
  222.       }
  223.     }
  224.   
  225.     close(THEFILE);    
  226.     return ($inPassword eq $thePassword);
  227.   }
  228.   else
  229.   {
  230.     return 1;
  231.   }
  232. }
  233. # --------------------------------------------------------------------------------
  234.  
  235.  
  236. # --------------------------------------------------------------------------------
  237. # Procedure to return directive value
  238. #
  239. sub getDirectiveValue
  240. {
  241.   my $inString = $_[0];
  242.   my $theIndex = index($inString, ' ');
  243.  
  244.   if($theIndex < 0)
  245.   {
  246.     return '';
  247.   }
  248.   else
  249.   {
  250.     return substr($inString, $theIndex + 1);
  251.   }
  252. }
  253. # --------------------------------------------------------------------------------
  254.  
  255.  
  256. # --------------------------------------------------------------------------------
  257. # Procedure to return array of server migration settings
  258. #
  259. sub getServerArray
  260. {
  261.   my $inServerStr = $_[0];
  262.  
  263.   my @theServers = split(',', $inServerStr);
  264.   my %theReturnVal = null;
  265.   my $theTempStr;
  266.   my $theServerNo;
  267.   my $theFlags;
  268.   my $theSettings;
  269.   my $theContent;
  270.   my $theMime;
  271.  
  272.   for(my $i = 0; $i < scalar(@theServers); $i++)
  273.   {
  274.    $theTempStr = $theServers[$i];
  275.    $theServerNo = base36to10(substr($theTempStr, 0, index($theTempStr, "=")));
  276.    $theFlags = base36to10(substr($theTempStr, index($theTempStr, "=") + 1));
  277.  
  278.    $theSettings = isSet($theFlags, $myMIGRATE_SETTINGS);
  279.    $theContent = isSet($theFlags, $myMIGRATE_CONTENT);
  280.    $theMime = isSet($theFlags, $myMIGRATE_MIME);
  281.    
  282.    $theReturnVal{$theServerNo} = "s=$theSettings,c=$theContent,m=$theMime";
  283.   }
  284.  
  285.   return %theReturnVal;
  286. }
  287. # --------------------------------------------------------------------------------
  288.  
  289.  
  290. # --------------------------------------------------------------------------------
  291. # Procedure to handle 'getservers' page mode
  292. #
  293. sub handleGetServers
  294. {
  295.   my $inRootDir = $_[0];
  296.   my $inConfigDirs = $_[1];
  297.  
  298.   print STDOUT "Content-type: text/html\n\n";
  299.  
  300.   $webconf = IISMuConf->new(
  301.     'tempdir'        => $myScriptDir,
  302.     'fileglob'       => $inConfigDirs,
  303.     'fileout'        => '',
  304.     'iiswwwroot'     => '',
  305.     'ldifdomain'     => '',
  306.     'perlmod'        => '',
  307.     'serverobj'      => '',
  308.     'userdbfullpath' => '/etc/',
  309.     'userobj'        => '',
  310.     'version'        => '',
  311.     'webserver'      => '',
  312.     'whoami'         => '',
  313.     'wwwroot'        => $inRootDir,
  314.     'wwwcgishl'      => '',
  315.     'wwwsupp'        => '',
  316.     'remote'         => 1,
  317.     'userglob'       => '/home/*'
  318.   );
  319.  
  320.   unless(defined($webconf))
  321.   {
  322.     print("Could not load configuration.<BR>\n") ;
  323.     exit(0);
  324.   }
  325.  
  326.   $computer = IISComputer->new( 'webconf' => $webconf ) ;
  327.  
  328.   # Write output.
  329.   if(defined($computer))
  330.   {
  331.     $computer->writeServers();
  332.   }
  333. }
  334. # --------------------------------------------------------------------------------
  335.  
  336.  
  337. # --------------------------------------------------------------------------------
  338. # Procedure to handle 'migrate' page mode
  339. #
  340. sub handleMigrate
  341. {
  342.   my $inRootDir = $_[0];
  343.   my $inConfigDirs = $_[1];
  344.   
  345.   %myServerSettings = getServerArray($_[2]);
  346.  
  347.   print STDOUT "Content-type: text/html\n\n";
  348.   printHeader();
  349.  
  350.   system("rm $myLogFilepath");
  351.   system("rm $myScriptDir" . "iismu.dirs");
  352.   system("rm $myTempDir" . "iismu.data");
  353.   system("rm $myTempDir" . "iismu.files");
  354.   
  355.   logMessage($myLogNOTICE, 'Starting migration...');
  356.   #$IISCore::debug = 1;
  357.  
  358.   $webconf = IISMuConf->new(
  359.     'tempdir'        => $myScriptDir,
  360.     'fileglob'       => $inConfigDirs,
  361.     'fileout'        => '',
  362.     'iiswwwroot'     => '',
  363.     'ldifdomain'     => '',
  364.     'perlmod'        => '',
  365.     'serverobj'      => '',
  366.     'userdbfullpath' => '/etc/',
  367.     'userobj'        => '',
  368.     'version'        => '',
  369.     'webserver'      => '',
  370.     'whoami'         => '',
  371.     'wwwroot'        => $inRootDir,
  372.     'wwwcgishl'      => '',
  373.     'wwwsupp'        => '',
  374.     'remote'         => 1,
  375.     'userglob'       => '/home/*'
  376.   );
  377.  
  378.   unless(defined($webconf))
  379.   {
  380.     print("Could not load configuration.<BR>\n") ;
  381.     exit(0);
  382.   }
  383.  
  384.   $computer = IISComputer->new( 'webconf' => $webconf ) ;
  385.  
  386.   # Write output.
  387.   if(defined($computer))
  388.   {
  389.     $computer->write($webconf->{'webserver'});
  390.     $computer->write_filelist($webconf->{'webserver'});
  391.   }
  392.  
  393.   printFooter();
  394. }
  395. # --------------------------------------------------------------------------------
  396.  
  397.  
  398. # --------------------------------------------------------------------------------
  399. # Procedure to html encode strings
  400. #
  401. sub htmlEncode
  402. {
  403.   my $inString = $_[0];
  404.   $inString =~ s/&/&\;/;
  405.   $inString =~ s/>/>\;/;
  406.   $inString =~ s/</<\;/;
  407.   $inString =~ s/"/"\;/;
  408.   return $inString;
  409. }
  410. # --------------------------------------------------------------------------------
  411.  
  412.  
  413. # --------------------------------------------------------------------------------
  414. # Procedure to return 1 (true) if the bitflag is set in the bitfield
  415. #
  416. sub isSet
  417. {
  418.   my $inBitField = $_[0];
  419.   my $inBitMask = $_[1];  
  420.   return (($inBitField & $inBitMask) > 0);
  421. }
  422. # --------------------------------------------------------------------------------
  423.  
  424.  
  425. # --------------------------------------------------------------------------------
  426. # Procedure to write log entries
  427. #
  428. sub logMessage
  429. {
  430.   my $inErrorLevel = $_[0];
  431.   my $inMessage = $_[1];  
  432.  
  433.  
  434.   my $theErrorLevel;
  435.  
  436.   if($inErrorLevel == $myLogNOTICE)
  437.   {
  438.     $theErrorLevel = 'NOTICE  ';
  439.   }
  440.   elsif($inErrorLevel == $myLogWARNING)
  441.   {
  442.     $theErrorLevel = 'WARNING ';
  443.   }
  444.   elsif($inErrorLevel == $myLogERROR)
  445.   {
  446.     $theErrorLevel = 'ERROR   ';
  447.   }
  448.   elsif($inErrorLevel == $myLogCONONLY)
  449.   {
  450.     $theErrorLevel = 'CONONLY ';
  451.   }
  452.   else
  453.   {
  454.     $theErrorLevel = 'UNKNOWN ';
  455.   }
  456.  
  457.  
  458.   my ($theSec, $theMin, $theHour, $theMDay, $theMon, $theYear, $theWDay, $theYDay, $theIsDst) = localtime(time);
  459.  
  460.   $theMon++;
  461.   if($theYear > 99) { $theYear -= 100 };
  462.  
  463.   my $theAMPM = "AM";
  464.  
  465.   if($theHour > 12)
  466.   {
  467.     $theHour -= 12;
  468.     $theAMPM = "PM";
  469.   }
  470.  
  471.   if($theMin < 10) { $theMin = '0' . $theMin };
  472.   if($theSec < 10) { $theSec = '0' . $theSec };
  473.   
  474.   my $theLogEntry = "$theErrorLevel $theMon/$theMDay/$theYear $theHour:$theMin:$theSec $theAMPM\t$inMessage\n";
  475.  
  476.  
  477.   if('' ne $myLogFilepath)
  478.   {
  479.     open(LOGFILE, '>>' . $myLogFilepath);
  480.     print LOGFILE $theLogEntry;
  481.     close(LOGFILE);
  482.   }
  483.  
  484.  
  485.   my $theHTMLMessage = htmlEncode($inMessage);
  486.   print STDOUT "$theHTMLMessage<BR>\n";
  487.  
  488.   if($inErrorLevel == $myLogERROR)
  489.   {
  490.     print STDOUT "Migration aborted.";
  491.     exit(0);
  492.   }
  493. }
  494. # --------------------------------------------------------------------------------
  495.  
  496.  
  497. # --------------------------------------------------------------------------------
  498. # Procedure to output to DIRS file
  499. #
  500. sub printDirs
  501. {
  502.   my $inDir = $_[0];
  503.   my $inScriptDir = $_[1];
  504.   my $inDocDir = $_[2];
  505.  
  506.   opendir(THEDIR, $inDir);
  507.   my @theChildElements = readdir(THEDIR);
  508.   closedir THEDIR;
  509.  
  510.   #$inDir =~ tr/[a-z]/[A-Z]/;
  511.   if((index($inDir . '/', $inScriptDir) != 0) && (index($inDir, $inDocDir) != 0))
  512.   {
  513.     my $outDir = $inDir;
  514.     $outDir =~ s/\//\\/g;
  515.     $outDir = "\\Inetpub\\$myServerName$outDir";
  516.  
  517.     open(DIRSFILE, '>>' . $myTempDir . '/iismu.dirs');
  518.     print DIRSFILE "$outDir\n";
  519.     close(DIRSFILE);
  520.   }
  521.  
  522.   foreach $theElement (@theChildElements)
  523.   {
  524.     my $theTestDir = $inDir . '/' . $theElement;
  525.  
  526.     if((-d $theTestDir) && ($theElement ne '.') && ($theElement ne '..'))
  527.     {
  528.       printDirs($theTestDir, $inScriptDir, $inDocDir);
  529.     }
  530.   }
  531. }
  532. # --------------------------------------------------------------------------------
  533.  
  534.  
  535. # --------------------------------------------------------------------------------
  536. # Procedure to output page footer text
  537. #
  538. sub printFooter
  539. {
  540.   print STDOUT '    </FONT>' . "\n\n";        
  541.   print STDOUT '    <SCRIPT LANGUAGE="JavaScript">' . "\n";
  542.   print STDOUT '      window.parent.location = "' . $myBackURL . '";' . "\n";
  543.   print STDOUT '    </SCRIPT>' . "\n";
  544.   print STDOUT '  </BODY>' . "\n";
  545.   print STDOUT '</HTML>' . "\n";
  546. }
  547. # --------------------------------------------------------------------------------
  548.  
  549.  
  550. # --------------------------------------------------------------------------------
  551. # Procedure to output page header text
  552. #
  553. sub printHeader
  554. {
  555.   print STDOUT '<HTML>' . "\n";
  556.   print STDOUT '  <BODY BGCOLOR="#FFFFFF">' . "\n";
  557.   print STDOUT '    <FONT FACE="Verdana" SIZE="2">' . "\n";
  558. }
  559. # --------------------------------------------------------------------------------
  560.  
  561.  
  562. # --------------------------------------------------------------------------------
  563. # Procedure to trim spaces off of a string
  564. #
  565. sub trim
  566. {
  567.   my $inString = $_[0];
  568.   $inString =~ s/\s*$//;
  569.   $inString =~ s/^\s*//;
  570.   return $inString;
  571.  }
  572. # --------------------------------------------------------------------------------
  573.  
  574.  
  575. # --------------------------------------------------------------------------------
  576. # Procedure to convert a string to uppercase
  577. #
  578. sub ucase
  579. {
  580.   my $inString = $_[0];
  581.   $inString =~ tr/a-z/A-Z/;
  582.   return $inString;
  583. }
  584. # --------------------------------------------------------------------------------
  585.  
  586.  
  587. # --------------------------------------------------------------------------------
  588. # Procedure to URL decode a string
  589. #
  590. sub urlDecode
  591. {
  592.   my $inString = $_[0];
  593.   $inString =~ tr/+/ /;
  594.   $inString =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
  595.   $inString =~ tr/+/ /;
  596.   $inString =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
  597.   return $inString;
  598. }
  599. # --------------------------------------------------------------------------------
  600.  
  601.  
  602. # --------------------------------------------------------------------------------
  603. # Procedure to write data file header
  604. #
  605. sub writeIismuDataHeader
  606. {
  607.   my $theSec;
  608.   my $theMin;
  609.   my $theHour;
  610.   my $theMDay;
  611.   my $theMon;
  612.   my $theYear;
  613.   my $theWDay;
  614.   my $theYDay;
  615.   my $theIsDst;
  616.   my $theAMPM;
  617.  
  618.   ($theSec, $theMin, $theHour, $theMDay, $theMon, $theYear, $theWDay, $theYDay, $theIsDst) = localtime(time);
  619.  
  620.   $theMon++;
  621.   if($theYear > 99) { $theYear -= 100 };
  622.   $theAMPM = "AM";
  623.  
  624.   if($theHour > 12)
  625.   {
  626.     $theHour -= 12;
  627.     $theAMPM = "PM";
  628.   }
  629.   
  630.   if($theMin < 10) { $theMin = '0' . $theMin };
  631.   if($theSec < 10) { $theSec = '0' . $theSec };
  632.  
  633.   print IISMUDATA "#IIsMigrationDataStart\n";
  634.   print IISMUDATA "###########################################################\n";
  635.   print IISMUDATA "#\n";
  636.   print IISMUDATA "# Microsoft IIS v.5 Migration Utility\n";
  637.   print IISMUDATA "# $theMon/$theMDay/$theYear $theHour:$theMin:$theSec $theAMPM\n";
  638.   print IISMUDATA "#\n";
  639.   print IISMUDATA "###########################################################\n\n";
  640. }
  641.  
  642. # --------------------------------------------------------------------------------
  643.  
  644.  
  645. #############################################################################
  646. #
  647. # iisldif.pm
  648. #
  649. # Copyright (c) MicroCrafts Corporation, 1997
  650. #
  651. #  IIS 4.0 Resource Kit Migration Utilty Perl module - LDIF to NT
  652. #  Resource Kit ADDUSERS module.
  653. #
  654. #############################################################################
  655.  
  656.  
  657. #############################################################################
  658. #
  659. #   IIsLDIF
  660. #
  661. #############################################################################
  662. package     IIsLDIF ;
  663. require     Exporter ;
  664. @ISA    = qw( Exporter ) ;
  665. @EXPORT = qw( _construct, write, dump ) ;
  666.  
  667. sub new {
  668.     my $class        = shift ;
  669.     my %params       = @_ ;
  670.     my $self         = {} ;
  671.     $self->{'class'} = $class ;
  672.     bless $self, $class ;
  673.     print( "NEW $class\n" ) if ( $IISCore::debug ) ;
  674.  
  675.     $self->{'name'}   = $params{'cn'} ;
  676.  
  677.     $self->_construct() ;
  678.  
  679.     return $self ;
  680. }
  681.  
  682. sub _construct {
  683.     my $self = shift ;
  684.     print( "CONSTRUCT $self->{'class'}\n" ) if ( $IISCore::debug ) ;
  685.     $self->dump() if ( $IISCore::debug ) ;
  686. }
  687.  
  688. sub write {
  689.     my $self = shift ;
  690.  
  691.     if ( $self->{'type'} eq 'user' ) {
  692.         printf( "%s,%s,,%s,,,,\n",
  693.                $self->{'uid'},
  694.                $self->{'name'},
  695.                $self->{'title'}
  696.                ) ;
  697.     } elsif ( $self->{'type'} eq 'local' ) {
  698.         printf( "%s, %s", $self->{'name'}, $self->{'description'} ) ;
  699.         @members = keys( %{$self->{'uniquemember'}} ) ;
  700.         foreach $member ( sort @members ) {
  701.             printf( "WHO %s\n", $self->{'user'}{'class'} ) ;
  702.             printf( ",<<domain>>\\%s", $self->{'user'}{$member}{'uid'} ) ;
  703.         }
  704.         print( "\n" ) ;
  705.     } elsif ( $self->{'type'} eq 'global' ) {
  706.     } else {
  707.         @content = keys( %$self ) ;
  708.         foreach $key ( sort @content ) {
  709.             if ( $key eq 'uniquemember' ) {
  710.                 @subcontent = keys( %{$self->{$key}} ) ;
  711.                 foreach $subkey ( sort @subcontent ) {
  712.                     printf( "%s, ", $subkey ) ;
  713.                 }
  714.                 print( "\n" ) ;
  715.             } else {
  716.                 printf( "%s%-20s = %s\n", $tab, $key, $self->{$key} ) ;
  717.             }
  718.         }
  719.     }
  720. }
  721.  
  722. sub dump {
  723.     print( "dump()\n" ) ;
  724.     $tab = "  " ;
  725.     my $self = shift ;
  726.     @content = keys( %$self ) ;
  727.     foreach $key ( sort @content ) {
  728.         printf( "%s%-20s = %s\n", $tab, $key, $self->{$key} ) ;
  729.     }
  730. }
  731.  
  732. #############################################################################
  733. #   !_IISLDIF_PM  NO CODE BEYOND THIS POINT
  734. 1 ;
  735.  
  736.  
  737.  
  738.  
  739.  
  740. #############################################################################
  741. #
  742. # iismucore.pm
  743. #
  744. # Copyright (c) MicroCrafts Corporation, 1997
  745. #
  746. #  IIS 4.0 Resource Kit Migration Utilty Perl module - core objects.
  747. #
  748. #############################################################################
  749.  
  750.  
  751. #############################################################################
  752. #
  753. #   IISComputer
  754. #
  755. #############################################################################
  756. package     IISComputer ;
  757. use         Cwd ;
  758. require     Exporter ;
  759. @ISA    = qw( Exporter ) ;
  760. @EXPORT = qw( write, write_filelist, dump, writeServers ) ;
  761.  
  762. sub new {
  763.     my $class        = shift ;
  764.     my %params       = @_ ;
  765.     my $self         = {} ;
  766.  
  767.     $self->{'class'} = $class ;
  768.     bless $self, $class ;
  769.     print( "NEW $class\n" ) if ( $IISCore::debug ) ;
  770.     print( "INC @INC\n" ) if ( $IISCore::debug > 1 ) ;
  771.  
  772.     unless($params{'webconf'})
  773.     {
  774.       print( "No web configuration object\n" ) ;
  775.       $@ = $!;
  776.       return undef ;
  777.     }
  778.  
  779.     $self->{'webconf'} = $params{'webconf'} ;
  780.     $self->_construct() ;
  781.     return $self ;
  782. }
  783.  
  784. sub _construct
  785. {
  786.     my $self = shift ;
  787.     print( "CONSTRUCT $self->{'class'}\n" ) if ( $IISCore::debug ) ;
  788.  
  789.     #
  790.     # Sequence through all virtual servers, processing configuration file(s).
  791.     #   vserver - hash indexed by virtual server name.
  792.     #
  793.     $webconf = $self->{'webconf'} ;
  794.     $olddir = cwd() ;
  795.     chdir( $webconf->{'fullpath'} ) or die( "Could not change to server root $webconf->{'fullpath'}\n" ) ;
  796.     $n = 1;
  797.     @filespec = $webconf->{'fileglob'} ;
  798.  
  799.     while ( <@filespec> ) {
  800.         chomp( $_ ) ;
  801.  
  802.         print( "VSERVER <$_>\n" ) if ( $IISCore::debug ) ;
  803.         $name = $_ ;
  804.         # Create virtual server object(s).
  805.         $obj = IISServer->new(
  806.                               'name'      => $name,
  807.                               'serverno'  => $n,
  808.                               'path'      => $webconf->{'fullpath'} . $_,
  809.                               'serverobj' => $webconf->{'serverobj'},
  810.                               'webconf'   => $webconf,
  811.                               ) ;
  812.         if ( defined($obj) ) {
  813.             $n++ ;
  814.             $self->{'vserver'}{ $name } = $obj ;
  815.             undef( $obj ) ;
  816.         }
  817.     }
  818.  
  819.     #
  820.     # There may be processing at computer level required.
  821.     #
  822.     if ( $webconf->{'computerobj'} ) {
  823.         $self->{'otherself'} = $webconf->{'computerobj'}->new( $self ) ;
  824.     }
  825.  
  826.     #
  827.     # Migrate user database.
  828.     #
  829.  
  830.     # remove whitespace at the end
  831.     $webconf->{'userdbfullpath'} =~ tr/\s*$//;
  832.  
  833.     if($webconf->{'userdbfullpath'})
  834.     {
  835.       $self->{'userdb'} = IISUserDb->new(
  836.        'fullpath' => $webconf->{'userdbfullpath'},
  837.        'userobj'  => $webconf->{'userobj'},
  838.        'userglob' => $webconf->{'userglob'},
  839.                                          );
  840.     }
  841.  
  842.     #
  843.     # Return to original directory.
  844.     #
  845.     chdir( $olddir ) ;
  846. }
  847.  
  848. sub write
  849. {
  850.   my $self = shift;
  851.   my $webserver = shift;
  852.   $webconf = $self->{'webconf'};
  853.   print( "WRITE $self->{'class'}\n" ) if ( $IISCore::debug );
  854.   $file = $self->{'webconf'}->{'fileout'} . ".data" ;
  855.  
  856.   open( FILE, ">" . $file ) or die( "Could not open $file" ) ;
  857.   select( FILE ) ;
  858.  
  859.   # Write file header.
  860.   ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time) ; 
  861.   $mon++;
  862.   if($year > 99) { $year -= 100 };
  863.   $ampm = "AM";
  864.  
  865.   if($hour > 12)
  866.   {
  867.     $hour -= 12;
  868.     $ampm = "PM";
  869.   }
  870.   
  871.  
  872.   print("#IIsMigrationDataStart\n" );
  873.   print("###########################################################\n");
  874.   print("#\n");
  875.   print("# Microsoft IIS v.5 Migration Utility\n");
  876.   print("# $mon/$mday/$year $hour:$min:$sec $ampm\n");
  877.   print("#\n");
  878.   print("###########################################################\n\n");
  879.  
  880.   $self->{'webconf'}->write();
  881.  
  882.   # Write W3SVC command
  883.   print('VSERVICE ' . chr(127) . "W3SVC\n");
  884.   print('VSET     ' . chr(127) . 'W3SVC' . chr(127) . 'KeyType' . chr(127) . "IIsWebService\n");
  885.   print('VSET     ' . chr(127) . 'W3SVC' . chr(127) . 'AccessRead' . chr(127) . "True\n");
  886.   print('VSET     ' . chr(127) . 'W3SVC' . chr(127) . 'EnableDefaultDoc' . chr(127) . "True\n");
  887.     
  888.   # Write each virtual server.
  889.   foreach $key (sort(keys %{$self->{'vserver'}}))
  890.   {
  891.      $self->{'vserver'}{$key}->write() ;
  892.   }
  893.  
  894.    print( "#IIsMigrationDataEnd\n");
  895.     
  896.   close( FILE ) ;
  897.   select( STDOUT ) ;
  898.   print( "Wrote $file <BR>\n" ) unless ( $self->{'webconf'}->{'remote'} ) ;
  899.  
  900.   # Write user database file
  901.   if($webconf->{'userdbfullpath'})
  902.   {
  903.     $file = $self->{'webconf'}->{'fileout'} . ".users";
  904.  
  905.     if($self->{'userdb'})
  906.     {
  907.       $self->{'userdb'}->write( $webserver, $webconf->{'ldifdomain'}, $file ) ;
  908.     }
  909.   }
  910. }
  911.  
  912. sub write_filelist
  913. {
  914.   my $self      = shift ;
  915.   my $webserver = shift ;
  916.   $webconf = $self->{'webconf'} ;
  917.   print( "WRITEFILES $self->{'class'}\n" ) if ( $IISCore::debug ) ;
  918.   $file = $self->{'webconf'}->{'fileout'} . ".files" ;
  919.  
  920.   open( FILE, ">" . $file ) or die( "Could not open $file" ) ;
  921.   select( FILE ) ;
  922.  
  923.   # Add .data, .users files to the list
  924.   print($topmain::myTempDir . "iismu.data\niismu.data\n");
  925.  
  926.   if(-e $topmain::myTempDir . "iismu.users")
  927.   {
  928.     print($topmain::myTempDir . "iismu.users\niismu.users\n");
  929.   }
  930.     
  931.   if(-e $topmain::myLogFilepath)
  932.   {
  933.     print($topmain::myLogFilepath . "\niismu.log\n");
  934.   }
  935.  
  936.   # Write each virtual server.
  937.   foreach $key (keys %{$self->{'vserver'}})
  938.   {
  939.     $self->{'vserver'}{$key}->write_filelist();
  940.   }
  941.     
  942.   if(-e $topmain::myScriptDir . 'iismu.dirs')
  943.   {
  944.     print($topmain::myScriptDir . "iismu.dirs\niismu.dirs\n");
  945.   }
  946.  
  947.   close( FILE );
  948.   select( STDOUT );
  949.   print( "Wrote $file <BR>\n" ) unless ( $self->{'webconf'}->{'remote'} );
  950. }
  951.  
  952. sub dump {
  953.     my $self = shift ;
  954.     print( "dump($self->{'class'})\n" ) ;
  955.     $tab = "  " ;
  956.     @content = keys( %$self ) ;
  957.     foreach $key ( sort @content ) {
  958.         printf( "%s%-20s = %s\n", $tab, $key, $self->{$key} ) ;
  959.     }
  960. }
  961.  
  962.  
  963. sub writeServers
  964. {
  965.   my $self = shift;
  966.   my $webserver = shift;
  967.   $webconf = $self->{'webconf'};
  968.   print( "WRITE $self->{'class'}\n" ) if ( $IISCore::debug );
  969.  
  970.   # Write each virtual server.
  971.   foreach $key (sort(keys %{$self->{'vserver'}}))
  972.   {
  973.     print('<SERVER>');
  974.     $self->{'vserver'}{$key}->writePath();
  975.     print('</SERVER>');
  976.   }
  977. }
  978.  
  979. #############################################################################
  980. #
  981. #   IISService
  982. #
  983. #############################################################################
  984. package     IISService ;
  985. require     Exporter ;
  986. @ISA    = qw( Exporter ) ;
  987. @EXPORT = qw( _construct, dump ) ;
  988.  
  989. sub new {
  990.  
  991.     my $class        = shift ;
  992.     my %params       = @_ ;
  993.     my $self         = {} ;
  994.     $self->{'class'} = $class ;
  995.     bless $self, $class ;
  996.     print( "NEW $class\n" ) if ( $IISCore::debug ) ;
  997.  
  998.     $self->_construct() ;
  999.  
  1000.     return $self ;
  1001. }
  1002.  
  1003. sub _construct
  1004. {
  1005. my $self = shift ;
  1006.     print( "CONSTRUCT $self->{'class'}\n" ) if ( $IISCore::debug ) ;
  1007. }
  1008.  
  1009. sub dump {
  1010.     my $self = shift ;
  1011.     topmain::dbgOut( "dump($self->{'class'})\n" ) ;
  1012.     $tab = "  " ;
  1013.     @content = keys( %$self ) ;
  1014.     foreach $key ( sort @content ) {
  1015.         printf( "%s%-20s = %s\n", $tab, $key, $self->{$key} ) ;
  1016.     }
  1017. }
  1018.  
  1019.  
  1020. #############################################################################
  1021. #
  1022. #   IISServer
  1023. #
  1024. #############################################################################
  1025. package IISServer;
  1026. require Exporter;
  1027. @ISA = qw(Exporter);
  1028. @EXPORT = qw( _construct, AddServerBinding, write, write_filelist, dump, writePath );
  1029.  
  1030.  
  1031. sub new 
  1032. {
  1033.   my $class        = shift ;
  1034.   my %params       = @_ ;
  1035.   my $self         = {} ;
  1036.   $self->{'class'} = $class ;
  1037.   bless $self, $class ;
  1038.   topmain::dbgOut( "NEW $class" ) if ( $IISCore::debug ) ;
  1039.  
  1040.   $self->{'name'}      = $params{'name'};
  1041.   $self->{'path'}      = $params{'path'};
  1042.   $self->{'serverno'}  = $params{'serverno'};
  1043.   $self->{'serverobj'} = $params{'serverobj'};
  1044.   $self->{'webconf'}   = $params{'webconf'};
  1045.  
  1046.   $self->{'AccessFlags'}       = $topmain::accessDefault;
  1047.   $self->{'AllowKeepAlive'}    = '';
  1048.   $self->{'AuthFlags'}         = $topmain::authDefault;
  1049.   $self->{'CGITimeout'}        = '';
  1050.   $self->{'ConnectionTimeout'} = '900';
  1051.   $self->{'DefaultDoc'}        = '';
  1052.   $self->{'DefaultDocFooter'}  = '';
  1053.   $self->{'DirBrowseFlags'}    = $topmain::dirbrowDefault;
  1054.   $self->{'EnableDocFooter'}   = '';
  1055.   $self->{'EnableDirBrowsing'} = 'False';
  1056.   $self->{'HttpCustomHeaders'} = '';
  1057.   $self->{'HttpErrors'}        = '';
  1058.   $self->{'HttpRedirect'}      = '';
  1059.   $self->{'KeyType'}           = 'IIsWebServer';
  1060.   $self->{'MaxConnections'}    = '-1';
  1061.   $self->{'MimeMap'}           = '';
  1062.   $self->{'Realm'}             = '';
  1063.   $self->{'SecureBindings'}    = '';
  1064.   $self->{'UseHostName'}       = '';
  1065.     
  1066.   # Ask web server object to fill in our parameters.
  1067.   my $otherself = $self->{'serverobj'}->new( $self );
  1068.   $self->{'otherself'} = $otherself ;
  1069.  
  1070.   unless(defined($otherself))
  1071.   {
  1072.     undef( $self->{'otherself'});
  1073.     $@ = $!;
  1074.     return undef;
  1075.   }
  1076.  
  1077.   return $self;
  1078. }
  1079.  
  1080. sub _construct
  1081. {
  1082.   my $self = shift ;
  1083.   topmain::dbgOut( "CONSTRUCT $self->{'class'}($self->{'name'})" ) if ( $IISCore::debug ) ;
  1084.     
  1085.   # Complete processing of virtual directories ([0] := ROOT).
  1086.   # Home-page
  1087.   $self->{'vdir'}[0]->{'DefaultDoc'} = $self->{'DefaultDoc'} ;
  1088.  
  1089.   # Default document footer. 
  1090.   $self->{'vdir'}[0]->{'DefaultDocFooter'}     = $self->{'DefaultDocFooter'} ;
  1091.   $self->{'vdir'}[0]->{'DefaultDocFooterType'} = $self->{'DefaultDocFooterType'} ;
  1092.   $self->{'vdir'}[0]->{'EnableDocFooter'}      = $self->{'EnableDocFooter'} ;
  1093.  
  1094.   # Directory browsing flags
  1095.   $self->{'vdir'}[0]->{'DirBrowseFlags'}       = $self->{'DirBrowseFlags'} ;
  1096.  
  1097.   $nvdir = scalar( @{$self->{'vdir'}} ) ;
  1098.  
  1099.   for($i = 0; $i < $nvdir ; $i++)
  1100.   {
  1101.     $self->{'vdir'}[$i]->_construct();
  1102.     $self->{'vdir'}[$i]->{'DefaultDoc'} = $self->{'DefaultDoc'};
  1103.     $self->{'vdir'}[$i]->{'DirBrowseFlags'} = $self->{'DirBrowseFlags'} ;
  1104.   }
  1105.     
  1106.   my $docdir = $self->{'vdir'}[0]->{'dir'} . '/iismu';
  1107.   
  1108.   if(-e $docdir)
  1109.   {
  1110.     $topmain::myDocDir = $docdir;
  1111.   }
  1112.  
  1113.   $self->dump() if ($IISCore::debug );
  1114. }
  1115.  
  1116. sub write
  1117. {
  1118.   my $self = shift ;
  1119.  
  1120.   if(! ($topmain::myServerSettings{$self->{'serverno'}} =~ /s=1/))
  1121.   {
  1122.     topmain::logMessage($topmain::myLogNOTICE, "Skipping settings for server: $self->{'serverno'}");
  1123.     return;
  1124.   }
  1125.  
  1126.   $pfx = "W3SVC/$self->{'serverno'}";
  1127.   # Create server.
  1128.   print('VSERVER  ' . chr(127) . $pfx . "\n");
  1129.   print('VSET     ' . chr(127) . $pfx . chr(127) . 'KeyType' . chr(127) . "IIsWebServer\n");
  1130.   print('VSET     ' . chr(127) . $pfx . chr(127) . 'AccessRead' . chr(127) . "True\n");
  1131.   print('VSET     ' . chr(127) . $pfx . chr(127) . 'EnableDefaultDoc' . chr(127) . "True\n");
  1132.  
  1133.   if('' ne $self->{'AllowKeepAlive'})
  1134.   {
  1135.     print('VSET     ' . chr(127) . $pfx . chr(127) . 'AllowKeepAlive' . chr(127) . $self->{'AllowKeepAlive'} . "\n");  
  1136.   }
  1137.  
  1138.   print('VSET     ' . chr(127) . $pfx . chr(127) . 'ConnectionTimeout' . chr(127) . $self->{'ConnectionTimeout'} . "\n") if('' ne $self->{'ConnectionTimeout'});
  1139.   print('VSET     ' . chr(127) . $pfx . chr(127) . 'ServerComment' . chr(127) . $self->{'name'} . "\n");
  1140.  
  1141.   @theServerBindings = split(',', $self->{'ServerBindings'});
  1142.  
  1143.   for($i = 0; $i < scalar(@theServerBindings); $i++)
  1144.   {
  1145.     if('' ne @theServerBindings[$i])
  1146.     {
  1147.       print('VSET     ' . chr(127) . $pfx . chr(127) . 'ServerBindings' . chr(127) . @theServerBindings[$i] . "\n");
  1148.     }
  1149.   }
  1150.  
  1151.   if('' ne $self->{'IdentityCheck'})
  1152.   {
  1153.     print('VSET     ' . chr(127) . $pfx . chr(127) . 'LogExtFileUserName' . chr(127) . $self->{'IdentityCheck'} . "\n");
  1154.   }
  1155.  
  1156.   if('' ne $self->{'ListenBacklog'})
  1157.   {
  1158.     print('VSET     ' . chr(127) . $pfx . chr(127) . 'ServerListenBacklog' . chr(127) . $self->{'ListenBacklog'} . "\n");
  1159.   }
  1160.  
  1161.  
  1162.   print('VSET     ' . chr(127) . $pfx . chr(127) . 'MaxConnections' . chr(127) . $self->{'MaxConnections'} . "\n") if (('' ne $self->{'MaxConnections'}) && ('-1' ne $self->{'MaxConnections'}));
  1163.   print('VSET     ' . chr(127) . $pfx . chr(127) . 'EnableDirBrowsing' . chr(127) . "$self->{'EnableDirBrowsing'}\n");
  1164.  
  1165.  
  1166.   if('' ne $self->{'AccessExecute'})
  1167.   {
  1168.     print('VSET     ' . chr(127) . $pfx . chr(127) . 'AccessExecute' . chr(127) . "$self->{'AccessExecute'}\n");
  1169.   }
  1170.  
  1171.   if('' ne topmain::trim($self->{'HttpRedirect'}))
  1172.   {
  1173.     print('VSET     ' . chr(127) . $pfx . chr(127) . 'HttpRedirect' . chr(127) . "$self->{'HttpRedirect'}\n");
  1174.   }
  1175.  
  1176.   $nvdir = scalar( @{$self->{'vdir'}} ) ;
  1177.  
  1178.   # MimeMap can only be created *after* ROOT created by 'vdir' processing.
  1179.   $self->{'MimeMap'}->write( $pfx ) if ($self->{'MimeMap'});
  1180.  
  1181.   # Process virtual directories ([0] := ROOT).
  1182.   for($i = 0 ; $i < $nvdir; $i++ )
  1183.   {
  1184.     $self->{'vdir'}[$i]->write( $pfx );
  1185.   }
  1186. }
  1187.  
  1188. sub write_filelist
  1189. {
  1190.   my $self = shift ;
  1191.   if(! ($topmain::myServerSettings{$self->{'serverno'}} =~ /c=1/))
  1192.   {
  1193.     topmain::logMessage($topmain::myLogNOTICE, "Skipping content for server: skipping $self->{'serverno'}");
  1194.     return;
  1195.   }
  1196.  
  1197.   $pfx = "W3SVC/<<$self->{'serverno'}>>" ;
  1198.   $nvdir = scalar( @{$self->{'vdir'}} ) ;
  1199.  
  1200.   # Process virtual directories ([0] := ROOT).
  1201.   for ( $i = 0 ; $i < $nvdir ; $i++ ) {
  1202.       $self->{'vdir'}[$i]->write_filelist($pfx);
  1203.   }
  1204. }
  1205.  
  1206. sub AddServerBinding {
  1207.     my $self = shift ;
  1208.     my $addr = shift ;
  1209.     my $port = shift ;
  1210.     my $name = shift ;
  1211.     #my $oc = '[' ;
  1212.     #my $cd = ']' ;
  1213.     my $oc = ',';
  1214.     my $cd = '';
  1215.  
  1216.     topmain::dbgOut( "AddServerBinding( |$addr|$port|$name| )" ) if ( $IISCore::debug ) ;
  1217.     if ( $self->{'ServerBindings'} ) {
  1218. #        $comma = ',' ;
  1219.     } else {
  1220.         $comma = '' ;
  1221.     }
  1222. #    if ( !$self->{'ServerBindings'} ) {
  1223.         $self->{'ServerBindings'} = join( '', $self->{'ServerBindings'}, $comma,
  1224.                                          $oc,
  1225.                                          $addr, ':',
  1226.                                          $port, ':',
  1227.                                          $name,
  1228.                                          $cd
  1229.                                          ) ;
  1230. #    } 
  1231. }
  1232.  
  1233. sub set {
  1234.     my $self = shift ;
  1235.     my $var  = shift ;
  1236.     my $val  = shift ;
  1237.  
  1238.     $self->{$var} = $val ;
  1239. }
  1240.  
  1241. sub dump {
  1242.     my $self = shift ;
  1243.     print( "dump($self->{'class'})\n" ) ;
  1244.     $tab = "  " ;
  1245.     @content = keys( %$self ) ;
  1246.     foreach $key ( sort @content ) {
  1247.         printf( "%s%-20s = %s\n", $tab, $key, $self->{$key} ) ;
  1248.     }
  1249.  
  1250.     $nvdir = scalar( @{$self->{'vdir'}} ) ;
  1251.     for ( $i = 0 ; $i < $nvdir ; $i++ ) {
  1252.         $self->{'vdir'}[$i]->dump() ;
  1253.     }
  1254. }
  1255.  
  1256.  
  1257. sub writePath
  1258. {
  1259.   #xyz
  1260.   my $self = shift;
  1261.   print '<ADSPATH>IIS://' . $ENV{'SERVER_NAME'} . '/W3SVC/' . $self->{'serverno'} . '</ADSPATH>';
  1262.   print '<PATH>' . $self->{'vdir'}[0]->{'dir'} . '</PATH>';
  1263. }
  1264.  
  1265. #############################################################################
  1266. #
  1267. #   IISVirtualDir
  1268. #
  1269. #############################################################################
  1270. package     IISVirtualDir ;
  1271. require     Exporter ;
  1272. @ISA    = qw( Exporter ) ;
  1273. @EXPORT = qw( _construct, write, write_filelist, dump ) ;
  1274.  
  1275. sub new
  1276. {
  1277.   my $class        = shift ;
  1278.   my %params       = @_ ;
  1279.   my $self         = {} ;
  1280.   $self->{'class'} = $class ;
  1281.  
  1282.   bless $self, $class ;
  1283.   print( "NEW $class\n" ) if ($IISCore::debug);
  1284.  
  1285.   $self->{'dir'}  = $params{'dir'} ;
  1286.   $self->{'from'} = $params{'from'} ;
  1287.   $self->{'type'} = $params{'type'} ;
  1288.   $self->{'name'} = $params{'name'} ;
  1289.  
  1290.   # Default IIS Virtual Directory Object property values.
  1291.   $self->{'AccessFlags'}      = $topmain::accessDefault;
  1292.   $self->{'AuthFlags'}        = $topmain::authDefault;
  1293.   $self->{'DefaultDoc'}       = '' ;
  1294.   $self->{'DefaultDocFooter'} = '' ;
  1295.   $self->{'EnableDocFooter'}  = '' ;
  1296.   $self->{'DirBrowseFlags'}   = $topMain::dirbrowDefault;
  1297.   $self->{'KeyType'}          = 'IIsWebVirtualDir' ;
  1298.   return $self ;
  1299. }
  1300.  
  1301. sub _construct
  1302. {
  1303.   my $self = shift;
  1304.   print( "CONSTRUCT $self->{'class'}($self->{'name'})\n" ) if ( $IISCore::debug );
  1305.   $self->{'root'} = "ROOT$self->{'from'}";
  1306.  
  1307.   my($vdrive, $vpath ) = split( ':', $self->{'dir'});
  1308.  
  1309.   #$vdrive =~ tr/a-z/A-Z/;
  1310.   $self->{'vdrive'} = $vdrive;
  1311.  
  1312.   # $vpath =~ tr/\//\\/ ;       # Forward slash to backslash.
  1313.   $vpath =~ tr/\s*$//;
  1314.   $self->{'vpath'} = $vpath;
  1315.  
  1316.   my $checkvpath = $vpath;
  1317.   #$checkvpath =~ tr/a-z/A-Z/;
  1318.   $checkvpath = $self->{'vdrive'} . $checkvpath;
  1319.     
  1320.   my $scriptdir = $topmain::myScriptDir;
  1321.   #$scriptdir =~ tr/a-z/A-Z/;
  1322.   $scriptdir =~ tr/\s*$//;
  1323.   $scriptdir =~ s/\\$//;
  1324.   $self->{'scriptdir'} = $scriptdir;
  1325.  
  1326.   #my $docdir = $topmain::myDocDir;
  1327.   #$docdir =~ tr/a-z/A-Z/;
  1328.   #$docdir =~ tr/\s*$//;
  1329.   #$self->{'docdir'} = $docdir;
  1330.  
  1331.   #print("pfx:" . $pfx . '<BR>checkvpath:' . $checkvpath . '<BR>scriptdir:' . $scriptdir . '<BR>docdir'. $docdir . "\n");
  1332.   #print("***:" . index($checkvpath, $scriptdir) . "\n");
  1333.  
  1334.   my $skip = 0;
  1335.   
  1336.   # mask out our own stuff
  1337.   if((index($checkvpath, $scriptdir) == 0) || (index($checkvpath, $topmain::myDocDir) == 0))
  1338.   {
  1339.     $skip = 1;
  1340.   }
  1341.  
  1342.   $self->{'skip'} = $skip;
  1343.  
  1344. }
  1345.  
  1346. sub write
  1347. {
  1348.   if($self->{'skip'})
  1349.   {
  1350.     return;
  1351.   }
  1352.   #xyz
  1353.   my $self = shift ;
  1354.   my $pfx  = shift ; 
  1355.   $vpath = $self->{'dir'};
  1356.   $vpath =~ s/^\\//;
  1357.   $vpath =~ tr/\s*$//;
  1358.   $vpath =~ tr/\//\\/;
  1359.  
  1360.           
  1361.   my $newpath = "Inetpub\\$topmain::myServerName$vpath";
  1362.  
  1363.   print('VCREATE  ' . chr(127) . "$pfx/$self->{'root'}" . chr(127) . $newpath . "\n");
  1364.   print('VSET     ' . chr(127) . "$pfx/$self->{'root'}" . chr(127) . 'KeyType' . chr(127) . "IIsWebVirtualDir\n");
  1365.  
  1366.   #print('VSET     ' . chr(127) . "$pfx/$self->{'root'}" . chr(127) . 'AuthFlags' . chr(127) . $self->{'AuthFlags'} . "\n");
  1367.   #print('VSET     ' . chr(127) . "$pfx/$self->{'root'}" . chr(127) . 'AccessFlags' . chr(127) . $self->{'AccessFlags'} . "\n");
  1368.   #print('VSET     ' . chr(127) . "$pfx/$self->{'root'}" . chr(127) . 'DirBrowseFlags' . chr(127) . $self->{'DirBrowseFlags'} . "\n");
  1369.  
  1370.   #IISCore::writeline('VSET     ', "$pfx/$self->{'root'} HttpErrors", $self->{'HttpErrors'}) if('' ne $self->{'HttpErrors'});
  1371.  
  1372.   my @theHttpErrors = split(']', $self->{'HttpErrors'});
  1373.   my $theHttpError;
  1374.  
  1375.   #xyz
  1376.   for($i = 0; $i < scalar(@theHttpErrors); $i++)
  1377.   {
  1378.     $theHttpError = topmain::trim($theHttpErrors[$i]);
  1379.     if(('' ne $theHttpError) && (index(topmain::ucase($theHttpError), "HTTP://") < 0))
  1380.     {
  1381.       $theHttpError = substr($theHttpError, 1);
  1382.       print('VSET     ' . chr(127) . "$pfx/$self->{'root'}" . chr(127) . 'HttpErrors' . chr(127) . $theHttpError . "\n");
  1383.     }
  1384.   }
  1385.  
  1386.   if('' ne $self->{'HostNameLookups'})
  1387.   {
  1388.     print('VSET     ' . chr(127) . "$pfx/$self->{'root'}" . chr(127) . 'EnableReverseDNS' . chr(127) . $self->{'HostNameLookups'} . "\n");
  1389.   }
  1390.  
  1391.   if('' ne $self->{'EnableDirBrowsing'})
  1392.   {
  1393.     print('VSET     ' . chr(127) . "$pfx/$self->{'root'}" . chr(127) . 'EnableDirBrowsing' . chr(127) . $self->{'EnableDirBrowsing'} . "\n");
  1394.   }
  1395.  
  1396.   if('' ne $self->{'AccessExecute'})
  1397.   {
  1398.     print('VSET     ' . chr(127) . "$pfx/$self->{'root'}" . chr(127) . 'AccessExecute' . chr(127) . $self->{'AccessExecute'} . "\n");
  1399.   }
  1400.  
  1401.     if('' ne $self->{'DefaultDoc'})
  1402.   {
  1403.     $vpath = $self->{'DefaultDoc'} ;
  1404.     # $vpath =~ tr/\//\\/ ;       # Forward slash to backslash.
  1405.     print('VSET     ' . chr(127) . "$pfx/$self->{'root'}" . chr(127) . 'EnableDefaultDoc' . chr(127) . "True\n");
  1406.     print('VSET     ' . chr(127) . "$pfx/$self->{'root'}" . chr(127) . 'DefaultDoc' . chr(127) . $vpath . "\n");
  1407.   }
  1408.  
  1409.   if($self->{'DefaultDocFooter'})
  1410.   {
  1411.     #$vfile = join
  1412.     #(
  1413.     #  '',
  1414.     #  ## $self->{'vddrive'},
  1415.     #  ## $self->{'vpath'},
  1416.     #  "/",
  1417.     #  $self->{'name'},
  1418.     #  "-docfooter."
  1419.     #);
  1420.     #
  1421.     #if($self->{'DefaultDocFooterType'} eq "text/html" )
  1422.     #{
  1423.     #  $vfile = join('', $vfile, "html" );
  1424.     #}
  1425.     #else
  1426.     #{
  1427.     #  $vfile = join( '', $vfile, "txt" ) ;
  1428.     #}
  1429.     #
  1430.     #$vfile =~ tr/\//\\/ ;   # Forward slash to backslash.
  1431.     #IISCore::writeline('VSET', "$pfx/$self->{'root'} DefaultDocFooter", $vfile);
  1432.     #IISCore::writeline('VSET', "$pfx/$self->{'root'} EnableDocFooter", "1");
  1433.   }
  1434.  
  1435.   if('' ne topmain::trim($self->{'HttpRedirect'}))
  1436.   {
  1437.     print('VSET     ' . chr(127) . "$pfx/$self->{'root'}" . chr(127) . 'HttpRedirect' . chr(127) . $self->{'HttpRedirect'} . "\n");
  1438.   }
  1439. }
  1440.  
  1441. sub write_filelist
  1442. {
  1443.   if($self->{'skip'})
  1444.   {
  1445.     return;
  1446.   }
  1447.  
  1448.   my $self = shift ;
  1449.   my $pfx  = shift ;
  1450.  
  1451.   #IISCore::writeline( 'VCREATE', "$pfx $self->{'root'}" ) ;
  1452.   $vpath = $self->{'vddrive'} . $self->{'vpath'} ;
  1453.   # $vpath =~ tr/\//\\/ ;       # Forward slash to backslash.
  1454.   #IISCore::writeline( 'VSET', "$pfx $self->{'root'} Path", $vpath ) ;
  1455.  
  1456.   # Create file copy list.
  1457.   use File::Find ;
  1458.   undef @vfilelist ;
  1459.   find( \&IISVirtualDir::vdir_wanted, $self->{'dir'} ) ;
  1460.   $len = length( $self->{'dir'} ) ;
  1461.   #IISCore::writeline( 'VFCOUNT', "$pfx $self->{'root'}", scalar(@vfilelist) ) ;
  1462.   $vdir_spec = $pfx . ' ' . $self->{'root'} ;
  1463.  
  1464.   my $checksrc;
  1465.   my $scriptdir = $self->{'scriptdir'};
  1466.   # my $docdir = $self->{'docdir'};
  1467.   
  1468.   topmain::printDirs($self->{'dir'}, $scriptdir, $topmain::myDocDir);
  1469.  
  1470.   for($i = 0; $i < scalar(@vfilelist); $i++ )
  1471.   {
  1472.     $src = $vfilelist[$i] ;
  1473.     # $src =~ tr/\//\\/ ;       # Forward slash to backslash.
  1474.     $src =~ tr/\s*$//;
  1475.     $checksrc = $src;
  1476.     #$checksrc =~ tr/a-z/A-Z/;
  1477.     
  1478.     if((index($checksrc, $topmain::myScriptDir) != 0) && (index($checksrc, $topmain::myDocDir) != 0))
  1479.     {
  1480.       $dst = substr($vfilelist[$i], $len) ;
  1481.       #$dst =~ tr/\//\\/ ;     # Forward slash to backslash.
  1482.       $self->write_copyfile($vdir_spec, $src, $dst);
  1483.     }        
  1484.   }
  1485.  
  1486.   @content = keys ( %{$self->{'copyfile'}} ) ;
  1487.   foreach $key ( @content )
  1488.   {
  1489.     $self->write_copyfile( $vdir_spec, $key, $self->{'copyfile'}{$key} ) ;
  1490.   }
  1491.  
  1492.   # Document footer.
  1493.   if ( $self->{'DefaultDocFooter'} ) {
  1494.       $vfile = join(
  1495.                       '',
  1496. ##                      $self->{'vddrive'},
  1497. ##                      $self->{'vpath'},
  1498.                       "/",
  1499.                       $self->{'name'},
  1500.                       "-docfooter."
  1501.                       ) ;
  1502.         if ( $self->{'DefaultDocFooterType'} eq "text/html" ) {
  1503.             $vfile = join( '', $vfile, "html" ) ;
  1504.         } else {
  1505.             $vfile = join( '', $vfile, "txt" ) ;
  1506.         }
  1507.         # $vfile =~ tr/\//\\/ ;   # Forward slash to backslash.
  1508.         #IISCore::writeline( 'VFILE', "$pfx $vfile",  $self->{'DefaultDocFooter'} ) ;
  1509.     }
  1510. }
  1511.  
  1512.  
  1513. # --------------------------------------------------------------------------------
  1514. # Method to write statement to .files file
  1515. #
  1516. sub write_copyfile
  1517. {
  1518.   my $theSelf = shift;
  1519.   my $theVdirSpec = shift;
  1520.   my $theSource = shift;
  1521.   my $theDestination = shift;
  1522.  
  1523.   my $theNewDest = substr($theSource, index($theSource, "\\") + 1);
  1524.   $theNewDest =~ tr/\//\\/;
  1525.  
  1526.   print "$theSource\nInetpub\\$topmain::myServerName$theNewDest\n";
  1527. }
  1528. # --------------------------------------------------------------------------------
  1529.  
  1530.  
  1531. sub vdir_wanted {
  1532.     push( @vfilelist, $File::Find::name ) if -f ;
  1533. }
  1534.  
  1535. sub dump {
  1536.     my $self = shift ;
  1537.     print( "dump($self->{'class'})\n" ) ;
  1538.     $tab = "  " ;
  1539.     @content = keys( %$self ) ;
  1540.     foreach $key ( sort @content ) {
  1541.         printf( "%s%-20s = %s\n", $tab, $key, $self->{$key} ) ;
  1542.     }
  1543. }
  1544.  
  1545.  
  1546. #############################################################################
  1547. #
  1548. #   IISMimeMap
  1549. #
  1550. #############################################################################
  1551. package     IISMimeMap ;
  1552. require     Exporter ;
  1553. @ISA    = qw( Exporter ) ;
  1554. @EXPORT = qw( write, dump ) ;
  1555.  
  1556. sub new {
  1557.     my $class        = shift ;
  1558.     my %params       = @_ ;
  1559.     my $self         = {} ;
  1560.     $self->{'class'} = $class ;
  1561.     bless $self, $class ;
  1562.     print( "NEW $class\n" ) if ( $IISCore::debug ) ;
  1563.  
  1564.     $self->{'MimeMap'}  = $params{'MimeMap'} ;
  1565.     $self->{'serverno'} = $params{'serverno'} ;
  1566.     $self->_construct() ;
  1567.  
  1568.     return $self ;
  1569. }
  1570.  
  1571. sub _construct {
  1572.     my $self = shift ;
  1573.     print( "CONSTRUCT $self->{'class'}\n" ) if ( $IISCore::debug ) ;
  1574.     $self->{'root'} = "ROOT" ;
  1575. }
  1576.  
  1577. sub write
  1578. {
  1579.   my $self = shift;
  1580.   my $pfx  = shift;
  1581.  
  1582.   if(! ($topmain::myServerSettings{$self->{'serverno'}} =~ /m=1/))
  1583.   {
  1584.     return;
  1585.   }
  1586.  
  1587.   topmain::logMessage($topmain::myLogNOTICE, "Migrating MIME types for server: $self->{'serverno'}");
  1588.   #xyz
  1589.   #IISCore::writeline( '#VCREATE', "$pfx $self->{'root'}" );
  1590.  
  1591.   my @theMimeTypes = split(']', $self->{'MimeMap'});
  1592.  
  1593.   foreach $theMimeType (@theMimeTypes)
  1594.   {
  1595.     $theMimeType = topmain::trim($theMimeType);
  1596.     $theMimeType = substr($theMimeType, 1);
  1597.     #$theMimeType =~ s/,/\x7f/;
  1598.  
  1599.     my @theTypeParts = split(',', $theMimeType);
  1600.     my $thePropertyData = $theTypeParts[1] . chr(127) . $theTypeParts[0];
  1601.     
  1602.     #IISCore::writeline( 'VSET', chr(127) . "$pfx/$self->{'root'}" . chr(127) . "MimeMap" . chr(127), $thePropertyData);
  1603.     IISCore::writeline( 'VSET', chr(127) . "$pfx" . chr(127) . "MimeMap" . chr(127), $thePropertyData); 
  1604.   }
  1605. }
  1606.  
  1607. sub dump {
  1608.     my $self = shift ;
  1609.     print( "dump($self->{'class'})\n" ) ;
  1610.     $tab = "  " ;
  1611.     @content = keys( %$self ) ;
  1612.     foreach $key ( sort @content ) {
  1613.         printf( "%s%-20s = %s\n", $tab, $key, $self->{$key} ) ;
  1614.     }
  1615. }
  1616.  
  1617.  
  1618. #############################################################################
  1619. #
  1620. #   IISUserDb - NT Resource Kit 'addusers' migration object.
  1621. #
  1622. #############################################################################
  1623. package     IISUserDb ;
  1624. require     Exporter ;
  1625. #use         IIsLDIF ;
  1626. @ISA    = qw( Exporter ) ;
  1627. @EXPORT = qw( write, dump ) ;
  1628.  
  1629. sub new {
  1630.     use File::Basename ;
  1631.     my $class        = shift ;
  1632.     my %params       = @_ ;
  1633.     my $self         = {} ;
  1634.     $self->{'class'} = $class ;
  1635.     bless $self, $class ;
  1636.     topmain::dbgOut( "NEW $class" ) if ( $IISCore::debug ) ;
  1637.  
  1638.     $self->{'fullpath'} = $params{'fullpath'} ;
  1639. #    $self->{'path'}     = $params{'path'} ;
  1640. #    $self->{'file'}     = $params{'file'} ;
  1641.     $self->{'userobj'}  = $params{'userobj'} ;
  1642.     $self->{'userglob'}  = $params{'userglob'} ;
  1643.  
  1644.     # Break path, filename into separate components from fullpath.
  1645.     $xpath = $self->{'fullpath'} ;
  1646.     $xpath =~ tr/\\/\// ;  # Backslash to Forward slash.
  1647.     ( $fname, $fpath, $fsfx ) = fileparse( $xpath ) ;
  1648.     $self->{'path'} = $fpath ;
  1649.     $self->{'file'} = $fname ;
  1650.  
  1651.     # Ask user database object to fill in our parameters.
  1652.     $self->{'userobj'}->new( $self ) ;
  1653.  
  1654.     return $self ;
  1655. }
  1656.  
  1657. sub _construct {
  1658.     my $self = shift ;
  1659.     topmain::dbgOut( "CONSTRUCT $self->{'class'}" ) if ( $IISCore::debug ) ;
  1660. }
  1661.  
  1662. sub write {
  1663.     my $self      = shift ;
  1664.     my $webserver = shift ;
  1665.     my $domain    = shift ;
  1666.     my $filename  = shift ;
  1667.  
  1668.     print( "WRITE $self->{'class'}\n" ) if ( $IISCore::debug ) ;
  1669.  
  1670.    #( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = localtime(time) ;
  1671.    #$year += 1900 ;
  1672.    #$file = sprintf( "%s.%4d%02d%02d.users", $webserver, $year, $mon+1, $mday ) ;
  1673.     $file = $filename ;
  1674.  
  1675.     #
  1676.     # Write 'addusers' file.
  1677.     #
  1678.     open( FILE, ">" . $file ) or die( "Could not open $file" ) ;
  1679.     select( FILE ) ;
  1680.  
  1681.     print( "[User]\n" ) ;
  1682.     foreach $key ( keys %{$self->{'user'}} )
  1683.     {
  1684.       printf( "apu%s,%s,,%s,,,,\n",
  1685.         $self->{'user'}{$key}{'uid'},
  1686.         $self->{'user'}{$key}{'name'},
  1687.         $self->{'user'}{$key}{'title'}) ;
  1688.     }
  1689.  
  1690.     print( "\n" ) ;
  1691.     print( "[Global]\n" ) ;
  1692.     print( "\n" ) ;
  1693.     
  1694.     print( "[Local]\n" ) ;
  1695.     foreach $key ( keys %{$self->{'local'}} ) 
  1696.     {
  1697.       my $atLeastOne = 0;
  1698.       my $prefix = 'apg';
  1699.  
  1700.       printf( "%s%s,Group%s",
  1701.         $prefix,
  1702.         $self->{'local'}{$key}{'name'},
  1703.         $self->{'local'}{$key}{'description'}) ;
  1704.       
  1705.       @members = keys( %{$self->{'local'}{$key}{'uniquemember'}} ) ;
  1706.       
  1707.       foreach $member ( sort @members )
  1708.       {
  1709.         $atLeastOne = 1;
  1710.         #printf( ",$domain\\%s", $self->{'user'}{$member}{'uid'} ) ;
  1711.         printf( ",apu%s", $self->{'user'}{$member}{'uid'} ) ;
  1712.       }
  1713.         
  1714.       if(! $atLeastOne)
  1715.       {
  1716.         print ',';
  1717.       }
  1718.         
  1719.       print( "\n" ) ;
  1720.     }
  1721.  
  1722.     print( "\n" ) ;
  1723.     close( FILE ) ;
  1724.     select( STDOUT ) ;
  1725. }
  1726.  
  1727. sub dump {
  1728.     my $self = shift ;
  1729.     topmain::dbgOut( "dump($self->{'class'})" ) ;
  1730.     $tab = "  " ;
  1731.     @content = keys( %$self ) ;
  1732.     foreach $key ( sort @content ) {
  1733.       topmain::dbgOut( sprintf("%s%-20s = %s", $tab, $key, $self->{$key}) ) ;
  1734.     }
  1735. }
  1736.  
  1737.  
  1738. #############################################################################
  1739. #
  1740. #   IISMuConf - Migration Utility web-server configuration.
  1741. #
  1742. #############################################################################
  1743. package     IISMuConf ;
  1744. require     Exporter ;
  1745. @ISA    = qw( Exporter ) ;
  1746. @EXPORT = qw( addmacrodef, write, dump ) ;
  1747.  
  1748. sub new {
  1749.     my $class        = shift ;
  1750.     my %params       = @_ ;
  1751.     my $self         = {} ;
  1752.     $self->{'class'} = $class ;
  1753.     bless $self, $class ;
  1754.     print( "NEW $class\n" ) if ( $IISCore::debug );
  1755.  
  1756.     $self->{'fileglob'}       = $params{'fileglob'};
  1757.     $self->{'fileout'}        = $params{'tempdir'} . 'iismu';   # $params{'fileout'};
  1758.     $self->{'iiswwwroot'}     = $params{'iiswwwroot'};
  1759.     $self->{'ldifdomain'}     = $params{'ldifdomain'};
  1760.     $self->{'perlmod'}        = 'IISMuAP.pm';                   # $params{'perlmod'};
  1761.     $self->{'serverobj'}      = 'IISServerAP';                  # $params{'serverobj'};
  1762.     $self->{'userdbfullpath'} = $params{'userdbfullpath'};
  1763.     $self->{'userobj'}        = 'IISUserDbAP';                 # $params{'userobj'};
  1764.     $self->{'version'}        = '3.x';                          # $params{'version'};
  1765.     $self->{'webserver'}      = 'AP';                          # $params{'webserver'};
  1766.     $self->{'whoami'}         = 'Apache';   # $params{'whoami'};
  1767.     $self->{'wwwroot'}        = $params{'wwwroot'} ;
  1768.     $self->{'wwwcgishl'}      = $params{'wwwcgishl'};
  1769.     $self->{'wwwsupp'}        = $params{'wwwsupp'};
  1770.     $self->{'remote'}         = $params{'remote'};
  1771.     $self->{'userglob'}       = $params{'userglob'};
  1772.     $self->{'defaultdrive'}   = $params{'defaultdrive'};
  1773.     $self->{'computerobj'}    = 'IISComputerAP';               # $params{'computerobj'};
  1774.     
  1775.     $fpath = $self->{'wwwroot'} ;
  1776.     $fpath =~ tr/\\/\// ; # Backslash to Forward slash.
  1777.     if ( '/' ne substr($fpath, length($fpath)-1) ) {
  1778.         $fpath .= '/' ;
  1779.     }
  1780.     $self->{'fullpath'} = $fpath ;
  1781.     
  1782.     #
  1783.     # Save support directory on our INC path.
  1784.     push( @INC, $self->{'wwwsupp'} ) ;
  1785.     print( "INC @INC\n" ) if ( $IISCore::debug ) ;
  1786.  
  1787.     #
  1788.     # Verify key parameters.
  1789.     unless ( $self->{'wwwroot'} ) {
  1790.         print( "No 'wwwroot' in file $webserverconf\n" ) ;
  1791.         $@ = $! ;
  1792.         return undef ;
  1793.     }
  1794.     unless ( $self->{'serverobj'} ) {
  1795.         print( "No 'serverobj' in file $webserverconf\n" ) ;
  1796.         $@ = $! ;
  1797.         return undef ;
  1798.     }
  1799.  
  1800.     $self->dump() if ( $IISCore::debug ) ;
  1801.     
  1802.     return $self ;
  1803. }
  1804.  
  1805. sub write {
  1806.     my $self = shift ;
  1807.  
  1808. #    print( "#############################################\n" ) ;
  1809. #    printf( "#\n# IIS 4.0 Migration Wizard Scavenger %s\n", &IISCore::version() ) ;
  1810. #    print( "# $self->{'whoami'} $self->{'version'} Migration\n" ) ;
  1811. #    ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = localtime(time) ;
  1812. #    $year += 1900 ;
  1813. #    printf( "# %4d-%02d-%02d %02d:%02d\n", $year, $mon+1, $mday, $hour, $min ) ;
  1814. #    print( "#\n#" ) ;
  1815. #    print( "#############################################\n\n" ) ;
  1816. }
  1817.  
  1818. sub dump {
  1819.     my $self = shift ;
  1820.     print( "dump($self->{'class'})\n" ) ;
  1821.     $tab = "  " ;
  1822.     @content = keys( %$self ) ;
  1823.     foreach $key ( sort @content ) {
  1824.         printf( "%s%-20s = %s\n", $tab, $key, $self->{$key} ) ;
  1825.     }
  1826.  
  1827.     @content = keys( %{$self->{'tokenmap'}} ) ;
  1828.     foreach $key ( sort @content ) {
  1829.         printf( "%s%-20s = %s\n", $tab, $key, $self->{'tokenmap'}{$key} ) ;
  1830.     }
  1831. }
  1832.  
  1833.  
  1834.  
  1835.  
  1836. #############################################################################
  1837. #
  1838. #   IISMigConf - IIS migration configuration.
  1839. #
  1840. #############################################################################
  1841. package     IISMigConf ;
  1842. require     Exporter ;
  1843. @ISA    = qw( Exporter ) ;
  1844. @EXPORT = qw( dump ) ;
  1845.  
  1846. sub new {
  1847.     use Cwd ;
  1848.     use File::Basename ;
  1849.     
  1850.     my $class        = shift ;
  1851. #    my %params       = @_ ;
  1852.     my $self         = {} ;
  1853.     $self->{'class'} = $class ;
  1854.     bless $self, $class ;
  1855.     print( "NEW $class\n" ) if ( $IISCore::debug ) ;
  1856.  
  1857.     #
  1858.     # Get web configuration file name.
  1859.     %webservers = (
  1860.                    'NE2' => 'iismine2.conf',
  1861.                    'NE3' => 'iismine3.conf',
  1862.                    ) ;
  1863.  
  1864.     $self->{'webserver'} = shift ;
  1865.     $self->{'webserver'} = uc( $self->{'webserver'} ) ;
  1866.     if ( !$self->{'webserver'} or !$webservers{$self->{'webserver'}} ) {
  1867.         $self->{'webserver'} = 'NE2' ;
  1868.     }
  1869.     $self->{'file'} = $webservers{$self->{'webserver'}} ;
  1870.     unless ( $self->{'file'} ) {
  1871.         print( "No web server configuration file for $self->{'webserver'}\n" ) ;
  1872.         $@ = $! ;
  1873.         return undef ;
  1874.     }
  1875.  
  1876.     #
  1877.     # Read file.
  1878.     open( FILE, $self->{'file'} ) or ( $@ = $!, return undef ) ;
  1879.     while ( <FILE> ) {
  1880.         next if /^\s*$/ ;
  1881.         next if /^#/ ;
  1882.         chomp( $_ ) ;
  1883.         ( $name, $value ) = split( /\s*=\s*/, $_ );
  1884.         $self->{$name} = $value ;
  1885.     }
  1886.     close( FILE ) ;
  1887.  
  1888.     #
  1889.     $curdir = cwd() ;
  1890.     ($curdrive) = split( ':', $curdir ) ;
  1891.     unless ( $self->{'sdir'} ) {
  1892.         $self->{'sdir'} = $curdrive . ":" ;
  1893.     }
  1894. #    $self->{'sdir'} = join( '', $self->{'sdir'}, ":" ) ;
  1895.     unless ( $self->{'ddir'} ) {
  1896.         $self->{'ddir'} = $curdrive ;
  1897.     }
  1898. #    $self->{'ddir'} = join( '', $self->{'ddir'}, ":/", $self->{'wwwroot'} ) ;
  1899.     $self->{'ddir'} = join( '', $self->{'ddir'}, $self->{'wwwroot'} ) ;
  1900.     unless ( $self->{'nserver'} ) {
  1901.         $self->{'nserver'} = '2' ;
  1902.     }
  1903.     
  1904.     $self->dump() if ( $IISCore::debug ) ;
  1905.  
  1906.     return $self ;
  1907. }
  1908.  
  1909. sub dump {
  1910.     my $self = shift ;
  1911.     print( "dump($self->{'class'})\n" ) ;
  1912.     $tab = "  " ;
  1913.     @content = keys( %$self ) ;
  1914.     foreach $key ( sort @content ) {
  1915.         printf( "%s%-20s = %s\n", $tab, $key, $self->{$key} ) ;
  1916.     }
  1917. }
  1918.  
  1919.  
  1920. #############################################################################
  1921. #
  1922. #   IISCore - utility functions.
  1923. #
  1924. #############################################################################
  1925. package     IISCore ;
  1926. require     Exporter ;
  1927. @ISA    = qw( Exporter ) ;
  1928. @EXPORT = qw( expandmacros, setdebug, webserver, writeline) ;
  1929.  
  1930. sub new {
  1931.     my $class        = shift ;
  1932.     my %params       = @_ ;
  1933.     my $self         = {} ;
  1934.     $self->{'class'} = $class ;
  1935.     bless $self, $class ;
  1936.  
  1937.     return $self ;
  1938. }
  1939.  
  1940. #
  1941. # expandmacros
  1942. #   expand all macros '<<macro>>' in input string 'istr' using web
  1943. #   configuration's token map.
  1944. #
  1945. #   Numeric macros '<<n>>' are assumed to be virtual server instances.
  1946. #   The value 'nserver' is added by the macro processing to arrive at
  1947. #   the final virtual server instance value.
  1948. #
  1949. #
  1950. #   Returns expanded string or original string if no macros expanded.
  1951. #
  1952. sub expandmacros {
  1953.     my( $istr, $webconf ) = @_ ;
  1954.     my $ostr ;
  1955.     my $s1 ;
  1956.     my $s2 ;
  1957.     my $s3 ;
  1958.     my $i ;
  1959.  
  1960.     my @tokens = split( "<<", $istr ) ;
  1961.     $ostr = $tokens[0] ;
  1962.     for ( $i = 1 ; $i < scalar(@tokens) ; $i++ ) {
  1963.         ( $s1, $s2 ) = split( '>>', $tokens[$i] ) ;
  1964.         $s3 = lc( $s1 ) ;       # Macros are case-insensitive.
  1965.         if ( $webconf->{'tokenmap'}{$s3} ) {
  1966.             $s1 = $webconf->{'tokenmap'}{$s3} ;
  1967.         }
  1968.         # If this is a <<n>> macro, add virtual server base value.
  1969.         if ( ($s1 =~ /[0-9]+/) and !($s1 =~ /[a-z,A-Z]/) ) {
  1970.             $s1 += $webconf->{'tokenmap'}{'nserver'} + 1 ;
  1971.         }
  1972.         $ostr = join( '', $ostr, $s1, $s2 ) ;
  1973.     }
  1974.  
  1975.     print( "EXPANDED |$istr| -> |$ostr|\n" ) if ( $IISCore::debug ) ;
  1976.     return $ostr ;
  1977. }
  1978.  
  1979.  
  1980. #
  1981. # setdebug
  1982. #
  1983. sub setdebug {
  1984.     my( $dbf ) = @_ ;
  1985.     $IISCore::debug = $dbf ;
  1986.     print( "DEBUG = $IISCore::debug\n" ) if ( $IISCore::debug ) ;
  1987. }
  1988.  
  1989. #
  1990. # version
  1991. #
  1992. sub version {
  1993.     return sprintf( "1.0.4" ) ;
  1994. }
  1995.  
  1996. #
  1997. # writeline - Write a command line in intermediate file format.
  1998. #
  1999. sub writeline {
  2000.     my( $vcmd, $vpath, $vparm ) = @_ ;
  2001.     printf( "%-8s %s%s\n", $vcmd, $vpath, $vparm) ;
  2002. }
  2003.  
  2004. #
  2005.  
  2006. # sprintf_vstring - Return formatted string suitable for intermediate data file.
  2007. # String format is:
  2008. #   <string-size> <string>
  2009. #
  2010. sub sprintf_vstring {
  2011.     my ( $str ) = @_ ;
  2012.     return sprintf( "%d %s", length($str), $str ) ;
  2013. }
  2014.  
  2015. #############################################################################
  2016. #   !_IISMUCORE_PM  NO CODE BEYOND THIS POINT
  2017. 1 ;
  2018.  
  2019.  
  2020.  
  2021. #############################################################################
  2022. #
  2023. # IISMuAP.pm
  2024. #
  2025. # Copyright (c) MicroCrafts Corporation, 1997
  2026. #
  2027. #  IIS 4.0 Resource Kit Migration Utilty Perl module for Netscape
  2028. #  Enterprise 2.x, SuiteSpot 3.x
  2029. #
  2030. #############################################################################
  2031.  
  2032.  
  2033. #############################################################################
  2034. #
  2035. #   IISComputerAP
  2036. #
  2037. #############################################################################
  2038. package     IISComputerAP ;
  2039. use         Cwd ;
  2040. require     Exporter ;
  2041. @ISA    = qw( Exporter ) ;
  2042. @EXPORT = qw( dump ) ;
  2043.  
  2044. sub new
  2045. {
  2046.   my $class = shift;
  2047.   #my %params = @_;
  2048.   my $self = {};
  2049.   my $otherself = shift;
  2050.  
  2051.   $self->{'_AClass'} = $class;
  2052.   bless $self, $class ;
  2053.   topmain::dbgOut("NEW $class") if ($IISCore::debug );
  2054.  
  2055.   $self->_construct( $otherself );
  2056.   return $self;
  2057. }
  2058.  
  2059. sub _construct
  2060. {
  2061.   my ($self, $otherself) = @_;
  2062.   topmain::dbgOut( "CONSTRUCT $self->{'_AClass'} USING $otherself" ) if ( $IISCore::debug ) ;
  2063.     
  2064.   # For each virtual host, add a virtual server object.
  2065.   my @vservers = keys(%{$otherself->{'vserver'}});
  2066.   my $n = scalar( @vservers ) + 1;
  2067.   my $conf;
  2068.   my $confobj;
  2069.   my $content;
  2070.   my $key;
  2071.   my $vhost;
  2072.   my $vhosts;
  2073.   my $vsvr1;
  2074.   my $vsvr2;
  2075.  
  2076.   foreach $key (sort @vservers)
  2077.   {
  2078.     $vsvr1 = $otherself->{'vserver'}{$key} ;
  2079.     $vsvr2 = $vsvr1->{'otherself'};
  2080.     @content = keys(%{$vsvr2} );
  2081.  
  2082.     foreach $conf (sort @content)
  2083.     {
  2084.       if ( $vsvr2->{$conf} =~ m'iisconfap'i )
  2085.       {
  2086.         $confobj = $vsvr2->{$conf} ;
  2087.         @vhosts = keys( %{$confobj->{'VirtualHost'}} ) ;
  2088.  
  2089.         foreach $vhost ( sort @vhosts )
  2090.         {
  2091.           if ( defined($confobj->{'VirtualHost'}{$vhost}) )
  2092.           {
  2093.             $self->_addServer( $otherself, $confobj->{'VirtualHost'}{$vhost}, $n ) ;
  2094.             $n++ ;
  2095.           }
  2096.         }
  2097.       }
  2098.     }
  2099.   }
  2100. }
  2101.  
  2102.  
  2103. # 'VirtualHost' directive.
  2104. sub _addServer {
  2105.   my ( $self, $otherself, $conf, $n ) = @_ ;
  2106.     my $dirname = $conf->{'_AName'} ;
  2107.     topmain::dbgOut( "$self ::_addServer( $n, $dirname ) to $otherself" ) if ( $IISCore::debug ) ;
  2108.     my $path = $dirname ;
  2109.     if ( $dirname =~ m'/$' ) { #'
  2110.         chop( $dirname ) ;
  2111.     }
  2112.     if ( $path =~ m'/$' ) { #'
  2113.         chop( $path ) ;
  2114.     }
  2115.  
  2116.     my $vsvr = IISServer->new(
  2117.                               'name'      => $dirname,
  2118.                               'path'      => $path,
  2119.                               'serverno'  => $n,
  2120.                               'serverobj' => 'IISServerAPEx',
  2121.                               'webconf'   => $otherself->{'webconf'}
  2122.                               ) ;
  2123.  
  2124.     # ROOT virtual directory.
  2125.     # NB: [0] reserved for this server ROOT.
  2126.     my $rootdir = IISServerAP::_getProperty( $self, 'DocumentRoot', $conf ) ;
  2127.     if ( $rootdir =~ m'/$' ) { #'
  2128.         chop( $rootdir ) ;
  2129.     }
  2130.     my $newvdir = IISVirtualDir->new(
  2131.                                      'from' => '',
  2132.                                      'dir'  => $rootdir,
  2133.                                      'type' => '',
  2134.                                      'name' => $dirname
  2135.                                      ) ;
  2136.     IISServerAP::_fancyIndexing( $self, $vsvr, $conf ) ;
  2137.     $vsvr->{'DirBrowseFlags'} .= ' Enabled' if ( $vsvr->{'_fancyIndexing'} =~ m'on'i ) ;
  2138.     IISServerAP::_options( $self, $vsvr, $conf->{'Options'} ) ;
  2139.     @{$vsvr->{'vdir'}}[0] = $newvdir ;
  2140.  
  2141.     # Server bindings.
  2142.     #JAQ $vsvr->AddServerBinding( '', $conf->{'Port'}, $dirname ) ;
  2143.     IISServer::AddServerBinding( $vsvr, '', $conf->{'Port'}, $dirname ) ;
  2144.     IISServerAP::_serverBindings( $self, $vsvr, $conf ) ;
  2145.  
  2146.     # Alias (virtual directories).
  2147.     IISServerAP::_aliasVDir( $self, $vsvr, $conf ) ;
  2148.  
  2149.     # ScriptAlias (virtual directories).
  2150.     IISServerAP::_scriptAliasVDir( $self, $vsvr, $conf ) ;
  2151.  
  2152.     # Allow keep alive.
  2153.     IISServerAP::_keepAlive( $self, $vsvr, $conf ) ;
  2154.     #IISServerAP::_setProperty( $self, $vsvr, 'KeepAlive', 'AllowKeepAlive', $conf ) ;
  2155.  
  2156.     # Connection timeout.
  2157.     IISServerAP::_setProperty( $self, $vsvr, 'Timeout', 'ConnectionTimeout', $conf ) ;
  2158.  
  2159.     # Default document.
  2160.     IISServerAP::_defaultDoc( $self, $vsvr, $conf ) ;
  2161.  
  2162.     # Max connections.
  2163.     IISServerAP::_setProperty( $self, $vsvr, 'MaxClients', 'MaxConnections', $conf ) ;
  2164.  
  2165.     IISServerAP::_redirects($self, $vsvr, $conf);
  2166.     IISServerAP::_hostNameLookups($self, $vsvr, $conf);
  2167.     IISServerAP::_identityCheck($self, $vsvr, $conf);
  2168.     IISServerAP::_errorDocument($self, $vsvr, $conf);
  2169.  
  2170.     my $tc;
  2171.     if($conf->{'TypesConfig'})
  2172.     {
  2173.       $tc = $conf->{'TypesConfig'};
  2174.     }
  2175.     
  2176.     my $mimetypes = IISMimeMapAP->new('_AFile' => $tc,
  2177.       'serverno' => $vsvr->{'serverno'});
  2178.     
  2179.     # Server comment.
  2180.     $vsvr->{'ServerComment'} = $conf->{'ServerName'} if ( $conf->{'ServerName'} ) ;
  2181.     my $servercomment = IISServerAP::_getProperty( $self, 'User', $conf ) ;
  2182.     $vsvr->{'ServerComment'} = $servercomment unless $vsvr->{'ServerComment'} ;
  2183.  
  2184.     # Handle '<Directory>' directives.
  2185.     IISServerAP::_directory( $self, $vsvr, $conf, $rootdir ) ;
  2186.     
  2187.     # UserDir (virtual directories).
  2188.     IISServerAP::_userDir( $self, $vsvr, $conf ) ;
  2189.     
  2190.     IISServerAP::_mimeMap($self, $mimetypes, $conf);
  2191.     $mimetypes->_exportMimeTypes( $vsvr ) ;
  2192.     
  2193.     ##################################################
  2194.     #
  2195.     # NB: Must do - complete construction of objects
  2196.     #
  2197.     ##################################################
  2198.     #JAQ $vsvr->_construct() ;
  2199.     IISServer::_construct( $vsvr ) ;
  2200.     
  2201.     # Add to IISComputer object.
  2202.     $otherself->{'vserver'}{$n} = $vsvr ;
  2203. }
  2204.  
  2205.  
  2206. #############################################################################
  2207. #
  2208. #   IISServerAP
  2209. #
  2210. #############################################################################
  2211. package     IISServerAP ;
  2212. require     Exporter ;
  2213. use         Cwd ;
  2214. @ISA    = qw( Exporter ) ;
  2215. @EXPORT = qw( dump ) ;
  2216.  
  2217. sub new {
  2218.     my $class        = shift ;
  2219. #    my %params      = @_ ;
  2220.     my $self         = {} ;
  2221.     my $otherself    = shift ;
  2222.     $self->{'_AClass'} = $class ;
  2223.     bless $self, $class ;
  2224.     print( "NEW $class USING $otherself \n" ) if ( $IISCore::debug ) ;
  2225.  
  2226.     $rc = $self->_construct( $otherself ) ;
  2227.  
  2228.     unless ( defined($rc) ) {
  2229.         $@ = $!;
  2230.         return undef;
  2231.     }
  2232.         
  2233.     return $self ;
  2234. }
  2235.  
  2236. sub _construct
  2237. {
  2238.   my( $self, $otherself ) = @_ ;
  2239.     print( "CONSTRUCT $self->{'_AClass'} USING $otherself\n" ) if ( $IISCore::debug ) ;
  2240.     my $olddir = cwd() ;
  2241.  
  2242.     #
  2243.     # Parse configuration file(s).
  2244.     chdir( $otherself->{'path'} ) or return undef ;
  2245.     my $httpd    = IISConfAP->new( '_AFile' => 'httpd.conf' ) ;
  2246.     if ( !defined($httpd) ) {
  2247.         chdir( $olddir ) ;
  2248.         return undef ;
  2249.     }
  2250.     $self->_httpdDefaults( $httpd ) ;
  2251.     my $srm       = IISConfAP->new( '_AFile' => $httpd->{'ResourceConfig'} ) ;
  2252.     my $access    = IISConfAP->new( '_AFile' => $httpd->{'AccessConfig'} ) ;
  2253.     my $tc ;
  2254.     if ( $httpd->{'TypesConfig'} ) {
  2255.         $tc = $httpd->{'TypesConfig'} ;
  2256.     } elsif ( $srm->{'TypesConfig'} ) {
  2257.         $tc = $srm->{'TypesConfig'} ;
  2258.     } elsif ( $access->{'TypesConfig'} ) {
  2259.         $tc = $access->{'TypesConfig'} ;
  2260.     } else {
  2261.         $tc = 'mime.types' ;
  2262.     }
  2263.     my $mimetypes = IISMimeMapAP->new( '_AFile'   => $tc,
  2264.       'serverno' => $otherself->{'serverno'} ) ;
  2265.  
  2266.     $self->_srmDefaults( $srm ) ;
  2267.  
  2268.     # Directory browsing enable for entire server.
  2269.     $self->_fancyIndexing( $otherself, ($access, $httpd, $srm) ) ;
  2270.     $otherself->{'DirBrowseFlags'} .= ' Enabled' if ( $otherself->{'_fancyIndexing'} =~ m'on'i ) ;
  2271.     
  2272.     # Determine document root, giving preference to last 'conf' object in parameter list.
  2273.     my $rootdir = $self->_getProperty( 'DocumentRoot', $access, $httpd, $srm ) ;
  2274.     if ( $rootdir =~ m'/$' ) { #'
  2275.         chop( $rootdir ) ;
  2276.     }
  2277.  
  2278.     # ROOT virtual directory.
  2279.     # NB: [0] reserved for this server ROOT.
  2280.     my $rvdir = IISVirtualDir->new(
  2281.                                      'from' => '',
  2282.                                      'dir'  => $rootdir,
  2283.                                      'type' => '',
  2284.                                      'name' => $otherself->{'name'}
  2285.                                      ) ;
  2286.     $rvdir->{'DirBrowseFlags'} .= ' Enabled' if ( $otherself->{'_fancyIndexing'} =~ m'on'i ) ;
  2287.     @{$otherself->{'vdir'}}[0] = $rvdir ;
  2288.     
  2289.     # HostNameLookup
  2290.     $self->_hostNameLookups( $otherself, $access ) ;
  2291.     $self->_hostNameLookups( $otherself, $srm ) ;
  2292.     $self->_hostNameLookups( $otherself, $httpd ) ;
  2293.  
  2294.     # IdentityCheck
  2295.     $self->_identityCheck( $otherself, $access ) ;
  2296.     $self->_identityCheck( $otherself, $srm ) ;
  2297.     $self->_identityCheck( $otherself, $httpd ) ;
  2298.  
  2299.     # ListenBacklog
  2300.     $self->_listenBacklog( $otherself, $access ) ;
  2301.     $self->_listenBacklog( $otherself, $srm ) ;
  2302.     $self->_listenBacklog( $otherself, $httpd ) ;
  2303.  
  2304.     # Server bindings.
  2305.     $self->_serverBindings( $otherself, $access ) ;
  2306.     $self->_serverBindings( $otherself, $srm ) ;
  2307.     $self->_serverBindings( $otherself, $httpd ) ;
  2308.  
  2309.     # Alias (virtual directories).
  2310.     $self->_aliasVDir( $otherself, $access ) ;
  2311.     $self->_aliasVDir( $otherself, $httpd ) ;
  2312.     $self->_aliasVDir( $otherself, $srm ) ;
  2313.  
  2314.     # ScriptAlias (virtual directories).
  2315.     $self->_scriptAliasVDir( $otherself, $access ) ;
  2316.     $self->_scriptAliasVDir( $otherself, $httpd ) ;
  2317.     $self->_scriptAliasVDir( $otherself, $srm ) ;
  2318.     
  2319.     # Allow keep alive.
  2320.     $self->_keepAlive( $otherself, $access ) ;
  2321.     $self->_keepAlive( $otherself, $srm ) ;
  2322.     $self->_keepAlive( $otherself, $httpd ) ;
  2323.  
  2324.     # Connection timeout.
  2325.     $self->_setProperty( $otherself, 'Timeout', 'ConnectionTimeout', $access, $srm, $httpd ) ;
  2326.  
  2327.     # Default document.
  2328.     $self->_defaultDoc( $otherself, $access ) ;
  2329.     $self->_defaultDoc( $otherself, $httpd ) ;
  2330.     $self->_defaultDoc( $otherself, $srm ) ;
  2331.  
  2332.     # Default document.
  2333.     $self->_errorDocument($otherself, $access);
  2334.     $self->_errorDocument($otherself, $httpd);
  2335.     $self->_errorDocument($otherself, $srm);
  2336.  
  2337.     # Http Redirects
  2338.     $self->_redirects( $otherself, $access);
  2339.     $self->_redirects( $otherself, $http);
  2340.     $self->_redirects( $otherself, $srm);
  2341.  
  2342.     
  2343.     # Max connections.
  2344.     $self->_setProperty( $otherself, 'MaxClients', 'MaxConnections', $access, $srm, $httpd ) ;
  2345.  
  2346.     # Server comment.
  2347.     $self->_setProperty( $otherself, 'ServerName', 'ServerComment', $access, $srm, $httpd ) ;
  2348.     my $servercomment = $self->_getProperty( 'User', $access, $srm, $httpd ) ;
  2349.     $otherself->{'ServerComment'} = $servercomment unless $otherself->{'ServerComment'} ;
  2350.  
  2351.     # Mime maps.
  2352.     $self->_mimeMap( $mimetypes, $access ) ;
  2353.     $self->_mimeMap( $mimetypes, $httpd ) ;
  2354.     $self->_mimeMap( $mimetypes, $srm ) ;
  2355.     $mimetypes->_exportMimeTypes( $otherself ) ;
  2356.  
  2357.     $self->_options($otherself, $access->{'Options'});
  2358.     $self->_options($otherself, $httpd->{'Options'});
  2359.     $self->_options($otherself, $srm->{'Options'});
  2360.  
  2361.     # Handle '<Directory>' directives.
  2362.     $self->_directory( $otherself, $access, $rootdir ) ;
  2363.     $self->_directory( $otherself, $httpd, $rootdir ) ;
  2364.     $self->_directory( $otherself, $srm, $rootdir ) ;
  2365.  
  2366.     # UserDir (virtual directories).
  2367.     $self->_userDir( $otherself, $access, $httpd, $srm ) ;
  2368.  
  2369.     # Save parameters for later use.
  2370.     $self->{'_AAccess'}   = $access ;
  2371.     $self->{'_AHttpd'}    = $httpd ;
  2372.     $self->{'_AMimetype'} = $mimetypes ;
  2373.     $self->{'_ASrm'}      = $srm ;
  2374.     
  2375.     ##################################################
  2376.     #
  2377.     # NB: Must do - complete construction of objects
  2378.     #
  2379.     ##################################################
  2380.     $otherself->_construct() ;
  2381.     
  2382.     chdir( $olddir ) ;
  2383. }
  2384.  
  2385. ######################################################
  2386.  
  2387. #
  2388. # 'HostNameLookups' directive
  2389. #
  2390. sub _hostNameLookups
  2391. {
  2392.   my ($self, $otherself, $obj ) = @_;
  2393.   my $theDirective = topmain::trim(topmain::ucase($obj->{'HostNameLookups'}));
  2394.   my $theValue = 'True';
  2395.   my $rvdir = $otherself->{'vdir'}[ 0 ] ;
  2396.  
  2397.   if($theDirective eq 'OFF')
  2398.   {
  2399.     $theValue = 'False';
  2400.   }
  2401.  
  2402.   $rvdir->{'HostNameLookups'} = $theValue;
  2403. }
  2404.  
  2405. #
  2406. # 'IdentityCheck' directive
  2407. #
  2408. sub _identityCheck
  2409. {
  2410.   my ($self, $otherself, $obj ) = @_;
  2411.   my $theDirective = topmain::trim(topmain::ucase($obj->{'IdentityCheck'}));
  2412.  
  2413.   if($theDirective eq 'ON')
  2414.   {
  2415.     $otherself->{'IdentityCheck'} = 'True';
  2416.   }
  2417.   elsif($theDirective eq 'OFF')
  2418.   {
  2419.     $otherself->{'IdentityCheck'} = 'False';
  2420.   }
  2421.  
  2422. }
  2423.  
  2424. #
  2425. # 'ListenBacklog' directive
  2426. #
  2427. sub _listenBacklog
  2428. {
  2429.   my ($self, $otherself, $obj ) = @_;
  2430.   my $theDirective = $obj->{'ListenBacklog'};
  2431.   my $theValue = '';
  2432.   my $rvdir = $otherself->{'vdir'}[ 0 ] ;
  2433.  
  2434.   if(($theDirective >= 5) && ($theDirective <= 500))
  2435.   {
  2436.     $theValue = $theDirective;
  2437.   }
  2438.  
  2439.   $otherself->{'ListenBacklog'} = $theValue;
  2440. }
  2441.  
  2442.  
  2443. #
  2444. # 'Redirect', 'RedirectTemp', 'RedirectPermanent' directives
  2445. #
  2446. sub _redirects
  2447. {
  2448.   my ($self, $otherself, $obj ) = @_;
  2449.  
  2450.   if($obj->{'redirects'})
  2451.   {
  2452.     for($i = 0 ; $i < scalar(@{$obj->{'redirects'}}) ; $i++)
  2453.     {
  2454.       my $redirect = $obj->{'redirects'}[$i];
  2455.  
  2456.       if('' ne $redirect)
  2457.       {
  2458.         my $theIndex = index($redirect, ' ');
  2459.         my $thePrefix = substr($redirect, 0, $theIndex);
  2460.         my $theSuffix = substr($redirect, $theIndex + 1);
  2461.  
  2462.         # Create virtual directory object.
  2463.         my $newvdir = IISVirtualDir->new(
  2464.           'from' => $thePrefix,
  2465.           'dir'  => '',
  2466.           'type' => $thePrefix,
  2467.           'name' => $otherself->{'name'});
  2468.  
  2469.         $newvdir->{'HttpRedirect'} = $theSuffix;
  2470.         push( @{$otherself->{'vdir'}}, $newvdir);
  2471.       }  
  2472.     }
  2473.   }
  2474. }
  2475.  
  2476.  
  2477. #
  2478. # 'Alias' directive.
  2479. #
  2480. sub _aliasVDir {
  2481.     my ( $self, $otherself, $obj ) = @_ ;
  2482.     my $name ;
  2483.     my $path ;
  2484.     my $vdir ;
  2485.  
  2486.     if ( $obj->{'Alias'} ) {
  2487.         for ( $i = 0 ; $i < scalar(@{$obj->{'Alias'}}) ; $i++ ) {
  2488.             ( $name, $path ) = split( ' ', $obj->{'Alias'}[$i] ) ;
  2489.             # Paths should not have trailing.
  2490.             if ( $path =~ m'/$' ) { #'
  2491.                 chop( $path ) ;
  2492.             }
  2493.             if ( $name =~ m'/$' ) { #'
  2494.                 chop( $name ) ;
  2495.             }
  2496.             $vdir = IISVirtualDir->new(
  2497.                                        'from' => $name,
  2498.                                        'dir'  => $path,
  2499.                                        'type' => '',
  2500.                                        'name' => $otherself->{'name'}
  2501.                                        ) ;
  2502.             $vdir->{'DirBrowseFlags'} .= ' Enabled' if ( $otherself->{'_fancyIndexing'} =~ m'on'i ) ;
  2503.             push( @{$otherself->{'vdir'}}, $vdir ) ;
  2504.         }
  2505.     }
  2506. }
  2507.  
  2508. #
  2509. # 'DirectoryIndex' directive.
  2510. #
  2511. sub _defaultDoc {
  2512.     my ( $self, $otherself, $obj ) = @_ ;
  2513.     my $dd ;
  2514.     if ( $obj->{'DirectoryIndex'} ) {
  2515.         $dd = $otherself->{'DefaultDoc'} ;
  2516.         @spec = split( ' ', $obj->{'DirectoryIndex'} ) ;
  2517.         for ( $i = 0 ; $i < scalar(@spec) ; $i++ ) {
  2518.             if ( $dd ) {
  2519.                 $dd .= "," . $spec[$i] ;
  2520.             } else {
  2521.                 $dd = $spec[$i] ;
  2522.             }
  2523.         }
  2524.         $otherself->{'DefaultDoc'} = $dd if ( $dd ) ;
  2525.     }
  2526. }
  2527.  
  2528. #
  2529. # '<Directory x>' directive.
  2530. #
  2531. sub _directory {
  2532.     my ( $self, $otherself, $obj, $inRoot ) = @_ ;
  2533.     my $dir ;
  2534.     my $dirname, @dirnamex, $fromx ;
  2535.     my $dirs ;
  2536.     my $opt ;
  2537.     my $options ;
  2538.     my $vdir ;
  2539.         
  2540.     @dirs = keys( %{$obj->{'Directory'}} ) ;
  2541.     foreach $dir ( sort @dirs ) {
  2542.         if ( defined($obj->{'Directory'}{$dir}) ) {
  2543.             $dirname = $obj->{'Directory'}{$dir}->{'_AName'} ;
  2544.             @dirnamex = split('/', $dirname ) ;
  2545.             $fromx = '/' . $dirnamex[ scalar(@dirnamex) - 1 ] ;
  2546.  
  2547.             my $vdir;
  2548.  
  2549.             if($dir eq $inRoot)
  2550.             {
  2551.               $vdir = $otherself->{'vdir'}[ 0 ] ;
  2552.             }
  2553.             else
  2554.             {
  2555.               $vdir = $self->_getVDir( $otherself, $fromx ) ;
  2556.             }
  2557.             
  2558.             
  2559.             # If this directory is already defined as virtual directory,
  2560.             # merge directives with existing vdir.
  2561.             # Otherwise, create new virtual directory and set properties.
  2562.             if ( defined($vdir) )
  2563.             {
  2564.               $self->_options( $vdir, $obj->{'Directory'}{$dir}{'Options'} ) ;
  2565.               undef( $vdir ) ;
  2566.             }
  2567.             else
  2568.             {
  2569.                 $vdir = IISVirtualDir->new(
  2570.                                            'from' => $fromx,
  2571.                                            'dir'  => $dirname,
  2572.                                            'type' => '',
  2573.                                            'name' => $otherself->{'name'}
  2574.                                            ) ;
  2575.                 push( @{$otherself->{'vdir'}}, $vdir ) ;
  2576.                 $self->_options( $vdir, $obj->{'Directory'}{$dir}{'Options'} ) ;
  2577.                 undef( $vdir ) ;
  2578.             }
  2579.         }
  2580.     }
  2581. }
  2582.  
  2583. #
  2584. # 'ErrorDocument' directive.
  2585. #
  2586. sub _errorDocument
  2587. {
  2588.   my ($self, $otherself, $obj) = @_;
  2589.   my $rvdir = $otherself->{'vdir'}[0];
  2590.   my $i;
  2591.   my $errorcode;
  2592.   my $errorspec;
  2593.  
  2594.  if(defined($rvdir) and ($obj->{'ErrorDocument'}))
  2595.  {
  2596.     for($i = 0 ; $i < scalar(@{$obj->{'ErrorDocument'}}) ; $i++)
  2597.     {
  2598.       $line = $obj->{'ErrorDocument'}[$i];
  2599.       $line =~ /\s+/ ;    # Skip past first word and whitespace.
  2600.       $errorcode = $`;
  2601.       $errorspec = $';
  2602.  
  2603.       #$self->__addHttpError($otherself, $rvdir, $errorcode, $errorspec);
  2604.       IISServerAP::__addHttpError($self, $otherself, $rvdir, $errorcode, $errorspec);
  2605.     }
  2606.   }
  2607. }
  2608.  
  2609. sub __addHttpError
  2610. {
  2611.   my ($self, $otherself, $rvdir, $errorcode, $errorspec) = @_;
  2612.   my $od = '[' ;
  2613.   my $cd = ']' ;
  2614.   my $fnpfx = '' ;
  2615.   my $path ;
  2616.   my $fn ;
  2617.   my $fnx ;
  2618.   my $msgtype = 'URL' ;
  2619.  
  2620.   if($errorspec =~ m'http://'i)
  2621.   {
  2622.     $fnpfx   = '';
  2623.   }
  2624.  
  2625.   my $xlat = '';
  2626.   my $errcontent = '';
  2627.  
  2628.   $errspec = $errorspec;
  2629.   
  2630.   if($errspec =~ m'^"')
  2631.   {
  2632.     $errspec = '/error_' . $errorcode . '.html';
  2633.     $errcontent = $errorspec;
  2634.     $errcontent =~ s/\"//g;
  2635.     $errcontent =~ s/ /+/g;
  2636.   }
  2637.  
  2638.  
  2639.   $fn = $fnpfx . $errspec;
  2640.   $fn =~ tr/\\/\//;          # Backslash to Forward slash.
  2641.  
  2642.   if($fnpfx)
  2643.   {
  2644.     $path = $rvdir->{'dir'} . $fnpfx . $errspec;
  2645.     $path =~ s/\/\//\//g;
  2646.   }
  2647.   else
  2648.   {
  2649.     $path = '';
  2650.   }
  2651.   
  2652.   $fnx = $fn;
  2653.   $fnx =~ tr/\//\\/;         # Forward slash to backslash for NT.
  2654.         
  2655.   if(! $errcontent)
  2656.   {
  2657.     if($errorcode eq '401')
  2658.     {
  2659.       # Subcodes 1-5 all set to same error response.
  2660.       for($i = 1 ; $i <= 5 ; ++$i)
  2661.       {
  2662.         $xlat = join('', $xlat, $od, $errorcode, ',', $i, ',', $msgtype, ',', $fn, $cd, " ");
  2663.       }
  2664.     
  2665.       $rvdir->{'copyfile'}{$path} = $fn if ($path and !$errcontent);
  2666.     }
  2667.     elsif($errorcode eq '403')
  2668.     {
  2669.       # Subcodes 1-12 all set to same error response.
  2670.       for($i = 1 ; $i <= 12 ; ++$i)
  2671.       {
  2672.         $xlat = join('', $xlat, $od, $errorcode, ',', $i, ',', $msgtype, ',', $fn, $cd, " ");
  2673.      }
  2674.       
  2675.      $rvdir->{'copyfile'}{$path} = $fn if ($path and !$errcontent);
  2676.     }
  2677.     else
  2678.     {
  2679.       $xlat = join('', $xlat, $od, $errorcode, ',*,', $msgtype, ',', $fn, $cd, " ");
  2680.       $rvdir->{'copyfile'}{$path} = $fn if ( $path and !$errcontent );
  2681.     }
  2682.   
  2683.     $rvdir->{'HttpErrors'} .= $xlat;
  2684.   }
  2685. }
  2686.  
  2687. #
  2688. # 'FancyIndexing', 'IndexOptions FancyIndexing' directives.
  2689. #
  2690. sub _fancyIndexing {
  2691.     my ( $self, $otherself, @objlist ) = @_ ;
  2692.     my $obj ;
  2693.     my $i ;
  2694.     my $j ;
  2695.  
  2696.     $otherself->{'_fancyIndexing'} = 'off' ;
  2697.     for ( $i = 0 ; $i < scalar(@objlist) ; $i++ ) {
  2698.         $obj = $objlist[ $i ] ;
  2699.         if ( defined($obj) ) {
  2700.             $otherself->{'_fancyIndexing'} = $obj->{'FancyIndexing'} if ( $obj->{'FancyIndexing'} ) ;
  2701.             if ( $obj->{'IndexOptions'} ) {
  2702.                 for ( $j = 0 ; $j < scalar(@{$obj->{'IndexOptions'}}) ; $j++ ) {
  2703.                     if ( $obj->{'IndexOptions'}[$j] =~ m'fancyindexing'i ) {
  2704.                         $otherself->{'_fancyIndexing'} = 'on' ;
  2705.                     }
  2706.                 }
  2707.             }
  2708.         }
  2709.     }
  2710. }
  2711.  
  2712. #
  2713. # 'KeepAlive' directive.
  2714. #
  2715. sub _keepAlive {
  2716.     # Keep alive could be a number (v1.1) or on/off (v1.2+).  n = 0
  2717.     # indicates disabled, so we purposely skip matching on '0'.
  2718.     my ( $self, $otherself, $obj ) = @_ ;
  2719.     my $prop = 'False' ;
  2720.     if ( defined($obj) ) {
  2721.         $prop = 'True' if ( ($obj->{'KeepAlive'} =~ m'on'i)
  2722.                       or ($obj->{'KeepAlive'} =~ m'1|2|3|4|5|6|7|8|9')
  2723.                       ) ;
  2724.         $otherself->{'AllowKeepAlive'} = $prop ;
  2725.     }
  2726. }
  2727.  
  2728. #
  2729. # 'AddType' directive.
  2730. #
  2731. sub _mimeMap
  2732. {
  2733.   my ( $self, $mimeobj, $obj ) = @_ ;
  2734.  
  2735.   if(defined($mimeobj))
  2736.   {
  2737.     if ($obj->{'AddType'})
  2738.     {
  2739.       for($i = 0 ; $i < scalar(@{$obj->{'AddType'}}) ; $i++ )
  2740.       {
  2741.         $mimeobj->_addMimeType( $obj->{'AddType'}[$i] ) ;
  2742.       }
  2743.     }
  2744.   }
  2745. }
  2746.  
  2747. #
  2748. # 'Options' directive.
  2749. #
  2750. sub _options
  2751. {
  2752.   my ($self, $vobj, $opt) = @_;
  2753.   
  2754.   @options = split(' ', $opt);
  2755.  
  2756.   foreach $opt (sort @options)
  2757.   {
  2758.     if(($opt eq 'Indexes') or ($opt eq '+Indexes'))
  2759.     {
  2760.       $vobj->{'EnableDirBrowsing'} = 'True';
  2761.     }
  2762.     elsif(($opt eq 'ExecCGI') or ($opt eq '+ExecCGI'))
  2763.     {
  2764.       $vobj->{'AccessExecute'} = 'True';
  2765.     }
  2766.     elsif(($opt eq 'All') or ($opt eq '+All'))
  2767.     {
  2768.       $vobj->{'EnableDirBrowsing'} = 'True';
  2769.       $vobj->{'AccessExecute'} = 'True';
  2770.     }
  2771.     elsif($opt eq '-Indexes')
  2772.     {
  2773.       $vobj->{'EnableDirBrowsing'} = 'False';
  2774.     }
  2775.     elsif($opt eq '-ExecCGI')
  2776.     {
  2777.       $vobj->{'AccessExecute'} = 'False';
  2778.     }
  2779.     elsif($opt eq '-All')
  2780.     {
  2781.       $vobj->{'EnableDirBrowsing'} = 'False';
  2782.       $vobj->{'AccessExecute'} = 'False';
  2783.     }
  2784.   }
  2785. }
  2786.  
  2787. #
  2788. # 'ScriptAlias' directive.
  2789. #
  2790. sub _scriptAliasVDir {
  2791.     my ( $self, $otherself, $obj ) = @_ ;
  2792.     my $name ;
  2793.     my $path ;
  2794.     my $vdir ;
  2795.  
  2796.     if ( $obj->{'ScriptAlias'} ) {
  2797.         for ( $i = 0 ; $i < scalar(@{$obj->{'ScriptAlias'}}) ; $i++ ) {
  2798.             ( $name, $path ) = split( ' ', $obj->{'ScriptAlias'}[$i] ) ;
  2799.             if ( $path =~ m'/$' ) { #'
  2800.                 chop( $path ) ;
  2801.             }
  2802.             if ( $name =~ m'/$' ) { #'
  2803.                 chop( $name ) ;
  2804.             }
  2805.             $vdir = IISVirtualDir->new(
  2806.                                        'from' => $name,
  2807.                                        'dir'  => $path,
  2808.                                        'type' => '',
  2809.                                        'name' => $otherself->{'name'}
  2810.                                        ) ;
  2811.             $vdir->{'AccessFlags'}    .= ' Script Execute' ;
  2812.             $vdir->{'DirBrowseFlags'} .= ' Enabled' if ( $otherself->{'_fancyIndexing'} =~ m'on'i ) ;
  2813.             push( @{$otherself->{'vdir'}}, $vdir ) ;
  2814.         }
  2815.     }
  2816. }
  2817.  
  2818. #
  2819. # 'BindAddress', 'Listen', 'ServerAlias', 'NameVirtualHost' directives.
  2820. #
  2821. sub _serverBindings {
  2822.     my ( $self, $otherself, $obj ) = @_ ;
  2823.     my $ip, $port, @spec, $host ;
  2824.  
  2825.     # Server bindings syntax is <ip_address>, <port>, <name>
  2826.     $otherself->AddServerBinding( '', $obj->{'Port'}, '' ) if ( $obj->{'Port'} ) ;
  2827.  
  2828.     $ba = $obj->{'BindAddress'} ;
  2829.     if ( $ba and ($ba =~ m'[a-z]') ) {
  2830.         $otherself->AddServerBinding( '', '', $ba ) if ( $ba and ($ba ne '*') ) ;
  2831.     } else {
  2832.         $otherself->AddServerBinding( $ba, '', '' ) if ( $ba and ($ba ne '*') ) ;
  2833.     }
  2834.  
  2835.     if ( $obj->{'Listen'} ) {
  2836.         for ( $i = 0 ; $i < scalar(@{$obj->{'Listen'}}) ; $i++ ) {
  2837.             if ( $obj->{'Listen'}[$i] =~ m':' ) {
  2838.                 ( $ip, $port ) = split( ':', $obj->{'Listen'}[$i] ) ;
  2839.             } else {
  2840.                 # Port-only specification.
  2841.                 $ip = '' ;
  2842.                 $port = $obj->{'Listen'}[$i] ;
  2843.             }
  2844.             $otherself->AddServerBinding( $ip, $port, '' ) ;
  2845.         }
  2846.     }
  2847.  
  2848.     if ( $obj->{'ServerAlias'} ) {
  2849.         for ( $i = 0 ; $i < scalar(@{$obj->{'ServerAlias'}}) ; $i++ ) {
  2850.             @spec = split( ' ', $obj->{'ServerAlias'}[$i] ) ;
  2851.             foreach $host ( @spec ) {
  2852.                 $otherself->AddServerBinding( '', $obj->{'Port'}, $host ) unless ( $host =~ m'\*|\?' ) ;
  2853.             }
  2854.         }
  2855.     }
  2856.  
  2857.     if ( $obj->{'NameVirtualHost'} ) {
  2858.         for ( $i = 0 ; $i < scalar(@{$obj->{'NameVirtualHost'}}) ; $i++ ) {
  2859.             ( $ip, $port ) = split( ':', $obj->{'NameVirtualHost'}[$i] ) ;
  2860.             $otherself->AddServerBinding( $ip, $port, '' ) ;
  2861.         }
  2862.     }
  2863. }
  2864.  
  2865. #
  2866. # 'UserDir' directive.
  2867. #
  2868. sub _userDir {
  2869.     my ( $self, $otherself, $obj1, $obj2, $obj3 ) = @_ ;
  2870.     my $i ;
  2871.     my $usr ;
  2872.  
  2873.     # Read/parse passwd file to translate user home directory to user
  2874.     # name.
  2875.     open( PFILE, '/etc/passwd' ) or die( "Could not open PASSWD\n" ) ;
  2876.     my %passwd ;
  2877.     while ( <PFILE> ) {
  2878.         chomp( $_ ) ;
  2879.         $line = $_ ;
  2880.         $line =~ m':' ;
  2881.         $usr = $` ;
  2882.         $line = $' ;
  2883.         @params = split( ':', $line ) ;
  2884.         $home = $params[ scalar(@params) - 2 ] ;
  2885.         $passwd{$home} = '/~' . $usr ;
  2886.     }
  2887.     close( PFILE ) ;
  2888.     
  2889.     # First combine all 'UserDir' directives into one (hash) list.
  2890.     # This has the added benefit of combining repeated directives
  2891.     # among the different '.conf' files.
  2892.     my @objlist ;
  2893.     @objlist = ( @objlist, @{$obj1->{'UserDir'}} ) if ( $obj1->{'UserDir'} ) ;
  2894.     @objlist = ( @objlist, @{$obj2->{'UserDir'}} ) if ( $obj2->{'UserDir'} ) ;
  2895.     @objlist = ( @objlist, @{$obj3->{'UserDir'}} ) if ( $obj3->{'UserDir'} ) ;
  2896.     for ( $i = 0 ; $i < scalar( @objlist ) ; $i++ ) {
  2897.         $self->{'userdir'}{$objlist[$i]} = 1 ;
  2898.     }
  2899.     my @userdir = sort( keys(%{$self->{'userdir'}}) ) ;
  2900.  
  2901.     # Create user list (prepend '~' for elements that don't have '/'
  2902.     # as their first character.
  2903.     my @users = split( ' ', $otherself->{'webconf'}->{'userglob'} ) ;
  2904.     my %usersaccess ;
  2905.     for ( $i = 0 ; $i < @users ; $i++ ) {
  2906.         if ( $users[$i] !~ m'^/' ) {
  2907.             $users[$i] = '~' . $users[$i] ;
  2908.         }
  2909.         $usersaccess{$users[$i]} = 1 ;
  2910.     }
  2911.  
  2912.     # Remove all users if global 'disabled' used.
  2913.     foreach $udir ( @userdir ) {
  2914.         if ( $udir =~ m'disabled'i ) {
  2915.             %usersaccess = () ;
  2916.             last ;
  2917.         }
  2918.     }
  2919.     # Include only users explicitly 'enabled'.
  2920.     foreach $udir ( @userdir ) {
  2921.         if ( $udir =~ m'enabled' ) {
  2922.             $udir =~ /\s+/ ;    # Skip past first word and whitespace.
  2923.             ( @userlist ) = split( ' ', $' ) ;
  2924.             foreach $usr ( @userlist ) {
  2925.                 $usersaccess{$usr} = 1 ;
  2926.             }
  2927.         }
  2928.     }
  2929.     # Remove users explicitly 'disabled'.
  2930.     foreach $udir ( @userdir ) {
  2931.         if ( $udir =~ m'disabled' ) {
  2932.             $udir =~ /\s+/ ;    # Skip past first word and whitespace.
  2933.             ( @userlist ) = split( ' ', $' ) ;
  2934.             foreach $usr ( @userlist ) {
  2935.                 delete( $usersaccess{$usr} ) ;
  2936.             }
  2937.         }
  2938.     }
  2939.     my %usersaccess1 ;
  2940.     foreach $key ( keys(%usersaccess) ) {
  2941.         if ( ($key !~ m'^/') and ($key !~ m'^~') ) {
  2942.             $key = '~' . $key ;
  2943.         }
  2944.         $usersaccess1{$key} = 1 ;
  2945.     }
  2946.     my %usersacc ;
  2947.     my @ua = keys( %usersaccess1 ) ;
  2948.     while ( <@ua> ) {
  2949.         $usersacc{$_} = 1 ;
  2950.     }
  2951.     
  2952.     # Prepend '~' for users that don't have '/'
  2953.     # as their first character.
  2954.     for ( $i = 0 ; $i < @users ; $i++ ) {
  2955.         if ( ($users[$i] !~ m'^/') and ($users[$i] !~ m'^~') ) {
  2956.             $users[$i] = '~' . $users[$i] ;
  2957.         }
  2958.     }
  2959.     # For each user, create a virtual directory for each UserDir spec.
  2960.     my $udir ;
  2961.     my $dirspec ;
  2962.     my $vdir ;
  2963.  
  2964.     while ( <@users> ) {
  2965.         chomp( $_ ) ;
  2966.         foreach $udir ( @userdir ) {
  2967.             if ( ($udir !~ m'enabled'i) and ($udir !~ m'disabled') ) {
  2968.                 $dirspec = $_ . '/' . $udir ;
  2969.                 if ( -d $dirspec and $passwd{$_} ) {
  2970.                     $vdir = IISVirtualDir->new(
  2971.                                                'from' => $passwd{$_},
  2972.                                                'dir'  => $dirspec,
  2973.                                                'type' => '',
  2974.                                                'name' => $otherself->{'name'}
  2975.                                                ) ;
  2976.                     push( @{$otherself->{'vdir'}}, $vdir ) ;
  2977.                 }
  2978.             }
  2979.         }
  2980.     }
  2981. }
  2982.  
  2983. #
  2984. # _httpdDefaults - sets defaults values for directives if not already
  2985. #      set.  Call before other processing.
  2986. sub _httpdDefaults {
  2987.     my( $self, $conf ) = @_ ;
  2988.     if ( defined($conf) ) {
  2989.         $conf->{'KeepAlive'}  = 'on' unless ( $conf->{'KeepAlive'} ) ;
  2990.         $conf->{'MaxClients'} = 256 unless ( $conf->{'MaxClients'} ) ;
  2991.         $conf->{'Timeout'}    = 300 unless ( $conf->{'Timeout'} ) ;
  2992.     }
  2993. }
  2994.  
  2995. #
  2996. # _srmDefaults - sets defaults values for directives if not already
  2997. #      set.  Call before other processing.
  2998. sub _srmDefaults {
  2999.     my( $self, $conf ) = @_ ;
  3000.     if ( defined($conf) and (not $conf->{'UserDir'}) ) {
  3001.         push( @{$conf->{'UserDir'}}, 'public_html' ) ;
  3002.     }
  3003. }
  3004.  
  3005. #
  3006. # _getVDir
  3007. #
  3008. sub _getVDir {
  3009.     my ( $self, $otherself, $dirname ) = @_ ;
  3010.     my $i ;
  3011.     my $ndir ;
  3012.     my $vdir ;
  3013.  
  3014.     $ndir = scalar( @{$otherself->{'vdir'}} ) ;
  3015.     if ( $dirname =~ m'/$' ) { #'
  3016.         chop( $dirname ) ;
  3017.     }
  3018.     undef( $vdir ) ;
  3019.     # Search for virtual directory.
  3020.     for ( $i = 0 ; $i < $ndir and !defined($vdir) ; $i++ ) {
  3021.         if ( $dirname eq $otherself->{'vdir'}[$i]->{'from'} ) {
  3022.             $vdir = $otherself->{'vdir'}[$i] ;
  3023.             last ;
  3024.         }
  3025.     }
  3026.  
  3027.     return $vdir ;
  3028. }
  3029.  
  3030. #
  3031. # _getProperty
  3032. #
  3033. sub _getProperty {
  3034.     my ( $self, $src_prop, $obj1, $obj2, $obj3 ) = @_ ;
  3035.  
  3036.     $prop = $obj1->{$src_prop} if ( defined($obj1) and ($obj1->{$src_prop}) ) ;
  3037.     $prop = $obj2->{$src_prop} if ( defined($obj2) and ($obj2->{$src_prop}) ) ;
  3038.     $prop = $obj3->{$src_prop} if ( defined($obj3) and ($obj3->{$src_prop}) ) ;
  3039.  
  3040.     return $prop ;
  3041. }
  3042.  
  3043. #
  3044. # _setProperty
  3045. #
  3046. sub _setProperty {
  3047.     my ( $self, $otherself, $src_prop, $dst_prop, $obj1, $obj2, $obj3 ) = @_ ;
  3048.     my $prop ;
  3049.  
  3050.     $prop = $obj1->{$src_prop} if ( defined($obj1) and ($obj1->{$src_prop}) ) ;
  3051.     $prop = $obj2->{$src_prop} if ( defined($obj2) and ($obj2->{$src_prop}) ) ;
  3052.     $prop = $obj3->{$src_prop} if ( defined($obj3) and ($obj3->{$src_prop}) ) ;
  3053.  
  3054.     $otherself->{$dst_prop} = $prop if ( $prop ) ;
  3055. }
  3056.  
  3057. sub dump {
  3058.     my $self = shift ;
  3059.     print( "dump($self->{'_AClass'})\n" ) ;
  3060.     $tab = " " ;
  3061.     $tabnum = $tablvl * length( $tab ) ;
  3062.     $fmt = "%" . $tabnum . "s%-20s = %s\n" ;
  3063.     @content = keys( %$self ) ;
  3064.     foreach $key ( sort @content ) {
  3065.         printf( $fmt, $tab, $key, $self->{$key} ) ;
  3066.     }
  3067. }
  3068.  
  3069.  
  3070. #############################################################################
  3071. #
  3072. #   IISServerAPEx
  3073. #
  3074. #############################################################################
  3075. package     IISServerAPEx ;
  3076. require     Exporter ;
  3077. use         Cwd ;
  3078. @ISA    = qw( Exporter ) ;
  3079. @EXPORT = qw( dump ) ;
  3080.  
  3081. sub new {
  3082.     my $class        = shift ;
  3083. #    my %params      = @_ ;
  3084.     my $self         = {} ;
  3085.     my $otherself    = shift ;
  3086.     $self->{'_AClass'} = $class ;
  3087.     bless $self, $class ;
  3088.     topmain::dbgOut( "NEW $class USING $otherself" ) if ( $IISCore::debug ) ;
  3089.  
  3090.     $rc = $self->_construct( $otherself ) ;
  3091.  
  3092.     unless ( defined($rc) ) {
  3093.         $@ = $!;
  3094.         return undef;
  3095.     }
  3096.         
  3097.     return $self ;
  3098. }
  3099.  
  3100. sub _construct
  3101. {
  3102.   my ( $self, $otherself ) = @_ ;
  3103.     topmain::dbgOut( "CONSTRUCT $self->{'_AClass'} USING $otherself" ) if ( $IISCore::debug ) ;
  3104.     return $self ;
  3105. }
  3106.  
  3107.  
  3108. #############################################################################
  3109. #
  3110. #   IISConfAP
  3111. #       Apache '.conf' parsing object.
  3112. #
  3113. #############################################################################
  3114. package     IISConfAP ;
  3115. require     Exporter ;
  3116. @ISA    = qw( Exporter ) ;
  3117. @EXPORT = qw( _construct, dump ) ;
  3118.  
  3119. sub new {
  3120.     my $class        = shift ;
  3121.     my %params       = @_ ;
  3122.     my $self         = {} ;
  3123.     $self->{'_AClass'} = $class ;
  3124.     bless $self, $class ;
  3125.     
  3126.     $self->{'_AFile'} = $params{'_AFile'} ;
  3127.     print( "NEW $class, $self->{'_AFile'}\n" ) if ( $IISCore::debug ) ;
  3128.  
  3129.     my $line ;
  3130.     my $fullline ;
  3131.  
  3132.     open( FILE, $self->{'_AFile'} ) or ( $@ = $!, return undef ) ;
  3133.  
  3134.     # Special initialization for 'httpd.conf'
  3135.     if ( $self->{'_AFile'} eq 'httpd.conf' ) {
  3136.         $self->{'ResourceConfig'} = 'srm.conf' ;
  3137.         $self->{'AccessConfig'}   = 'access.conf' ;
  3138. #        $self->{'TypesConfig'}    = 'mime.types' ;
  3139.         $self->{'TypesConfig'}    = '' ;
  3140.     }
  3141.  
  3142.     my $obj ;
  3143.     undef( $obj ) ;
  3144.     while ( <FILE> ) {
  3145.         $fullline = $_ ;
  3146.         # Accumulate line if line-continuation encountered.
  3147.         while ( /\\$/ ) {
  3148.             $line = <FILE> ;
  3149.             $_ = $' . $line ;
  3150.             $fullline = join( '', $fulline, $line ) ;
  3151.             # Exit loop if we encounter EOF.
  3152.             last if ( $_ eq $' ) ;
  3153.         }
  3154.  
  3155.         # Skip blank and comment lines
  3156.         next if /^\s*$/ ;
  3157.         next if /^#/ ;
  3158.  
  3159.         if ( m'^<' and !m'^</' ) {
  3160.             # This is a nested directive object.
  3161.             # One of <Directory>, <Files>, <Limit>, <Location>, <VirtualHost>
  3162.             $obj = IISDirectiveObjAP->new( '_ALine' => $' ) ;
  3163.         } elsif ( defined($obj) ) {
  3164.             # Look for object terminator.
  3165.             if ( $obj->isTerminator($_) ) {
  3166.                 # Add object to our hash.
  3167.                 $self->{$obj->{'_AType'}}{$obj->{'_AName'}} = $obj ;
  3168.                 undef( $obj ) ;
  3169.             } else {
  3170.                 # Add directive to our current object.
  3171.                 $self->_addDirective( $_, $obj ) ;
  3172.             }
  3173.         } else {
  3174.             # Add directive to top-level object.
  3175.             $self->_addDirective( $_, $self ) ;
  3176.         }
  3177.                 
  3178.     }
  3179.     close( FILE ) ;
  3180.     $self->dump() if ( $IISCore::debug ) ;
  3181.  
  3182.     return $self ;
  3183. }
  3184.  
  3185. sub _addDirective
  3186. {
  3187.   my ($self, $line, $obj) = @_;
  3188.     
  3189.   chomp($line);
  3190.  
  3191.   # Split into name/value pairs
  3192.   ($name, $value) = /(\w+)\s+(.*)/;
  3193.  
  3194.   if($name eq 'AddEncoding'
  3195.     or $name eq 'AddHandler'
  3196.     or $name eq 'AddLanguage'
  3197.     or $name eq 'AddType'
  3198.     or $name eq 'Alias'
  3199.     or $name eq 'ErrorDocument'
  3200.     or $name eq 'IndexOptions'
  3201.     or $name eq 'Listen'
  3202.     #or $name eq 'Options'
  3203.     or $name eq 'NameVirtualHost'
  3204.     or $name eq 'ScriptAlias'
  3205.     or $name eq 'ServerAlias'
  3206.     or $name eq 'UserDir'
  3207.     or $name eq 'Redirect'
  3208.     or $name eq 'RedirectTemp'
  3209.     or $name eq 'RedirectPermanent')
  3210.   {
  3211.     if(index($name, 'Redirect') == 0)
  3212.     {
  3213.       $name = 'redirects';
  3214.     }
  3215.  
  3216.     push(@{$obj->{$name}}, $value );
  3217.   }
  3218.   else
  3219.   {
  3220.     $obj->{$name} = $value;
  3221.   }
  3222. }
  3223.  
  3224. sub dump {
  3225.     my $self = shift ;
  3226.     print( "dump($self->{'_AClass'})\n" ) ;
  3227.     my $tab = "  " ;
  3228.     my $tablvl = 0 ;
  3229.     my $fmt = "%" . $tabnum . "s%-20s = %s\n" ;
  3230.     my @content = keys( %$self ) ;
  3231.     foreach $key ( sort @content ) {
  3232.         printf( "%s%-20s = %s\n", $tab, $key, $self->{$key} ) ;
  3233.     }
  3234. }
  3235.  
  3236. sub rdump {
  3237.     my $self   = shift ;
  3238.     my $key    = shift ;
  3239.     my $tablvl = shift ;
  3240.     $tab = " " ;
  3241.     $tabnum = $tablvl * length( $tab ) ;
  3242.     $fmt = "%" . $tabnum . "s%-20s = %s\n" ;
  3243.     
  3244.     if ( $self->{$key} =~ m'hash'i ) {
  3245.         printf( $fmt, $tab, $key, $self->{$key} ) ;
  3246.         @content = keys( %{$self->{$key}} ) ;
  3247.         $tablvl++ ;
  3248.         foreach $subkey ( sort @content ) {
  3249.             $self->{$key}{$subkey}->dump() ;
  3250.         }
  3251.     } elsif ( $self->{$key} =~ m'array'i ) {
  3252.         printf( $fmt, $tab, $key, $self->{$key} ) ;
  3253.         for ( $i = 0 ; $i < scalar( @{$self->{$key}} ) ; $i++ ) {
  3254.             printf( $fmt, $tab, " ", $self->{$key}[$i] ) ;
  3255.         }
  3256.     } else {
  3257.         printf( $fmt, $tab, $key, $self->{$key} ) ;
  3258.     }
  3259. }
  3260.  
  3261.  
  3262. #############################################################################
  3263. #
  3264. #   IISDirectiveObjAP
  3265. #       Apache '.conf' directive object.
  3266. #
  3267. #############################################################################
  3268. package     IISDirectiveObjAP ;
  3269. require     Exporter ;
  3270. @ISA    = qw( Exporter ) ;
  3271. @EXPORT = qw( isTerminator, dump ) ;
  3272.  
  3273. sub new {
  3274.     my $class        = shift ;
  3275.     my %params       = @_ ;
  3276.     my $self         = {} ;
  3277.     $self->{'_AClass'} = $class ;
  3278.     bless $self, $class ;
  3279.  
  3280.     $self->{'_ALine'} = $params{'_ALine'} ;
  3281.     chomp( $self->{'_ALine'} ) ;
  3282.     print( "NEW $class, $self->{'_ALine'}\n" ) if ( $IISCore::debug ) ;
  3283.     
  3284.     my $line = $params{'_ALine'} ;
  3285.     chomp( $line ) ;
  3286.     $line =~ /\s+/ ;            # Skip past first word and whitespace.
  3287.     
  3288.     my $AType = $` ;
  3289.     #$AType =~ tr/[A-Z]/[a-z]/;
  3290.     $AType = topmain::ucase(substr($AType, 0, 1)) . substr($AType, 1);
  3291.     $self->{'_AType'} = $AType;
  3292.     
  3293.     $line = $' ;
  3294.     $line =~ s/>$// ;           # Get rid of final '>'
  3295.     $self->{'_AName'} = $line ;
  3296.     $self->dump() if ( $IISCore::debug ) ;
  3297.     
  3298.     return $self ;
  3299. }
  3300.  
  3301. sub isTerminator {
  3302.     my $self = shift ;
  3303.     my $line = shift ;
  3304.  
  3305.     return ( $line =~ /$self->{'_AType'}/i ) ;
  3306. }
  3307.  
  3308. sub dump {
  3309.     my $self = shift ;
  3310.     print( "dump($self->{'_AClass'})\n" ) ;
  3311.     $tab = "  " ;
  3312.     @content = keys( %$self ) ;
  3313.     foreach $key ( sort @content ) {
  3314.         printf( "%s%-20s = %s\n", $tab, $key, $self->{$key} ) ;
  3315.     }
  3316. }
  3317.  
  3318.  
  3319. #############################################################################
  3320. #
  3321. #   IISMimeMapAP
  3322. #       Apache 'mime.types' parsing object.
  3323. #
  3324. #############################################################################
  3325. package     IISMimeMapAP ;
  3326. require     Exporter ;
  3327. @ISA    = qw( Exporter ) ;
  3328. @EXPORT = qw( _addMimeType, _construct, _exportMimeTypes, dump ) ;
  3329.  
  3330. sub new {
  3331.     my $class        = shift ;
  3332.     my %params       = @_ ;
  3333.     my $self         = {} ;
  3334.     $self->{'_AClass'} = $class ;
  3335.     bless $self, $class ;
  3336.     
  3337.     $self->{'_AFile'}   = $params{'_AFile'} ;
  3338.     $self->{'serverno'} = $params{'serverno'} ;
  3339.     print( "NEW $class, $self->{'_AFile'}\n" ) if ( $IISCore::debug ) ;
  3340.  
  3341.     my $line ;
  3342.     my $exts ;
  3343.     my $fullline ;
  3344.     my $mimetype ;
  3345.  
  3346.     #open( FILE, $self->{'_AFile'} ) or ( $@ = $!, return undef)  ;
  3347.     open( FILE, $self->{'_AFile'} ) or return $self;
  3348.     
  3349.     while ( <FILE> ) {
  3350.         $fullline = $_ ;
  3351.         # Accumulate line if line-continuation encountered.
  3352.         while ( /\\$/ ) {
  3353.             $line = <FILE> ;
  3354.             $_ = $' . $line ;
  3355.             $fullline = join( '', $fulline, $line ) ;
  3356.             # Exit loop if we encounter EOF.
  3357.             last if ( $_ eq $' ) ;
  3358.         }
  3359.  
  3360.         # Skip blank and comment lines
  3361.         next if /^\s*$/ ;
  3362.         next if /^#/ ;
  3363.  
  3364.         # Add mime type to hash.
  3365.         chomp( $fulline ) ;
  3366.         $fullline =~ /\s+/ ;    # Skip past first word/whitespace
  3367.         $mimetype = $` ;        # First word is mime-type.
  3368.         $exts     = $' ;        # Remaining is extention(s).
  3369.         $exts =~ s/^\s*(.*?)\s*$/$1/ ; # Trim whitespace
  3370.         if ( $exts ) {
  3371.             $self->{'mimetype'}{$exts} = $mimetype ;
  3372.         }
  3373.     }
  3374.     close( FILE ) ;
  3375.     $self->dump() if ( $IISCore::debug ) ;
  3376.  
  3377.     return $self ;
  3378. }
  3379.  
  3380. sub _addMimeType {
  3381.     my $self = shift ;
  3382.     my $line = shift ;
  3383.     my $mimetype ;
  3384.     my $exts ;
  3385.  
  3386.     chomp( $line ) ;
  3387.     $line =~ /\s+/ ;            # Skip past first word/whitespace
  3388.     $mimetype = $` ;            # First word is mime-type.
  3389.     $exts     = $' ;            # Remaining is extention(s).
  3390.     $exts =~ s/\.//g ;          # Remove '.' from extensions.
  3391.     $exts =~ s/^\s*(.*?)\s*$/$1/ ; # Trim whitespace
  3392.     if ( $exts ) {
  3393.         $self->{'mimetype'}{$exts} = $mimetype ;
  3394.     }
  3395. }
  3396.  
  3397. sub _exportMimeTypes {
  3398.     my $self      = shift ;
  3399.     my $otherself = shift ;
  3400.  
  3401.     my $content ;
  3402.     my $ext ;
  3403.     my $exts ;
  3404.     my $mimetype ;
  3405.     my $mimemap ;
  3406.     my $key ;
  3407.  
  3408.     @content = keys( %{$self->{'mimetype'}} ) ;
  3409.     foreach $key ( sort @content ) {
  3410.         @exts = split( ' ', $key ) ;
  3411.         foreach $ext ( sort @exts ) {
  3412.             $mimetype = "[." . $ext . "," . $self->{'mimetype'}{$key} . "]" ;
  3413.             $mimemap .= $mimetype ;
  3414.         }
  3415.     }
  3416.     $otherself->{'MimeMap'} = IISMimeMap->new( 'MimeMap'  => $mimemap,
  3417.                                                'serverno' => $self->{'serverno'} ) ;
  3418. }
  3419.  
  3420. sub dump {
  3421.     my $self = shift ;
  3422.     print( "dump($self->{'_AClass'})\n" ) ;
  3423.     $tablvl = 0 ;
  3424.     $tab = "  " ;
  3425.     $tabnum = $tablvl * length( $tab ) ;
  3426.     $fmt = "%" . $tabnum . "s%-20s = %s\n" ;
  3427.     @content = keys( %$self ) ;
  3428.     foreach $key ( sort @content ) {
  3429.         printf( $fmt, $tab, $key, $self->{$key} ) ;
  3430.     }
  3431.     @content = keys( %{$self->{'mimetype'}} ) ;
  3432.     foreach $key ( sort @content ) {
  3433.         printf( $fmt, $tab, $key, $self->{'mimetype'}{$key} ) ;
  3434.     }
  3435. }
  3436.  
  3437.  
  3438. #############################################################################
  3439. #
  3440. #   IISUserDbAP - convert LDIF format to NT Resource Kit 'addusers'.
  3441. #
  3442. #############################################################################
  3443. package     IISUserDbAP ;
  3444. require     Exporter ;
  3445. use         Cwd ;
  3446. @ISA    = qw(