1 package webman.stager; 2 3 import org.apache.log4j.*; 4 import java.net.*; 5 import java.security.*; 6 import java.io.*; 7 import java.util.*; 8 import javax.net.ssl.*; 9 import javax.security.cert.X509Certificate; 11 import java.security.KeyStore ; 12 13 24 public class SiteTransmitter extends Stager 25 { 26 27 public final String INTERNAL_VERSION = "1.59"; 28 29 private final static Category CAT = Category.getInstance(SiteTransmitter.class); 30 31 32 public final static String DEFAULT_BASE_PROPERTY_RESOURCE = "sitetransmitter"; 33 34 public final static String DEFAULT_KEYSTORE_FILE = "testkeys.sitetransmitter"; 35 36 public final static String DEFAULT_KEYSTORE_PASSWORD = "passphrase"; 37 38 public final static String DEFAULT_TARGET_PORT = "4242"; 39 40 public final static String DEFAULT_OPEN_SOCKET_TIMEOUT_SECONDS = "60"; 41 42 public final static String LOG_END_TAG = "### THE END ###"; 43 44 private final static int MAX_OPEN_TIMEOUT_SECONDS = 300; 45 46 private final static int SHOW_LOG_TIMEOUT = 300000; 47 48 private final static int OPEN_SOCKET_WAIT = 2000; 49 50 private final static int MAX_SHOW_TIME = 60000; 51 52 private final static int SLEEP_TIME = 100; 53 54 private final static int MILLIS_PER_SECOND = 1000; 55 56 private final static int BUFSIZE = 2048; 57 58 private static final int MIN_PORT = 1024; 59 60 private static final int MAX_PORT = 65535; 61 62 private static final int INITIAL_TEMP_LOG_BUFFER_CAPACITY = 100; 63 65 66 private Vector propertySetList; 67 68 private int currentPropertySet; 69 70 private boolean isCurrentParsedPropertySetFinal; 71 72 private PropertySet baseProperties = null; 73 74 private String confroot = null; 75 76 78 private ServerStarter starter = null; 79 80 private SSLSocket clientSocket = null; 81 82 private SSLSocketFactory socketFactory = null; 83 84 private File zippedSite = null; 85 87 private SitePacker sitePacker; 88 89 private boolean success; 90 91 private boolean fehler; 92 93 94 private Socket outSocket = null; 95 96 private boolean showLogOnly; 97 98 private boolean reuseZipfile = false; 99 100 private boolean useDB = false; 101 102 private String fuckJTest = "Dummystring für JTest-kompatible Dummyanweisungen"; 103 104 108 public static void main(String [] args) 109 { 110 (new SiteTransmitter()).startMain(args); 111 } 112 113 117 private void startMain(String [] args) 118 { 119 try 120 { 121 CAT.debug("Am Anfang war der Beginn! (Wir starten um: " + new Date() + ")"); 122 fehler = false; 123 124 boolean useConfig = true, transferChangedOnly = false; 128 int openSocketTimeout, outPort = -1; 130 outStream = System.out; if ( args.length > 3 ) 132 { 133 printUsage(); 134 } 135 136 151 152 try 154 { 155 PropertySet arguments = new PropertySet(parseArguments(args)); 156 try 157 { 158 outPort = Integer.parseInt(arguments.get("port")); 159 } 160 catch (Exception e) 161 { 162 outPort = -1; 163 } 164 if ( outPort > -1 ) 166 { 167 try 168 { 169 outSocket = new Socket(InetAddress.getLocalHost(), outPort); 170 outStream = new PrintStream(outSocket.getOutputStream(), true); 171 System.setErr(outStream); 172 System.setOut(outStream); 173 } 174 catch (Throwable t) 175 { 176 error("Wrong configuration of port",t); 177 error("writing to stdout..."); 178 } 179 } 180 181 showLogOnly = "true".equals(arguments.get("showlog")); 183 if ( showLogOnly ) 185 { 186 printHeader("webman - Log(s) of last Transmission(s)"); 187 } else 189 { printHeader("webman - Transmission of Site(s)"); 191 } 192 193 String baseResourceDescriptor = arguments.get("configuration"); 194 if ( baseResourceDescriptor == null ) { 196 baseResourceDescriptor = arguments.get("propertyfile"); if ( baseResourceDescriptor == null ) 198 { 199 baseResourceDescriptor = DEFAULT_BASE_PROPERTY_RESOURCE; 201 try 202 { com.teamkonzept.webman.db.TKWebmanDBManager.initConnection("/webmandb.ini", false); 207 useDB = true; 208 logAndPrint("<FONT color=white>Using WebMan-PropertyGroup " + baseResourceDescriptor + " as base property-resource.</FONT>"); 209 } 210 catch (Throwable t) 211 { 212 error("Could not retrieve WebMan Properties due to error while accessing database: " + t.toString()); 213 error("Stopping SiteTransmitter."); 214 System.exit(-1); 215 } 216 } 217 } 218 else 219 { 220 logAndPrint("<FONT color=white>Using file " + baseResourceDescriptor + " as base property-resource.</FONT>"); 221 } 222 223 propertySetList = new Vector(); 224 try 225 { 226 CAT.debug("PARSING baseProperties..."); 227 baseProperties = readProperties(baseResourceDescriptor); 228 } 229 catch (WrongConfigurationException w) 230 { 231 error("Wrong property configuration in base property-resource (" + baseResourceDescriptor + "): " + w.getMessage()); 232 error("SiteTransmitter stopped."); 233 System.exit(-1); 234 } 235 236 Vector propertyResourceDescriptors = baseProperties.getPropertyGroup("TargetProperties"); 238 if ( propertyResourceDescriptors.size() > 0) { 240 CAT.debug("PARSING TargetProperties..."); 241 String resourceDescriptor; 242 for ( int i = 0; i < propertyResourceDescriptors.size(); i++ ) 243 { 244 resourceDescriptor = (String )(propertyResourceDescriptors.elementAt(i)); 245 try 246 { 247 propertySetList.add(readProperties(resourceDescriptor)); 248 } 249 catch (WrongConfigurationException w) 250 { 251 error("Wrong property configuration in property-resource " + resourceDescriptor,w); 252 if ( i < propertyResourceDescriptors.size() - 1 ) { 254 logAndPrint("omitting the respective target"); 255 } 256 } 257 } 258 if ( propertySetList.size() == 0 ) { 260 error("No valid extended property-resource found. Using base property-resource (" + baseResourceDescriptor + ")"); 261 try { 263 propertySetList.add(parseProperties(baseProperties)); 266 ((PropertySet)propertySetList.lastElement()).set("ResourceDescriptor",baseResourceDescriptor); 267 } 268 catch (WrongConfigurationException w) 269 { 270 error("Wrong property configuration in base property-resource (" + baseResourceDescriptor + ")",w); 271 print("SiteTransmitter stopped."); 272 System.exit(-1); 273 } 274 } 275 } 276 else { 278 propertySetList.add(baseProperties); 279 propertyResourceDescriptors.add(baseResourceDescriptor); 280 } 281 } 282 catch (Exception e) { 284 error("Unknown error while reading configuration",e); 285 error("SiteTransmitter stopped."); 286 System.exit(-1); 287 } 288 finally { 290 if ( useDB ) 291 { 292 com.teamkonzept.webman.db.TKWebmanDBManager.deregister(false); 293 } 294 } 295 296 300 currentPropertySet = 0; 301 while ( currentPropertySet < propertySetList.size() ) { 303 success = true; PropertySet props = (PropertySet)propertySetList.elementAt(currentPropertySet); 306 CAT.info( "NEW STAGING PROCESS BEGINS FOR " + props.get("ResourceDescriptor")); 307 logAndPrint("<BR>============================================================================"); 309 310 if ( showLogOnly ) 311 { 312 showLog(props.get("logFile")); 313 currentPropertySet++; 315 continue; 316 } 317 318 if ( !logFinished(props.get("logFile")) ) 321 { print("<B>There is an active process, showing log</B>"); 324 print("<FONT size=-1>(waiting not more than " + MAX_SHOW_TIME/MILLIS_PER_SECOND + " seconds for log continuation...)</FONT><BR>"); 325 showLog(props.get("logFile")); 326 currentPropertySet++; continue; 328 } 329 330 switch (props.get("filesToTransmit").charAt(0)) 331 { 332 case 'c': useConfig = true; 333 transferChangedOnly = true; 334 break; 335 case 'a': useConfig = true; 336 transferChangedOnly = false; 337 break; 338 case 'd': useConfig = false; 339 transferChangedOnly = false; 340 break; 341 default: fuckJTest = "wurde vorher abgefangen verdammte scheiße noch mal!"; 342 } 343 openSocketTimeout = MILLIS_PER_SECOND * Integer.parseInt(props.get("OpenSocketTimeoutSeconds")); 344 345 logfile = openLog(props.get("logFile"),props.get("appendLog").equals("true")); 347 348 logAndPrint("<H2>Staging to target " + (currentPropertySet + 1) + " of " + propertySetList.size() 349 + " (as defined in " + props.get("ResourceDescriptor") + ")</H2>"); 350 logAndPrint("<!------------------------------------------------------------------------------------------------------------------------------------->"); 351 logAndPrint("<B>WebMan SiteTransmitter started at " + new java.util.Date () + "</B>"); 352 logAndPrint("DocumentRoot: " + markAsFile(props.get("documentRoot"))); 353 logAndPrint("TargetCGI: " + props.get("targetCGI")); 354 String targetCGIServer = ServerStarter.serverPart(props.get("targetCGI")); 355 logAndPrint("<FONT color=white>Staging to " + targetCGIServer + "</FONT>"); 356 try 357 { 358 if ( !props.get("targetHost").equals(targetCGIServer) ) 359 { 360 logAndPrint("<FONT color=white>But connecting to: " + InetAddress.getByName(props.get("targetHost")) + "</FONT>"); 361 } 362 else 363 { 364 logAndPrint("Connecting to: " + InetAddress.getByName(props.get("targetHost"))); 365 } 366 } 367 catch (Exception e) 368 { 369 error("Lookup failed: TargetHost " + props.get("targetHost") + " is unknown!"); 370 closeLog(); 371 fehler = true; 372 currentPropertySet++; 374 continue; 375 } 376 logAndPrint("TargetPort: " + props.get("targetPort")); 377 378 if ( props.get("siteDocumentsConfig") != null ) 379 { 380 logAndPrint("using SiteDocumentsConfiguration: " + markAsFile(props.get("siteDocumentsConfig"))); 381 if ( !useConfig ) 382 { 383 logAndPrint("(but ignoring include and exclude rules)"); 384 } 385 } 386 else 387 { 388 logAndPrint("using TargetDir: " + markAsFile(props.get("TargetDir"))); 389 } 390 391 logAndPrint("Storing list of site documents in " + markAsFile(props.get("siteDocumentsListing"))); 392 393 if ( transferChangedOnly ) 394 { 395 logAndPrint("Transmitting changed files only"); 396 } 397 else 398 { 399 logAndPrint("Transmitting all files"); 400 } 401 402 if ( logfile == null ) 403 { 404 error("Warning: couldn't open logfile " + markAsFile(props.get("logFile"))); 405 } 406 else 407 { 408 if ( props.get("appendLog").equals("true") ) 409 { 410 logAndPrint("Appending log to " + markAsFile(props.get("logFile"))); 411 } 412 else 413 { 414 logAndPrint("Creating log in " + markAsFile(props.get("logFile"))); 415 } 416 } 417 CAT.debug("Staging begins..."); 419 if ( !methodSucceed(initSSL(), "initializing ssl") 425 || !methodSucceed(assembleSite(props.get("documentRoot"), 427 props.get("siteDocumentsConfig"), 428 props.get("TargetDir"), 429 props.get("siteDocumentsListing"), 430 useConfig)) 431 || !methodSucceed(packSite(props.get("tempDir"),transferChangedOnly)) 433 || !methodSucceed(prepareSSL(props.get("keyStore"),props.get("keyStorePassword"), 435 props.get("keyPassword"),props.get("trustStore"))) 436 || !methodSucceed(createConnection(props.get("targetCGI"), props.get("targetHost"), 438 new Integer (props.get("targetPort")).intValue(), 439 props.get("userName"), props.get("passWord"), 440 props.get("proxyHost"), props.get("proxyPort"), 441 openSocketTimeout, props.getReceiverProperties()) ) 442 || !transmitSite(zippedSite) 444 || !methodSucceed(transmitSiteInfo(), "transmitting list of site documents") 446 || !methodSucceed(receiveLog(),"receiving log of SiteReceiver") ) 448 { 449 success = false; 450 } 451 452 if ( starter != null ) 454 { 455 if ( starter.gotReceiverOutput() ) 456 { 457 logAndPrint("Starting output of SiteReceiver:"); 458 logAndPrint(" "); 459 starter.startOutput(); 460 logAndPrint(" "); } 462 CAT.debug("waiting for starter to end"); 463 synchronized ( starter.lock ) 464 { 465 CAT.debug("ServerStarter ended"); 466 } 467 if ( !starter.success ) 468 { 469 success = false; 470 } 471 } 472 473 if ( success ) 475 { 476 logAndPrint("<FONT color=#00cc00>Everything is fine, stored new list of site documents in: " + markAsFile(props.get("siteDocumentsListing")) + "</FONT>"); 477 try 478 { 479 sitePacker.saveToFile(props.get("siteDocumentsListing")); 480 } 481 catch (java.io.IOException e) 482 { 483 error("Warning: unable to store new list"); 484 logAndPrint(e.toString()); 485 error("next publication of changed files might be inaccurate"); 486 error("please transfer all files next time (set FilesToTransmit = a)"); 487 } 488 } 489 else 490 { 491 error("Something went wrong, please contact your system administrator."); 492 Enumeration appenders = CAT.getRoot().getAllAppenders(); 494 Vector logNames = new Vector(); 495 Object appender = null; 496 while ( appenders.hasMoreElements() ) 497 { 498 appender = appenders.nextElement(); 499 if ( appender instanceof FileAppender ) 500 { 501 logNames.add( ((FileAppender)appender).getFile() ); 502 } 503 } 504 if ( logNames.size() > 0 ) 505 { 506 String hint = "He should also check the Log4J-Logfiles: "; 507 for ( int i=0; i<logNames.size(); i++ ) 508 { 509 hint += (String )logNames.elementAt(i); 510 if ( i<logNames.size()-1 ) 511 { 512 hint += ", "; 513 } 514 } 515 error(hint + "."); 516 } 517 fehler = true; 518 } 519 if ( clientSocket != null ) 522 { 523 try 524 { 525 clientSocket.close(); 526 CAT.debug("socket closed"); 527 } 528 catch (Exception e) 529 { 530 CAT.warn("could not close socket to receiver",e); 531 logAndPrint("warning: unable to close socket to receiver"); 532 } 533 } 534 535 logAndPrint("end of log"); 536 closeLog(); 537 try 538 { 539 if ( !reuseZipfile && (zippedSite != null) ) 540 { 541 zippedSite.delete(); 542 } 543 } 544 catch (Exception e) 545 { 546 print("Note: zipfile could not be deleted - you can manually delete it."); 547 CAT.error("zipfile could not be deleted: " + e); 548 } 549 currentPropertySet++; } } 552 catch (Throwable t) 553 { 554 CAT.error("Unknown error occurred",t); 555 } 556 try 557 { 558 outSocket.close(); 559 } 560 catch (Exception e) 561 { 562 CAT.warn("Could not close interprocess socket (STDOUT-Redirect)",e); 563 } 564 printFooter(); System.exit(success && !fehler ? 0 : 1); 566 } 567 568 574 private PropertySet readProperties(String resourceDescriptor) throws WrongConfigurationException 575 { 576 PropertySet source, result; 577 try 578 { 579 if ( useDB ) 580 { 581 source = new PropertySet(com.teamkonzept.lib.PropertyManager.getPropertyManager(resourceDescriptor)); 582 } 583 else { 585 if ( confroot == null ) 586 { String classname = getClass().getName(); 588 String docroot = new File(getClass().getResource(classname.substring(classname.lastIndexOf(".") + 1) + ".class").getFile()).getParent(); 589 confroot = new File(getAbsoluteName(docroot,resourceDescriptor)).getParent(); 590 resourceDescriptor = getAbsoluteName(docroot,resourceDescriptor); 591 } 592 else 593 { resourceDescriptor = getAbsoluteName(confroot,resourceDescriptor); 595 } 596 Properties p = new Properties(); 597 p.load(new FileInputStream(resourceDescriptor)); 598 source = new PropertySet(p); 599 } 600 } 601 catch (Exception e) 602 { 603 throw new WrongConfigurationException("Could not read property-resource \"" + resourceDescriptor + "\": " + e.toString()); 604 } 605 result = parseProperties(source); 606 result.set("ResourceDescriptor",resourceDescriptor); return result; 608 } 609 610 617 private PropertySet parseProperties(PropertySet source) throws WrongConfigurationException 618 { 619 631 PropertySet result = new PropertySet(); 632 isCurrentParsedPropertySetFinal = true; 635 try 636 { 637 if ( baseProperties == null ) 638 { CAT.debug("TargetPropertiesDescriptors..."); 640 Vector resourceDescriptors = source.getPropertyGroup("TargetProperties"); 641 if ( resourceDescriptors.size() > 0 ) 642 { 643 for (int i=0; i<resourceDescriptors.size(); i++) 644 { result.set("TargetProperties" + i,(String )(resourceDescriptors.elementAt(i))); 646 } 647 isCurrentParsedPropertySetFinal = false; 649 } 650 } 653 String temp = null; File tempFile = null; 656 try 658 { 659 temp = getProperty(source,"LogName"); 660 } 661 catch (PropertyNotFoundException p) 662 { temp = getProperty(source,"logFile"); 664 } 665 if ( temp != null ) 666 { 667 try 668 { 669 temp = getAbsoluteName(confroot,temp); 670 } 671 catch (IllegalArgumentException e) 672 { 673 if ( useDB ) 674 { 675 throw new WrongConfigurationException("When using WebMan properties for " 676 + "configuration, it is not possible to use a relative path " 677 + "(\"" + temp + "\") for LogName. Specify an absolute path!"); 678 } 679 else 680 { 681 throw e; 682 } 683 } 684 try 685 { 686 temp = new File(temp).getCanonicalPath(); 687 } 688 catch (IOException e) 689 { 690 CAT.warn("Could not form canonical path for " + temp); 691 } 692 } 693 result.set("LogFile",temp); 694 CAT.debug("LogFile=" + temp); 695 if ( showLogOnly ) 697 { 698 return result; 699 } 700 701 temp = getProperty(source,"DocumentRoot"); 702 if ( temp != null ) 703 { 704 if ( temp.endsWith(File.separator) ) 705 { 706 temp = temp.substring(0,temp.length()-File.separator.length()); 707 } 708 else if ( temp.endsWith("/") ) { 710 temp = temp.substring(0,temp.length()-"/".length()); 711 } 712 if ( !(new File(temp).exists()) ) 713 { 714 throw new WrongConfigurationException("DocumentRoot " + temp + " doesn't exist."); 715 } 716 try 717 { 718 temp = new File(temp).getCanonicalPath(); 719 } 720 catch (Exception e) 721 { 722 CAT.warn("Could not form canonical path for " + temp); 723 } 724 result.set("documentRoot",temp); 725 } 726 CAT.debug("DocumentRoot=" + result.get("documentRoot")); 727 728 try 730 { 731 temp = getProperty(source, "AppendLog"); 732 if ( temp != null && temp.toLowerCase().equals("yes") ) 733 { 734 result.set("appendLog","true"); 735 } 736 else 737 { 738 result.set("appendLog","false"); 739 } 740 } 741 catch (Exception e) 742 { 743 result.set("appendLog","false"); } 745 CAT.debug("AppendLog=" + result.get("AppendLog")); 746 747 try 748 { temp = getProperty(source,"OpenSocketTimeoutSeconds"); 750 if ( temp != null && (Integer.parseInt(temp) < 1 || Integer.parseInt(temp) > MAX_OPEN_TIMEOUT_SECONDS) ) 752 { 753 throw new WrongConfigurationException("OpenSocketTimeoutSeconds must be within 1.." + MAX_OPEN_TIMEOUT_SECONDS); 754 } 755 } 756 catch ( PropertyNotFoundException p ) 757 { 758 temp = DEFAULT_OPEN_SOCKET_TIMEOUT_SECONDS; 759 } 760 result.set("OpenSocketTimeoutSeconds",temp); 761 CAT.debug("OpenSocketTimeoutSeconds=" + result.get("OpenSocketTimeoutSeconds")); 762 763 temp = getProperty(source,"TargetCGI"); 764 if ( temp != null ) { 766 if ( !temp.startsWith("http://") ) 768 { 769 temp = "http://" + temp; 770 } 771 result.set("TargetCGI",temp); 772 } 773 CAT.debug("TargetCGI=" + result.get("TargetCGI")); 774 775 temp = source.get("TargetHost"); if ( temp != null ) { 782 if ( temp.startsWith("http://") ) 784 { 785 temp = temp.substring(7); 786 } 787 } 788 else if ( baseProperties != null && baseProperties.get("TargetHost") != null ) 789 { temp = baseProperties.get("TargetHost"); } 792 else { temp = getProperty(source,"TargetCGI"); 795 if ( temp != null && isCurrentParsedPropertySetFinal ) 797 { temp = ServerStarter.serverPart(temp); 799 } 800 else { temp = null; 803 } 804 } 805 if ( temp != null ) { 807 result.set("TargetHost",temp); } 809 CAT.debug("TargetHost=" + result.get("TargetHost")); 810 811 try 812 { 813 temp = getProperty(source,"TargetPort"); 814 if ( temp != null ) 815 { 816 try 817 { 818 int port = Integer.parseInt(temp); if ( port < MIN_PORT || port > MAX_PORT ) 820 { 821 throw new NumberFormatException (); 822 } 823 } 824 catch (NumberFormatException n) 825 { 826 throw new WrongConfigurationException("TargetPort must be within 1024...65535"); 827 } 828 } 829 else 830 { 831 temp = DEFAULT_TARGET_PORT; 832 } 833 result.set("TargetPort",temp); 834 } 835 catch (PropertyNotFoundException e) 836 { 837 result.set("TargetPort",DEFAULT_TARGET_PORT); 838 } 839 CAT.debug("TargetPort=" + result.get("TargetPort")); 840 841 try 843 { temp = getProperty(source,"ProxyHost"); } 846 catch (PropertyNotFoundException e) 847 { 848 temp = null; 849 } 850 if ( temp != null ) { 852 try 853 { 854 int port = Integer.parseInt(getProperty(source,"proxyPort")); if ( port < 0 || port > MAX_PORT ) 856 { 857 throw new NumberFormatException (); 858 } 859 result.set("proxyHost",temp); 860 result.set("proxyPort",getProperty(source,"ProxyPort")); 861 } 862 catch (NumberFormatException n) 863 { 864 throw new WrongConfigurationException("proxyPort must be within 0..." + MAX_PORT); 865 } 866 } 867 CAT.debug("ProxyHost=" + result.get("ProxyHost")); 868 CAT.debug("ProxyPort=" + result.get("ProxyPort")); 869 870 temp = getProperty(source,"TempDir"); 871 if ( temp != null ) 872 { 873 try 874 { 875 result.set("tempDir",getAbsoluteName(result.get("documentRoot"),temp)); 876 } 877 catch (IllegalArgumentException e) 878 { 879 throw new WrongConfigurationException("when using a relative pathname for TempDir, DocumentRoot must be set as well."); 880 } 881 try 882 { 883 temp = new File(temp).getCanonicalPath(); 884 } 885 catch (Exception e) 886 { 887 CAT.warn("Could not form canonical path for " + temp); 888 } 889 } 890 CAT.debug("TempDir=" + result.get("TempDir")); 891 892 try 895 { 896 temp = getProperty(source,"KeyStore"); 897 if ( temp == null ) 898 { throw new PropertyNotFoundException("keyStore"); } 901 else 902 { 903 result.set("keyStore",temp); 904 } 905 } 906 catch (PropertyNotFoundException p) 907 { 908 result.set("keyStore",""); 909 } 910 CAT.debug("KeyStore=" + result.get("KeyStore")); 911 912 try 913 { 914 temp = getProperty(source,"TrustStore"); 915 if ( temp == null ) 916 { throw new PropertyNotFoundException("TrustStore"); } 919 result.set("trustStore",temp); 920 } 921 catch (PropertyNotFoundException p) 922 { 923 result.set("trustStore",DEFAULT_KEYSTORE_FILE); 924 } 925 CAT.debug("TrustStore=" + result.get("TrustStore")); 926 927 temp = source.get("KeyStorePassword"); 930 if ( temp != null ) 931 { 932 result.set("KeyStorePassword",temp); 933 temp = source.get("KeyPassword"); 934 if ( temp != null ) 935 { 936 result.set("KeyPassword",temp); 937 } 938 else 939 { 940 result.set("KeyPassword",result.get("KeyStorePassword")); 941 } 942 } 943 else 944 { 945 try 946 { 947 result.set("KeyStorePassword",getProperty(source,"KeyStorePassword")); 948 } 949 catch (PropertyNotFoundException p) 950 { 951 result.set("KeyStorePassword",DEFAULT_KEYSTORE_PASSWORD); 952 } 953 954 try 955 { 956 result.set("KeyPassword",getProperty(source,"KeyPassword")); 957 } 958 catch (PropertyNotFoundException p) 959 { 960 result.set("KeyPassword",result.get("KeyStorePassword")); 961 } 962 } 963 CAT.debug("KeyStorePassword=" + result.get("KeyStorePassword")); 964 CAT.debug("KeyPassword=" + result.get("KeyPassword")); 965 966 970 temp = source.get("SiteDocumentsConfig"); 972 if ( temp != null ) 973 { 974 try 975 { 976 temp = getAbsoluteName(confroot,temp); 977 } 978 catch (IllegalArgumentException e) 979 { 980 if ( useDB ) 981 { 982 throw new WrongConfigurationException("When using WebMan properties for " 983 + "configuration, it is not possible to use a relative path " 984 + "(\"" + temp + "\") for SiteDocumentsConfig. Specify an absolute path!"); 985 } 986 else 987 { 988 throw e; 989 } 990 } 991 try 992 { 993 temp = new File(temp).getCanonicalPath(); 994 } 995 catch (Exception e) 996 { 997 CAT.warn("Could not form canonical path for " + temp); 998 } 999 tempFile = new File(temp); 1000 if ( !tempFile.exists() || !tempFile.canRead() ) 1001 { 1002 throw new WrongConfigurationException("Cannot find or read site documents configuration file " + temp); 1003 } 1004 result.set("SiteDocumentsConfig",temp); 1005 } 1006 else { temp = source.get("TargetDir"); 1009 if ( temp != null ) { 1011 result.set("TargetDir",temp); 1012 } 1013 else if ( isCurrentParsedPropertySetFinal ) 1014 { 1015 if ( baseProperties != null ) { if ( baseProperties.get("SiteDocumentsConfig") != null ) 1018 { result.set("SiteDocumentsConfig",baseProperties.get("SiteDocumentsConfig")); 1020 } 1021 else 1022 { 1023 if ( baseProperties.get("TargetDir") != null ) 1024 { 1025 result.set("TargetDir",baseProperties.get("TargetDir")); 1026 } 1027 else { 1029 throw new WrongConfigurationException("TargetDir or SiteDocumentsConfig must be set"); 1030 } 1031 } 1032 } 1033 else { 1035 throw new WrongConfigurationException("TargetDir or SiteDocumentsConfig must be set"); 1036 } 1037 } } 1039 CAT.debug("SiteDocumentsConfig=" + result.get("SiteDocumentsConfig")); 1040 CAT.debug("TargetDir=" + result.get("TargetDir")); 1041 1042 temp = getProperty(source,"SiteDocumentsListing"); 1043 if ( temp != null ) 1044 { 1045 try 1046 { 1047 temp = getAbsoluteName(confroot,temp); 1048 } 1049 catch (IllegalArgumentException e) 1050 { 1051 if ( useDB ) 1052 { 1053 throw new WrongConfigurationException("When using WebMan properties for " 1054 + "configuration, it is not possible to use a relative path " 1055 + "(\"" + temp + "\") for SiteDocumentsListing. Specify an absolute path!"); 1056 } 1057 else 1058 { 1059 throw e; 1060 } 1061 } 1062 try 1063 { 1064 temp = new File(temp).getCanonicalPath(); 1065 } 1066 catch (Exception e) 1067 { 1068 CAT.warn("Could not form canonical path for " + temp); 1069 } 1070 tempFile = new File(temp); 1071 if ( !tempFile.exists() ) 1072 { 1073 throw new WrongConfigurationException("Cannot find SiteDocumentsListing " + temp); 1074 } 1075 if ( !tempFile.canWrite() || !tempFile.canRead() ) 1076 { 1077 throw new WrongConfigurationException("SiteDocumentsListing " + temp + " is not readable and writable."); 1078 } 1079 for (int i=0; i<propertySetList.size(); i++) 1080 { if ( temp.equals( ((PropertySet)propertySetList.elementAt(i)).get("siteDocumentsListing") ) ) 1082 { 1083 throw new WrongConfigurationException("SiteDocumentsListing must be unique for each target! " 1084 + "(filename " + temp + " is used in more than one property-resource (or inherited from base property-resource))") ; 1085 } 1086 } 1087 result.set("SiteDocumentsListing",temp); 1088 } 1089 CAT.debug("SiteDocumentsListing=" + result.get("SiteDocumentsListing")); 1090 1091 try 1092 { 1093 temp = getProperty(source, "TargetCGIPasswordProtected"); 1094 } 1095 catch (PropertyNotFoundException p) 1096 { 1097 temp = null; 1098 } 1099 if ( temp != null) 1100 { 1101 if ( temp.toLowerCase().equals("yes") ) 1102 { 1103 result.set("userName",getProperty(source,"TargetCGIUserName")); 1104 result.set("passWord",getProperty(source,"TargetCGIPassword")); 1105 CAT.debug("TargetCGIUserName=" + result.get("userName")); 1106 CAT.debug("TargetCGIPassword=" + result.get("passWord")); 1107 } 1108 } 1109 1110 temp = getProperty(source,"FilesToTransmit"); 1111 if ( temp != null ) 1112 { 1113 temp = temp.toLowerCase(); 1114 if ( (temp.equals("c") || temp.equals("a") || temp.equals("d")) ) 1115 { 1116 result.set("FilesToTransmit",temp); 1117 } 1118 else 1119 { 1120 throw new WrongConfigurationException("entry FilesToTransmit must be one of c, a or d"); 1121 } 1122 } 1123 else 1124 { 1125 result.set("FilesToTransmit","a"); 1126 } 1127 CAT.debug("FilesToTransmit=" + result.get("FilesToTransmit")); 1128 1130 try 1133 { 1134 result.set("ReceiverSiteDocumentsListing",getProperty(source,"ReceiverSiteDocumentsListing")); 1135 } 1136 catch (PropertyNotFoundException p) 1137 { temp = null; 1139 } 1140 CAT.debug("ReceiverSiteDocumentsListing=" + result.get("ReceiverSiteDocumentsListing")); 1141 1142 try 1143 { 1144 result.set("ReceiverLogFile",getProperty(source,"ReceiverLogFile")); 1145 } 1146 catch (PropertyNotFoundException p) 1147 { temp = null; 1149 } 1150 CAT.debug("ReceiverLogFile=" + result.get("ReceiverLogFile")); 1151 if ( isCurrentParsedPropertySetFinal ) 1154 { 1155 PropertySet props; 1156 for (int i=0; i<propertySetList.size(); i++) 1158 { 1159 props = (PropertySet)propertySetList.elementAt(i); 1160 if ( props.get("TargetHost").equals(result.get("TargetHost")) ) 1162 { 1163 if ( props.get("ReceiverSiteDocumentsListing") == null ) 1168 { 1169 throw new WrongConfigurationException("ReceiverSiteDocumentsListing must be set for EACH target for targets on the same host! "); 1170 } 1171 if ( result.get("ReceiverSiteDocumentsListing").equals(props.get("ReceiverSiteDocumentsListing")) ) 1173 { 1174 throw new WrongConfigurationException("ReceiverSiteDocumentsListing must be unique for each target for targets on the same host! "); 1175 } 1176 try 1177 { if ( result.get("ReceiverLogFile").equals(props.get("ReceiverLogFile")) ) 1179 { 1180 throw new PropertyNotFoundException(null); } 1182 } 1183 catch (PropertyNotFoundException p) 1184 { 1185 logAndPrint("Note: it is recommended to use distinct values for ReceiverLogFile when staging to multiple targets on the same host."); 1186 } 1187 } 1188 } 1189 } 1190 temp = source.get("ReceiverAfterBurner"); 1193 if ( temp != null ) 1194 { 1195 if ( temp.equals("") ) 1198 { 1199 return result; 1200 } 1201 result.set("ReceiverAfterBurner",temp); 1202 temp = source.get("ReceiverAfterBurnerNoJava"); 1203 if ( temp != null && temp.equals("yes") ) 1204 { 1205 result.set("ReceiverAfterBurnerNoJava","true"); 1206 } 1207 Vector params = source.getPropertyGroup("ReceiverAfterBurnerParameter"); 1208 for ( int i=0; i<params.size(); i++) 1209 { 1210 result.set("ReceiverAfterBurnerParameter" + i,params.elementAt(i)); 1211 } 1212 } 1213 else if (baseProperties != null ) 1214 { 1215 temp = baseProperties.get("ReceiverAfterBurner"); 1216 if ( temp != null ) 1217 { 1218 result.set("ReceiverAfterBurner",temp); 1219 temp = source.get("ReceiverAfterBurnerNoJava"); 1220 if ( temp != null && temp.equals("yes") ) 1221 { 1222 result.set("ReceiverAfterBurnerNoJava","true"); 1223 } 1224 CAT.debug("ReceiverAfterBurnerParameter..."); 1225 Vector params = baseProperties.getPropertyGroup("ReceiverAfterBurnerParameter"); 1227 for ( int i=0; i<params.size(); i++) 1228 { 1229 result.set("ReceiverAfterBurnerParameter" + i,params.elementAt(i)); 1230 CAT.debug("ReceiverAfterBurnerParameter" + i + "=" + 1231 result.get("ReceiverAfterBurnerParameter"+i)); 1232 } 1233 } 1234 } 1235 CAT.debug("ReceiverAfterBurner=" + result.get("ReceiverAfterBurner")); 1236 1237 try 1239 { 1240 temp = getProperty(source,"ReceiverSkipErrors"); 1241 if ( temp != null && temp.toLowerCase().equals("yes") ) 1242 { 1243 result.set("ReceiverSkipErrors","yes"); 1244 } 1245 } 1246 catch (PropertyNotFoundException p) 1247 { 1248 temp = null; 1249 } 1250 CAT.debug("ReceiverSkipErrors=" + result.get("ReceiverSkipErrors")); 1251 1252 try 1254 { 1255 temp = getProperty(source,"ReceiverSimulate"); 1256 if ( temp != null && temp.toLowerCase().equals("yes") ) 1257 { 1258 result.set("ReceiverSimulate","yes"); 1259 } 1260 } 1261 catch (PropertyNotFoundException p) 1262 { 1263 temp = null; 1264 } 1265 CAT.debug("ReceiverSimulate=" + result.get("ReceiverSimulate")); 1266 } 1267 catch (Exception e) { 1269 if ( !(e instanceof WrongConfigurationException) ) 1270 { CAT.error("Unknown Exception: " + e.getMessage(),e); throw new WrongConfigurationException(e.toString()); 1273 } 1274 else 1275 { throw (WrongConfigurationException)e; 1277 } 1278 } 1279 return result; 1280 } 1281 1282 1289 private String getProperty(PropertySet p, String key) throws PropertyNotFoundException 1290 { 1291 String s = p.get(key); 1292 1293 if ( s == null || s.equals("") ) 1294 { 1295 if ( baseProperties != null ) { s = baseProperties.get(key); 1298 } 1299 } 1300 if ( (s == null || s.equals("")) && isCurrentParsedPropertySetFinal ) 1301 { 1302 throw new PropertyNotFoundException(key); 1303 } 1304 return s; 1305 } 1306 1307 1313 private Hashtable parseArguments(String [] argStrings) 1314 { 1315 Hashtable args = new Hashtable(); 1316 int delimiter; 1317 String key,value; 1318 for (int i = 0; i<argStrings.length ; i++) 1319 { 1320 delimiter = argStrings[i].indexOf('='); 1321 if (delimiter > -1) 1322 { 1323 key = argStrings[i].substring(0,delimiter); 1324 value = argStrings[i].substring(delimiter+1); 1325 if (value.length() > 0) 1326 { 1327 args.put(key,value); 1328 } 1329 } 1330 else 1331 { args.put("configuration",argStrings[i]); 1333 } 1334 } 1335 return args; 1336 } 1337 1338 1349 private String assembleSite(String documentRoot, String siteConfig, String targetDir, String siteDocumentsListing, boolean useConfig) 1350 { 1351 logAndPrint("<b>assembling site</b>"); 1352 SiteDocumentsListing oldListing = null; 1353 try 1354 { 1355 oldListing = new SiteDocumentsListing(siteDocumentsListing); 1356 } 1357 catch ( IOException e) 1358 { 1359 logAndPrint("Found no old listing at " + siteDocumentsListing); 1360 CAT.debug("Found no old siteDocumentsListing: " + e.toString()); 1361 } 1362 try 1363 { 1364 sitePacker = new SitePacker(documentRoot, siteConfig, targetDir, oldListing, useConfig); 1365 } 1366 catch ( IOException e) 1367 { 1368 return e.toString(); 1369 } 1370 return null; 1371 } 1372 1373 1379 private String packSite(String tempDir, boolean changedOnly) 1380 { 1381 if ( reuseZipfile ) { 1383 return null; 1384 } 1385 1386 logAndPrint("<b>packing site</b>"); 1387 File tempSite, zip; 1389 try 1390 { 1391 tempSite = File.createTempFile("webman_site","",new File(tempDir)); 1392 tempSite.delete(); 1393 CAT.info("Assembling site in temporary directory " + tempSite.getPath()); 1394 zip = File.createTempFile("webman",".zip",new File(tempDir)); 1395 zip.delete(); 1396 CAT.info("Packing site into temporary file " + zip.getPath()); 1397 } 1398 catch (IOException e) 1399 { 1400 CAT.debug("Unable to create temporary file in directory " + tempDir,e); 1401 return "Unable to create temporary file in " + tempDir + ": " + e.getMessage(); 1402 } 1403 try 1404 { 1405 zippedSite = sitePacker.zipSite(zip.getAbsolutePath(),tempSite.getAbsolutePath(),changedOnly); 1406 } 1407 catch (IOException e) 1408 { 1409 return "Unable to zip site into file " + zip.getAbsolutePath() + NEWLINE + e.toString(); 1410 } 1411 deleteFile(tempSite.getAbsolutePath()); 1412 return null; 1413 } 1414 1415 1419 private String transmitSiteInfo() 1420 { 1421 CAT.debug("transmitting site info..."); 1422 ObjectOutputStream oos = null; 1423 try 1424 { 1425 oos = new ObjectOutputStream(clientSocket.getOutputStream()); 1426 oos.writeObject(sitePacker); 1427 oos.flush(); 1428 } 1429 catch (IOException e) 1430 { 1431 return "unable to transmit site documents listing" + NEWLINE + e.toString(); 1432 } 1433 return null; 1434 } 1435 1436 1444 private String prepareSSL(String keyStore, String keyStorePassword, String keyPassword, String trustStore) 1445 { 1446 logAndPrint("<b>preparing ssl connection</b>"); 1447 try 1448 { 1449 1451 com.sun.net.ssl.SSLContext ssl = com.sun.net.ssl.SSLContext.getInstance("SSL"); 1452 KeyStore ks = KeyStore.getInstance("JKS"); 1453 1454 com.sun.net.ssl.TrustManagerFactory tmf = com.sun.net.ssl.TrustManagerFactory.getInstance("SunX509"); 1455 ks.load(Stager.getResourceInputStream(this.getClass(),trustStore),null); 1456 tmf.init(ks); 1457 logAndPrint("using TrustStore " + markAsFile(trustStore) + " (for server authentication)"); 1458 1459 com.sun.net.ssl.KeyManagerFactory kmf = null; 1461 if ( !keyStore.equals("") ) 1462 { 1463 kmf = com.sun.net.ssl.KeyManagerFactory.getInstance("SunX509"); 1464 ks.load(Stager.getResourceInputStream(this.getClass(),keyStore),keyStorePassword.toCharArray()); 1465 kmf.init(ks, keyPassword.toCharArray()); 1466 logAndPrint("using KeyStore " + markAsFile(keyStore) + " (for client authentication)"); 1467 } 1468 1469 ssl.init((kmf==null ? null : kmf.getKeyManagers()), tmf.getTrustManagers(), null); 1470 socketFactory = ssl.getSocketFactory(); 1472 } 1473 catch (Exception e) 1474 { 1475 return "unable to create ssl socket factory: " + e; 1476 } 1477 return null; 1478 } 1479 1480 1493 String createConnection(String receiverCGI, String receiverHost, int receiverPort, 1494 String userName, String passWord, String proxyHost, String proxyPort, 1495 int openSocketTimeout, Hashtable receiverProperties) 1496 { 1497 logAndPrint("<b>creating connection</b>"); 1498 try 1499 { 1500 if ( proxyHost != null && proxyPort != null) 1502 { 1503 System.setProperty("http.proxyHost",proxyHost); 1504 System.setProperty("http.proxyPort",proxyPort); 1505 logAndPrint("using HTTP-Proxy " + proxyHost + ":" + proxyPort); 1506 } 1507 } 1508 catch (Exception e) 1509 { 1510 logAndPrint("Could not set proxy parameters; connection may fail."); 1511 } 1512 1513 starter = new ServerStarter(receiverCGI, this, userName, passWord, receiverProperties); 1514 starter.start(); 1515 1516 logAndPrint("Start opening socket at " + new java.util.Date ()); 1517 long start_time = System.currentTimeMillis(); 1518 Exception exc = null; 1519 while ( System.currentTimeMillis() - start_time < (long)openSocketTimeout ) 1520 { 1521 exc = null; 1522 if ( clientSocket != null && starter.isOK() ) 1523 { try 1527 { 1528 String line = readFromSocket(clientSocket); 1533 if ( line == null ) 1534 { 1535 CAT.info("received null instead of ready at " + new java.util.Date ()); 1536 logAndPrint("Socket not ready, trying again..."); 1537 } 1538 else if ( line.indexOf("ready") == -1 ) 1539 { 1540 return "SiteReceiver did not respond or authentication failed"; 1541 } 1542 else 1543 { 1544 logAndPrint("Connected at " + new java.util.Date () + " on " + clientSocket); 1545 break; 1546 } 1547 } 1548 catch (Exception e) 1551 { 1552 if (e.getMessage() != null ) { 1554 if ( e.getMessage().indexOf("SocketException") > -1 ) 1555 { 1556 error(e.getMessage()); 1557 if ( e.getMessage().indexOf("Connection aborted by peer: socket write error") > -1 ) 1558 { 1559 logAndPrint("This error may arise from a failed SSL client authentication"); 1560 logAndPrint("See if SiteReceiver demands SSL client authentication and if so," 1561 + " check that KeyStore is specified for SiteTransmitter and that it containes the required certificate."); 1562 return "unable to establish SSL connection"; 1564 } 1565 } 1566 else if ( e.getMessage().indexOf("SSLException") > -1 ) 1567 { 1568 error(e.getMessage()); 1569 if ( e.getMessage().indexOf("untrusted server cert chain") > -1 ) 1570 { 1571 logAndPrint("Check if the SiteReceiver has the appropriate certificate to authenticate to the SiteTransmitter and vice versa."); 1572 } 1573 else 1574 { 1575 logAndPrint("Check the SSL configuration!"); 1576 } 1577 CAT.error("unable to read from socket",e); 1578 return "unable to establish SSL connection"; 1580 1581 } 1582 } 1583 CAT.warn("unable to read from socket",e); 1584 CAT.info("trying again..."); 1585 } 1586 } 1587 if ( ! starter.isOK() ) 1588 { 1589 logAndPrint("Connector stopped at " + new java.util.Date ()); 1590 break; 1591 } 1592 try 1593 { 1594 Thread.sleep(OPEN_SOCKET_WAIT); 1595 clientSocket = (SSLSocket)socketFactory. 1596 createSocket(InetAddress.getByName(receiverHost), receiverPort); 1597 } 1598 catch (Exception e) 1599 { 1600 exc = e; 1601 } 1602 } 1603 if ( exc != null ) 1604 { 1605 logAndPrint("Stopped opening socket at " + new java.util.Date ()); 1606 return "unable to create ssl socket: " + exc; 1607 } 1608 if ( clientSocket == null ) 1609 { 1610 return "socket closed at " + new java.util.Date (); 1611 } 1612 try 1613 { 1614 clientSocket.setSoTimeout(0); 1615 } 1616 catch (Exception e) 1617 { 1618 logAndPrint("Stopped opening socket at " + new java.util.Date ()); 1619 return "unable to set timeout: " + e.toString(); 1620 } 1621 if ( !starter.isOK() ) 1622 { 1623 return "unable to create ssl socket."; 1624 } 1625 return null; 1626 } 1627 1628 1633 private boolean transmitSite(File zip) 1634 { 1635 logAndPrint("<b>transmitting site</b>"); 1637 try 1638 { 1639 long zipsize = zip.length(); 1640 logAndPrint("Sending site (" + zipsize + " bytes)"); 1641 logAndPrint("begin: " + (new Date()).toString() + " "); 1642 printToSocket(clientSocket, "zip.size=" + zipsize); 1644 FileInputStream fin = new FileInputStream(zip); 1645 BufferedOutputStream out = new BufferedOutputStream(clientSocket.getOutputStream()); 1646 1647 byte[] buf = new byte[BUFSIZE]; 1648 int read; 1649 while ( (read = fin.read(buf, 0, BUFSIZE)) != -1) 1650 { 1651 out.write(buf, 0, read); 1652 } 1653 out.flush(); 1654 logAndPrint(" end: " + (new Date()).toString()); 1655 logAndPrint("<b>... done</b><BR><BR>"); 1656 fin.close(); 1657 zip.delete(); 1658 } 1659 catch (Exception e) 1660 { 1661 error("Unable to transmit zip file",e); 1662 return false; 1663 } 1664 return true; 1665 } 1666 1667 1671 private String receiveLog() 1672 { 1673 CAT.debug("receiving log..."); 1674 BufferedReader in = null; 1675 String last = null, line = null; 1676 Vector log = new Vector(); 1677 int lineCount = 0; 1678 1679 try 1680 { 1681 in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 1682 while ( (line = in.readLine()) != null ) 1683 { 1684 lineCount++; 1685 if ( line.startsWith("abort") ) 1686 { 1687 starter.setLog(log); 1688 throw new Exception ("SiteReceiver aborted operation due to an error."); 1689 } 1690 last = line; 1691 log.add(line); 1692 } 1693 starter.setLog(log); 1694 if ( last == null || !last.startsWith("end") ) 1695 { 1696 throw new Exception ("SiteReveiver did not finish log transmission."); 1697 } 1698 } 1699 catch (Exception e) 1700 { 1701 return e.toString(); 1702 } 1703 return null; 1704 } 1705 1706 1709 protected void printUsage() 1710 { 1711 print("Usage: SiteTransmitter [[configuration=]<propertyFile>] [showlog=true] [port=<port>]"); 1712 } 1713 1714 1718 protected void deleteFile(String name) 1719 { 1720 File f = new File(name); 1721 if ( f.exists() ) 1722 { 1723 if ( f.isDirectory() ) 1724 { 1725 String [] list = f.list(); 1726 for ( int i = 0; i < list.length; i++ ) 1727 { 1728 deleteFile(name + File.separator + list[i]); 1729 } 1730 } 1731 f.delete(); 1732 } 1733 } 1734 1735 1741 protected void showLog(String filename) 1742 { 1743 CAT.info("showing log..."); 1744 try 1745 { 1746 Vector tempLogBuffer = new Vector(INITIAL_TEMP_LOG_BUFFER_CAPACITY); 1747 boolean end_reached = false; 1748 boolean appendedLog = false; int skip = 0; 1750 File file = new File(filename); 1751 long startTime = System.currentTimeMillis(); 1752 print("<H2>Showing Log (" + markAsFile(filename) + ")</H2>"); 1753 while ( !end_reached && System.currentTimeMillis() - startTime < MAX_SHOW_TIME ) 1754 { 1755 Thread.sleep(SLEEP_TIME); 1756 BufferedReader in = new BufferedReader(new FileReader(filename)); 1757 String line = null; 1763 while ( (line = in.readLine()) != null ) 1764 { 1765 if ( line.indexOf(LOG_END_TAG) == -1 ) 1766 { 1767 skip++; 1768 tempLogBuffer.add(line); 1769 } 1770 else 1771 { 1772 line = in.readLine(); 1773 if ( line != null ) { appendedLog = true; 1776 tempLogBuffer = new Vector(INITIAL_TEMP_LOG_BUFFER_CAPACITY); 1777 skip++; 1778 tempLogBuffer.add(line); 1779 } 1780 else { 1782 end_reached = true; 1783 break; 1784 } 1785 } 1786 } 1787 if ( !end_reached && !appendedLog ) 1791 { 1792 while ( tempLogBuffer.size() > 0 ) 1794 { print((String )tempLogBuffer.remove(0) + NEWLINE); 1796 } 1797 if ( (System.currentTimeMillis() - file.lastModified() > SHOW_LOG_TIMEOUT) 1799 || (System.currentTimeMillis() - startTime > MAX_SHOW_TIME) ) 1800 1801 { 1802 tempLogBuffer.add(NEWLINE + NEWLINE + "...[log has not been properly finished]"); 1803 log("...[log has not been properly finished]"); 1804 closeLog(); 1805 end_reached = true; 1806 } 1807 } 1808 } 1809 for ( int i=0; i<tempLogBuffer.size(); i++ ) 1810 { 1811 print((String )tempLogBuffer.elementAt(i) + NEWLINE); 1812 } 1813 } 1814 catch (Exception e) 1815 { 1816 error("Error while reading logfile",e); 1817 if ( e instanceof FileNotFoundException ) 1818 { 1819 print("Note: This may indicate that the referring staging process was not performed, maybe due to a wrong configuration. "); 1820 } 1821 fehler = true; 1822 } 1823 } 1824 1825 1832 protected boolean logFinished(String filename) 1833 { 1834 try 1835 { 1836 File f = new File(filename); 1837 if ( !f.exists() ) 1838 { 1839 return true; 1840 } 1841 if ( System.currentTimeMillis() - f.lastModified() > SHOW_LOG_TIMEOUT ) 1844 { 1845 return true; 1846 } 1847 BufferedReader in = new BufferedReader(new FileReader(f)); 1848 String line = null, 1849 lastLine = null; 1850 while ((line = in.readLine()) != null) 1852 { 1853 lastLine = line; 1854 } 1855 return lastLine == null || lastLine.indexOf(LOG_END_TAG) > -1; 1856 } 1857 catch (Exception e) 1858 { 1859 print("Error while reading logfile: " + e); 1860 CAT.error("Error while reading logfile",e); 1861 } 1862 return true; 1863 } 1864 1865 1868 protected void closeLog() 1869 { 1870 log(LOG_END_TAG); 1871 super.closeLog(); 1872 } 1873 1874 1879 private void printHeader(String title) 1880 { 1881 print("<HTML><HEAD>" 1882 + "<TITLE>" + title + "</TITLE>" 1883 + "</HEAD><BODY BGCOLOR=#FFFFFF TEXT=#000000>" 1884 + "<FONT FACE=Geneva, Arial, sans-serif>" 1885 + "<H1>WebMan Stager: SiteTransmitter</H1>" 1886 + "Java version: " + System.getProperty("java.version") 1887 + ", Java vendor: " + System.getProperty("java.vendor") 1888 + ", SiteTransmitter-Version: " + INTERNAL_VERSION + "<BR>"); 1889 } 1890 1891 1894 private void printFooter() 1895 { 1896 print("</FONT></FONT></BODY></HTML>"); 1897 } 1898 1899 1905 private String mapReceiverOutputMarker(String str) 1906 { 1907 String result = str; 1908 String tag=""; 1909 if ( str.startsWith(starter.RECEIVER_OUTPUT_MARKER) ) 1910 { 1911 result = str.substring(starter.RECEIVER_OUTPUT_MARKER.length()); 1912 if ( result.trim().toLowerCase().startsWith("<h") || result.trim().toLowerCase().startsWith("<b") ) 1914 { 1915 tag = result.substring(0,result.indexOf(">") + 1); 1916 result = result.substring(result.indexOf(">") + 1); 1917 } 1918 for ( int i=0; i<starter.RECEIVER_OUTPUT_MARKER.length(); i++) 1920 { 1921 if ( starter.RECEIVER_OUTPUT_MARKER.charAt(i) == ' ' ) 1922 { 1923 result = " " + result; 1924 } 1925 else 1926 { 1927 result = starter.RECEIVER_OUTPUT_MARKER.charAt(i) + result; 1928 } 1929 } 1930 } 1931 return tag + result; 1932 } 1933 1934 1938 private void print(String str) 1939 { 1940 StringTokenizer tokens = new StringTokenizer(str,NEWLINE); 1941 while ( tokens.hasMoreElements() ) 1942 { 1943 outStream.println(mapReceiverOutputMarker(tokens.nextToken()) + "<BR>"); 1944 } 1945 outStream.flush(); 1946 } 1947 1948 1952 protected void logAndPrint(String line) 1953 { 1954 print(line); 1955 log(line); 1956 } 1957} 1958 1959 1960 1966class ServerStarter extends Thread 1967{ 1968 1969 Object lock = new Object (); 1970 1971 boolean success = true; 1972 1973 1974 private String server = null; 1975 1976 private String user = null; 1977 1978 private String pass = null; 1979 1980 private BufferedReader in = null; 1981 1982 private Vector buffer = new Vector(); 1983 1984 private Hashtable receiverProperties; 1985 1986 private boolean outputStartet = false; 1987 1988 private SiteTransmitter caller = null; 1989 1990 private Vector receiverLog = new Vector(); 1991 1992 private boolean ok = true; 1996 1997 public final static String RECEIVER_OUTPUT_MARKER = " > "; 1998 1999 private final static Category CAT = Category.getInstance(ServerStarter.class); 2000 2001 2009 ServerStarter(String server_url, SiteTransmitter caller, String userName, String passWord, Hashtable receiverProperties) 2010 { 2011 server = server_url; 2012 this.caller = caller; 2013 this.user = userName; 2014 this.pass = passWord; 2015 this.receiverProperties = receiverProperties; 2016 } 2017 2018 2021 public void run() 2022 { 2023 synchronized( lock ) 2024 { 2025 boolean done = false; ok = true; CAT.debug("running ServerStarter"); 2028 String line; 2029 if ( receiverProperties.size() > 0 ) 2031 { 2032 Enumeration keys = receiverProperties.keys(); 2033 server += "?"; 2034 String key; 2035 while ( keys.hasMoreElements() ) 2036 { 2037 key = (String )keys.nextElement(); 2038 server += URLEncoder.encode(key.substring("Receiver".length())) + "=" 2039 + URLEncoder.encode((String )receiverProperties.get(key)); 2040 if ( keys.hasMoreElements() ) 2041 { 2042 server += "&"; 2043 } 2044 } 2045 caller.logAndPrint("Submitting receiver properties: URL=" + server); 2046 } 2047 2048 URL start_receiver = null; 2049 try 2050 { 2051 start_receiver = new URL(server); 2052 } 2053 catch (java.net.MalformedURLException e) 2054 { 2055 caller.error("Bad URL format: " + server); 2056 return; 2057 } 2058 HttpURLConnection uc = null; 2059 try 2060 { 2061 uc = (HttpURLConnection)start_receiver.openConnection(); 2062 } 2063 catch (IOException e) 2064 { 2065 caller.error("Cannot open connection to: " + uc + ": " + e.toString()); 2066 } 2067 try 2068 { 2069 if ( user != null && user.length() > 0 && pass != null ) 2071 { 2072 String userPassword = user + ":" + pass; 2073 String encoding = new sun.misc.BASE64Encoder().encode (userPassword.getBytes()); 2074 uc.setRequestProperty ("Authorization", "Basic " + encoding); 2075 caller.logAndPrint("prepared authentication - done"); 2076 } 2077 boolean retry = false; 2078 do 2079 { 2080 try 2081 { 2082 CAT.debug("run(): now getting InputStream"); 2083 long start = new Date().getTime(); 2084 in = new BufferedReader(new InputStreamReader(uc.getInputStream())); 2085 long end = new Date().getTime(); 2086 CAT.debug("run(): getting InputStream took " + (end - start) + " ms."); 2087 retry = false; } 2089 catch (NullPointerException n) 2090 { 2091 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 2092 n.printStackTrace(new PrintStream(baos)); 2093 if ( baos.toString().indexOf("sun.net.www.http.ChunkedInputStream.readChunkSize") > -1 ) 2094 { CAT.warn("run(): NPE in readChunkSize() while getting InputStream from socket"); 2097 retry = true; 2098 } 2099 else 2100 { 2101 throw n; 2102 } 2103 } 2104 } while ( retry ); 2105 CAT.debug("run(): got InputStream"); 2106 int lineCount = 0; 2108 do 2109 { 2110 try 2111 { 2112 while ( (line = in.readLine()) != null ) 2113 { 2114 lineCount++; 2115 if ( line.startsWith("abort") ) 2116 { 2117 success = false; 2119 caller.error("SiteReceiver has aborted"); 2120 break; 2121 } 2122 if ( line.equals("end of http output") ) 2123 { 2124 CAT.info("run(): SiteReceiver has ended http output"); 2125 break; 2126 } 2127 if ( line.startsWith("end") ) 2128 { 2129 caller.logAndPrint("SiteReceiver has ended"); 2131 break; 2132 } 2133 if ( buffer != null ) 2134 { 2135 buffer.add(line); 2136 } 2137 else 2138 { 2139 caller.logAndPrint(line); 2140 } 2141 } 2142 retry = false; CAT.debug("run(): read " + lineCount + " lines. leaving read-in-loop..."); 2144 } 2145 catch (NullPointerException n) 2146 { 2147 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 2148 n.printStackTrace(new PrintStream(baos)); 2149 if ( baos.toString().indexOf("sun.net.www.http.ChunkedInputStream.readChunkSize") > -1 ) 2150 { CAT.warn("run(): NPE in readChunkSize() while reading from socket in ServerStarter.run()"); 2153 retry = true; 2154 } 2155 else 2156 { 2157 throw n; 2158 } 2159 } 2160 } while ( retry ); 2161 CAT.debug("run(): closing InputStream..."); 2162 done = true; 2164 in.close(); 2165 } 2166 catch (FileNotFoundException e) 2167 { 2168 String response = uc.getHeaderField(0); response = response.substring(response.indexOf(" ") + 1); if ( response.startsWith("404") ) 2172 { 2173 caller.error(server + " not found! Possibly the URL is misspelled (note that the filename part of an URL may be case sensitive.)"); 2174 } 2175 else if ( response.startsWith("403") ) 2176 { 2177 caller.error(server + " is a forbidden URL. Check the web server/filesystem-permissions for this URL!"); 2178 } 2179 else if ( response.startsWith("5") ) 2180 { 2181 caller.error(server + " generated an Internal Server Error."); 2182 caller.error("This indicates a wrong CGI-processing, so you should check the cgi-file and related configuration files."); 2183 caller.error("It is also possible that the cgi-file has not the proper permissions for reading/execution."); 2184 } 2185 else if ( response.startsWith("401") ) 2186 { 2187 caller.error("You're not authorized to call " + server); 2188 caller.error("Check these properties: TargetCGIPasswordProtected, TargetCGIUser, TargetCGIPassword (for this URL)!"); 2189 } 2190 else 2191 { 2192 caller.error("Error while calling " + server + " - HTTP-Response: " + response); 2193 } 2194 CAT.error("run(): HTTP-Response: " + response); 2195 } 2197 catch (java.net.UnknownHostException e) 2198 { 2199 caller.error("Server not found: " + serverPart(server)); 2200 caller.error("Either the URL is misspelled, or the server is not online or reachable."); 2201 } 2202 catch ( ConnectException c ) 2203 { 2204 caller.error("Couldn't connect to " + serverPart(server) + "."); 2205 caller.error("There is probably no web server running at this URL."); 2206 CAT.error("run(): " + c); 2207 } 2208 catch (Exception e) 2209 { 2210 caller.error("Unknown exception: " + e.toString()); 2211 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 2212 e.printStackTrace(new PrintStream(baos)); 2213 CAT.error("run(): " + baos.toString()); 2214 } 2215 finally 2216 { 2217 ok = done; 2218 } 2219 } 2220 } 2221 2222 2227 public static String serverPart(String url) 2228 { 2229 String result = url; 2230 if ( url.indexOf("//") > -1 ) 2231 { result = url.substring(url.indexOf("//") + 2); 2234 } 2235 int ende1 = result.indexOf("/"); 2236 if ( ende1 == -1 ) 2237 { 2238 ende1 = result.length(); 2239 } 2240 int ende2 = result.indexOf(":"); if ( ende2 == -1 ) 2242 { 2243 ende2 = result.length(); 2244 } 2245 return result.substring(0,ende1 < ende2 ? ende1 : ende2); 2246 } 2247 2248 2251 public boolean isOK() 2252 { 2253 return ok; 2254 } 2255 2256 2260 public void startOutput() 2261 { 2262 synchronized ( lock ) 2263 { 2264 CAT.debug("startOutput()..."); 2265 if ( outputStartet ) 2266 { 2267 return; 2268 } 2269 outputStartet = true; 2270 if ( buffer != null ) 2271 { 2272 for ( int i = 0; i < buffer.size(); i++ ) 2273 { 2274 caller.logAndPrint(RECEIVER_OUTPUT_MARKER + (String )buffer.get(i)); 2275 } 2276 buffer = null; 2277 } 2278 for ( int i = 0; i < receiverLog.size(); i++ ) 2280 { 2281 caller.logAndPrint(RECEIVER_OUTPUT_MARKER + (String )receiverLog.get(i)); 2282 } 2283 } 2284 } 2285 2286 2290 public boolean gotReceiverOutput() 2291 { 2292 return (buffer.size() > 0) || (receiverLog.size() > 0); 2293 } 2294 2295 2299 public void setLog(Vector log) 2300 { 2301 receiverLog = log; 2302 } 2303} 2304 | Popular Tags |