--- /dev/null
+Mon Aug 27 00:29:02 EDT 2001
+
+jcifs-0.5.1
+
+Chris did some great testing at the CIFS Conference Interoperability
+Lab and found three minor bugs. They are described in detail here:
+
+http://lists.samba.org/pipermail/jcifs/2001-August/001428.html
+
+These packages will now work with Java 1.1 as well as Java 2.
+
+Sun Jul 29 04:01:18 EDT 2001
+
+jcifs-0.5
+
+This is the final release of the 0.5 series. It is the most stable and
+complete product the jCIFS team has to offer. There are no known bugs. A bug
+in the renameTo operation (would not always return false when it should have)
+has been fixed, API documentation improvements have been made, and a
+entry to the FAQ has been added.
+
+Fri Jul 13 18:54:37 EDT 2001
+
+jcifs-0.5b2
+
+Thanks to Rob for realizing that attempting to read the same file from
+different processes/threads yielded an "The file is being used by another
+process" exception. We had the share flags and access masks wrong. A
+Log.CRITICAL_EXCEPTIONS mask has been added for logging messages to the
+console. If:
+
+ Log.setMask( Log.CRITICAL_EXCEPTIONS );
+
+is set, the "Access denied", "Bad password", and "The device is not
+ready" sorts of exceptions will NOT be printed. The default is still
+Log.EXCEPTIONS which encompasses both Log.CRITICAL_EXCEPTIONS and regular
+Log.EXCEPTIONS so existing code will not be affected.
+
+Thu Jun 28 21:04:15 EDT 2001
+
+jcifs-0.5b
+
+This is the beta release of jcifs-0.5. The 0.5 series has already been
+through a stable release and there are no know bugs so we are confident
+that it will perform well. New features since jcifs-0.4 include:
+
+o SmbFile.list() Bug Fix - The jcifs-0.4 package had a serious bug that
+ caused a TRANS2_FIND_FIRST2/NEXT2 endless loop. It has been properly
+ fixed. This should be the first *complete* stable release.
+o Share, Server, and Workroup Enumeration - jCIFS can now list the shares
+ on a server, servers of a workgroup, and workgroups on a network.
+o CallNamedPipe, TransactNamedPipe, and CreateFile Named Pipe API (Paul)
+o Complete SMB Filesharing URL Scheme IETF Draft Support - The smb://
+ URL scheme has been fully implemented. (Chris)
+o Transactions and RAP API
+o Transactions - Full multi-part Transaction requests(used by Transact
+ Named Pipes)
+o Daylight Savings Bug Fix - jCIFS was not properly correcting for
+ daylight savings. (Urban)
+o Full SmbComNTCreateAndX Support - We now look just like NT 4 instead
+ of Winblows 95 :~)
+o Unicode Alignment Bug Fix - Unicode alignment was generally not
+ correct and caused many problems in early 0.5dev releases.
+o SmbFile Method Behaviors - Fixed canRead() and re-thought and soul
+ searched over the meaning of each of these methods and their behavior
+ in the smb://, smb://name, and Named Pipe contexts. These methods
+ should start to get pretty stable at this point.
+o Clean, No Wait Exiting - Examples and other programs would wait 15
+ seconds before exiting. This has been fixed by making the Transport
+ thread setDaemon( true ). Same for the NameServiceClient Thread.
+o Full Tuneable Batching
+o NetBIOS Scope Fix
+o New getServer, getShare, isWorkgroup Methods
+o SmbShell and SmbCrawler Utilities
+
+Thanks deserved for this release to Chris, Steve, Paul, The DJ, Urban,
+James, Thierry, savaJe Technologies, and Josef.
+
+FILES:
+
+ jcifs-0.5b.tgz jar and javadoc only for UNIX
+ jcifs-0.5b.zip jar and javadoc only for WINDOWS
+ jcifs-0.5b.jar jar file only
+
+NOTE: The source code is included in the above packages. If
+you would like to actually build jCIFS the ANT jar files are packaged
+separately:
+
+ ant.tgz ant jar files
+ ant.zip ditto
+
+Just unpack one of the above in the jcifs_0.5b directory, set JAVA_HOME in
+build.{sh,bat} to bootstrap Ant, and run $ ./build.sh smb or > build smb.
+
+IMPORTANT:
+
+The jcifs.netbios.ns.nameserver has been changed to jcifs.netbios.wins
+and the jcifs.util.Config class should now be referenced as
+jcifs.Config. Programs written for jcifs-0.4 will not run without making
+these two changes at least.
+
+The jCIFS project uses the 'Ant' build tool available here:
+
+ http://jakarta.apache.org/ant/
+
+If you have *any* trouble please let us know on the mailing list by
+sending mail to jcifs@samba.org or to myself at mballen@erols.com.
+
+Enjoy,
+Michael B. Allen <mballen@erols.com>
+
+--8<--
+
+ JCIFS
+ Common Internet File System Client in 100% Java
+ http://jcifs.samba.org
+
+
+This is the JCIFS SMB client library written in Java. In short it
+will enable Java applications to remotely access shared directories
+on SMB file servers(i.e. a Microsoft Windows "share"). It is a fairly
+religious implementation of the CIFS specification supporting Unicode,
+batching, multiplexing, encrypted authentication, transactions, named
+pipes, share/server/workgroup enumeration, and more. It is licensed
+under LGPL which means commercial organizations can legitimately use it
+with their propertietary code(you just can't modify the library itself
+without reciprocation).
+
+REQUIREMENTS:
+
+Java 1.1 or above - http://java.sun.com/products/
+
+INSTALLATION
+
+Just add the jar file to you classpath as you would with any other
+jar. More specifically:
+
+UNIX:
+
+1) Go to http://jcifs.samba.org and download jcifs-0.5b.tgz
+2) Put it someplace reasonable and extract it with:
+
+ $ gunzip jcifs-0.5b.tgz
+ $ tar -xvf jcifs-0.5b.tar
+
+3) Add the jar to your classpath. There are two ways to do this. One is to
+explicitly set it on the command line when you run your application like:
+
+ $ java -cp path/to/jcifs-0.4b.jar MyApplication
+
+or perhaps export it in your .profile/.bash_profile like:
+
+ CLASSPATH=$CLASSPATH:/home/miallen/path/to/jcifs-0.5b.jar
+ export CLASSPATH
+
+WINDOWS:
+
+1) Go to http://jcifs.samba.org and download jcifs-0.5b.zip
+2) Extract it with winzip and put the files someplace reasonable.
+3) Add the jar to your classpath. There are two ways to do this. One is to
+explicitly set it on the command line when you run your application like:
+
+ C:\jcifs> java -cp jcifs-0.4b.jar MyApplication
+
+The other way is to alter your system environment but I'm not confident
+I can tell you accurately how to do that.
+
+It is also common that the CLASSPATH be specified in a shell script or
+batch file. See build.{sh,bat} as a hint.
+
+RUNNING JCIFS:
+
+In general the public API is extremely simple. The jcifs.smb.SmbFile,
+jcifs.smb.SmbFileInputStream, and jcifs.smb.SmbFileOutputStream
+classes are analogous to the java.io.File, java.io.FileInputStream,
+and java.io.FileOutputStream classes so if you know how to use those it
+should be quite obvious how to use JCIFS provided you set any necessary
+properties(such as wins) and understand the smb:// URL syntax.
+
+Here's an example to retrieve a file:
+
+ import jcifs.smb.*;
+
+ jcifs.Config.setProperty( "wins", "192.168.1.230" );
+ SmbFileInputStream in = new SmbFileInputStream(
+ "smb://username:password@host/c/My Documents/report.txt" );
+ byte[] b = new byte[65535];
+ int n;
+ while(( n = in.read( b )) > 0 ) {
+ System.out.write( b, 0, n );
+ }
+
+You can also write, rename, list contents of a directory, enumerate
+shares, communicate with Win32 Named Pipe Servers, ...etc.
+
+The protocol handler for java.net.URL is also in place which means you
+retrieve files using the URL class as you would with other protocols. For
+example:
+
+ Class.forName( "jcifs.Config" ); //ensure protocol handler is loaded
+ URL url = new URL( "smb://user:pass@host/share/dir/file.txt" );
+ InputStream in = url.openStream();
+
+This will also work with whatever else uses the URL class internally. For
+example if you use RMI you can serve class files from an SMB share and
+use the codebase property:
+
+ -Djava.rmi.server.codebase=smb://mymachine/c/download/myapp.jar
+
+To execute the Put example you might do:
+
+$ java -cp examples:jcifs-0.4b.jar Put smb://usr:pass@host/share/file.zip
+##########
+582K transfered
+
+API documentation is included.
+
+WHAT IS SMB AND CIFS?
+
+Server Message Block (SMB) is an application layer networking protocol
+for file and print sharing. It is the de-facto networking protocol for
+Microsoft Windows platforms. The Common Internet File System (CIFS)
+is the more generic name for all that encompasses the protocol and its
+many layers. Collectively this is the networking protocol used when you
+"Map Network Drive...", issue "net use * \\server\share" commands, use
+smbclient on UNIX, smbfs on Linux, Sharity, OS2, server vendors such as
+Network Appliance, EMC, and others.
+
+WHY DO YOU NEED JCIFS?
+
+This client is 100% Java and will work the same in a variety of
+environments from Palm Pilots and applets to any UNIX that supports
+Java. Naturally you can choose to run your applications on a platform
+that supports mapping or mounting remote volumes into the local
+filesystem but this assumes you know what shares you are accessing in
+advance and what platform your application is running on(do you use
+/mnt/pnt or H:\dir). Such an approach is not portable, unstable due to
+unnecessary dependencies, and can be difficult to manage. JCIFS offers
+Java applications that require access to SMB file services portability
+and therefore the added stability that the UNIX environment can
+provide. The JCIFS infrastructure is also highly extensible. If there
+is a demand it will include a great deal of additional functionality
+not available through a filesystem API such as printing, RPC, NT file
+change notification, etc.
+
+ACKNOWLEDGEMENTS
+
+Special thanks to the Samba organization and Christopher R. Hertel for
+starting the JCIFS project.
--- /dev/null
+@echo off
+
+REM set JAVA_HOME=C:\Program Files\JavaSoft\JRE\1.2
+set JAVA_HOME=C:\jdk1.2.2
+
+set JAVA=%JAVA_HOME%\bin\java
+set CLASSPATH=ant\ant.jar;ant\jaxp.jar;ant\parser.jar
+
+"%JAVA%" -classpath "%CLASSPATH%" -Dant.home=ant org.apache.tools.ant.Main %1 %2 %3 %4 %5 %6 %7 %8 %9 -buildfile build.xml
+
--- /dev/null
+#!/bin/sh
+
+JAVA_HOME=/usr/local/java
+CLASSPATH=ant/ant.jar:ant/jaxp.jar:ant/parser.jar:${JAVA_HOME}/lib/tools.jar
+
+$JAVA_HOME/bin/java -classpath $CLASSPATH org.apache.tools.ant.Main -buildfile build.xml $@
--- /dev/null
+<?xml version="1.0"?>
+<!--
+
+ This is an "Ant" build file. See http://jakarta.apache.org/ant/index.html for details.
+
+-->
+<project name="jcifs" default="main" basedir=".">
+ <target name="main">
+ <echo message=" TARGETS:"/>
+ <echo message=" smb <-- to build jcifs"/>
+ <echo message=" netbios"/>
+ <echo message=" util"/>
+ <echo message=" clean"/>
+ <echo message=" jar"/>
+ <echo message=" tgz"/>
+ <echo message=" zip"/>
+ <echo message=" javadoc"/>
+ </target>
+
+ <target name="util">
+ <mkdir dir="build"/>
+ <javac srcdir="src"
+ destdir="build"
+ includes="jcifs/util/*.java"
+ debug="on"/>
+ <javac srcdir="src"
+ destdir="build"
+ includes="jcifs/Config.java"
+ debug="on"/>
+ </target>
+ <target name="netbios" depends="util">
+ <mkdir dir="build"/>
+ <javac srcdir="src"
+ destdir="build"
+ includes="jcifs/netbios/*.java"
+ debug="on"/>
+ </target>
+ <target name="smb" depends="netbios,util">
+ <mkdir dir="build"/>
+ <javac srcdir="src"
+ destdir="build"
+ includes="jcifs/smb/*.java"
+ debug="on"/>
+ </target>
+
+ <target name="clean">
+ <delete dir="build"/>
+ </target>
+ <target name="jar" depends="smb">
+ <jar jarfile="jcifs-0.5.1.jar" basedir="build"/>
+ </target>
+
+ <target name="tgz">
+ <copy todir="dist_tmp/jcifs_0.5.1">
+ <fileset dir="." excludes="ant,**/.*,build,jcifs.prp,**/*.tgz,**/*.zip"/>
+ </copy>
+ <tar tarfile="jcifs-0.5.1.tar" basedir="dist_tmp"/>
+ <gzip src="jcifs-0.5.1.tar" zipfile="jcifs-0.5.1.tgz"/>
+ <delete file="jcifs-0.5.1.tar"/>
+ <delete dir="dist_tmp"/>
+ </target>
+ <target name="zip">
+ <copy todir="dist_tmp/jcifs_0.5.1">
+ <fileset dir="." excludes="ant,**/.*,build,jcifs.prp,**/*.tgz,**/*.zip"/>
+ </copy>
+ <fixcrlf srcdir="dist_tmp" cr="add" tab="remove" tablength="4" excludes="**/*.jar,**/*.exe"/>
+ <zip zipfile="jcifs-0.5.1.zip" basedir="dist_tmp"/>
+ <delete dir="dist_tmp"/>
+ </target>
+
+ <target name="javadoc">
+ <delete dir="docs/api"/>
+ <mkdir dir="docs/api"/>
+ <javadoc sourcefiles="jcifs/netbios/NbtAddress,jcifs/smb/SmbFile,jcifs/smb/SmbNamedPipe,jcifs/smb/SmbFileInputStream,jcifs/smb/SmbFileOutputStream,jcifs/smb/SmbURLConnection,jcifs/util/Config,jcifs/util/PropertiesTree,jcifs/util/Log"
+ sourcepath="src"
+ destdir="docs/api"
+ overview="docs/overview.html"
+ author="true"
+ version="true"
+ use="true"
+ windowtitle="jcifs API">
+ <!--link href="http://java.sun.com/products/jdk/1.2/docs/api/"/-->
+ </javadoc>
+ </target>
+</project>
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import jcifs.smb.SmbFile;
+import jcifs.smb.SmbFileOutputStream;
+
+public class Append {
+
+ public static void main( String argv[] ) throws Exception {
+
+ SmbFile f = new SmbFile( argv[0] );
+ SmbFileOutputStream out = new SmbFileOutputStream( f, true );
+
+ byte[] msg;
+ int i = 0;
+ while( i++ < 10 ) {
+ msg = new String( "this is msg #" + i ).getBytes();
+ out.write( msg );
+ Thread.sleep( 17000 );
+ }
+
+ out.close();
+ }
+}
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import jcifs.smb.SmbNamedPipe;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+
+public class CallNamedPipe {
+
+ public static void main( String[] argv ) throws Exception {
+
+ if( argv.length < 2 ) {
+ throw new IllegalArgumentException( "args: <smburl> <filedatatosend> <filetowriterecvdata>" );
+ }
+
+ byte[] b = new byte[65535];
+ FileInputStream fin = new FileInputStream( argv[1] );
+ FileOutputStream fos = new FileOutputStream( argv[2] );
+
+ SmbNamedPipe pipe = new SmbNamedPipe( argv[0],
+ SmbNamedPipe.PIPE_TYPE_RDWR | SmbNamedPipe.PIPE_TYPE_CALL );
+ OutputStream out = pipe.getNamedPipeOutputStream();
+ InputStream in = pipe.getNamedPipeInputStream();
+
+ int n = fin.read( b );
+ System.out.println( "writing " + n + " bytes" );
+ out.write( b, 0, n );
+ n = in.read(b);
+ System.out.println( "read " + n + " bytes" );
+ fos.write(b, 0, n );
+
+ fin.close();
+ fos.close();
+ out.close();
+ }
+}
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import java.util.Date;
+import java.util.TimeZone;
+
+public class CifsTime {
+
+ // Observed dates reporting ServerTimeZone=240
+ // file last modified date = { low, high };
+
+ // Mon Mar 26 23:14:42 EST 2001 (no DST)
+ static final int[] D = { 0x10BE3D00, 0x01C0B66C };
+
+ // Mon Apr 30 03:17:14 EST 2001 (in DST)
+ //static final int[] D = { 0x9474B900, 0x01C0D145 };
+
+ static final long MILLISECONDS_BETWEEN_1970_AND_1601 = 11644473600000L;
+
+ static long calcDate() {
+ int lo, hi;
+ long t;
+
+ t = ((long)D[1] << 32 ) | ( (long)D[0] & 0xFFFFFFFFL );
+ t = ( t / 10000L - MILLISECONDS_BETWEEN_1970_AND_1601 );
+
+ if( TimeZone.getDefault().inDaylightTime( new Date() )) {
+ // in dst
+
+ if( TimeZone.getDefault().inDaylightTime( new Date( t ))) {
+ // t was also generated in dst too so no correction
+ return t;
+ }
+ // t was not generated during dst so add 1 hour
+ return t + 3600000L;
+ } else {
+ // not in dst
+
+ if( TimeZone.getDefault().inDaylightTime( new Date( t ))) {
+ // t was generated in dst so subtract 1 hour
+ return t - 3600000L;
+ }
+ // t was also not generated in dst so no correction
+ return t;
+ }
+ }
+ public static void main( String[] argv ) throws Exception {
+ System.out.println( new Date( calcDate() ));
+ }
+}
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import jcifs.smb.SmbFileOutputStream;
+
+public class CreateFile {
+
+ public static void main( String argv[] ) throws Exception {
+
+ SmbFileOutputStream out = new SmbFileOutputStream( argv[0], true );
+ out.close();
+ }
+}
+
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import jcifs.smb.SmbFile;
+
+public class Delete {
+
+ public static void main( String argv[] ) throws Exception {
+
+ long t0 = System.currentTimeMillis();
+
+ SmbFile f = new SmbFile( argv[0] );
+ if( f.delete() ) {
+ System.out.println( f.getCanonicalPath() + " deleted " + ( System.currentTimeMillis() - t0 ) + "ms" );
+ } else {
+ System.out.println( f.getCanonicalPath() + " deleted failed" );
+ }
+ }
+}
+
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import jcifs.smb.SmbFile;
+
+public class Exists {
+
+ public static void main( String argv[] ) throws Exception {
+
+ SmbFile f = new SmbFile( argv[0] );
+ if( f.exists() ) {
+ System.out.println( argv[0] + " exists" );
+ } else {
+ System.out.println( argv[0] + " does not exist" );
+ }
+ }
+}
+
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Test the following file operations:
+ *
+ * canRead
+ * false - a target that is already open by another process
+ * false - the target does not exist
+ * true - the file exists and there are no sharing issues
+ * canWrite
+ * true - the file exists and there are no sharing issues
+ * false - the file is marked read-only
+ * false - the file does not exist
+ * delete
+ * true - the file existed and was succcessfully deleted
+ * false - the target did not exist
+ * false - the target is a share, server, workgroup or similar
+ * false - the target or file under the target directory failed was read-only
+ * exists
+ * true - the target, share, IPC share, named pipe, server, or workgroup exists
+ * false - the opposite of the above
+ * isDirectory
+ * true - the target is a workgroup, server, share, or directory
+ * false - the target is not one of the above
+ * isFile
+ * direct opposite of isDirectory
+ * isHidden
+ * true - target is share ending in $ or marked as hidden
+ * length
+ * the file was created to be no larger than ~2G and reports back the size specified
+ * mkdir
+ * true - a directory was created successfully
+ * false - the directory could not be created
+ * renameTo
+ * true - the target was renamed
+ */
+
+import jcifs.smb.*;
+import java.io.IOException;
+
+public class FileOps {
+
+ public static void main( String argv[] ) throws Exception {
+
+ if( argv.length != 1 ) {
+ System.out.println( "Must provide an SMB URL of a remote location on which tests will be conducted." );
+ System.exit( 1 );
+ }
+
+ SmbFile s = new SmbFile( argv[0] );
+ SmbFile d = new SmbFile( s, "JcifsTestOpsDir" );
+
+ // delete - Delete the directory if it exists
+
+ if( d.delete() ) {
+ System.out.println( "okay - delete " + d + " successfull" );
+ } else {
+ System.out.println( "okay - delete " + d + " failed" );
+ }
+
+ // exists - Test the directory that should not exist
+
+ if( d.exists() ) {
+ System.out.println( "fail - " + d + " still exists" );
+ System.exit( 1 );
+ } else {
+ System.out.println( "okay - " + d + " does not exist" );
+ }
+
+ // mkdir - Create the directory
+
+ if( d.mkdir() ) {
+ System.out.println( "okay - mkdir " + d + " successfull" );
+ } else {
+ System.out.println( "fail - mkdir " + d + " failed" );
+ System.exit( 1 );
+ }
+
+ // exist - Test the directory with should exist now
+
+ if( d.exists() ) {
+ System.out.println( "okay - " + d + " exists" );
+ } else {
+ System.out.println( "fail - " + d + " was not successfully created" );
+ System.exit( 1 );
+ }
+
+ // mkdir - Try to create a directory even though it already exists
+
+ if( d.mkdir() ) {
+ System.out.println( "fail - mkdir " + d + " successfull" );
+ System.exit( 1 );
+ } else {
+ System.out.println( "okay - mkdir " + d + " failed" );
+ }
+
+ // Create a file to test against
+
+ SmbFile f = null;
+ try {
+ f = new SmbFile( d, "foo.txt" );
+ SmbFileOutputStream o = new SmbFileOutputStream( f );
+ o.write( "The Common Internet File System (CIFS) is the de-facto file sharing protocol on the Microsoft Windows platform. It is the underlying networking protocol used when accessing shares with Windows Explorer, the Network Neighborhood, via a Map Network Drive... dialog, the C:\\> net use * \\\\server\\share commands, or smbclient on UNIX, smbfs on Linux, and elsewhere.\r\n".getBytes() );
+ o.close();
+ } catch( IOException ioe ) {
+ System.out.println( "fail - could not create file " + d + "/aboutcifs.txt");
+ }
+ System.out.println( "okay - created file " + d + "/aboutcifs.txt" );
+
+ // canRead - Test to see if the new file can be read
+
+ if( f.canRead() ) {
+ System.out.println( "okay - canRead " + f + " successfull" );
+ } else {
+ System.out.println( "fail - canRead " + f + " failed" );
+ System.exit( 1 );
+ }
+
+ // canWrite - Test the file for writing
+
+ if( f.canWrite() ) {
+ System.out.println( "okay - canWrite " + f + " successfull" );
+ } else {
+ System.out.println( "fail - canWrite " + f + " failed" );
+ System.exit( 1 );
+ }
+
+ // ASK USER TO FLIP ON READ-ONLY
+
+ System.out.println( "Please change the file " + f + " to read-only (hit return to continue)" );
+ System.in.read();
+
+ // canWrite - Test the file for writing
+
+ if( f.canWrite() ) {
+ System.out.println( "fail - canWrite " + f + " returned true but it should have been marked read-only ... continuing on" );
+ } else {
+ System.out.println( "okay - canWrite " + f + " failed" );
+ }
+
+ // Try to open the file for writing
+
+ try {
+ SmbFileOutputStream w = new SmbFileOutputStream( f );
+ w.close();
+ System.out.println( "fail - successfully opened " + f + " for writing even though it should be marked read-only ... continuing on" );
+ } catch( IOException ioe ) {
+ System.out.println( "okay - correctly failed to open " + f + " for writing" );
+ }
+
+ // renameTo - rename the file to bar.txt
+
+ SmbFile b = new SmbFile( d, "bar.txt" );
+
+ if( f.renameTo(b) ) {
+ System.out.println( "okay - renameTo " + f + " to " + b + " successfull even with read-only" );
+ if( b.renameTo(f) == false ) {
+ System.out.println( "fail - but failed to rename file back to original!" );
+ System.exit( 1 );
+ }
+ } else {
+ System.out.println( "fail - renameTo " + f + " should have been successfull even though the file is marked read-only" );
+ }
+
+ // ASK USER TO FLIP ON HIDDEN FLAG
+
+ System.out.println( "Please turn on the hidden attribute for " + f + " (hit return to continue)" );
+ System.in.read();
+
+ // isHidden - Test to see if the file is hidden
+
+ if( f.isHidden() ) {
+ System.out.println( "okay - isHidden " + f + " is hidden" );
+ } else {
+ System.out.println( "fail - isHidden " + f + " is not hidden but it should be ... continuing on" );
+ }
+
+ // canRead - Test canRead again with both hidden and read-only on
+
+ if( f.canRead() ) {
+ System.out.println( "okay - canRead " + f + " was successfull with read-only and hidden both on" );
+ } else {
+ System.out.println( "fail - canRead " + f + " failed with read-only and hidden both on" );
+ }
+
+ // canWrite - Test the file for writing again with read-only and hidden
+
+ if( f.canWrite() ) {
+ System.out.println( "fail - canWrite " + f + " was successfull even though read-only is set ... continuing on" );
+ } else {
+ System.out.println( "okay - canWrite " + f + " failed as it should being that read-only is set" );
+ }
+
+ // isDirectory - Test file as a directory
+
+ if( f.isDirectory() ) {
+ System.out.println( "fail - isDirectory " + f + " returned true but it is NOT a directory" );
+ } else {
+ System.out.println( "okay - isDirectory " + f + " is not a directory" );
+ }
+
+ // isDirectory - Test directory as a directory
+
+ if( d.isDirectory() ) {
+ System.out.println( "okay - isDirectory " + d + " is a directory" );
+ } else {
+ System.out.println( "fail - isDirectory " + d + " returned false but it really is a directory" );
+ }
+
+ // isFile - Test file as a file
+
+ if( f.isFile() ) {
+ System.out.println( "okay - isFile " + f + " is a file" );
+ } else {
+ System.out.println( "fail - isFile " + f + " return false but it is NOT a file" );
+ }
+
+ // isFile - Test directory as a file
+
+ if( d.isFile() ) {
+ System.out.println( "fail - isFile " + d + " returned true but it is NOT a file" );
+ } else {
+ System.out.println( "okay - isFile " + d + " is not a file" );
+ }
+
+ // delete - See if we can delete the file even though it's read-only
+
+ if( f.delete() ) {
+ System.out.println( "fail - delete " + f + " should not have been successfull because it is read-only" );
+ } else {
+ System.out.println( "okay - delete " + f + " failed because it is read-only" );
+ }
+
+ // Flip off both read-only and hidden
+
+ System.out.println( "Flipp off both read-only and hidden flags for " + f + " (hit return to continue)" );
+ System.in.read();
+
+ // length - Check to ensure that the length of the file is correct
+
+ if( f.length() == 363 ) {
+ System.out.println( "okay - length " + f + " is correct" );
+ } else {
+ System.out.println( "fail - length " + f + " is wrong: " + f.length() );
+ }
+
+ SmbFile r = new SmbFile( d.getParent(), "JcifsDeleteMe" );
+
+ // Must delete any left over directory from a previous run
+
+ if( r.delete() ) {
+ System.out.println( "okay - delete " + r + " successfull" );
+ } else {
+ System.out.println( "okay - delete " + r + " probably wasn't there" );
+ }
+
+ // renameTo - Rename the whole directory to JcifsDeleteMe
+
+ if( d.renameTo( r )) {
+ System.out.println( "okay - renameTo " + d + " successfull even though it is a directory" );
+ } else {
+ System.out.println( "fail - renameTo " + d + " failed" );
+ }
+
+ // delete - Now delete the whole workspace
+
+ if( r.delete() ) {
+ System.out.println( "okay - delete " + d + " successfull" );
+ } else {
+ System.out.println( "fail - delete " + d + " failed" );
+ }
+ }
+}
+
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import jcifs.smb.SmbFile;
+import jcifs.smb.SmbFileInputStream;
+import java.io.FileOutputStream;
+
+public class Get {
+
+ public static void main( String argv[] ) throws Exception {
+
+ SmbFile f = new SmbFile( argv[0] );
+ SmbFileInputStream in = new SmbFileInputStream( f );
+ FileOutputStream out = new FileOutputStream( f.getName() );
+
+ long t0 = System.currentTimeMillis();
+
+ byte[] b = new byte[65535];
+ int n, tot = 0;
+ long t1 = t0;
+ long t2;
+ while(( n = in.read( b )) > 0 ) {
+ out.write( b, 0, n );
+ tot += n;
+ System.out.print( '#' );
+ t2 = System.currentTimeMillis();
+ System.out.print( t2 - t1 + "" );
+ t1 = t2;
+ }
+
+ long t = System.currentTimeMillis() - t0;
+
+ System.out.println();
+ System.out.println( tot + " bytes transfered in " + ( t / 1000 ) + " seconds at " + (( tot / 1000 ) / Math.max( 1, ( t / 1000 ))) + "Kbytes/sec" );
+
+ in.close();
+ out.close();
+ }
+}
+
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import java.util.Date;
+import jcifs.smb.SmbFile;
+import java.text.SimpleDateFormat;
+import java.util.GregorianCalendar;
+
+public class GetDate {
+
+ public static void main( String argv[] ) throws Exception {
+ SmbFile f = new SmbFile( argv[0] );
+ Date d = new Date( f.lastModified() );
+ SimpleDateFormat sdf = new SimpleDateFormat( "EEEE, MMMM d, yyyy h:mm:ss a" );
+ sdf.setCalendar( new GregorianCalendar() );
+ System.out.println( sdf.format( d ));
+ }
+}
+
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import java.net.URL;
+import java.io.InputStream;
+
+public class GetURL {
+
+ public static void main( String argv[] ) throws Exception {
+
+ Class.forName( "jcifs.Config" );
+
+ URL url = new URL( argv[0] );
+ InputStream in = url.openStream();
+
+ if( in != null ) {
+ byte[] buf = new byte[4096];
+ int n;
+ while(( n = in.read( buf )) != -1 ) {
+ System.out.write( buf, 0, n );
+ }
+ } else {
+ System.out.println( "stream waz null" );
+ }
+ in.close();
+ }
+}
+
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import jcifs.smb.*;
+
+public class Interleave {
+
+ static class IThread extends Thread {
+ String url;
+
+ IThread( String url ) {
+ this.url = url;
+ }
+
+ public void run() {
+ try {
+ yield();
+ System.out.println( getName() + ": started" );
+ SmbFileOutputStream o = new SmbFileOutputStream( url );
+ o.close();
+ System.out.println( getName() + ": done" );
+ } catch( Exception x ) {
+ x.printStackTrace();
+ }
+ }
+ }
+
+ public static void main(String[] argv) throws Exception {
+ if( argv.length < 2 ) {
+ System.out.println( "java Interleave dir numThreads" );
+ return;
+ }
+
+ int numThreads = Integer.parseInt( argv[1] );
+ IThread[] t = new IThread[numThreads];
+ for( int i = 0; i < numThreads; i++ ) {
+ t[i] = new IThread( argv[0] + "/it" + i + ".tmp" );
+ }
+ for( int j = 0; j < numThreads; j++ ) {
+ t[j].start();
+ }
+ }
+}
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import jcifs.smb.SmbFile;
+import jcifs.util.Log;
+import java.util.Date;
+
+public class List {
+
+ public static void main( String[] argv ) throws Exception {
+
+ SmbFile file = new SmbFile( argv[0] );
+
+ long t1 = System.currentTimeMillis();
+ String[] files = file.list();
+ long t2 = System.currentTimeMillis() - t1;
+
+ if( files != null ) {
+ for( int i = 0; i < files.length; i++ ) {
+ System.out.print( " " + files[i] );
+ }
+ System.out.println();
+ System.out.println( files.length + " files in " + t2 + "ms" );
+ } else {
+ System.out.println( "no such file or directory" );
+ }
+ }
+}
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import jcifs.util.Log;
+
+public class LogTest {
+
+ public static void main( String[] argv ) {
+ Log.setMask(( Log.ALL | Log.EXCEPTIONS ) & ~Log.HEX_DUMPS );
+
+ Log.println( Log.WARNINGS, "LogTest warning", "you've been warned" );
+ Log.println( Log.DEBUGGING, "This is a debugging message", "MADE IT!" );
+ Log.printHexDump( "This will not be printed", "hello, world".getBytes() );
+ try {
+ int i = 10/0;
+ } catch( Exception x ) {
+ Log.printStackTrace( "LogTest exception", x );
+ }
+ }
+}
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import jcifs.util.Log;
+import jcifs.smb.SmbFile;
+
+public class Mkdir {
+
+ public static void main( String argv[] ) throws Exception {
+
+ SmbFile f = new SmbFile( argv[0] );
+ if( f.mkdir() ) {
+ System.out.println( f.getCanonicalPath() + " created" );
+ } else {
+ System.out.println( "mkdir failed: " + f.getCanonicalPath() );
+ }
+ }
+}
+
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import jcifs.smb.SmbNamedPipe;
+import java.io.OutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+
+public class PipeTalk {
+
+ static class ReceiverThread extends Thread {
+ InputStream in;
+ byte[] buf = new byte[20];
+ int n;
+
+ ReceiverThread( InputStream in ) {
+ this.in = in;
+ }
+ public void run() {
+ try {
+ while(( n = in.read( buf )) != -1 ) {
+ System.out.println( new String( buf, 0, n ));
+ }
+ } catch( IOException ioe ) {
+ ioe.printStackTrace();
+ }
+ }
+ }
+
+ public static void main( String argv[] ) throws Exception {
+
+ SmbNamedPipe pipe = new SmbNamedPipe( argv[0], SmbNamedPipe.PIPE_TYPE_RDWR );
+ InputStream in = pipe.getNamedPipeInputStream();
+ OutputStream out = pipe.getNamedPipeOutputStream();
+
+ ReceiverThread rt = new ReceiverThread( in );
+ rt.start();
+
+ StringBuffer sb = new StringBuffer();
+ String msg;
+ int c;
+ while(( c = System.in.read() ) != -1 ) {
+ if( c == '\n' ) {
+ msg = sb.toString();
+ if( msg.startsWith( "exi" )) {
+ break;
+ }
+ System.out.println( sb.toString() );
+ out.write( msg.getBytes() );
+ sb.setLength( 0 );
+ } else {
+ sb.append( (char)c );
+ }
+ }
+ in.close();
+ out.close();
+ }
+}
+
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import jcifs.smb.SmbFile;
+import jcifs.smb.SmbFileOutputStream;
+import java.io.FileInputStream;
+
+public class Put {
+
+ public static void main( String argv[] ) throws Exception {
+
+ SmbFile f = new SmbFile( argv[0] );
+ FileInputStream in = new FileInputStream( f.getName() );
+ SmbFileOutputStream out = new SmbFileOutputStream( f );
+
+ long t0 = System.currentTimeMillis();
+
+ byte[] b = new byte[65535];
+ int n, tot = 0;
+ while(( n = in.read( b )) > 0 ) {
+ out.write( b, 0, n );
+ tot += n;
+ System.out.print( '#' );
+ }
+
+ long t = System.currentTimeMillis() - t0;
+
+ System.out.println();
+ System.out.println( tot + " bytes transfered in " + ( t / 1000 ) + " seconds at " + (( tot / 1000 ) / Math.max( 1, ( t / 1000 ))) + "Kbytes/sec" );
+
+ in.close();
+ out.close();
+ }
+}
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import jcifs.netbios.NbtAddress;
+
+public class Query {
+
+ public static void main( String argv[] ) throws Exception {
+ System.out.println( NbtAddress.getByName( argv[0], 0x1b, "" ));
+ }
+}
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import jcifs.smb.SmbFile;
+
+public class RenameTo {
+
+ public static void main( String argv[] ) throws Exception {
+
+ SmbFile from = new SmbFile( argv[0] );
+ SmbFile to = new SmbFile( argv[1] );
+ if( from.renameTo( to )) {
+ System.out.println( from.getCanonicalPath() + " renamed to " + to.getCanonicalPath() );
+ } else {
+ System.out.println( "Failed to rename " + from.getCanonicalPath() + " to " + to.getCanonicalPath() );
+ }
+ }
+}
+
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import jcifs.smb.SmbFile;
+import jcifs.smb.SmbFileInputStream;
+import java.io.FileOutputStream;
+
+public class SlowRead {
+
+ public static void main( String argv[] ) throws Exception {
+
+ SmbFileInputStream in = new SmbFileInputStream( argv[0] );
+
+ byte[] b = new byte[10];
+ int n, tot = 0;
+ while(( n = in.read( b )) > 0 ) {
+ System.out.write( b, 0, n );
+ tot += n;
+ Thread.sleep( 17000 );
+ }
+
+ in.close();
+ }
+}
+
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import jcifs.smb.SmbFileOutputStream;
+
+public class SlowWrite {
+
+ public static void main( String argv[] ) throws Exception {
+
+ SmbFileOutputStream out = new SmbFileOutputStream( argv[0] );
+
+ for( int i = 0; i < 2; i++ ) {
+ out.write( (new String( "hello" + i )).getBytes() );
+ Thread.sleep( 17000 );
+ }
+
+ out.close();
+ }
+}
+
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import jcifs.smb.SmbFile;
+import java.util.LinkedList;
+import java.util.ListIterator;
+import java.net.MalformedURLException;
+import java.io.IOException;
+
+public class SmbCrawler {
+
+ int maxDepth;
+
+ SmbCrawler( int maxDepth ) {
+ this.maxDepth = maxDepth;
+ }
+
+ void traverse( SmbFile f, int depth ) throws MalformedURLException, IOException {
+
+ if( depth == 0 ) {
+ return;
+ }
+
+ String[] l = f.list();
+
+ for(int i = 0; l != null && i < l.length; i++ ) {
+ try {
+ SmbFile d = new SmbFile( f, l[i] );
+ for( int j = maxDepth - depth; j > 0; j-- ) {
+ System.out.print( " " );
+ }
+ System.out.println( l[i] );
+ if( d.isDirectory() ) {
+ traverse( d, depth - 1 );
+ }
+ } catch( IOException ioe ) {
+ System.out.println( l[i] + ": " + ioe.getMessage() );
+ }
+ }
+ }
+
+ public static void main(String[] argv) throws Exception {
+ int depth = Integer.parseInt( argv[1] );
+ SmbCrawler sc = new SmbCrawler( depth );
+ sc.traverse( new SmbFile( argv[0] ), depth );
+ }
+}
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import jcifs.smb.*;
+import java.net.UnknownHostException;
+import java.net.MalformedURLException;
+
+public class SmbShell {
+
+ public static String readLine() throws Exception {
+ int c;
+ StringBuffer sb = new StringBuffer();
+ while(( c = System.in.read() ) != '\n' ) {
+ sb.append( (char)c );
+ }
+ return sb.toString().trim();
+ }
+
+ public static void main( String[] argv ) throws Exception {
+ int c;
+ String cmd, prompt;
+ SmbFile conn, tmp;
+
+ conn = new SmbFile( "smb://" );
+ while( true ) {
+ try {
+ if( conn.exists() ) {
+ prompt = new SmbFile( conn.getCanonicalPath() ).getName() + "> ";
+ } else {
+ System.out.println( "error reading " + conn );
+ conn = new SmbFile( "smb://" );
+ continue;
+ }
+ System.out.print( prompt );
+
+ cmd = readLine();
+ if( cmd.equals( "" ) ) {
+ } else if( cmd.startsWith( "cd" )) {
+ int i = cmd.indexOf( ' ' );
+ String dir;
+ if( i == -1 || (dir = cmd.substring( i ).trim()).length() == 0 ) {
+ conn = new SmbFile( "smb://" );
+ continue;
+ }
+ tmp = new SmbFile( conn.getCanonicalPath(), dir );
+ if( tmp.exists() ) {
+ if( tmp.isDirectory() ) {
+ conn = tmp;
+ } else {
+ System.out.println( dir + " is not a directory" );
+ }
+ } else {
+ System.out.println( "no such directory" );
+ }
+ } else if( cmd.startsWith( "ls" )) {
+ int i = cmd.indexOf( ' ' );
+ SmbFile d = conn;
+ String dir;
+ if( i != -1 && (dir = cmd.substring( i ).trim()).length() != 0 ) {
+ d = new SmbFile( conn, dir );
+ }
+ String[] list = d.list();
+ if( list != null ) {
+ for( int j = 0; j < list.length; j++ ) {
+ System.out.print( " " + list[j] );
+ }
+ System.out.println();
+ System.out.println( list.length + " items" );
+ } else {
+ System.out.println( "no such file or directory" );
+ }
+ } else if( cmd.startsWith( "pwd" )) {
+ System.out.println( conn.getCanonicalPath() );
+ } else if( cmd.startsWith( "q" ) ||
+ cmd.startsWith( "x" ) ||
+ cmd.startsWith( "ex" ) ||
+ cmd.startsWith( "by" )) {
+ break;
+ } else {
+ System.out.println( "commands:" );
+ System.out.println( " ls [dir|file]" );
+ System.out.println( " cd dir" );
+ System.out.println( " pwd" );
+ System.out.println( " quit" );
+ }
+ } catch( UnknownHostException uhe ) {
+ uhe.printStackTrace();
+ } catch( MalformedURLException mue ) {
+ mue.printStackTrace();
+ conn = null;
+ }
+ }
+ System.exit( 0 );
+ }
+}
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import java.io.File;
+
+public class TestFile {
+
+ public static void main( String argv[] ) throws Exception {
+ File f = new File( argv[0] );
+ System.out.println( "toString()=" + f.toString());
+ System.out.println( "getCanonicalPath()=" + f.getCanonicalPath());
+ System.out.println( "getName()=" + f.getName());
+ System.out.println( "getParent()=" + f.getParent());
+ System.out.println( "getPath()=" + f.getPath());
+ System.out.println( "toURL().toString()=" + f.toURL().toString());
+ System.out.println( "equals( " + argv[1] + " )=" + f.equals( new File( argv[1] )));
+ }
+}
+
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import jcifs.smb.*;
+
+public class TestSmbFile {
+
+ public static void main( String argv[] ) throws Exception {
+ SmbFile f;
+ if( argv.length == 1 ) {
+ f = new SmbFile( argv[0] );
+ } else {
+ f = new SmbFile( argv[0], argv[1] );
+ }
+ System.out.println( "toString()=" + f.toString());
+ System.out.println( "getCanonicalPath()=" + f.getCanonicalPath());
+ System.out.println( "getName()=" + f.getName());
+ System.out.println( "getParent()=" + f.getParent());
+ System.out.println( "getPath()=" + f.getPath());
+ System.out.println( "getServer()=" + f.getServer());
+ System.out.println( "getShare()=" + f.getShare());
+ System.out.println( "isWorkgroup()=" + f.isWorkgroup());
+ System.out.println( "toURL().toString()=" + f.toURL().toString());
+ if( argv.length > 2 ) {
+ System.out.println( "equals( " + argv[1] + " )=" + f.equals( new SmbFile( argv[1] )));
+ }
+ }
+}
+
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import jcifs.smb.SmbFile;
+import jcifs.util.Log;
+import java.util.LinkedList;
+import java.util.ListIterator;
+import java.net.MalformedURLException;
+import java.io.IOException;
+
+public class ThreadedSmbCrawler {
+
+ class DirEntry {
+ SmbFile dir;
+ int depth;
+
+ DirEntry( SmbFile dir, int depth ) {
+ this.dir = dir;
+ this.depth = depth;
+ }
+ }
+
+ class SmbCrawlerThread extends Thread {
+
+ StringBuffer sb = new StringBuffer();
+
+ SmbCrawlerThread() {
+ }
+
+ public void run() {
+ while( true ) {
+ try {
+ DirEntry e;
+
+ synchronized( dirList ) {
+ while( dirList.isEmpty() ) {
+ dirList.wait( 500 );
+ }
+ e = (DirEntry)dirList.remove( 0 );
+ }
+
+ if( e.depth == 0 ) {
+ continue;
+ }
+
+ String[] l = e.dir.list();
+
+ int n = maxDepth - e.depth;
+
+ for(int i = 0; l != null && i < l.length; i++ ) {
+ try {
+ sb.setLength( 0 );
+ for( int k = 0; k < n; k++ ) {
+ sb.append( " " );
+ }
+ SmbFile d = new SmbFile( e.dir, l[i] );
+ System.out.println( sb.append( d ));
+ if( d.isDirectory() ) {
+ synchronized( dirList ) {
+ dirList.add( new DirEntry( d, e.depth - 1 ));
+ dirList.notify();
+ }
+ }
+ } catch( IOException ioe ) {
+ ioe.printStackTrace();
+ }
+ }
+ } catch( Exception x ) {
+ x.printStackTrace();
+ }
+ }
+ }
+ }
+
+ LinkedList dirList;
+ int maxDepth;
+
+ ThreadedSmbCrawler( String dir, int maxDepth, int numThreads ) throws Exception {
+ this.maxDepth = maxDepth;
+ dirList = new LinkedList();
+ dirList.add( new DirEntry( new SmbFile( dir ), maxDepth ));
+ for( int i = 0; i < numThreads; i++ ) {
+ (new SmbCrawlerThread()).start();
+ }
+ }
+
+ public static void main(String[] argv) throws Exception {
+ if( argv.length < 3 ) {
+ System.out.println( "usage: ThreadedSmbCrawler dir depth numThreads" );
+ return;
+ }
+ Log.setMask( Log.CRITICAL_EXCEPTIONS );
+ new ThreadedSmbCrawler( argv[0], Integer.parseInt( argv[1] ), Integer.parseInt( argv[2] ));
+ }
+}
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import java.util.*;
+import jcifs.smb.*;
+
+class TortureTest3 {
+
+ static final int NUM_OF_THREADS = 4;
+
+ java.util.List dirList;
+
+ TortureTest3() throws Exception {
+ dirList = Collections.synchronizedList( new LinkedList());
+ }
+
+ void execute() {
+ for( int i = 0; i < NUM_OF_THREADS; i++ ) {
+ Thread t = new Worker( this );
+ t.start();
+ }
+ }
+
+ class Worker extends Thread {
+ TortureTest3 con;
+ int count = 0;
+
+ Worker( TortureTest3 con ) {
+ this.con = con;
+ }
+
+ public void run() {
+ try {
+ SmbFile dir, file;
+ String[] list;
+ while( true ) {
+ synchronized( con.dirList ) {
+ while( con.dirList.isEmpty() ) {
+ con.dirList.wait( 100 );
+ System.out.println( "name=" + getName() + ",count=" + count );
+ }
+ dir = (SmbFile)con.dirList.remove( 0 );
+ }
+ list = dir.list();
+ for( int i = 0; i < list.length; i++ ) {
+ file = new SmbFile( dir, list[i] );
+ if( file.isDirectory() ) {
+ synchronized( con.dirList ) {
+ con.dirList.add( file );
+ con.dirList.notify();
+ }
+ System.out.println( "d " + file );
+ } else {
+ count++;
+ System.out.println( " " + file );
+ }
+ }
+ }
+ } catch( Exception e ) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public static void main( String argv[] ) throws Exception {
+ TortureTest3 con = new TortureTest3();
+ con.dirList.add( new SmbFile( argv[0] ));
+ con.execute();
+ }
+}
+
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import jcifs.smb.*;
+import jcifs.netbios.NbtAddress;
+import jcifs.util.*;
+import java.util.Enumeration;
+
+public class TortureTest4 extends Thread {
+
+ String url;
+ SmbFile file;
+
+ TortureTest4( String domain,
+ String username,
+ String password,
+ String server,
+ String share ) {
+
+ StringBuffer sb = new StringBuffer( "smb://" );
+
+ if( username != null ) {
+ if( domain != null ) {
+ sb.append( domain ).append( ';' );
+ }
+ sb.append( username );
+ if( password != null ) {
+ sb.append( ':' ).append( password );
+ }
+ sb.append( '@' );
+ }
+ sb.append( server + "/" + share + "/foo.txt" );
+
+ url = sb.toString();
+ }
+
+ public void run() {
+ try {
+System.out.println( "url=" + url );
+ file = new SmbFile( url );
+ file.exists();
+ } catch( Exception e ) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void main( String[] argv ) throws Exception {
+ Thread[] threads = new Thread[5];
+ String key;
+ Object val;
+ PropertiesTree shares = (PropertiesTree)jcifs.Config.get( argv[0] );
+ String server = shares.getProperty( "server" );
+ int i = 0;
+ for( Enumeration e = shares.keys(); e.hasMoreElements(); ) {
+ key = (String)e.nextElement();
+ val = shares.get( key );
+ if( val instanceof PropertiesTree ) {
+ threads[i++] = new TortureTest4( shares.getProperty( key + ".domain" ),
+ shares.getProperty( key + ".username" ),
+ shares.getProperty( key + ".password" ),
+ server,
+ key );
+ }
+ }
+ for( int t = 0; t < i; t++ ) {
+ threads[t].start();
+ }
+ for( int j = 0; j < i; j++ ) {
+ threads[j].join();
+ }
+ System.exit( 0 );
+ }
+}
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import jcifs.netbios.*;
+import java.util.Enumeration;
+
+public class TortureTest5 extends Thread {
+
+ String name;
+
+ TortureTest5( String name ) {
+ this.name = name;
+ }
+
+ public void run() {
+ try {
+ System.out.println( NbtAddress.getByName( name ));
+ } catch( Exception e ) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void main( String[] argv ) throws Exception {
+ // jcifs.util.Log.setMask( jcifs.util.Log.EXCEPTIONS | jcifs.util.Log.HEX_DUMPS );
+ // jcifs.util.Config.setProperty( "retryCount", "1" );
+ jcifs.util.Config.setProperty( "soTimeout", "1000" );
+
+ Thread[] threads = new Thread[30];
+ for( int i = 0; i < argv.length; i++ ) {
+ threads[i] = new TortureTest5( argv[i] );
+ }
+ for( int t = 0; t < argv.length; t++ ) {
+ threads[t].start();
+ }
+ for( int j = 0; j < argv.length; j++ ) {
+ threads[j].join();
+ }
+ System.exit( 0 );
+ }
+}
--- /dev/null
+/* examples for the jcifs smb client library in Java
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+import jcifs.smb.SmbNamedPipe;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+
+public class TransactNamedPipe {
+
+ public static void main( String[] argv ) throws Exception {
+
+ if( argv.length < 2 ) {
+ throw new IllegalArgumentException(
+ "args: <smburl> <filedatatosend> <filetowriterecvdata>" );
+ }
+
+ byte[] b = new byte[65535];
+ FileInputStream fin = new FileInputStream( argv[1] );
+ FileOutputStream fos = new FileOutputStream( argv[2] );
+
+ SmbNamedPipe pipe = new SmbNamedPipe( argv[0],
+ SmbNamedPipe.PIPE_TYPE_RDWR | SmbNamedPipe.PIPE_TYPE_TRANSACT );
+ OutputStream out = pipe.getNamedPipeOutputStream();
+ InputStream in = pipe.getNamedPipeInputStream();
+
+ int n = fin.read( b );
+ System.out.println( "writing " + n + " bytes" );
+ out.write( b, 0, n );
+ n = in.read(b);
+ System.out.println( "read " + n + " bytes" );
+ fos.write(b, 0, n );
+
+ fin.close();
+ fos.close();
+ out.close();
+ }
+}
--- /dev/null
+# example jcifs properties tree file
+;baddr=192.168.1.255
+;domain=foo
+username=me
+password=bar
+;wins=146.123.82.22
+;log=all
--- /dev/null
+/* examples for the jcifs smb client library in Java\r
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
+ */\r
+\r
+/* callnp.c - Call a Named Pipe\r
+ */\r
+\r
+#include <stdio.h>\r
+#include <Windows.h>\r
+#include <stdlib.h>\r
+\r
+int\r
+hexstrtoi(const char *str)\r
+{\r
+ int i;\r
+ for (i = 0; str[i] != '\0'; i++) {\r
+ if (str[i] != 'x' && (str[i] < 48 || str[i] > 57)) {\r
+ errno = 1;\r
+ return 0;\r
+ }\r
+ }\r
+ return (int)strtol(str, NULL, 16);\r
+}\r
+\r
+int\r
+main(int argc, char *argv[])\r
+{\r
+ int i;\r
+ int bufferSize, timeout, bytesRead;\r
+ char *target, *send_buf, *recv_buf;\r
+ HANDLE inFile, outFile;\r
+\r
+ inFile = NULL;\r
+ outFile = NULL;\r
+ bufferSize = 65535;\r
+ bytesRead = 0;\r
+\r
+ if (argc == 1 || argv[1][1] == '\?') {\r
+ printf("defaults\r\n");\r
+ printf(" inFile = <none>\r\n");\r
+ printf(" outFile = <none>\r\n");\r
+ printf(" bufferSize = 65535\r\n");\r
+\r
+ printf("\r\ncallnp \\\\server\\pipe\\name /I inFile /O outFile /B bufferSize\r\n");\r
+\r
+ return 0;\r
+ }\r
+\r
+ if(argv[1][0] != '\\' && argv[1][1] != '\\') {\r
+ printf("Error: must specify target\r\n");\r
+ }\r
+ target = argv[1];\r
+ for(i = 2; i < argc; i++) {\r
+ if(argv[i][0] != '/') {\r
+ printf("Error: invalid switch\r\n");\r
+ }\r
+ errno = 0;\r
+ switch(argv[i++][1]) {\r
+ case 'I':\r
+ inFile = CreateFile(argv[i], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); \r
+ if(outFile == INVALID_HANDLE_VALUE) {\r
+ printf("Error: cannot open inFile: %s\r\n", argv[i]);\r
+ return 0;\r
+ }\r
+ break;\r
+ case 'O':\r
+ outFile = CreateFile(argv[i], GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); \r
+ if(outFile == INVALID_HANDLE_VALUE) {\r
+ printf("Error: cannot open outFile: %s\r\n", argv[i]);\r
+ return 0;\r
+ }\r
+ break;\r
+ case 'B':\r
+ bufferSize = atoi(argv[i]);\r
+ break;\r
+ default:\r
+ printf("Error: no such option\r\n");\r
+ return 0;\r
+ }\r
+ if(errno) {\r
+ printf("Error: values must be in hex.\r\n");\r
+ return 0;\r
+ }\r
+ }\r
+ send_buf = malloc(bufferSize);\r
+ recv_buf = malloc(bufferSize);\r
+ if(send_buf == NULL || recv_buf == NULL) {\r
+ printf("Error: failed to allocate buffers\r\n");\r
+ return 0;\r
+ }\r
+ if(inFile != NULL && ReadFile(inFile, send_buf, bufferSize, &bytesRead, NULL) == 0) {\r
+ printf("Error: failed to read from inFile\r\n");\r
+ return 0;\r
+ }\r
+ if (WaitNamedPipe(target, NMPWAIT_WAIT_FOREVER) == 0) {\r
+ printf("Error: WaitNamedPipe operation failed: %u\r\n", GetLastError());\r
+ return 0;\r
+ }\r
+ if (CallNamedPipe(target, send_buf, bytesRead, recv_buf, bufferSize, &bytesRead, NMPWAIT_WAIT_FOREVER) == 0) {\r
+ printf("Error: CallNamedPipe operation failed: %u\r\n", GetLastError());\r
+ return 0;\r
+ }\r
+ if(outFile != NULL && WriteFile(outFile, recv_buf, bytesRead, &bytesRead, NULL) == 0) {\r
+ printf("Error: failed to write to outFile\r\n");\r
+ }\r
+ printf("Success: operation performed successfully\r\n");\r
+ return 1;\r
+}\r
+\r
--- /dev/null
+/* examples for the jcifs smb client library in Java\r
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
+ */\r
+\r
+/* createf.c - Create a file with the CreateFile call.\r
+ */\r
+\r
+\r
+#include <stdio.h>\r
+#include <Windows.h>\r
+#include <stdlib.h>\r
+\r
+#define hexstrtoui(s) ((int)strtoul((s), NULL, 16))\r
+\r
+int\r
+main(int argc, char *argv[])\r
+{\r
+ int i;\r
+ int desiredAccess, shareMode, disposition, flags, bufferSize, bytesRead;\r
+ char *target, *buf;\r
+ HANDLE h, inFile, outFile;\r
+\r
+ inFile = NULL;\r
+ outFile = NULL;\r
+ desiredAccess = GENERIC_READ;\r
+ shareMode = 0;\r
+ disposition = CREATE_ALWAYS;\r
+ flags = FILE_ATTRIBUTE_NORMAL;\r
+ bufferSize = 65535;\r
+\r
+ if (argc == 1 || argv[1][1] == '\?') {\r
+\r
+ /* dwDesiredAccess\r
+ */\r
+ printf("dwDesiredAccess\r\n");\r
+ printf(" 0x%08x GENERIC_READ\r\n", GENERIC_READ);\r
+ printf(" 0x%08x GENERIC_WRITE\r\n", GENERIC_WRITE);\r
+ printf(" 0x%08x DELETE\r\n", DELETE);\r
+ printf(" 0x%08x READ_CONTROL\r\n", READ_CONTROL);\r
+ printf(" 0x%08x WRITE_DAC\r\n", WRITE_DAC);\r
+ printf(" 0x%08x WRITE_OWNER\r\n", WRITE_OWNER);\r
+ printf(" 0x%08x SYNCHRONIZE\r\n", SYNCHRONIZE);\r
+ printf(" 0x%08x STANDARD_RIGHTS_REQUIRED\r\n", STANDARD_RIGHTS_REQUIRED);\r
+ printf(" 0x%08x STANDARD_RIGHTS_READ\r\n", STANDARD_RIGHTS_READ);\r
+ printf(" 0x%08x STANDARD_RIGHTS_WRITE\r\n", STANDARD_RIGHTS_WRITE);\r
+ printf(" 0x%08x STANDARD_RIGHTS_EXECUTE\r\n", STANDARD_RIGHTS_EXECUTE);\r
+ printf(" 0x%08x STANDARD_RIGHTS_ALL\r\n", STANDARD_RIGHTS_ALL);\r
+ printf(" 0x%08x SPECIFIC_RIGHTS_ALL\r\n", SPECIFIC_RIGHTS_ALL);\r
+ printf(" 0x%08x ACCESS_SYSTEM_SECURITY\r\n", ACCESS_SYSTEM_SECURITY);\r
+ printf(" 0x%08x MAXIMUM_ALLOWED\r\n", MAXIMUM_ALLOWED);\r
+ printf(" 0x%08x GENERIC_EXECUTE\r\n", GENERIC_EXECUTE);\r
+ printf(" 0x%08x GENERIC_ALL\r\n", GENERIC_ALL);\r
+ /* dwShareMode\r
+ */\r
+ printf("dwShareMode\n");\r
+ printf(" 0x%08x FILE_SHARE_DELETE\r\n", FILE_SHARE_DELETE);\r
+ printf(" 0x%08x FILE_SHARE_READ\r\n", FILE_SHARE_READ);\r
+ printf(" 0x%08x FILE_SHARE_WRITE\r\n", FILE_SHARE_WRITE);\r
+ printf(" 0x%08x the file cannot be shared\r\n", 0);\r
+ /* dwCreateDisposition\r
+ */\r
+ printf("dwCreateDisposition\r\n");\r
+ printf(" 0x%08x CREATE_NEW\r\n", CREATE_NEW);\r
+ printf(" 0x%08x CREATE_ALWAYS\r\n", CREATE_ALWAYS);\r
+ printf(" 0x%08x OPEN_EXISTING\r\n", OPEN_EXISTING);\r
+ printf(" 0x%08x OPEN_ALWAYS\r\n", OPEN_ALWAYS);\r
+ printf(" 0x%08x TRUNCATE_EXISTING\r\n", TRUNCATE_EXISTING);\r
+ /* dwFlagsAndAttributes\r
+ */\r
+ printf("dwFlagsAndAttributes\r\n");\r
+ printf(" 0x%08x FILE_ATTRIBUTE_ARCHIVE\r\n", FILE_ATTRIBUTE_ARCHIVE);\r
+ printf(" 0x%08x FILE_ATTRIBUTE_ENCRYPTED\r\n", FILE_ATTRIBUTE_ENCRYPTED);\r
+ printf(" 0x%08x FILE_ATTRIBUTE_HIDDEN\r\n", FILE_ATTRIBUTE_HIDDEN);\r
+ printf(" 0x%08x FILE_ATTRIBUTE_NORMAL\r\n", FILE_ATTRIBUTE_NORMAL);\r
+ printf(" 0x%08x FILE_ATTRIBUTE_NOT_CONTENT_INDEXED\r\n", FILE_ATTRIBUTE_NOT_CONTENT_INDEXED);\r
+ printf(" 0x%08x FILE_ATTRIBUTE_OFFLINE\r\n", FILE_ATTRIBUTE_OFFLINE);\r
+ printf(" 0x%08x FILE_ATTRIBUTE_READONLY\r\n", FILE_ATTRIBUTE_READONLY);\r
+ printf(" 0x%08x FILE_ATTRIBUTE_SYSTEM\r\n", FILE_ATTRIBUTE_SYSTEM);\r
+ printf(" 0x%08x FILE_ATTRIBUTE_TEMPORARY\r\n", FILE_ATTRIBUTE_TEMPORARY);\r
+ \r
+ printf(" 0x%08x FILE_FLAG_WRITE_THROUGH\r\n", FILE_FLAG_WRITE_THROUGH);\r
+ printf(" 0x%08x FILE_FLAG_OVERLAPPED\r\n", FILE_FLAG_OVERLAPPED);\r
+ printf(" 0x%08x FILE_FLAG_NO_BUFFERING\r\n", FILE_FLAG_NO_BUFFERING);\r
+ printf(" 0x%08x FILE_FLAG_RANDOM_ACCESS\r\n", FILE_FLAG_RANDOM_ACCESS);\r
+ printf(" 0x%08x FILE_FLAG_SEQUENTIAL_SCAN\r\n", FILE_FLAG_SEQUENTIAL_SCAN);\r
+ printf(" 0x%08x FILE_FLAG_DELETE_ON_CLOSE\r\n", FILE_FLAG_DELETE_ON_CLOSE);\r
+ printf(" 0x%08x FILE_FLAG_BACKUP_SEMANTICS\r\n", FILE_FLAG_BACKUP_SEMANTICS);\r
+ printf(" 0x%08x FILE_FLAG_POSIX_SEMANTICS\r\n", FILE_FLAG_POSIX_SEMANTICS);\r
+ \r
+ printf(" 0x%08x FILE_FLAG_OPEN_REPARSE_POINT\r\n", FILE_FLAG_OPEN_REPARSE_POINT);\r
+ printf(" 0x%08x FILE_FLAG_OPEN_NO_RECALL\r\n", FILE_FLAG_OPEN_NO_RECALL);\r
+ printf(" 0x%08x SECURITY_ANONYMOUS\r\n", SECURITY_ANONYMOUS);\r
+ printf(" 0x%08x SECURITY_IDENTIFICATION\r\n", SECURITY_IDENTIFICATION);\r
+ printf(" 0x%08x SECURITY_IMPERSONATION\r\n", SECURITY_IMPERSONATION);\r
+ printf(" 0x%08x SECURITY_DELEGATION\r\n", SECURITY_DELEGATION);\r
+ printf(" 0x%08x SECURITY_CONTEXT_TRACKING\r\n", SECURITY_CONTEXT_TRACKING);\r
+ printf(" 0x%08x SECURITY_EFFECTIVE_ONLY\r\n", SECURITY_EFFECTIVE_ONLY);\r
+\r
+ printf("defaults\r\n");\r
+ printf(" dwDesiredAccess = GENERIC_READ\r\n");\r
+ printf(" dwShareMode = FILE_SHARE_READ\r\n");\r
+ printf(" dwCreateDisposition = CREATE_ALWAYS\r\n");\r
+ printf(" dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL\r\n");\r
+ printf(" inFile = none\r\n");\r
+ printf(" outFile = none\r\n");\r
+ printf(" bufferSize = 65535\r\n");\r
+\r
+ printf("\r\ncreatef \\\\server\\share\\path /A access /S share /D disposition /F flags /I inFile /O outFile /B bufferSize\r\n");\r
+\r
+ return 0;\r
+ }\r
+\r
+ if(argv[1][0] != '\\' && argv[1][1] != '\\') {\r
+ printf("Error: must specify target\r\n");\r
+ }\r
+ target = argv[1];\r
+ for(i = 2; i < argc; i++) {\r
+ if(argv[i][0] != '/') {\r
+ printf("Error: invalid switch\r\n");\r
+ }\r
+ errno = 0;\r
+ switch(argv[i++][1]) {\r
+ case 'A':\r
+ desiredAccess = hexstrtoui(&argv[i][2]);\r
+ break;\r
+ case 'S':\r
+ shareMode = hexstrtoui(argv[i]);\r
+ break;\r
+ case 'D':\r
+ disposition = hexstrtoui(argv[i]);\r
+ break;\r
+ case 'F':\r
+ flags = hexstrtoui(argv[i]);\r
+ break;\r
+ case 'I':\r
+ inFile = CreateFile(argv[i], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); \r
+ if(inFile == INVALID_HANDLE_VALUE) {\r
+ printf("Error: cannot open inFile: %s\r\n", argv[i]);\r
+ CloseHandle(outFile);\r
+ return 0;\r
+ }\r
+ break;\r
+ case 'O':\r
+ outFile = CreateFile(argv[i], GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); \r
+ if(outFile == INVALID_HANDLE_VALUE) {\r
+ printf("Error: cannot open outFile: %s\r\n", argv[i]);\r
+ CloseHandle(inFile);\r
+ return 0;\r
+ }\r
+ break;\r
+ default:\r
+ printf("Error: no such option\r\n");\r
+ return 0;\r
+ }\r
+ if(errno) {\r
+ printf("Error: %s\r\n", strerror(errno));\r
+ return 0;\r
+ }\r
+ }\r
+\r
+ buf = malloc(bufferSize);\r
+ if(buf == NULL) {\r
+ printf("Error: failed to allocate buffer\r\n");\r
+ CloseHandle(inFile);\r
+ CloseHandle(outFile);\r
+ return 0;\r
+ }\r
+ h = CreateFile(target, desiredAccess, shareMode, NULL, disposition, flags, NULL);\r
+ if (h == INVALID_HANDLE_VALUE) {\r
+ printf("Error: CreateFile operation failed: %u\r\n", GetLastError());\r
+ CloseHandle(inFile);\r
+ CloseHandle(outFile);\r
+ return 0;\r
+ }\r
+ if(inFile != NULL || outFile != NULL) {\r
+ /* need to do reading or writing of some sort on the pipe */\r
+\r
+ if(inFile == NULL) {\r
+ inFile = h;\r
+ }\r
+ if(outFile == NULL) {\r
+ outFile = h;\r
+ }\r
+ while(ReadFile(inFile, buf, bufferSize, &bytesRead, NULL) > 0) {\r
+ WriteFile(outFile, buf, bytesRead, &bytesRead, NULL);\r
+ }\r
+ }\r
+ printf("Success: operation performed successfully\r\n");\r
+ CloseHandle(inFile);\r
+ CloseHandle(outFile);\r
+ CloseHandle(h);\r
+ return 1;\r
+}\r
+\r
--- /dev/null
+/* examples for the jcifs smb client library in Java\r
+ * Copyright (C) 2001 "Michael B. Allen" <mballen@erols.com>\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ * \r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
+ */\r
+\r
+/* createnp.c - Create a named pipe with CreateNamedPipe.\r
+ */\r
+\r
+#include <stdio.h>\r
+#include <Windows.h>\r
+#include <stdlib.h>\r
+\r
+#define hexstrtoui(s) ((int)strtoul((s), NULL, 16))\r
+\r
+int\r
+main(int argc, char *argv[])\r
+{\r
+ int i;\r
+ int openMode, pipeMode, bufferSize, defaultTimeout, bytesRead;\r
+ char *target, *buf;\r
+ HANDLE h, inFile, outFile;\r
+\r
+ inFile = NULL;\r
+ outFile = NULL;\r
+ openMode = PIPE_ACCESS_DUPLEX;\r
+ pipeMode = PIPE_TYPE_BYTE | PIPE_WAIT;\r
+ bufferSize = 65535;\r
+\r
+ if (argc == 1 || argv[1][1] == '\?') {\r
+\r
+ /* dwOpenMode\r
+ */\r
+ printf("dwOpenMode\r\n");\r
+ printf(" 0x%08x PIPE_ACCESS_DUPLEX\r\n", PIPE_ACCESS_DUPLEX);\r
+ printf(" 0x%08x PIPE_ACCESS_INBOUND\r\n", PIPE_ACCESS_INBOUND);\r
+ printf(" 0x%08x PIPE_ACCESS_OUTBOUND\r\n", PIPE_ACCESS_OUTBOUND);\r
+ printf(" 0x%08x FILE_FLAG_WRITE_THROUGH\r\n", FILE_FLAG_WRITE_THROUGH);\r
+ printf(" 0x%08x FILE_FLAG_OVERLAPPED\r\n", FILE_FLAG_OVERLAPPED);\r
+ printf(" 0x%08x WRITE_DAC\r\n", WRITE_DAC);\r
+ printf(" 0x%08x WRITE_OWNER\r\n", WRITE_OWNER);\r
+ printf(" 0x%08x ACCESS_SYSTEM_SECURITY\r\n", ACCESS_SYSTEM_SECURITY);\r
+ /* dwPipeMode\r
+ */\r
+ printf("dwPipeMode\r\n");\r
+ printf(" 0x%08x PIPE_TYPE_BYTE\r\n", PIPE_TYPE_BYTE);\r
+ printf(" 0x%08x PIPE_TYPE_MESSAGE\r\n", PIPE_TYPE_MESSAGE);\r
+ printf(" 0x%08x PIPE_READMODE_BYTE\r\n", PIPE_READMODE_BYTE);\r
+ printf(" 0x%08x PIPE_READMODE_MESSAGE\r\n", PIPE_READMODE_MESSAGE);\r
+ printf(" 0x%08x PIPE_WAIT\r\n", PIPE_WAIT);\r
+ printf(" 0x%08x PIPE_NOWAIT\r\n", PIPE_NOWAIT);\r
+\r
+ printf("defaults\r\n");\r
+ printf(" inFile = <read from pipe input>\r\n");\r
+ printf(" outFile = <write to pipe output>\r\n");\r
+ printf(" dwOpenMode = PIPE_ACCESS_DUPLEX\r\n");\r
+ printf(" dwPipeMode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT\r\n");\r
+ printf(" bufferSize = 65535\r\n");\r
+\r
+ printf("\r\ncreatenp \\\\.\\pipe\\name /I inFile /O outFile /M mode /P pmode /B bufferSize\r\n");\r
+\r
+ return 0;\r
+ }\r
+\r
+ if(argv[1][0] != '\\' && argv[1][1] != '\\') {\r
+ printf("Error: must specify target\r\n");\r
+ }\r
+ target = argv[1];\r
+ for(i = 2; i < argc; i++) {\r
+ if(argv[i][0] != '/') {\r
+ printf("Error: invalid switch\r\n");\r
+ }\r
+ errno = 0;\r
+ switch(argv[i++][1]) {\r
+ case 'I':\r
+ inFile = CreateFile(argv[i], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); \r
+ if(inFile == INVALID_HANDLE_VALUE) {\r
+ printf("Error: cannot open inFile: %s\r\n", argv[i]);\r
+ CloseHandle(outFile);\r
+ return 0;\r
+ }\r
+ break;\r
+ case 'O':\r
+ outFile = CreateFile(argv[i], GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); \r
+ if(outFile == INVALID_HANDLE_VALUE) {\r
+ printf("Error: cannot open outFile: %s\r\n", argv[i]);\r
+ CloseHandle(inFile);\r
+ return 0;\r
+ }\r
+ break;\r
+ case 'M':\r
+ openMode = hexstrtoui(argv[i]);\r
+ break;\r
+ case 'P':\r
+ pipeMode = hexstrtoui(argv[i]);\r
+ break;\r
+ case 'B':\r
+ bufferSize = atoi(argv[i]);\r
+ break;\r
+ default:\r
+ printf("Error: no such option\r\n");\r
+ CloseHandle(inFile);\r
+ CloseHandle(outFile);\r
+ return 0;\r
+ }\r
+ if(errno) {\r
+ printf("Error: values must be in hex.\r\n");\r
+ CloseHandle(inFile);\r
+ CloseHandle(outFile);\r
+ return 0;\r
+ }\r
+ }\r
+ h = CreateNamedPipe(target, openMode, pipeMode, 1, bufferSize, bufferSize, NMPWAIT_WAIT_FOREVER, NULL);\r
+ if (h == INVALID_HANDLE_VALUE) {\r
+ printf("Error: CreateNamedPipe operation failed: %u\r\n", GetLastError());\r
+ CloseHandle(inFile);\r
+ CloseHandle(outFile);\r
+ return 0;\r
+ }\r
+ if(ConnectNamedPipe(h, NULL) == 0 && GetLastError() != ERROR_PIPE_CONNECTED) {\r
+ printf("Error: ConnectNamedPipe operation failed: %u\r\n", GetLastError());\r
+ CloseHandle(inFile);\r
+ CloseHandle(outFile);\r
+ CloseHandle(h);\r
+ return 0;\r
+ }\r
+ buf = malloc(bufferSize);\r
+ if(buf == NULL) {\r
+ printf("Error: failed to allocate buffer\r\n");\r
+ CloseHandle(inFile);\r
+ CloseHandle(outFile);\r
+ DisconnectNamedPipe(h);\r
+ CloseHandle(h);\r
+ return 0;\r
+ }\r
+ if(inFile == NULL) {\r
+ inFile = h;\r
+ }\r
+ if(outFile == NULL) {\r
+ outFile = h;\r
+ }\r
+ while(ReadFile(inFile, buf, bufferSize, &bytesRead, NULL) > 0) {\r
+ WriteFile(outFile, buf, bytesRead, &bytesRead, NULL);\r
+ }\r
+ printf("Success: operation performed successfully\r\n");\r
+ CloseHandle(inFile);\r
+ CloseHandle(outFile);\r
+ DisconnectNamedPipe(h);\r
+ CloseHandle(h);\r
+ return 1;\r
+}\r
+\r
--- /dev/null
+# config for TortureTest4
+
+;baddr=192.168.1.255
+wins=146.123.82.22
+;log=all
+
+<strauss>
+ server = strauss
+ username = goober
+ password = mypass
+ <download>
+ place = holder
+ </download>
+ <etc>
+ place = holder
+ </etc>
+ <temp>
+ username = someone
+ password = hello
+ </temp>
+</strauss>
+<hendrix>
+ server = hendrix
+ username = mike
+ password = x%43hhj
+ <temp>
+ place = holder
+ </temp>
+ <etc>
+ place = holder
+ </etc>
+ <My Documents>
+ place = holder
+ </My Documents>
+</hendrix>
+<fruit>
+ server = fruit
+ username = guest
+ password =
+ <orange>
+ place = holder
+ </orange>
+ <apple>
+ username = whooly
+ password = cranapple
+ </apple>
+ <grape>
+ username = gardner
+ password = hoe
+ </grape>
+</fruit>
--- /dev/null
+
+import jcifs.smb.*;
+
+public class zzz implements Runnable
+{
+ public zzz()
+ {
+ }
+ public void run() {
+ try {
+ SmbFile f = new SmbFile("smb://username:password@server/share/file.txt");
+ SmbFileInputStream fin = new SmbFileInputStream(f);
+ fin.close();
+ }
+ catch(Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ static public void main(String args[]) {
+ jcifs.util.Config.setProperty( "wins", "146.123.82.22" );
+// jcifs.util.Config.setProperty( "maxMpxCount", "1" );
+ int i,j;
+ int iterations = 1;
+ int numthreads = 100;
+ for(i=0; i<iterations; ++i)
+ {
+ System.out.println("Iteration " + i);
+ Thread threads[] = new Thread[numthreads];
+ for(j=0; j<numthreads; ++j) {
+ threads[j] = new Thread(new zzz());
+ threads[j].start();
+ }
+ try {
+ for(j=0; j<numthreads; ++j) {
+ threads[j].join();
+ }
+ } catch(InterruptedException e) {
+e.printStackTrace();
+ }
+ }
+ System.out.println("Closing");
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs;
+
+import jcifs.util.Log;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.InetAddress;
+
+/**
+ * This class extends the {@link jcifs.util.Config} class to simply add
+ * additional configuration information specific to the jcifs smb library.
+ * <p>
+ * See also <a href="../../overview-summary.html#scp">Setting JCIFS Properties</a>
+ */
+
+public class Config {
+
+ static {
+ Properties sys;
+ String mask;
+ String filename;
+ FileInputStream in = null;
+
+ sys = System.getProperties();
+ synchronized( sys ) {
+ String pkgs = sys.getProperty( "java.protocol.handler.pkgs" );
+ if( pkgs == null ) {
+ pkgs = "jcifs";
+ } else {
+ pkgs += "|jcifs";
+ }
+ sys.put( "java.protocol.handler.pkgs", pkgs );
+ }
+
+ try {
+ filename = sys.getProperty( "jcifs.properties" );
+ if( filename != null && filename.length() > 1 ) {
+ in = new FileInputStream( filename );
+ }
+ jcifs.util.Config.load( in );
+ } catch( IOException ioe ) {
+ ioe.printStackTrace();
+ }
+
+ if(( mask = jcifs.util.Config.getProperty( "jcifs.util.log" )) != null ) {
+
+ StringTokenizer st = new StringTokenizer( mask, "," );
+ while( st.hasMoreTokens() ) {
+ String s = st.nextToken().toUpperCase();
+ if( s.startsWith( "ALL" )) {
+ Log.addMask( Log.ALL );
+ } else if( s.startsWith( "EXC" )) {
+ Log.addMask( Log.EXCEPTIONS );
+ } else if( s.startsWith( "WAR" )) {
+ Log.addMask( Log.WARNINGS );
+ } else if( s.startsWith( "DEB" )) {
+ Log.addMask( Log.DEBUGGING );
+ } else if( s.startsWith( "HEX" )) {
+ Log.addMask( Log.HEX_DUMPS );
+ } else if( s.startsWith( "NON" )) {
+ Log.setMask( Log.NONE );
+ break;
+ }
+ }
+ }
+ jcifs.util.Config.printProperties( "properties loaded" );
+ }
+
+ public static void load( InputStream in ) throws IOException {
+ jcifs.util.Config.load( in );
+ }
+ public static void list( PrintStream out ) throws IOException {
+ jcifs.util.Config.list( out );
+ }
+ public static String setProperty( String key, String value ) {
+ return jcifs.util.Config.setProperty( key, value );
+ }
+ public static Object get( String key ) {
+ return jcifs.util.Config.get( key );
+ }
+ public static String getProperty( String key, String def ) {
+ return jcifs.util.Config.getProperty( key, def );
+ }
+ public static String getProperty( String key ) {
+ return jcifs.util.Config.getProperty( key );
+ }
+ public static int getInt( String key, int def ) {
+ return jcifs.util.Config.getInt( key, def );
+ }
+ public static int getInt( String key ) {
+ return jcifs.util.Config.getInt( key );
+ }
+ public static InetAddress getInetAddress( String key, InetAddress def ) {
+ return jcifs.util.Config.getInetAddress( key, def );
+ }
+ public static boolean getBoolean( String key, boolean def ) {
+ return jcifs.util.Config.getBoolean( key, def );
+ }
+}
+
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.netbios;
+
+import jcifs.Config;
+import jcifs.smb.SmbFileInputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.util.Hashtable;
+import java.net.UnknownHostException;
+
+class Lmhosts {
+
+ static String filename = Config.getProperty( "jcifs.netbios.lmhosts" );
+ static Hashtable tab = new Hashtable();
+ static long lastModified = 1L;
+ static int alt;
+
+ synchronized static NbtAddress getByName( Name name ) {
+ NbtAddress result = null;
+
+ try {
+ if( filename != null ) {
+ File f = new File( filename );
+ long lm;
+
+ if(( lm = f.lastModified() ) > lastModified ) {
+ lastModified = lm;
+ tab.clear();
+ alt = 0;
+ populate( new FileReader( f ));
+ }
+ result = (NbtAddress)tab.get( name );
+ }
+ } catch( FileNotFoundException fnfe ) {
+ Log.println( Log.WARNINGS, "netbios name service exception",
+ "lmhosts file not found: " + filename );
+ } catch( IOException ioe ) {
+ Log.printStackTrace( "netbios name service exception", ioe );
+ }
+ return result;
+ }
+
+ static void populate( Reader r ) throws IOException {
+ String line;
+ BufferedReader br = new BufferedReader( r );
+
+ while(( line = br.readLine() ) != null ) {
+ line = line.toUpperCase().trim();
+ if( line.length() == 0 ) {
+ continue;
+ } else if( line.charAt( 0 ) == '#' ) {
+ if( line.startsWith( "#INCLUDE " )) {
+ line = line.substring( line.indexOf( '\\' ));
+ String url = "smb:" + line.replace( '\\', '/' );
+
+ if( alt > 0 ) {
+ try {
+ populate( new InputStreamReader( new SmbFileInputStream( url )));
+ } catch( IOException ioe ) {
+ Log.println( Log.WARNINGS, "netbios name service warning",
+ "failed to load lmhosts alternate include: " + url );
+ continue;
+ }
+
+ /* An include was loaded successfully. We can skip
+ * all other includes up to the #END_ALTERNATE tag.
+ */
+
+ alt--;
+ while(( line = br.readLine() ) != null ) {
+ line = line.toUpperCase().trim();
+ if( line.startsWith( "#END_ALTERNATE" )) {
+ break;
+ }
+ }
+ } else {
+ populate( new InputStreamReader( new SmbFileInputStream( url )));
+ }
+ } else if( line.startsWith( "#BEGIN_ALTERNATE" )) {
+ alt++;
+ } else if( line.startsWith( "#END_ALTERNATE" ) && alt > 0 ) {
+ alt--;
+ throw new IOException( "no lmhosts alternate includes loaded" );
+ }
+ } else if( Character.isDigit( line.charAt( 0 ))) {
+ char[] data = line.toCharArray();
+ int ip, i, j;
+ Name name;
+ NbtAddress addr;
+ char c;
+
+ c = '.';
+ ip = i = 0;
+ for( ; i < data.length && c == '.'; i++ ) {
+ int b = 0x00;
+
+ for( ; i < data.length && ( c = data[i] ) >= 48 && c <= 57; i++ ) {
+ b = b * 10 + c - '0';
+ }
+ ip = ( ip << 8 ) + b;
+ }
+ while( i < data.length && Character.isWhitespace( data[i] )) {
+ i++;
+ }
+ j = i;
+ while( j < data.length && Character.isWhitespace( data[j] ) == false ) {
+ j++;
+ }
+
+ name = new Name( line.substring( i, j ), 0x20, null );
+ addr = new NbtAddress( name, ip, false, NbtAddress.B_NODE );
+ tab.put( name, addr );
+ }
+ }
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.netbios;
+
+import java.util.Hashtable;
+import java.util.Enumeration;
+
+/**
+ * Provides logging methods specific to the netbios package. Log class
+ * members are applied to the Log's mask(set as an arithmetic expression
+ * from {@link jcifs.util.Log#setMask(int mask)}) to "flip on" logging of
+ * netbios specific information.
+ * <p><blockquote><pre>
+ * Log.setMask( Log.EXCEPTIONS +
+ * jcifs.netbios.Log.SESSION_SERVICE_PACKET_DATA );
+ * </pre></blockquote>
+ * <p>
+ * See the {@link jcifs.util.Log} parent class for details about this
+ * logging style.
+ *
+ * @version 0.1, 00/03/13
+ * @author Michael B. Allen
+ * @see jcifs.util.Log
+ * @since jcifs-0.1
+ */
+
+public class Log extends jcifs.util.Log {
+
+ // supress javadoc constructor summary
+ Log() {}
+
+ public static final int NONE = 0xFFFFFF0F;
+ public static final int ALL = 0x000000F0;
+
+/**
+ *
+ * This mask produces limited netbios name service packet information. See
+ * <a href="http://www.cis.ohio-state.edu/rfc/rfc1002.txt">RFC 1002</a>
+ * for a detailed description of packet contents and their meaning.
+ * <p><blockquote><pre>
+ * Mar 13 09:17:04 - name service packet
+ * angus.mimosa.com/192.168.1.152:137 [62]
+ * 28887 Positive Name Query Response
+ * authoritative answer,unicast,recursion desired,recursion available
+ * </pre></blockquote>
+ *
+ * @see jcifs.util.Log#setMask(int mask)
+ */
+
+ public static final int NAME_SERVICE_PACKET_DATA = 0x00000010;
+
+ public static final int SESSION_SERVICE_PACKET_DATA = 0x00000020;
+
+/**
+ * This mask produces the contents of the netbios address cache.
+ *
+ * @see jcifs.util.Log#setMask(int mask)
+ */
+
+ public static final int ADDRESS_CACHE = 0x00000040;
+
+/**
+ * reserved for this package
+ */
+ public static final int RESERVED8 = 0x00000080;
+
+ static void printPacketData( String desc, SessionServicePacket ssp ) {
+ try {
+ if(( SESSION_SERVICE_PACKET_DATA & mask ) == 0 ) {
+ return;
+ }
+ out.println( desc, ssp.toString() );
+ } catch( Exception e ) {
+ Log.printStackTrace( "jcifs.netbios.Log.printPacketData()", e );
+ }
+ }
+
+ static void printPacketData( String desc, NameServicePacket nsp ) {
+ try {
+ if(( NAME_SERVICE_PACKET_DATA & mask ) == 0 ) {
+ return;
+ }
+ out.println( desc, nsp.toString() );
+ } catch( Exception e ) {
+ Log.printStackTrace( "jcifs.netbios.Log.printPacketData()", e );
+ }
+ }
+ static void printAddressCache( String desc, Hashtable addressCache ) {
+ if(( ADDRESS_CACHE & mask ) == 0 )
+ return;
+ StringBuffer sb = new StringBuffer();
+ NbtAddress.CacheEntry ce;
+ for( Enumeration e = addressCache.elements(); e.hasMoreElements(); ) {
+ ce = (NbtAddress.CacheEntry)e.nextElement();
+ sb.append( ' ' ).append( ce.hostName );
+ sb.append( ' ' ).append( ce.address ).append( NL );
+ }
+ out.println( desc, sb.toString() );
+ }
+}
+
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ * "Christopher R. Hertel" <crh@nts.umn.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.netbios;
+
+import jcifs.Config;
+
+class Name {
+
+ static final char[] HEX_DIGITS = {
+ '0' , '1' , '2' , '3' , '4' , '5' ,
+ '6' , '7' , '8' , '9' , 'A' , 'B' ,
+ 'C' , 'D' , 'E' , 'F'
+ };
+
+ static String toHexChars( int val ) {
+ int len = 2;
+ byte[] tmp = new byte[2];
+ while( len > 0 ) {
+ tmp[ len - 1 ] = (byte)HEX_DIGITS[ val & 0x000F ];
+ if( val != 0 ) {
+ val >>>= 4;
+ }
+ len--;
+ }
+ return new String( tmp );
+ }
+
+ static final int TYPE_OFFSET = 31;
+ static final int SCOPE_OFFSET = 33;
+
+ static String defaultScope = Config.getProperty( "jcifs.netbios.scope" );
+
+ String name, scope;
+ int type;
+
+ Name( String name, int type, String scope ) {
+ this.name = name;
+ this.type = type;
+ if( scope != null ) {
+ this.scope = scope;
+ } else {
+ this.scope = defaultScope;
+ }
+ }
+
+ int writeWireFormat( byte[] dst, int dstIndex ) {
+ // write 0x20 in first byte
+ dst[dstIndex] = 0x20;
+
+ // write name
+ name = ( name.length() > 15 ) ?
+ name.substring( 0, 15 ).toUpperCase() :
+ name.toUpperCase();
+ byte tmp[] = name.getBytes();
+ int i;
+ for( i = 0; i < tmp.length; i++ ) {
+ dst[dstIndex + ( 2 * i + 1 )] = (byte)((( tmp[i] & 0xF0 ) >> 4 ) + 0x41 );
+ dst[dstIndex + ( 2 * i + 2 )] = (byte)(( tmp[i] & 0x0F ) + 0x41 );
+ }
+ for( ; i < 15; i++ ) {
+ dst[dstIndex + ( 2 * i + 1 )] = (byte)0x43;
+ dst[dstIndex + ( 2 * i + 2 )] = (byte)0x41;
+ }
+ dst[dstIndex + TYPE_OFFSET] = (byte)((( type & 0xF0 ) >> 4 ) + 0x41 );
+ dst[dstIndex + TYPE_OFFSET + 1] = (byte)(( type & 0x0F ) + 0x41 );
+ return SCOPE_OFFSET + writeScopeWireFormat( dst, dstIndex + SCOPE_OFFSET );
+ }
+
+ int readWireFormat( byte[] src, int srcIndex ) {
+
+ byte tmp[] = new byte[SCOPE_OFFSET];
+ int length = 15;
+ for( int i = 0; i < 15; i++ ) {
+ tmp[i] = (byte)((( src[srcIndex + ( 2 * i + 1 )] & 0xFF ) - 0x41 ) << 4 );
+ tmp[i] |= (byte)((( src[srcIndex + ( 2 * i + 2 )] & 0xFF ) - 0x41 ) & 0x0F );
+ if( tmp[i] != (byte)' ' ) {
+ length = i + 1;
+ }
+ }
+ name = new String( tmp, 0, length );
+ type = (( src[srcIndex + TYPE_OFFSET] & 0xFF ) - 0x41 ) << 4;
+ type |= (( src[srcIndex + TYPE_OFFSET + 1] & 0xFF ) - 0x41 ) & 0x0F;
+ return SCOPE_OFFSET + readScopeWireFormat( src, srcIndex + SCOPE_OFFSET );
+ }
+ int writeScopeWireFormat( byte[] dst, int dstIndex ) {
+ if( scope == null || scope.length() == 0 ) {
+ dst[dstIndex] = (byte)0x00;
+ return 1;
+ }
+
+ // copy new scope in
+ dst[dstIndex++] = (byte)'.';
+ System.arraycopy( scope.getBytes(), 0, dst, dstIndex, scope.length() );
+ dstIndex += scope.length();
+
+ dst[dstIndex++] = (byte)0x00;
+
+ // now go over scope backwards converting '.' to label length
+
+ int i = dstIndex - 2;
+ int e = i - scope.length();
+ int c = 0;
+
+ do {
+ if( dst[i] == '.' ) {
+ dst[i] = (byte)c;
+ c = 0;
+ } else {
+ c++;
+ }
+ } while( i-- > e );
+ return scope.length() + 2;
+ }
+ int readScopeWireFormat( byte[] src, int srcIndex ) {
+ int start = srcIndex;
+ int n;
+
+ if(( n = src[srcIndex++] & 0xFF ) == 0 ) {
+ scope = null;
+ return 1;
+ }
+
+ StringBuffer sb = new StringBuffer( new String( src, srcIndex, n ));
+ srcIndex += n;
+ while(( n = src[srcIndex++] & 0xFF ) != 0 ) {
+ sb.append( '.' ).append( new String( src, srcIndex, n ));
+ srcIndex += n;
+ }
+ return srcIndex - start;
+ }
+
+ public int hashCode() {
+ int result = name.toUpperCase().hashCode();
+ result += 65599 * type;
+ if( scope != null && scope.length() != 0 ) {
+ result += scope.hashCode();
+ }
+ return result;
+ }
+ public boolean equals( Object obj ) {
+ if( !( obj instanceof Name )) {
+ return false;
+ }
+ Name n = (Name)obj;
+ name = ( name.length() > 15 ) ?
+ name.substring( 0, 15 ).toUpperCase() :
+ name.toUpperCase();
+ n.name = ( n.name.length() > 15 ) ?
+ n.name.substring( 0, 15 ).toUpperCase() :
+ n.name.toUpperCase();
+ if(( scope == null || scope.length() == 0 ) &&
+ ( n.scope == null || n.scope.length() == 0 )) {
+ return name.equals( n.name ) && type == n.type;
+ }
+ return name.equals( n.name ) && type == n.type && scope.equals( n.scope );
+ }
+ String getName() {
+ return ( name.length() > 15 ) ?
+ name.substring( 0, 15 ).toUpperCase() :
+ name.toUpperCase();
+ }
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ String n = getName();
+
+ // fix MSBROWSE name
+ if( n.charAt( 0 ) == 0x01 ) {
+ byte b[] = n.getBytes();
+ b[0] = (byte)'.';
+ b[1] = (byte)'.';
+ b[14] = (byte)'.';
+ n = new String( b );
+ }
+
+ sb.append( n ).append( "<" ).append( toHexChars( type )).append( ">" );
+ if( scope != null && scope.length() != 0 ) {
+ sb.append( "." ).append( scope );
+ }
+ return sb.toString();
+ }
+
+}
+
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.netbios;
+
+class NameQueryRequest extends NameServicePacket {
+
+ NameQueryRequest( Name name ) {
+ questionName = name;
+ questionType = NB;
+ }
+
+ int writeBodyWireFormat( byte[] dst, int dstIndex ) {
+ return writeQuestionSectionWireFormat( dst, dstIndex );
+ }
+ int readBodyWireFormat( byte[] src, int srcIndex ) {
+ return readQuestionSectionWireFormat( src, srcIndex );
+ }
+ int writeRDataWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readRDataWireFormat( byte[] src, int srcIndex ) {
+ return 0;
+ }
+ public String toString() {
+ return new String( "NameQueryRequest[" +
+ super.toString() + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.netbios;
+
+class NameQueryResponse extends NameServicePacket {
+
+ NbtAddress addrEntry;
+
+ NameQueryResponse() {
+ recordName = new Name( null, 0, null );
+ }
+
+ int writeBodyWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readBodyWireFormat( byte[] src, int srcIndex ) {
+ return readResourceRecordWireFormat( src, srcIndex );
+ }
+ int writeRDataWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readRDataWireFormat( byte[] src, int srcIndex ) {
+ if( resultCode != 0 || opCode != QUERY ) {
+ return 0;
+ }
+ boolean groupName = (( src[srcIndex] & 0x80 ) == 0x80 ) ? true : false;
+ int nodeType = ( src[srcIndex] & 0x60 ) >> 5;
+ srcIndex += 2;
+ int address = readInt4( src, srcIndex );
+ addrEntry = new NbtAddress( recordName, address, groupName, nodeType );
+ return 6;
+ }
+ public String toString() {
+ return new String( "NameQueryResponse[" +
+ super.toString() +
+ ",addrEntry=" + addrEntry + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.netbios;
+
+import java.net.InetAddress;
+import java.net.DatagramSocket;
+import java.net.DatagramPacket;
+import java.net.UnknownHostException;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+import jcifs.Config;
+
+class NameServiceClient implements Runnable {
+
+ static final int DEFAULT_SO_TIMEOUT = 5000;
+ static final int DEFAULT_RCV_BUF_SIZE = 576;
+ static final int DEFAULT_SND_BUF_SIZE = 576;
+ static final int NAME_SERVICE_UDP_PORT = 137;
+ static final int DEFAULT_RETRY_COUNT = 2;
+ static final int DEFAULT_RETRY_TIMEOUT = 3000;
+
+ static final int RESOLVER_WINS = 0;
+ static final int RESOLVER_BCAST = 1;
+ static final int RESOLVER_DNS = 2;
+ static final int RESOLVER_LMHOSTS = 3;
+
+ NbtAddress localhost;
+ InetAddress laddr, baddr, nbns;
+ int port, soTimeout, retryCount, retryTimeout, closeTimeout;
+ int snd_buf_size, rcv_buf_size;
+ byte[] snd_buf, rcv_buf;
+ DatagramSocket socket;
+ DatagramPacket in, out;
+ Hashtable responseTable;
+ Thread thread;
+ int nextNameTrnId;
+ Object socketLock;
+ int[] resolveOrder;
+
+ NameServiceClient() {
+ this( Config.getInt( "jcifs.netbios.lport", 0 ),
+ Config.getInetAddress( "jcifs.netbios.laddr", null ));
+ }
+ NameServiceClient( int port, InetAddress laddr ) {
+ this.port = port;
+ this.laddr = laddr;
+
+ try {
+ baddr = Config.getInetAddress( "jcifs.netbios.baddr",
+ InetAddress.getByName( "255.255.255.255" ));
+
+ InetAddress inet = laddr;
+ if( inet == null ) {
+ inet = InetAddress.getLocalHost();
+ }
+ String name = Config.getProperty( "jcifs.netbios.hostname", null );
+ if( name == null || name.length() == 0 ) {
+ byte[] addr = inet.getAddress();
+ name = "JCIFS" +
+ ( addr[2] & 0xFF ) + "_" +
+ ( addr[3] & 0xFF ) + "_" +
+ Name.toHexChars( (int)( Math.random() * (double)0xFF ));
+ }
+ localhost = NbtAddress.getByName( inet.getHostAddress(),
+ 0x00, Config.getProperty( "jcifs.netbios.scope", null ));
+ localhost.hostName.name = name;
+ NbtAddress.cacheAddress( localhost.hostName, localhost, NbtAddress.FOREVER );
+ } catch( UnknownHostException uhe ) {
+ }
+
+ nbns = Config.getInetAddress( "jcifs.netbios.wins", null );
+
+ String ro = Config.getProperty( "jcifs.netbios.resolveOrder" );
+ if( ro == null || ro.length() == 0 ) {
+
+ /* No resolveOrder has been specified, use the
+ * default which is LMHOSTS,WINS,BCAST,DNS or just
+ * LMHOSTS,BCAST,DNS if jcifs.netbios.wins has not
+ * been specified.
+ */
+
+ if( nbns == null ) {
+ resolveOrder = new int[3];
+ resolveOrder[0] = RESOLVER_LMHOSTS;
+ resolveOrder[1] = RESOLVER_BCAST;
+ resolveOrder[2] = RESOLVER_DNS;
+ } else {
+ resolveOrder = new int[4];
+ resolveOrder[0] = RESOLVER_LMHOSTS;
+ resolveOrder[1] = RESOLVER_WINS;
+ resolveOrder[2] = RESOLVER_BCAST;
+ resolveOrder[3] = RESOLVER_DNS;
+ }
+ } else {
+ int[] tmp = new int[4];
+ StringTokenizer st = new StringTokenizer( ro, "," );
+ int i = 0;
+ while( st.hasMoreTokens() ) {
+ String s = st.nextToken().trim();
+ if( s.equalsIgnoreCase( "LMHOSTS" )) {
+ tmp[i++] = RESOLVER_LMHOSTS;
+ } else if( s.equalsIgnoreCase( "WINS" )) {
+ if( nbns == null ) {
+ Log.println( Log.WARNINGS, "netbios name service warning",
+ " resolveOrder specifies WINS however the " +
+ "jcifs.netbios.wins property has not been set" );
+ continue;
+ }
+ tmp[i++] = RESOLVER_WINS;
+ } else if( s.equalsIgnoreCase( "BCAST" )) {
+ tmp[i++] = RESOLVER_BCAST;
+ } else if( s.equalsIgnoreCase( "DNS" )) {
+ tmp[i++] = RESOLVER_DNS;
+ } else {
+ Log.println( Log.WARNINGS, "netbios name service warning",
+ "unknown resolver method: " + s );
+ }
+ }
+ resolveOrder = new int[i];
+ System.arraycopy( tmp, 0, resolveOrder, 0, i );
+ }
+
+ soTimeout = Config.getInt( "jcifs.netbios.soTimeout", DEFAULT_SO_TIMEOUT );
+ retryCount = Config.getInt( "jcifs.netbios.retryCount", DEFAULT_RETRY_COUNT );
+ retryTimeout = Config.getInt( "jcifs.netbios.retryTimeout", DEFAULT_RETRY_TIMEOUT);
+ rcv_buf_size = Config.getInt( "jcifs.netbios.rcv_buf_size", DEFAULT_RCV_BUF_SIZE );
+ snd_buf_size = Config.getInt( "jcifs.netbios.snd_buf_size", DEFAULT_SND_BUF_SIZE );
+ rcv_buf = new byte[rcv_buf_size];
+ snd_buf = new byte[snd_buf_size];
+ in = new DatagramPacket( rcv_buf, rcv_buf_size );
+ out = new DatagramPacket( snd_buf, snd_buf_size, baddr, NAME_SERVICE_UDP_PORT );
+ responseTable = new Hashtable();
+ nextNameTrnId = 0;
+ socketLock = new Object();
+ }
+
+ int getNextNameTrnId() {
+ if(( ++nextNameTrnId & 0xFFFF ) == 0 ) {
+ nextNameTrnId = 1;
+ }
+ return nextNameTrnId;
+ }
+ void ensureOpen( int timeout ) throws IOException {
+ closeTimeout = 0;
+ if( soTimeout != 0 ) {
+ closeTimeout = Math.max( soTimeout, timeout );
+ }
+ // If socket is still good, the new closeTimeout will
+ // be ignored; see tryClose comment.
+ if( socket == null ) {
+ socket = new DatagramSocket( port, laddr );
+ thread = new Thread( this );
+ thread.setDaemon( true );
+ thread.start();
+ }
+ }
+ void tryClose() {
+ synchronized( socketLock ) {
+
+ /* Yes, there is the potential to drop packets
+ * because we might close the socket during a
+ * request. However the chances are slim and the
+ * retry code should ensure the overall request
+ * is serviced. The alternative complicates things
+ * more than I think is worth it.
+ */
+
+ if( socket != null ) {
+ socket.close();
+ socket = null;
+ }
+ thread = null;
+ responseTable.clear();
+ }
+ }
+ public void run() {
+ int nameTrnId;
+ NameServicePacket response;
+
+ while( thread == Thread.currentThread() ) {
+ in.setLength( rcv_buf_size );
+ try {
+ socket.setSoTimeout( closeTimeout );
+ socket.receive( in );
+ } catch( IOException ioe ) {
+ tryClose();
+ continue;
+ }
+
+ Log.println( Log.DEBUGGING, "nbt name service debugging",
+ " new data read from socket" );
+
+ nameTrnId = NameServicePacket.readNameTrnId( rcv_buf, 0 );
+ response = (NameServicePacket)responseTable.get( new Integer( nameTrnId ));
+ if( response == null || response.received ) {
+ continue;
+ }
+ synchronized( response ) {
+ response.readWireFormat( rcv_buf, 0 );
+ response.received = true;
+
+ Log.printPacketData( "nbt name service packet receviced", response );
+ Log.printHexDump( "datagram packet received from: " +
+ in.getAddress().toString(), rcv_buf, 0, in.getLength() );
+
+ response.notify();
+ }
+ }
+ }
+ void send( NameServicePacket request,
+ NameServicePacket response, int timeout ) throws IOException {
+ Integer nid = null;
+
+ synchronized( response ) {
+ try {
+ synchronized( socketLock ) {
+ request.nameTrnId = getNextNameTrnId();
+ nid = new Integer( request.nameTrnId );
+
+ out.setAddress( request.addr );
+ out.setLength( request.writeWireFormat( snd_buf, 0 ));
+ response.received = false;
+
+ responseTable.put( nid, response );
+ ensureOpen( timeout + 1000 );
+ socket.send( out );
+
+ Log.printPacketData( "nbt name service packet sent", request );
+ Log.printHexDump( "datagram packet sent to: " +
+ out.getAddress().toString(), snd_buf, 0, out.getLength() );
+ }
+
+ response.wait( timeout );
+
+ } catch( InterruptedException ie ) {
+ } finally {
+ responseTable.remove( nid );
+ }
+ }
+ }
+ NbtAddress getByName( Name name ) throws UnknownHostException {
+ NameQueryRequest request = new NameQueryRequest( name );
+ NameQueryResponse response = new NameQueryResponse();
+
+ for( int i = 0; i < resolveOrder.length; i++ ) {
+ try {
+ switch( resolveOrder[i] ) {
+ case RESOLVER_LMHOSTS:
+ NbtAddress ans = Lmhosts.getByName( name );
+ if( ans != null ) {
+ return ans;
+ }
+ break;
+ case RESOLVER_WINS:
+ case RESOLVER_BCAST:
+ if( resolveOrder[i] == RESOLVER_WINS &&
+ nbns != null &&
+ name.name != NbtAddress.MASTER_BROWSER_NAME &&
+ name.type != 0x1d ) {
+ request.addr = nbns;
+ request.isBroadcast = false;
+ } else {
+ request.addr = baddr;
+ request.isBroadcast = true;
+ }
+
+ int n = retryCount;
+ while( n-- > 0 ) {
+ try {
+ send( request, response, retryTimeout );
+ } catch( IOException ioe ) {
+ Log.printStackTrace( "nbt name service send:", ioe );
+ throw new UnknownHostException( ioe.getMessage() );
+ }
+ if( response.received && response.resultCode == 0 ) {
+ return response.addrEntry;
+ }
+ }
+ break;
+ case RESOLVER_DNS:
+ if( name.type == 0x20 || name.type == 0x00 ) {
+ InetAddress addr = InetAddress.getByName( name.name );
+ return new NbtAddress( new Name( NbtAddress.ALL_HOSTS_NAME,
+ name.type, name.scope ), addr.hashCode(), false,
+ NbtAddress.B_NODE );
+ }
+ }
+ } catch( IOException ioe ) {
+ }
+ }
+ throw new UnknownHostException( name.name );
+ }
+ NbtAddress[] getNodeStatus( NbtAddress addr ) throws UnknownHostException {
+ NodeStatusRequest request = new NodeStatusRequest( addr.hostName );
+ NodeStatusResponse response = new NodeStatusResponse( addr );
+ request.addr = addr.getInetAddress();
+ int n = retryCount;
+ while( n-- > 0 ) {
+ try {
+ send( request, response, retryTimeout );
+ } catch( IOException ioe ) {
+ Log.printStackTrace( "nbt name service send:", ioe );
+ throw new UnknownHostException( ioe.getMessage() );
+ }
+ if( response.received && response.resultCode == 0 ) {
+ return response.addressArray;
+ }
+ }
+ throw new UnknownHostException( addr.hostName.name );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.netbios;
+
+import java.net.InetAddress;
+
+abstract class NameServicePacket {
+
+ // opcode
+ static final int QUERY = 0;
+ static final int WACK = 7;
+
+ // rcode
+ static final int FMT_ERR = 0x1;
+ static final int SRV_ERR = 0x2;
+ static final int IMP_ERR = 0x4;
+ static final int RFS_ERR = 0x5;
+ static final int ACT_ERR = 0x6;
+ static final int CFT_ERR = 0x7;
+
+ // type/class
+ static final int NB_IN = 0x00200001;
+ static final int NBSTAT_IN = 0x00210001;
+ static final int NB = 0x0020;
+ static final int NBSTAT = 0x0021;
+ static final int IN = 0x0001;
+ static final int A = 0x0001;
+ static final int NS = 0x0002;
+ static final int NULL = 0x000a;
+
+ static final int HEADER_LENGTH = 12;
+
+ // header field offsets
+ static final int OPCODE_OFFSET = 2;
+ static final int QUESTION_OFFSET = 4;
+ static final int ANSWER_OFFSET = 6;
+ static final int AUTHORITY_OFFSET = 8;
+ static final int ADDITIONAL_OFFSET = 10;
+
+ static void writeInt2( int val, byte[] dst, int dstIndex ) {
+ dst[dstIndex++] = (byte)(( val >> 8 ) & 0xFF );
+ dst[dstIndex] = (byte)( val & 0xFF );
+ }
+ static void writeInt4( int val, byte[] dst, int dstIndex ) {
+ dst[dstIndex++] = (byte)(( val >> 24 ) & 0xFF );
+ dst[dstIndex++] = (byte)(( val >> 16 ) & 0xFF );
+ dst[dstIndex++] = (byte)(( val >> 8 ) & 0xFF );
+ dst[dstIndex] = (byte)( val & 0xFF );
+ }
+ static int readInt2( byte[] src, int srcIndex ) {
+ return (( src[srcIndex] & 0xFF ) << 8 ) +
+ ( src[srcIndex + 1] & 0xFF );
+ }
+ static int readInt4( byte[] src, int srcIndex ) {
+ return (( src[srcIndex] & 0xFF ) << 24 ) +
+ (( src[srcIndex + 1] & 0xFF ) << 16 ) +
+ (( src[srcIndex + 2] & 0xFF ) << 8 ) +
+ ( src[srcIndex + 3] & 0xFF );
+ }
+
+ static int readNameTrnId( byte[] src, int srcIndex ) {
+ return readInt2( src, srcIndex );
+ }
+
+ int nameTrnId;
+
+ int opCode,
+ resultCode,
+ questionCount,
+ answerCount,
+ authorityCount,
+ additionalCount;
+ boolean received,
+ isResponse,
+ isAuthAnswer,
+ isTruncated,
+ isRecurDesired,
+ isRecurAvailable,
+ isBroadcast;
+
+ Name questionName;
+ Name recordName;
+
+ int questionType,
+ questionClass,
+ recordType,
+ recordClass,
+ ttl,
+ rDataLength;
+
+ InetAddress addr;
+
+ NameServicePacket() {
+ isRecurDesired = true;
+ isBroadcast = true;
+ questionCount = 1;
+ questionClass = IN;
+ }
+
+ int writeWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+ dstIndex += writeHeaderWireFormat( dst, dstIndex );
+ dstIndex += writeBodyWireFormat( dst, dstIndex );
+ return dstIndex - start;
+ }
+ int readWireFormat( byte[] src, int srcIndex ) {
+ int start = srcIndex;
+ srcIndex += readHeaderWireFormat( src, srcIndex );
+ srcIndex += readBodyWireFormat( src, srcIndex );
+ return srcIndex - start;
+ }
+
+ int writeHeaderWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+ writeInt2( nameTrnId, dst, dstIndex );
+ dst[dstIndex + OPCODE_OFFSET] = (byte)(( isResponse ? 0x80 : 0x00 ) +
+ (( opCode << 3 ) & 0x78 ) +
+ ( isAuthAnswer ? 0x04 : 0x00 ) +
+ ( isTruncated ? 0x02 : 0x00 ) +
+ ( isRecurDesired ? 0x01 : 0x00 ));
+ dst[dstIndex + OPCODE_OFFSET + 1] = (byte)(( isRecurAvailable ? 0x80 : 0x00 ) +
+ ( isBroadcast ? 0x10 : 0x00 ) +
+ ( resultCode & 0x0F ));
+ writeInt2( questionCount, dst, start + QUESTION_OFFSET );
+ writeInt2( answerCount, dst, start + ANSWER_OFFSET );
+ writeInt2( authorityCount, dst, start + AUTHORITY_OFFSET );
+ writeInt2( additionalCount, dst, start + ADDITIONAL_OFFSET );
+ return HEADER_LENGTH;
+ }
+ int readHeaderWireFormat( byte[] src, int srcIndex ) {
+ nameTrnId = readInt2( src, srcIndex );
+ isResponse = (( src[srcIndex + OPCODE_OFFSET] & 0x80 ) == 0 ) ? false : true;
+ opCode = ( src[srcIndex + OPCODE_OFFSET] & 0x78 ) >> 3;
+ isAuthAnswer = (( src[srcIndex + OPCODE_OFFSET] & 0x04 ) == 0 ) ? false : true;
+ isTruncated = (( src[srcIndex + OPCODE_OFFSET] & 0x02 ) == 0 ) ? false : true;
+ isRecurDesired = (( src[srcIndex + OPCODE_OFFSET] & 0x01 ) == 0 ) ? false : true;
+ isRecurAvailable =
+ (( src[srcIndex + OPCODE_OFFSET + 1] & 0x80 ) == 0 ) ? false : true;
+ isBroadcast = (( src[srcIndex + OPCODE_OFFSET + 1] & 0x10 ) == 0 ) ? false : true;
+ resultCode = src[srcIndex + OPCODE_OFFSET + 1] & 0x0F;
+ questionCount = readInt2( src, srcIndex + QUESTION_OFFSET );
+ answerCount = readInt2( src, srcIndex + ANSWER_OFFSET );
+ authorityCount = readInt2( src, srcIndex + AUTHORITY_OFFSET );
+ additionalCount = readInt2( src, srcIndex + ADDITIONAL_OFFSET );
+ return HEADER_LENGTH;
+ }
+ int writeQuestionSectionWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+ dstIndex += questionName.writeWireFormat( dst, dstIndex );
+ writeInt2( questionType, dst, dstIndex );
+ dstIndex += 2;
+ writeInt2( questionClass, dst, dstIndex );
+ dstIndex += 2;
+ return dstIndex - start;
+ }
+ int readQuestionSectionWireFormat( byte[] src, int srcIndex ) {
+ int start = srcIndex;
+ srcIndex += questionName.readWireFormat( src, srcIndex );
+ questionType = readInt2( src, srcIndex );
+ srcIndex += 2;
+ questionClass = readInt2( src, srcIndex );
+ srcIndex += 2;
+ return srcIndex - start;
+ }
+ int writeResourceRecordWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+ if( recordName == questionName ) {
+ dst[dstIndex++] = (byte)0xC0; // label string pointer to
+ dst[dstIndex++] = (byte)0x0C; // questionName (offset 12)
+ } else {
+ dstIndex += recordName.writeWireFormat( dst, dstIndex );
+ }
+ writeInt2( recordType, dst, dstIndex );
+ dstIndex += 2;
+ writeInt2( recordClass, dst, dstIndex );
+ dstIndex += 2;
+ writeInt4( ttl, dst, dstIndex );
+ dstIndex += 4;
+ rDataLength = writeRDataWireFormat( dst, dstIndex + 2 );
+ writeInt2( rDataLength, dst, dstIndex );
+ dstIndex += 2 + rDataLength;
+ return dstIndex - start;
+ }
+ int readResourceRecordWireFormat( byte[] src, int srcIndex ) {
+ int start = srcIndex;
+ if(( src[srcIndex] & 0xC0 ) == 0xC0 ) {
+ recordName = questionName; // label string pointer to questionName
+ srcIndex += 2;
+ } else {
+ srcIndex += recordName.readWireFormat( src, srcIndex );
+ }
+ recordType = readInt2( src, srcIndex );
+ srcIndex += 2;
+ recordClass = readInt2( src, srcIndex );
+ srcIndex += 2;
+ ttl = readInt4( src, srcIndex );
+ srcIndex += 4;
+ rDataLength = readInt2( src, srcIndex );
+ srcIndex += 2;
+ readRDataWireFormat( src, srcIndex );
+ srcIndex += rDataLength;
+ return srcIndex - start;
+ }
+
+ abstract int writeBodyWireFormat( byte[] dst, int dstIndex );
+ abstract int readBodyWireFormat( byte[] src, int srcIndex );
+ abstract int writeRDataWireFormat( byte[] dst, int dstIndex );
+ abstract int readRDataWireFormat( byte[] src, int srcIndex );
+
+ public String toString() {
+ String opCodeString,
+ resultCodeString,
+ questionTypeString,
+ questionClassString,
+ recordTypeString,
+ recordClassString;
+
+ switch( opCode ) {
+ case QUERY:
+ opCodeString = "QUERY";
+ break;
+ case WACK:
+ opCodeString = "WACK";
+ break;
+ default:
+ opCodeString = Integer.toString( opCode );
+ }
+ switch( resultCode ) {
+ case FMT_ERR:
+ resultCodeString = "FMT_ERR";
+ break;
+ case SRV_ERR:
+ resultCodeString = "SRV_ERR";
+ break;
+ case IMP_ERR:
+ resultCodeString = "IMP_ERR";
+ break;
+ case RFS_ERR:
+ resultCodeString = "RFS_ERR";
+ break;
+ case ACT_ERR:
+ resultCodeString = "ACT_ERR";
+ break;
+ case CFT_ERR:
+ resultCodeString = "CFT_ERR";
+ break;
+ default:
+ resultCodeString = "0x" + Log.getHexString( resultCode, 1 );
+ }
+ switch( questionType ) {
+ case NB:
+ questionTypeString = "NB";
+ case NBSTAT:
+ questionTypeString = "NBSTAT";
+ default:
+ questionTypeString = "0x" + Log.getHexString( questionType, 4 );
+ }
+ switch( recordType ) {
+ case A:
+ recordTypeString = "A";
+ break;
+ case NS:
+ recordTypeString = "NS";
+ break;
+ case NULL:
+ recordTypeString = "NULL";
+ break;
+ case NB:
+ recordTypeString = "NB";
+ case NBSTAT:
+ recordTypeString = "NBSTAT";
+ default:
+ recordTypeString = "0x" + Log.getHexString( recordType, 4 );
+ }
+
+ return new String(
+ "nameTrnId=" + nameTrnId +
+ ",isResponse=" + isResponse +
+ ",opCode=" + opCodeString +
+ ",isAuthAnswer=" + isAuthAnswer +
+ ",isTruncated=" + isTruncated +
+ ",isRecurAvailable=" + isRecurAvailable +
+ ",isRecurDesired=" + isRecurDesired +
+ ",isBroadcast=" + isBroadcast +
+ ",resultCode=" + resultCode +
+ ",questionCount=" + questionCount +
+ ",answerCount=" + answerCount +
+ ",authorityCount=" + authorityCount +
+ ",additionalCount=" + additionalCount +
+ ",questionName=" + questionName +
+ ",questionType=" + questionTypeString +
+ ",questionClass=" + ( questionClass == IN ? "IN" :
+ "0x" + Log.getHexString( questionClass, 4 )) +
+ ",recordName=" + recordName +
+ ",recordType=" + recordTypeString +
+ ",recordClass=" + ( recordClass == IN ? "IN" :
+ "0x" + Log.getHexString( recordClass, 4 )) +
+ ",ttl=" + ttl +
+ ",rDataLength=" + rDataLength );
+ }
+}
+
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.netbios;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.net.SocketException;
+import java.io.IOException;
+import java.util.Hashtable;
+import jcifs.Config;
+
+/**
+ * This class represents a NetBIOS over TCP/IP address. Under normal
+ * conditions, users of jCIFS need not be concerned with this class as
+ * name resolution and session services are handled internally by the smb package.
+ *
+ * <p> Applications can use the methods <code>getLocalHost</code>,
+ * <code>getAllByName</code>, and
+ * <code>getAllByAddress</code> to create a new NbtAddress instance. This
+ * class is symmetric with {@link java.net.InetAddress}.
+ *
+ * <p><b>About NetBIOS:</b> The NetBIOS name
+ * service is a dynamic distributed service that allows hosts to resolve
+ * names by broadcasting a query, directing queries to a server such as
+ * Samba or WINS. NetBIOS is currently the primary networking layer for
+ * providing name service, datagram service, and session service to the
+ * Microsoft Windows platform. A NetBIOS name can be 15 characters long
+ * and hosts usually registers several names on the network. From a
+ * Windows command prompt you can see
+ * what names a host registers with the nbtstat command.
+ * <p><blockquote><pre>
+ * C:\>nbtstat -a 192.168.1.15
+ *
+ * NetBIOS Remote Machine Name Table
+ *
+ * Name Type Status
+ * ---------------------------------------------
+ * JMORRIS2 <00> UNIQUE Registered
+ * BILLING-NY <00> GROUP Registered
+ * JMORRIS2 <03> UNIQUE Registered
+ * JMORRIS2 <20> UNIQUE Registered
+ * BILLING-NY <1E> GROUP Registered
+ * JMORRIS <03> UNIQUE Registered
+ *
+ * MAC Address = 00-B0-34-21-FA-3B
+ * </blockquote></pre>
+ * <p> The hostname of this machine is <code>JMORRIS2</code>. It is
+ * a member of the group(a.k.a workgroup and domain) <code>BILLING-NY</code>. To
+ * obtain an {@link java.net.InetAddress} for a host one might do:
+ *
+ * <pre>
+ * InetAddress addr = NbtAddress.getByName( "jmorris2" ).getInetAddress();
+ * </pre>
+ * <p>From a UNIX platform with Samba installed you can perform similar
+ * diagnostics using the <code>nmblookup</code> utility.
+ *
+ * @author Michael B. Allen
+ * @see java.net.InetAddress
+ * @since jcifs-0.1
+ */
+
+public final class NbtAddress {
+
+ Name hostName;
+ int address, nodeType;
+ boolean groupName,
+ isBeingDeleted,
+ isInConflict,
+ isActive,
+ isPermanent,
+ isDataFromNodeStatus;
+ byte[] macAddress;
+
+ private static final byte[] MASTER_BROWSER_BYTES = {
+ (byte)0x01, (byte)0x02, (byte)0x5F, (byte)0x5F, (byte)0x4D, (byte)0x53,
+ (byte)0x42, (byte)0x52, (byte)0x4F, (byte)0x57, (byte)0x53, (byte)0x45,
+ (byte)0x5F, (byte)0x5F, (byte)0x02
+ };
+ private static final byte[] SMBSERVER_BYTES = {
+ (byte)0x2a, (byte)0x53, (byte)0x4d, (byte)0x42, (byte)0x53, (byte)0x45,
+ (byte)0x52, (byte)0x56, (byte)0x45, (byte)0x52, (byte)0x20, (byte)0x20,
+ (byte)0x20, (byte)0x20, (byte)0x20
+ };
+ private static final byte[] ALL_HOSTS_BYTES = {
+ (byte)0x2A, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x00
+ };
+
+ // Node Types
+
+/**
+ * A B node only broadcasts name queries. This is the default if a
+ * nameserver such as WINS or Samba is not specified.
+ */
+
+ public static final int B_NODE = 0;
+
+/**
+ * A Point-to-Point node, or P node, unicasts queries to a nameserver
+ * only. Natrually the <code>jcifs.netbios.nameserver</code> property must
+ * be set.
+ */
+
+ public static final int P_NODE = 1;
+
+/**
+ * Try Broadcast queries first, then try to resolve the name using the
+ * nameserver.
+ */
+
+ public static final int M_NODE = 2;
+
+/**
+ * A Hybrid node tries to resolve a name using the nameserver first. If that fails use the
+ * broadcast address. This is the default if a nameserver is provided. This
+ * is the behavior of Microsoft Windows machines.
+ */
+
+ public static final int H_NODE = 3;
+
+/**
+ * This is a special name for querying the master browser that serves the
+ * list of hosts found in "Network Neighborhood".
+ */
+
+ public static final String MASTER_BROWSER_NAME = new String( MASTER_BROWSER_BYTES );
+
+/**
+ * A special generic name specified when connecting to a host for which a name is not known. Not all servers respond to this name.
+ */
+
+ public static final String SMBSERVER_NAME = new String( SMBSERVER_BYTES );
+
+/**
+ * This is a special name that means all hosts. If you wish to find all hosts
+ * on a network querying a workgroup group name is the preferred method.
+ */
+
+ static final String ALL_HOSTS_NAME = new String( ALL_HOSTS_BYTES );
+
+ NbtAddress( Name hostName, int address, boolean groupName, int nodeType ) {
+ this.hostName = hostName;
+ this.address = address;
+ this.groupName = groupName;
+ this.nodeType = nodeType;
+ }
+ NbtAddress( Name hostName,
+ int address,
+ boolean groupName,
+ int nodeType,
+ boolean isBeingDeleted,
+ boolean isInConflict,
+ boolean isActive,
+ boolean isPermanent,
+ byte[] macAddress ) {
+
+ this.hostName = hostName;
+ this.address = address;
+ this.groupName = groupName;
+ this.nodeType = nodeType;
+ this.isBeingDeleted = isBeingDeleted;
+ this.isInConflict = isInConflict;
+ this.isActive = isActive;
+ this.isPermanent = isPermanent;
+ this.macAddress = macAddress;
+ isDataFromNodeStatus = true;
+ }
+
+/**
+ * Determines if the address is a group address. This is also
+ * known as a workgroup name or group name.
+ *
+ * @throws UnknownHostException if the host cannot be resolved to find out.
+ */
+
+ public boolean isGroupAddress() throws UnknownHostException {
+ checkData();
+ return groupName;
+ }
+
+/**
+ * Checks the node type of this address.
+ * @return {@link jcifs.netbios.NbtAddress#B_NODE}, {@link jcifs.netbios.NbtAddress#P_NODE}, {@link jcifs.netbios.NbtAddress#M_NODE}, {@link jcifs.netbios.NbtAddress#H_NODE}
+ *
+ * @throws UnknownHostException if the host cannot be resolved to find out.
+ */
+
+ public int getNodeType() throws UnknownHostException {
+ checkData();
+ return nodeType;
+ }
+
+/**
+ * Determines if this address in the process of being deleted.
+ *
+ * @throws UnknownHostException if the host cannot be resolved to find out.
+ */
+
+ public boolean isBeingDeleted() throws UnknownHostException {
+ checkNodeStatusData();
+ return isBeingDeleted;
+ }
+
+/**
+ * Determines if this address in conflict with another address.
+ *
+ * @throws UnknownHostException if the host cannot be resolved to find out.
+ */
+
+ public boolean isInConflict() throws UnknownHostException {
+ checkNodeStatusData();
+ return isInConflict;
+ }
+
+/**
+ * Determines if this address is active.
+ *
+ * @throws UnknownHostException if the host cannot be resolved to find out.
+ */
+
+ public boolean isActive() throws UnknownHostException {
+ checkNodeStatusData();
+ return isActive;
+ }
+
+/**
+ * Determines if this address is set to be permanent.
+ *
+ * @throws UnknownHostException if the host cannot be resolved to find out.
+ */
+
+ public boolean isPermanent() throws UnknownHostException {
+ checkNodeStatusData();
+ return isPermanent;
+ }
+
+/**
+ * Retrieves the MAC address of the remote network interface. Samba returns all zeros.
+ *
+ * @return the MAC address as an array of six bytes
+ * @throws UnknownHostException if the host cannot be resolved to determine the MAC address.
+ */
+
+ public byte[] getMacAddress() throws UnknownHostException {
+ checkNodeStatusData();
+ return macAddress;
+ }
+
+/**
+ * The hostname of this address. If the hostname is null the local machines
+ * IP address is returned.
+ *
+ * @return the text representation of the hostname associated with this address
+ */
+
+ public String getHostName() {
+ try {
+ checkData();
+ } catch( UnknownHostException uhe ) {
+ return getHostAddress();
+ }
+ return hostName.getName();
+ }
+
+ // just for the above methods
+
+ void checkData() throws UnknownHostException {
+ if( hostName.name == ALL_HOSTS_NAME || hostName.name == null ) {
+ getAllByAddress( this );
+ }
+ }
+ void checkNodeStatusData() throws UnknownHostException {
+ if( isDataFromNodeStatus == false ) {
+ getAllByAddress( this );
+ }
+ }
+
+/**
+ * Returns the raw IP address of this NbtAddress. The result is in network
+ * byte order: the highest order byte of the address is in getAddress()[0].
+ *
+ * @return a four byte array
+ */
+
+ public byte[] getAddress() {
+ byte[] addr = new byte[4];
+
+ addr[0] = (byte)(( address >>> 24 ) & 0xFF );
+ addr[1] = (byte)(( address >>> 16 ) & 0xFF );
+ addr[2] = (byte)(( address >>> 8 ) & 0xFF );
+ addr[3] = (byte)( address & 0xFF );
+ return addr;
+ }
+
+/**
+ * To convert this address to an <code>InetAddress</code>.
+ *
+ * @return the {@link java.net.InetAddress} representation of this address.
+ */
+
+ public InetAddress getInetAddress() throws UnknownHostException {
+ return InetAddress.getByName( getHostAddress() );
+ }
+
+/**
+ * Returns this IP adress as a {@link java.lang.String} in the form "%d.%d.%d.%d".
+ */
+
+ public String getHostAddress() {
+ return (( address >>> 24 ) & 0xFF ) + "." +
+ (( address >>> 16 ) & 0xFF ) + "." +
+ (( address >>> 8 ) & 0xFF ) + "." +
+ (( address >>> 0 ) & 0xFF );
+ }
+
+/**
+ * Returned the hex code associated with this name(e.g. 0x20 is for the file service)
+ */
+
+ public int getNameType() {
+ return hostName.type;
+ }
+
+/**
+ * Returns a hashcode for this IP address. The hashcode comes from the IP address
+ * and is not generated from the string representation. So because NetBIOS nodes
+ * can have many names, all names associated with an IP will have the same
+ * hashcode.
+ */
+
+ public int hashCode() {
+ return address;
+ }
+
+/**
+ * Determines if this address is equal two another. Only the IP Addresses
+ * are compared. Similar to the {@link #hashCode} method, the comparison
+ * is based on the integer IP address and not the string representation.
+ */
+
+ public boolean equals( NbtAddress nbAddr ) {
+ return ( nbAddr != null ) && ( nbAddr.address == address );
+ }
+
+/**
+ * Returns the {@link java.lang.String} representaion of this address.
+ */
+
+ public String toString() {
+ return hostName.toString() + "/" + getHostAddress();
+ }
+
+/**
+ * Retrieves the local host address.
+ *
+ * @throws UnknownHostException This is not likely as the IP returned by <code>InetAddress</code> should be available
+ */
+
+ public static NbtAddress getLocalHost() throws UnknownHostException {
+ return client.localhost;
+ }
+
+ static final int DEFAULT_CACHE_POLICY = 30;
+ static final int FOREVER = -1;
+
+ static int cachePolicy = Config.getInt( "jcifs.netbios.cachePolicy",
+ DEFAULT_CACHE_POLICY );
+ static Hashtable addressCache = new Hashtable();
+ static NbtAddress unknownAddress;
+ static NbtAddress[] unknown_array;
+
+ static final class CacheEntry {
+ Name hostName;
+ NbtAddress address;
+ long expiration;
+
+ CacheEntry( Name hostName, NbtAddress address, long expiration ) {
+ this.hostName = hostName;
+ this.address = address;
+ this.expiration = expiration;
+ }
+ }
+
+ static void cacheAddress( Name hostName, NbtAddress addr ) {
+ if( cachePolicy == 0 ) {
+ return;
+ }
+ long expiration = -1;
+ if( cachePolicy != FOREVER ) {
+ expiration = System.currentTimeMillis() + cachePolicy * 1000;
+ }
+ cacheAddress( hostName, addr, expiration );
+ }
+ static void cacheAddress( Name hostName, NbtAddress addr, long expiration ) {
+ if( cachePolicy == 0 ) {
+ return;
+ }
+ synchronized( addressCache ) {
+ CacheEntry entry = (CacheEntry)addressCache.get( hostName );
+ if( entry == null ) {
+ entry = new CacheEntry( hostName, addr, expiration );
+ addressCache.put( hostName, entry );
+ } else {
+ entry.address = addr;
+ entry.expiration = expiration;
+ }
+ Log.printAddressCache( "name service address cache", addressCache );
+ }
+ }
+ static void cacheAddressArray( NbtAddress[] addrs ) {
+ if( cachePolicy == 0 ) {
+ return;
+ }
+ long expiration = -1;
+ if( cachePolicy != FOREVER ) {
+ expiration = System.currentTimeMillis() + cachePolicy * 1000;
+ }
+ synchronized( addressCache ) {
+ for( int i = 0; i < addrs.length; i++ ) {
+ CacheEntry entry = (CacheEntry)addressCache.get( addrs[i].hostName );
+ if( entry == null ) {
+ entry = new CacheEntry( addrs[i].hostName, addrs[i], expiration );
+ addressCache.put( addrs[i].hostName, entry );
+ } else {
+ entry.address = addrs[i];
+ entry.expiration = expiration;
+ }
+ }
+ Log.printAddressCache( "name service address cache", addressCache );
+ }
+ }
+ static NbtAddress getCachedAddress( Name hostName ) {
+ if( cachePolicy == 0 ) {
+ return null;
+ }
+ synchronized( addressCache ) {
+ CacheEntry entry = (CacheEntry)addressCache.get( hostName );
+ if( entry != null && entry.expiration < System.currentTimeMillis() &&
+ entry.expiration >= 0 ) {
+ entry = null;
+ }
+ return entry != null ? entry.address : null;
+ }
+ }
+
+ static NameServiceClient client = new NameServiceClient();
+
+ static {
+ unknownAddress = new NbtAddress( new Name( "0.0.0.0", 0x00, "" ), 0, false, B_NODE );
+ unknown_array = new NbtAddress[1];
+ unknown_array[0] = unknownAddress;
+ addressCache.put( unknownAddress.hostName,
+ new CacheEntry( unknownAddress.hostName, unknownAddress, FOREVER ));
+ }
+
+ static NbtAddress doNameQuery( Name name ) throws UnknownHostException {
+
+ NbtAddress addr = getCachedAddress( name );
+
+ if( addr == null ) {
+ try {
+ addr = client.getByName( name );
+ } catch( UnknownHostException uhe ) {
+ addr = unknownAddress;
+ } finally {
+ cacheAddress( name, addr );
+ }
+ }
+ if( addr == unknownAddress ) {
+ throw new UnknownHostException( name.toString() );
+ }
+ return addr;
+ }
+
+/**
+ * Determines the address of a host given it's host name. The name can be a
+ * machine name like "jcifs.samba.org" or an IP address like "192.168.1.15".
+ *
+ * @param host hostname to resolve
+ * @throws java.net.UnknownHostException if there is an error resolving the name
+ */
+
+ public static NbtAddress getByName( String host )
+ throws UnknownHostException {
+ return getByName( host, 0, null );
+ }
+
+/**
+ * Determines the address of a host given it's host name. NetBIOS
+ * names also have a <code>type</code>. Types(aka Hex Codes)
+ * are used to distiquish the various services on a host. <a
+ * href="../../../nbtcodes.html">Here</a> is
+ * a fairly complete list of NetBIOS hex codes. Scope is not used but is
+ * still functional in other NetBIOS products and so for completeness it has been
+ * implemented. A <code>scope</code> of <code>null</code> or <code>""</code>
+ * signifies no scope.
+ *
+ * @param host the name to resolve
+ * @param type the hex code of the name
+ * @param scope the scope of the name
+ * @throws java.net.UnknownHostException if there is an error resolving the name
+ */
+
+ public static NbtAddress getByName( String host,
+ int type,
+ String scope )
+ throws UnknownHostException {
+
+ if( host == null || host.length() == 0 ) {
+ return getLocalHost();
+ }
+ if( !Character.isDigit( host.charAt(0) )) {
+ return (NbtAddress)doNameQuery( new Name( host, type, scope ));
+ } else {
+ int IP = 0x00;
+ int hitDots = 0;
+ char[] data = host.toCharArray();
+
+ for( int i = 0; i < data.length; i++ ) {
+ char c = data[i];
+ if( c < 48 || c > 57 ) {
+ return (NbtAddress)doNameQuery( new Name( host, type, scope ));
+ }
+ int b = 0x00;
+ while( c != '.' ) {
+ if( c < 48 || c > 57 ) {
+ return (NbtAddress)doNameQuery( new Name( host, type, scope ));
+ }
+ b = b * 10 + c - '0';
+
+ if( ++i >= data.length )
+ break;
+
+ c = data[i];
+ }
+ if( b > 0xFF ) {
+ return (NbtAddress)doNameQuery( new Name( host, type, scope ));
+ }
+ IP = ( IP << 8 ) + b;
+ hitDots++;
+ }
+ if( hitDots != 4 || host.endsWith( "." )) {
+ return (NbtAddress)doNameQuery( new Name( host, type, scope ));
+ }
+ return new NbtAddress( new Name( ALL_HOSTS_NAME, type, scope ),
+ IP, false, B_NODE );
+ }
+ }
+
+/**
+ * Retrieve all addresses of a host by it's address. NetBIOS hosts can
+ * have many names for a given IP address. The name and IP address make the
+ * NetBIOS address. This provides a way to retrieve the other names for a
+ * host with the same IP address.
+ *
+ * @param host hostname to lookup all addresses for
+ * @throws java.net.UnknownHostException if there is an error resolving the name
+ */
+
+
+ public static NbtAddress[] getAllByAddress( String host ) throws UnknownHostException {
+ return getAllByAddress( getByName( host, 0x00, null ));
+ }
+
+
+/**
+ * Retrieve all addresses of a host by it's address. NetBIOS hosts can
+ * have many names for a given IP address. The name and IP address make
+ * the NetBIOS address. This provides a way to retrieve the other names
+ * for a host with the same IP address. See {@link #getByName}
+ * for a description of <code>type</code>
+ * and <code>scope</code>.
+ *
+ * @param host hostname to lookup all addresses for
+ * @param type the hexcode of the name
+ * @param scope the scope of the name
+ * @throws java.net.UnknownHostException if there is an error resolving the name
+ */
+
+
+ public static NbtAddress[] getAllByAddress( String host,
+ int type,
+ String scope )
+ throws UnknownHostException {
+ return getAllByAddress( getByName( host, type, scope ));
+ }
+
+
+/**
+ * Retrieve all addresses of a host by it's address. NetBIOS hosts can
+ * have many names for a given IP address. The name and IP address make the
+ * NetBIOS address. This provides a way to retrieve the other names for a
+ * host with the same IP address.
+ *
+ * @param addr the address to query
+ * @throws UnknownHostException if address cannot be resolved
+ */
+
+ public static NbtAddress[] getAllByAddress( NbtAddress addr )
+ throws UnknownHostException {
+ try {
+ NbtAddress[] addrs = client.getNodeStatus( addr );
+ cacheAddressArray( addrs );
+ return addrs;
+ } catch( UnknownHostException uhe ) {
+ throw new UnknownHostException( "no name with type 0x" +
+ Name.toHexChars( addr.hostName.type ) +
+ ((( addr.hostName.scope == null ) ||
+ ( addr.hostName.scope.length() == 0 )) ?
+ " with no scope" : " with scope " + addr.hostName.scope ) +
+ " for host " + addr.getHostAddress() );
+ }
+ }
+}
+
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.netbios;
+
+import java.io.IOException;
+
+public class NbtException extends IOException {
+
+ // error classes
+ public static final int SUCCESS = 0;
+ public static final int ERR_NAM_SRVC = 0x01;
+ public static final int ERR_SSN_SRVC = 0x02;
+
+ // name service error codes
+ public static final int FMT_ERR = 0x1;
+ public static final int SRV_ERR = 0x2;
+ public static final int IMP_ERR = 0x4;
+ public static final int RFS_ERR = 0x5;
+ public static final int ACT_ERR = 0x6;
+ public static final int CFT_ERR = 0x7;
+
+ // session service error codes
+ public static final int CONNECTION_REFUSED = -1;
+ public static final int NOT_LISTENING_CALLED = 0x80;
+ public static final int NOT_LISTENING_CALLING = 0x81;
+ public static final int CALLED_NOT_PRESENT = 0x82;
+ public static final int NO_RESOURCES = 0x83;
+ public static final int UNSPECIFIED = 0x8F;
+
+ public int errorClass;
+ public int errorCode;
+
+ public static String getErrorString( int errorClass, int errorCode ) {
+ String result = "";
+ switch( errorClass ) {
+ case SUCCESS:
+ result += "SUCCESS";
+ break;
+ case ERR_NAM_SRVC:
+ result += "ERR_NAM_SRVC/";
+ switch( errorCode ) {
+ case FMT_ERR:
+ result += "FMT_ERR: Format Error";
+ default:
+ result += "Unknown error code: " + errorCode;
+ }
+ break;
+ case ERR_SSN_SRVC:
+ result += "ERR_SSN_SRVC/";
+ switch( errorCode ) {
+ case CONNECTION_REFUSED:
+ result += "Connection refused";
+ break;
+ case NOT_LISTENING_CALLED:
+ result += "Not listening on called name";
+ break;
+ case NOT_LISTENING_CALLING:
+ result += "Not listening for calling name";
+ break;
+ case CALLED_NOT_PRESENT:
+ result += "Called name not present";
+ break;
+ case NO_RESOURCES:
+ result += "Called name present, but insufficient resources";
+ break;
+ case UNSPECIFIED:
+ result += "Unspecified error";
+ break;
+ default:
+ result += "Unknown error code: " + errorCode;
+ }
+ break;
+ default:
+ result += "unknown error class: " + errorClass;
+ }
+ return result;
+ }
+
+ public NbtException( int errorClass, int errorCode ) {
+ super( getErrorString( errorClass, errorCode ));
+ this.errorClass = errorClass;
+ this.errorCode = errorCode;
+ }
+ public String toString() {
+ return new String( "errorClass=" + errorClass + ",errorCode=" + errorCode + ",errorString=" + getErrorString( errorClass, errorCode ));
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.netbios;
+
+import java.net.Socket;
+import java.net.InetAddress;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+
+/**
+ * This class represents a netbios TCP/IP socket. Under no
+ * conditions will users of jcifs need not be concerned with this class as
+ * netbios services are handled internally to the smb package. It is
+ * only public so the smb package can access it.
+ */
+
+public class NbtSocket extends Socket {
+
+ private static final int SSN_SRVC_PORT = 139;
+ private static final int BUFFER_SIZE = 512;
+
+ NbtAddress address;
+ Name calledName;
+
+ public NbtSocket() {
+ super();
+ }
+ public NbtSocket( NbtAddress address, int port ) throws IOException {
+ this( address, port, null, 0 );
+ }
+ public NbtSocket( NbtAddress address, int port,
+ InetAddress localAddr, int localPort ) throws IOException {
+ this( address, null, port, localAddr, localPort );
+ }
+ public NbtSocket( NbtAddress address, String calledName, int port,
+ InetAddress localAddr, int localPort ) throws IOException {
+ super( address.getInetAddress(), ( port == 0 ? SSN_SRVC_PORT : port ),
+ localAddr, localPort );
+ this.address = address;
+ if( calledName == null ) {
+ this.calledName = address.hostName;
+ } else {
+ this.calledName = new Name( calledName, 0x20, null );
+ }
+ connect();
+ }
+
+ public NbtAddress getNbtAddress() {
+ return address;
+ }
+ InputStream getRawInputStream() throws IOException {
+ return super.getInputStream();
+ }
+ OutputStream getRawOutputStream() throws IOException {
+ return super.getOutputStream();
+ }
+ public InputStream getInputStream() throws IOException {
+ return new SocketInputStream( super.getInputStream() );
+ }
+ public OutputStream getOutputStream() throws IOException {
+ return new SocketOutputStream( super.getOutputStream() );
+ }
+ public int getPort() {
+ return super.getPort();
+ }
+ public InetAddress getLocalAddress() {
+ return super.getLocalAddress();
+ }
+ public int getLocalPort() {
+ return super.getLocalPort();
+ }
+ public String toString() {
+ return "NbtSocket[addr=" + address +
+ ",port=" + super.getPort() +
+ ",localport=" + super.getLocalPort() + "]";
+ }
+ private void connect() throws IOException {
+ byte[] buffer = new byte[BUFFER_SIZE];
+
+ InputStream in = super.getInputStream();
+ OutputStream out = super.getOutputStream();
+
+ address.checkData();
+ SessionServicePacket ssp0 = new SessionRequestPacket( calledName, NbtAddress.getLocalHost().hostName );
+ out.write( buffer, 0, ssp0.writeWireFormat( buffer, 0 ));
+
+ switch( ssp0.readPacketType( in, buffer, 0 )) {
+ case SessionServicePacket.POSITIVE_SESSION_RESPONSE:
+ Log.println( Log.WARNINGS, "session service warning", " session established ok with " + address );
+ return;
+ case SessionServicePacket.NEGATIVE_SESSION_RESPONSE:
+ int errorCode = (int)( in.read() & 0xFF );
+ throw new NbtException( NbtException.ERR_SSN_SRVC, errorCode );
+ case -1:
+ throw new NbtException( NbtException.ERR_SSN_SRVC, NbtException.CONNECTION_REFUSED );
+ default:
+ throw new NbtException( NbtException.ERR_SSN_SRVC, 0 );
+ }
+ }
+ public void close() throws IOException {
+ Log.println( Log.WARNINGS, "netbios socket closed", this );
+ super.close();
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.netbios;
+
+class NodeStatusRequest extends NameServicePacket {
+
+ NodeStatusRequest( Name name ) {
+ questionName = name;
+ questionType = NBSTAT;
+ }
+
+ int writeBodyWireFormat( byte[] dst, int dstIndex ) {
+ int tmp = questionName.type;
+ questionName.type = 0x00; // type has to be 0x00 for node status
+ int result = writeQuestionSectionWireFormat( dst, dstIndex );
+ questionName.type = tmp;
+ return result;
+ }
+ int readBodyWireFormat( byte[] src, int srcIndex ) {
+ return 0;
+ }
+ int writeRDataWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readRDataWireFormat( byte[] src, int srcIndex ) {
+ return 0;
+ }
+ public String toString() {
+ return new String( "NodeStatusRequest[" +
+ super.toString() + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.netbios;
+
+class NodeStatusResponse extends NameServicePacket {
+
+ NbtAddress queryAddress;
+
+ int numberOfNames;
+ NbtAddress[] addressArray;
+ byte[] macAddress;
+ byte[] stats;
+
+ /* It is a little awkward but prudent to pass the quering address
+ * so that it may be included in the list of results. IOW we do
+ * not want to create a new NbtAddress object for this particular
+ * address from which the query is constructed, we want to populate
+ * the data of the existing address that should be one of several
+ * returned by the node status.
+ */
+
+ NodeStatusResponse( NbtAddress queryAddress ) {
+ this.queryAddress = queryAddress;
+ recordName = new Name( null, 0, null );
+ macAddress = new byte[6];
+ }
+
+ int writeBodyWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readBodyWireFormat( byte[] src, int srcIndex ) {
+ return readResourceRecordWireFormat( src, srcIndex );
+ }
+ int writeRDataWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readRDataWireFormat( byte[] src, int srcIndex ) {
+ int start = srcIndex;
+ numberOfNames = src[srcIndex] & 0xFF;
+ int namesLength = numberOfNames * 18;
+ int statsLength = rDataLength - namesLength - 1;
+ numberOfNames = src[srcIndex++] & 0xFF;
+ // gotta read the mac first so we can populate addressArray with it
+ System.arraycopy( src, srcIndex + namesLength, macAddress, 0, 6 );
+ srcIndex += readNodeNameArray( src, srcIndex );
+ stats = new byte[statsLength];
+ System.arraycopy( src, srcIndex, stats, 0, statsLength );
+ srcIndex += statsLength;
+ return srcIndex - start;
+ }
+ private int readNodeNameArray( byte[] src, int srcIndex ) {
+ int start = srcIndex;
+
+ addressArray = new NbtAddress[numberOfNames];
+
+ String n;
+ int type;
+ String scope = queryAddress.hostName.scope;
+ boolean groupName;
+ int ownerNodeType;
+ boolean isBeingDeleted;
+ boolean isInConflict;
+ boolean isActive;
+ boolean isPermanent;
+ int j;
+ boolean addrFound = false;
+ for( int i = 0; i < numberOfNames; srcIndex += 18, i++ ) {
+ for( j = srcIndex + 14; src[j] == 0x20; j-- )
+ ;
+ n = new String( src, srcIndex, j - srcIndex + 1 );
+ type = src[srcIndex + 15] & 0xFF;
+ groupName = (( src[srcIndex + 16] & 0x80 ) == 0x80 ) ? true : false;
+ ownerNodeType = ( src[srcIndex + 16] & 0x60 ) >> 5;
+ isBeingDeleted = (( src[srcIndex + 16] & 0x10 ) == 0x10 ) ? true : false;
+ isInConflict = (( src[srcIndex + 16] & 0x08 ) == 0x08 ) ? true : false;
+ isActive = (( src[srcIndex + 16] & 0x04 ) == 0x04 ) ? true : false;
+ isPermanent = (( src[srcIndex + 16] & 0x02 ) == 0x02 ) ? true : false;
+ if( !addrFound && queryAddress.hostName.type == type &&
+ ( queryAddress.hostName.name == null ||
+ queryAddress.hostName.name.equals( NbtAddress.ALL_HOSTS_NAME ) ||
+ queryAddress.hostName.name.equalsIgnoreCase( n ))) {
+ queryAddress.hostName.name = n;
+ queryAddress.groupName = groupName;
+ queryAddress.nodeType = ownerNodeType;
+ queryAddress.isBeingDeleted = isBeingDeleted;
+ queryAddress.isInConflict = isInConflict;
+ queryAddress.isActive = isActive;
+ queryAddress.isPermanent = isPermanent;
+ queryAddress.macAddress = macAddress;
+ queryAddress.isDataFromNodeStatus = true;
+ addrFound = true;
+ addressArray[i] = queryAddress;
+ } else {
+ addressArray[i] = new NbtAddress( new Name( n, type, scope ),
+ queryAddress.address,
+ groupName,
+ ownerNodeType,
+ isBeingDeleted,
+ isInConflict,
+ isActive,
+ isPermanent,
+ macAddress );
+ }
+ }
+ return srcIndex - start;
+ }
+ public String toString() {
+ return new String( "NodeStatusResponse[" +
+ super.toString() + "]" );
+ }
+}
+
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.netbios;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+class SessionRequestPacket extends SessionServicePacket {
+
+ Name calledName, callingName;
+
+ SessionRequestPacket() {
+ calledName = new Name( null, 0, null );
+ callingName = new Name( null, 0, null );
+ }
+ SessionRequestPacket( Name calledName, Name callingName ) {
+ type = SESSION_REQUEST;
+ this.calledName = calledName;
+ this.callingName = callingName;
+ }
+ int writeTrailerWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+ dstIndex += calledName.writeWireFormat( dst, dstIndex );
+ dstIndex += callingName.writeWireFormat( dst, dstIndex );
+ return dstIndex - start;
+ }
+ int readTrailerWireFormat( InputStream in,
+ byte[] buffer,
+ int bufferIndex )
+ throws IOException {
+ int start = bufferIndex;
+ if( in.read( buffer, bufferIndex, length ) != length ) {
+ throw new IOException( "invalid session request wire format" );
+ }
+ bufferIndex += calledName.readWireFormat( buffer, bufferIndex );
+ bufferIndex += callingName.readWireFormat( buffer, bufferIndex );
+ return bufferIndex - start;
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.netbios;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+class SessionRetargetResponsePacket extends SessionServicePacket {
+
+ NbtAddress retargetAddress;
+ int retargetPort;
+
+ SessionRetargetResponsePacket() {
+ type = SESSION_RETARGET_RESPONSE;
+ length = 6;
+ }
+
+ int writeTrailerWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readTrailerWireFormat( InputStream in,
+ byte[] buffer,
+ int bufferIndex )
+ throws IOException {
+ if( in.read( buffer, bufferIndex, length ) != length ) {
+ throw new IOException( "unexpected EOF reading netbios retarget session response" );
+ }
+ int addr = readInt4( buffer, bufferIndex );
+ bufferIndex += 4;
+ retargetAddress = new NbtAddress( null, addr, false, NbtAddress.B_NODE );
+ retargetPort = readInt2( buffer, bufferIndex );
+ return length;
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.netbios;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+abstract class SessionServicePacket {
+
+ // session service packet types
+ static final int SESSION_MESSAGE = 0x00;
+ static final int SESSION_REQUEST = 0x81;
+ static final int POSITIVE_SESSION_RESPONSE = 0x82;
+ static final int NEGATIVE_SESSION_RESPONSE = 0x83;
+ static final int SESSION_RETARGET_RESPONSE = 0x84;
+ static final int SESSION_KEEP_ALIVE = 0x85;
+
+ static final int MAX_MESSAGE_SIZE = 0x0001FFFF;
+ static final int HEADER_LENGTH = 4;
+
+ static void writeInt2( int val, byte[] dst, int dstIndex ) {
+ dst[dstIndex++] = (byte)(( val >> 8 ) & 0xFF );
+ dst[dstIndex] = (byte)( val & 0xFF );
+ }
+ static void writeInt4( int val, byte[] dst, int dstIndex ) {
+ dst[dstIndex++] = (byte)(( val >> 24 ) & 0xFF );
+ dst[dstIndex++] = (byte)(( val >> 16 ) & 0xFF );
+ dst[dstIndex++] = (byte)(( val >> 8 ) & 0xFF );
+ dst[dstIndex] = (byte)( val & 0xFF );
+ }
+ static int readInt2( byte[] src, int srcIndex ) {
+ return (( src[srcIndex] & 0xFF ) << 8 ) +
+ ( src[srcIndex + 1] & 0xFF );
+ }
+ static int readInt4( byte[] src, int srcIndex ) {
+ return (( src[srcIndex] & 0xFF ) << 24 ) +
+ (( src[srcIndex + 1] & 0xFF ) << 16 ) +
+ (( src[srcIndex + 2] & 0xFF ) << 8 ) +
+ ( src[srcIndex + 3] & 0xFF );
+ }
+ static int readLength( byte[] src, int srcIndex ) {
+ srcIndex++;
+ return (( src[srcIndex++] & 0x01 ) << 16 ) +
+ (( src[srcIndex++] & 0xFF ) << 8 ) +
+ ( src[srcIndex++] & 0xFF );
+ }
+ static int readPacketType( InputStream in,
+ byte[] buffer,
+ int bufferIndex )
+ throws IOException {
+ int n;
+ if(( n = in.read( buffer, bufferIndex, HEADER_LENGTH )) != HEADER_LENGTH ) {
+ if( n == -1 ) {
+ return -1;
+ }
+ throw new IOException( "unexpected EOF reading netbios session header" );
+ }
+ int t = buffer[bufferIndex] & 0xFF;
+ return t;
+ }
+
+ int type, length;
+
+ int writeWireFormat( byte[] dst, int dstIndex ) {
+ length = writeTrailerWireFormat( dst, dstIndex + HEADER_LENGTH );
+ writeHeaderWireFormat( dst, dstIndex );
+ return HEADER_LENGTH + length;
+ }
+ int readWireFormat( InputStream in, byte[] buffer, int bufferIndex ) throws IOException {
+ readHeaderWireFormat( in, buffer, bufferIndex );
+ return HEADER_LENGTH + readTrailerWireFormat( in, buffer, bufferIndex );
+ }
+ int writeHeaderWireFormat( byte[] dst, int dstIndex ) {
+ dst[dstIndex++] = (byte)type;
+ if( length > 0x0000FFFF ) {
+ dst[dstIndex] = (byte)0x01;
+ }
+ dstIndex++;
+ writeInt2( length, dst, dstIndex );
+ return HEADER_LENGTH;
+ }
+ int readHeaderWireFormat( InputStream in,
+ byte[] buffer,
+ int bufferIndex )
+ throws IOException {
+ type = buffer[bufferIndex++] & 0xFF;
+ length = (( buffer[bufferIndex] & 0x01 ) << 16 ) + readInt2( buffer, bufferIndex + 1 );
+ return HEADER_LENGTH;
+ }
+
+ abstract int writeTrailerWireFormat( byte[] dst, int dstIndex );
+ abstract int readTrailerWireFormat( InputStream in,
+ byte[] buffer,
+ int bufferIndex )
+ throws IOException;
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.netbios;
+
+import java.io.InputStream;
+import java.io.IOException;
+
+class SocketInputStream extends InputStream {
+
+ private static final int TMP_BUFFER_SIZE = 256;
+ private InputStream in;
+ private SessionServicePacket ssp;
+ private int tot, bip, n;
+ private byte[] header, tmp;
+
+ SocketInputStream( InputStream in ) {
+ this.in = in;
+ header = new byte[4];
+ tmp = new byte[TMP_BUFFER_SIZE];
+ }
+
+ public synchronized int read() throws IOException {
+ if( read( tmp, 0, 1 ) < 0 ) {
+ return -1;
+ }
+ return tmp[0] & 0xFF;
+ }
+ public synchronized int read( byte[] b ) throws IOException {
+ return read( b, 0, b.length );
+ }
+
+ /* This method will not return until len bytes have been read
+ * or the stream has been closed.
+ */
+
+ public synchronized int read( byte[] b, int off, int len ) throws IOException {
+ if( len == 0 ) {
+ return 0;
+ }
+ tot = 0;
+
+ while( true ) {
+ while( bip > 0 ) {
+ n = in.read( b, off, Math.min( len, bip ));
+ if( n == -1 ) {
+ return tot > 0 ? tot : -1;
+ }
+ tot += n;
+ off += n;
+ len -= n;
+ bip -= n;
+ if( len == 0 ) {
+ return tot;
+ }
+ }
+
+ switch( SessionServicePacket.readPacketType( in, header, 0 )) {
+ case SessionServicePacket.SESSION_KEEP_ALIVE:
+ break;
+ case SessionServicePacket.SESSION_MESSAGE:
+ bip = SessionServicePacket.readLength( header, 0 );
+ break;
+ case -1:
+ if( tot > 0 ) {
+ return tot;
+ }
+ return -1;
+ }
+ }
+ }
+ public synchronized long skip( long numbytes ) throws IOException {
+ if( numbytes <= 0 ) {
+ return 0;
+ }
+ long n = numbytes;
+ while( n > 0 ) {
+ int r = read( tmp, 0, (int)Math.min( (long)TMP_BUFFER_SIZE, n ));
+ if (r < 0) {
+ break;
+ }
+ n -= r;
+ }
+ return numbytes - n;
+ }
+ public int available() throws IOException {
+ if( bip > 0 ) {
+ return bip;
+ }
+ return in.available();
+ }
+ public void close() throws IOException {
+ in.close();
+ }
+}
+
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.netbios;
+
+import java.io.FilterOutputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+import jcifs.util.Log;
+
+class SocketOutputStream extends FilterOutputStream {
+
+ private static int DEFAULT_BUFR_SIZE = 1500;
+
+ private byte[] bufr;
+ private int count, writeSize;
+
+ SocketOutputStream( OutputStream out ) {
+ this( out, DEFAULT_BUFR_SIZE );
+ }
+ SocketOutputStream( OutputStream out, int size ) {
+ super( out );
+ writeSize = jcifs.Config.getInt( "jcifs.netbios.client.writeSize", size );
+ if( writeSize <= 0 ) {
+ throw new IllegalArgumentException( "buffer size <= 0" );
+ } else if( writeSize > SessionServicePacket.MAX_MESSAGE_SIZE ) {
+ throw new IllegalArgumentException( "buffer exceeds max netbios message size" );
+ }
+ writeSize += 4;
+ bufr = new byte[writeSize];
+ bufr[0] = (byte)SessionServicePacket.SESSION_MESSAGE;
+ count = 4;
+ }
+
+ public synchronized void write( int b ) throws IOException {
+ if( count >= bufr.length ) {
+ flush();
+ }
+ bufr[count++] = (byte)b;
+ }
+ public synchronized void write( byte[] b, int off, int len ) throws IOException {
+ if( len >= bufr.length ) {
+ Log.println( Log.WARNINGS, "session service warning",
+ "write len exceeds pre-allocated buffer size; performance " +
+ "will suffer: len=" + len + ",writeSize=" + writeSize );
+ flush();
+ byte[] tmp = bufr;
+ bufr = new byte[len + 4]; /* at least mantain a permainent fixed size buffer */
+ System.arraycopy( b, off, bufr, count, len ); /* doah! */
+ count += len;
+ flush();
+ bufr = tmp;
+ return;
+ }
+ if( len > bufr.length - count ) {
+ flush();
+ }
+ System.arraycopy( b, off, bufr, count, len );
+ count += len;
+ }
+ public synchronized void flush() throws IOException {
+ if( count == 4 ) {
+ return;
+ }
+ int n = count - 4;
+ bufr[1] = (byte)(( n & 0x010000 ) == 0x00 ? 0x00 : 0x01 );
+ bufr[2] = (byte)(( n >> 8 ) & 0xFF );
+ bufr[3] = (byte)( n & 0xFF );
+ out.write( bufr, 0, count );
+ out.flush();
+ count = 4;
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import java.io.InputStream;
+import java.io.IOException;
+
+abstract class AndXServerMessageBlock extends ServerMessageBlock {
+
+ static final int ANDX_COMMAND_OFFSET = 1;
+ static final int ANDX_RESERVED_OFFSET = 2;
+ static final int ANDX_OFFSET_OFFSET = 3;
+
+ ServerMessageBlock andx = null;
+ byte andxCommand = (byte)0xFF;
+ int andxOffset = 0;
+
+ AndXServerMessageBlock() {
+ }
+ AndXServerMessageBlock( ServerMessageBlock andx ) {
+ this.andx = andx;
+ if( andx != null ) {
+ andxCommand = andx.command;
+ }
+ }
+
+ /* The SmbComReadAndXResponse can read from the InputStream
+ * directly by implementing this method. The default
+ * behavior is to arraycopy all bytes into the buffer and call
+ * readBytesWireFormat. The alternative would have been to overload
+ * the readAndXWireFormat method but that would have resulted in
+ * copying a fairly large chunck of code into the subclass.
+ */
+
+ abstract int readBytesDirectWireFormat( InputStream in, int byteCount ) throws IOException;
+
+ int getBatchLimit( byte command ) {
+ /* the default limit is 0 batched messages before this
+ * one, meaning this message cannot be batched.
+ */
+ return 0;
+ }
+
+ /*
+ * We overload this method from ServerMessageBlock because
+ * we want writeAndXWireFormat to write the parameterWords
+ * and bytes. This is so we can write batched smbs because
+ * all but the first smb of the chaain do not have a header
+ * and therefore we do not want to writeHeaderWireFormat. We
+ * just recursivly call writeAndXWireFormat.
+ */
+
+ int writeWireFormat( byte[] dst, int dstIndex ) {
+ int start = headerStart = dstIndex;
+ dstIndex += writeHeaderWireFormat( dst, dstIndex );
+ dstIndex += writeAndXWireFormat( dst, dstIndex );
+ length = dstIndex - start;
+ return length;
+ }
+
+ /*
+ * We overload this because we want readAndXWireFormat to
+ * read the parameter words and bytes. This is so when
+ * commands are batched together we can recursivly call
+ * readAndXWireFormat without reading the non-existent header.
+ */
+
+ int readWireFormat( InputStream in,
+ byte[] buffer,
+ int bufferIndex )
+ throws IOException {
+ int start = bufferIndex;
+
+ if( in.read( buffer, bufferIndex, HEADER_LENGTH ) != HEADER_LENGTH ) {
+ throw new IOException( "unexpected EOF reading smb header" );
+ }
+ bufferIndex += readHeaderWireFormat( buffer, bufferIndex );
+ bufferIndex += readAndXWireFormat( in, buffer, bufferIndex );
+
+ length = bufferIndex - start;
+ return length;
+ }
+ int writeAndXWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+
+ wordCount = writeParameterWordsWireFormat( dst,
+ start + ANDX_OFFSET_OFFSET + 2 );
+ wordCount += 4; // for command, reserved, and offset
+ dstIndex += wordCount + 1;
+ wordCount /= 2;
+ dst[start] = (byte)( wordCount & 0xFF );
+
+ byteCount = writeBytesWireFormat( dst, dstIndex + 2 );
+ dst[dstIndex++] = (byte)( byteCount & 0xFF );
+ dst[dstIndex++] = (byte)(( byteCount >> 8 ) & 0xFF );
+ dstIndex += byteCount;
+
+ /* Normally, without intervention everything would batch
+ * with everything else. If the below clause evaluates true
+ * the andx command will not be written and therefore the
+ * response will not read a batched command and therefore
+ * the 'received' member of the response object will not
+ * be set to true indicating the send and sendTransaction
+ * methods that the next part should be sent. This is a
+ * very indirect and simple batching control mechanism.
+ */
+
+
+ if( andx == null || useBatching == false ||
+ batchLevel >= getBatchLimit( andx.command )) {
+ andxCommand = (byte)0xFF;
+ andx = null;
+
+ dst[start + ANDX_COMMAND_OFFSET] = (byte)0xFF;
+ dst[start + ANDX_RESERVED_OFFSET] = (byte)0x00;
+ dst[start + ANDX_OFFSET_OFFSET] = (byte)0x00;
+ dst[start + ANDX_OFFSET_OFFSET + 1] = (byte)0x00;
+
+ // andx not used; return
+ return dstIndex - start;
+ }
+
+ /* The message provided to batch has a batchLimit that is
+ * higher than the current batchLevel so we will now encode
+ * that chained message. Before doing so we must increment
+ * the batchLevel of the andx message in case it itself is an
+ * andx message and needs to perform the same check as above.
+ */
+
+ andx.batchLevel = batchLevel + 1;
+
+
+ dst[start + ANDX_COMMAND_OFFSET] = andxCommand;
+ dst[start + ANDX_RESERVED_OFFSET] = (byte)0x00;
+ andxOffset = dstIndex - headerStart;
+ writeInt2( andxOffset, dst, start + ANDX_OFFSET_OFFSET );
+
+ andx.useUnicode = useUnicode;
+ if( andx instanceof AndXServerMessageBlock ) {
+
+ /*
+ * A word about communicating header info to andx smbs
+ *
+ * This is where we recursively invoke the provided andx smb
+ * object to write it's parameter words and bytes to our outgoing
+ * array. Incedentally when these andx smbs are created they are not
+ * necessarily populated with header data because they're not writing
+ * the header, only their body. But for whatever reason one might wish
+ * to populate fields if the writeXxx operation needs this header data
+ * for whatever reason. I copy over the uid here so it appears correct
+ * in logging output. Logging of andx segments of messages inadvertantly
+ * print header information because of the way toString always makes a
+ * super.toString() call(see toString() at the end of all smbs classes).
+ */
+
+ andx.uid = uid;
+ dstIndex += ((AndXServerMessageBlock)andx).writeAndXWireFormat( dst, dstIndex );
+ } else {
+ // the andx smb is not of type andx so lets just write it here and
+ // were done.
+ int andxStart = dstIndex;
+ andx.wordCount = andx.writeParameterWordsWireFormat( dst, dstIndex );
+ dstIndex += andx.wordCount + 1;
+ andx.wordCount /= 2;
+ dst[andxStart] = (byte)( andx.wordCount & 0xFF );
+
+ andx.byteCount = andx.writeBytesWireFormat( dst, dstIndex + 2 );
+ dst[dstIndex++] = (byte)( andx.byteCount & 0xFF );
+ dst[dstIndex++] = (byte)(( andx.byteCount >> 8 ) & 0xFF );
+ dstIndex += andx.byteCount;
+ }
+
+ return dstIndex - start;
+ }
+ int readAndXWireFormat( InputStream in,
+ byte[] buffer,
+ int bufferIndex )
+ throws IOException {
+ int start = bufferIndex;
+
+ /*
+ * read wordCount
+ */
+
+ if(( wordCount = in.read() ) == -1 ) {
+ throw new IOException( "unexpected EOF reading smb wordCount" );
+ }
+ buffer[bufferIndex++] = (byte)( wordCount & 0xFF );
+
+ /*
+ * read parameterWords
+ */
+
+ if( wordCount != 0 ) {
+ if( in.read( buffer, bufferIndex, wordCount * 2 ) != ( wordCount * 2 )) {
+ throw new IOException( "unexpected EOF reading andx parameter words" );
+ }
+
+ /*
+ * these fields are common to all andx commands
+ * so let's populate them here
+ */
+
+ andxCommand = buffer[bufferIndex];
+ bufferIndex += 2;
+ andxOffset = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+
+ /*
+ * no point in calling readParameterWordsWireFormat if there are no more
+ * parameter words. besides, win98 doesn't return "OptionalSupport" field
+ */
+
+ if( wordCount > 2 ) {
+ bufferIndex += readParameterWordsWireFormat( buffer, bufferIndex );
+ }
+ }
+
+ /*
+ * read byteCount
+ */
+
+ if( in.read( buffer, bufferIndex, 2 ) != 2 ) {
+ throw new IOException( "unexpected EOF reading smb byteCount" );
+ }
+ byteCount = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+
+ /*
+ * read bytes
+ */
+
+ if( byteCount != 0 ) {
+ int n;
+ n = readBytesDirectWireFormat( in, byteCount );
+ if( n == 0 ) {
+ if( in.read( buffer, bufferIndex, byteCount ) != byteCount ) {
+ throw new IOException( "unexpected EOF reading andx bytes" );
+ }
+ n = readBytesWireFormat( buffer, bufferIndex );
+ }
+ if( n != byteCount ) {
+ Log.println( Log.WARNINGS, "smb andx packet format warning", "byteCount=" +
+ byteCount + " but readBytesWireFormat returned " + n );
+ }
+ bufferIndex += byteCount;
+ }
+
+ /*
+ * if there is an andx and it itself is an andx then just recur by
+ * calling this method for it. otherwise just read it's parameter words
+ * and bytes as usual. Note how we can't just call andx.readWireFormat
+ * because there's no header.
+ */
+
+
+ if( errorCode > 0 || andxCommand == (byte)0xFF ) {
+ andxCommand = (byte)0xFF;
+ andx = null;
+ } else if( andx == null ) {
+ andxCommand = (byte)0xFF;
+ throw new IOException( "no andx command supplied with response" );
+ } else {
+
+ /*
+ * This is where we take into account andxOffset
+ *
+ * Before we call readAndXWireFormat on the next andx
+ * part we must take into account the andxOffset. The
+ * input stream must be positioned at this location. The
+ * new location is the just read andxOffset(say 68)
+ * minus the current bufferIndex(say 65). But this packet
+ * construction/deconstruction technique does not require that
+ * the bufferIndex begin at 0. The header might be at another
+ * location(say 4). So we must subtract the current buffer
+ * index from the real start of the header and substract that
+ * from the andxOffset(like 68 - ( 65 - 0 ) if headerStart
+ * were 0 or 68 - ( 69 - 4 ) if the headerStart were 4. We
+ * also need to communicate to our newly instantiated andx
+ * smb the headerStart value so that it may perform the same
+ * calculation as this is a recursive process.
+ */
+
+ bufferIndex += in.read( buffer, bufferIndex,
+ andxOffset - ( bufferIndex - headerStart ));
+
+ andx.headerStart = headerStart;
+ andx.command = andxCommand;
+ andx.errorCode = errorCode;
+ andx.flags = flags;
+ andx.flags2 = flags2;
+ andx.tid = tid;
+ andx.pid = pid;
+ andx.uid = uid;
+ andx.mid = mid;
+ andx.useUnicode = useUnicode;
+
+ if( andx instanceof AndXServerMessageBlock ) {
+ bufferIndex += ((AndXServerMessageBlock)andx).readAndXWireFormat(
+ in, buffer, andxOffset - headerStart );
+ } else {
+
+ /*
+ * Just a plain smb. Read it as normal.
+ */
+
+ /*
+ * read wordCount
+ */
+
+ if(( andx.wordCount = in.read() ) == -1 ) {
+ throw new IOException( "unexpected EOF reading smb wordCount" );
+ }
+ buffer[bufferIndex++] = (byte)( andx.wordCount & 0xFF );
+
+ /*
+ * read parameterWords
+ */
+
+ if( andx.wordCount != 0 ) {
+ if( in.read( buffer, bufferIndex, andx.wordCount * 2 ) !=
+ ( andx.wordCount * 2 )) {
+ throw new IOException( "unexpected EOF reading andx parameter words" );
+ }
+
+ /*
+ * no point in calling readParameterWordsWireFormat if there are no more
+ * parameter words. besides, win98 doesn't return "OptionalSupport" field
+ */
+
+ if( andx.wordCount > 2 ) {
+ bufferIndex +=
+ andx.readParameterWordsWireFormat( buffer, bufferIndex );
+ }
+ }
+
+ /*
+ * read byteCount
+ */
+
+ if( in.read( buffer, bufferIndex, 2 ) != 2 ) {
+ throw new IOException( "unexpected EOF reading smb byteCount" );
+ }
+ andx.byteCount = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+
+ /*
+ * read bytes
+ */
+
+ if( andx.byteCount != 0 ) {
+ if( in.read( buffer, bufferIndex, andx.byteCount ) != andx.byteCount ) {
+ throw new IOException( "unexpected EOF reading andx bytes" );
+ }
+ int n;
+ if(( n = andx.readBytesWireFormat( buffer, bufferIndex )) != andx.byteCount ) {
+ Log.println( Log.WARNINGS, "smb andx packet format warning",
+ "byteCount=" + andx.byteCount +
+ " but readBytesWireFormat returned " + n );
+ }
+ bufferIndex += andx.byteCount;
+ }
+ }
+ andx.received = true;
+ }
+
+
+ return bufferIndex - start;
+ }
+ public String toString() {
+ return new String( super.toString() +
+ ",andxCommand=0x" + Log.getHexString( andxCommand, 2 ) +
+ ",andxOffset=" + andxOffset );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+import java.io.IOException;
+
+public class Handler extends URLStreamHandler {
+
+ SmbURL url;
+
+ public URLConnection openConnection( URL u ) throws IOException {
+ return new SmbURLConnection( u, url );
+ }
+ protected void parseURL( URL u, String spec, int start, int limit ) {
+ try {
+ url = new SmbURL( spec, null, start, limit );
+ } catch( IOException ioe ) {
+ Log.printStackTrace( "smb URLStreamHandler exception", ioe );
+ }
+ setURL( u, "smb", url.server, url.port, url.canonicalPath, null );
+ }
+ protected String toExternalForm( URL u ) {
+ return url.toString();
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+interface Info {
+ int getAttributes();
+ long getLastWriteTime();
+ long getSize();
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+/**
+ * Provides logging methods specific to the smb package. Log class
+ * members are applied to the Log's mask(set as an arithmetic expression
+ * from {@link jcifs.util.Log#setMask(int mask)}) to "flip on" logging of
+ * smb specific information.
+ * <p><blockquote><pre>
+ * Log.setMask( Log.EXCEPTIONS |
+ * jcifs.smb.Log.MESSAGE_DATA );
+ * </pre></blockquote>
+ * <p>
+ * See the {@link jcifs.util.Log} parent class for details about this
+ * logging style.
+ *
+ * @see jcifs.util.Log
+ * @since jcifs-0.1
+ */
+
+public class Log extends jcifs.util.Log {
+
+ // supress javadoc constructor summary
+ Log() {}
+
+ public static final int MESSAGE_DATA = 0x00000100;
+ public static final int TEST1 = 0x00000200;
+ public static final int RESERVED2 = 0x00000400;
+ public static final int RESERVED3 = 0x00000800;
+
+ static void printMessageData( String desc, ServerMessageBlock smb ) {
+ if(( mask & MESSAGE_DATA ) == 0 ) {
+ return;
+ }
+ try {
+ out.println( desc, smb.toString() + NL );
+ } catch( Exception e ) {
+ Log.printStackTrace( "jcifs.smb.Log.printMessageData()", e );
+ }
+ }
+}
+
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+class NetServerEnum2 extends SmbComTransaction {
+
+ static final int SV_TYPE_ALL = 0xFFFFFFFF;
+ static final int SV_TYPE_DOMAIN_ENUM = 0x80000000;
+
+ static final byte[] descripters = new String(
+ "WrLehDz" + '\0' + "B16BBDz" + '\0' ).getBytes();
+
+ String domain;
+ int serverTypes;
+
+ NetServerEnum2( String domain, int serverTypes ) {
+ this.domain = domain;
+ this.serverTypes = serverTypes;
+ command = SMB_COM_TRANSACTION;
+ name = "\\PIPE\\LANMAN";
+
+ maxParameterCount = 8;
+ maxSetupCount = (byte)0x00;
+ setupCount = 0;
+ timeout = 5000;
+ }
+
+ int writeSetupWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeParametersWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+
+ writeInt2( NET_SERVER_ENUM2, dst, dstIndex );
+ dstIndex += 2;
+ System.arraycopy( descripters, 0, dst, dstIndex, descripters.length );
+ dstIndex += descripters.length;
+ writeInt2( 0x0001, dst, dstIndex );
+ dstIndex += 2;
+ writeInt2( maxDataCount, dst, dstIndex );
+ dstIndex += 2;
+ writeInt4( serverTypes, dst, dstIndex );
+ dstIndex += 4;
+ dstIndex += writeString( domain.toUpperCase(), dst, dstIndex, false );
+
+ return dstIndex - start;
+ }
+ int writeDataWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ public String toString() {
+ return new String( "NetServerEnum2[" + super.toString() + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import jcifs.util.Log;
+import java.io.InputStream;
+import java.io.IOException;
+
+class NetServerEnum2Response extends SmbComTransactionResponse {
+
+ // transaction response status
+ static final int NERR_Success = 0;
+ static final int ERROR_MORE_DATA = 234;
+ static final int NERR_ServerNotStarted = 2114;
+ static final int NERR_BasicTransactConfig = 2141;
+
+ class ServerInfo1 {
+ String name;
+ int versionMajor;
+ int versionMinor;
+ int type;
+ String commentOrMasterBrowser;
+
+ public String toString() {
+ return new String( "ServerInfo1[" +
+ "name=" + name +
+ ",versionMajor=" + versionMajor +
+ ",versionMinor=" + versionMinor +
+ ",type=0x" + Log.getHexString( type, 8 ) +
+ ",commentOrMasterBrowser=" + commentOrMasterBrowser + "]" );
+ }
+ }
+
+ ServerInfo1[] results;
+ int status, converter, entriesReturned, totalAvailableEntries;
+
+ NetServerEnum2Response() {
+ }
+
+ int writeSetupWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeParametersWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeDataWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ int start = bufferIndex;
+
+ status = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ converter = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ entriesReturned = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ totalAvailableEntries = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+
+ return bufferIndex - start;
+ }
+ int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ int start = bufferIndex;
+
+ results = new ServerInfo1[entriesReturned];
+ for( int i = 0; i < entriesReturned; i++ ) {
+ results[i] = new ServerInfo1();
+ results[i].name = new String( buffer, bufferIndex,
+ readStringLength( buffer, bufferIndex, 16 ));
+ bufferIndex += 16;
+ results[i].versionMajor = (int)( buffer[bufferIndex++] & 0xFF );
+ results[i].versionMinor = (int)( buffer[bufferIndex++] & 0xFF );
+ results[i].type = readInt4( buffer, bufferIndex );
+ bufferIndex += 4;
+ int off = readInt4( buffer, bufferIndex );
+ bufferIndex += 4;
+ off = ( off & 0xFFFF ) - converter;
+ off = start + off;
+ results[i].commentOrMasterBrowser = new String( buffer, off,
+ readStringLength( buffer, off, 48 ));
+Log.println( Log.DEBUGGING, "net server enum response entry", results[i] );
+ }
+
+ return bufferIndex - start;
+ }
+ public String toString() {
+ return new String( "NetServerEnum2Response[" +
+ super.toString() +
+ ",status=" + status +
+ ",converter=" + converter +
+ ",entriesReturned=" + entriesReturned +
+ ",totalAvailableEntries=" + totalAvailableEntries + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+class NetShareEnum extends SmbComTransaction {
+
+ static final byte[] descripters = new String(
+ "WrLeh" + '\0' + "B13BWz" + '\0' ).getBytes();
+
+ NetShareEnum() {
+ command = SMB_COM_TRANSACTION;
+ name = new String( "\\PIPE\\LANMAN" );
+ maxParameterCount = 8;
+
+ maxDataCount = 4096;
+ maxSetupCount = (byte)0x00;
+ setupCount = 0;
+ timeout = 5000;
+ }
+
+ int writeSetupWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeParametersWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+
+ writeInt2( NET_SHARE_ENUM, dst, dstIndex );
+ dstIndex += 2;
+ System.arraycopy( descripters, 0, dst, dstIndex, descripters.length );
+ dstIndex += descripters.length;
+ writeInt2( 0x0001, dst, dstIndex );
+ dstIndex += 2;
+ writeInt2( maxDataCount, dst, dstIndex );
+ dstIndex += 2;
+
+ return dstIndex - start;
+ }
+ int writeDataWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ public String toString() {
+ return new String( "NetShareEnum[" + super.toString() + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import jcifs.util.Log;
+import java.io.InputStream;
+import java.io.IOException;
+
+class NetShareEnumResponse extends SmbComTransactionResponse {
+
+ // transaction response status
+ static final int NERR_Success = 0;
+ static final int ERROR_ACCESS_DENIED = 5;
+ static final int ERROR_NETWORK_ACCESS_DENIED = 65;
+ static final int ERROR_MORE_DATA = 234;
+ static final int NERR_ServerNotStarted = 2114;
+ static final int NERR_BasicTransactConfig = 2141;
+
+ class ShareInfo1 {
+ String netName;
+ int type;
+ String remark;
+
+ public String toString() {
+ return new String( "ShareInfo1[" +
+ "netName=" + netName +
+ ",type=0x" + Log.getHexString( type, 4 ) +
+ ",remark=" + remark + "]" );
+ }
+ }
+
+ ShareInfo1[] results;
+ int status, converter, entriesReturned, totalAvailableEntries;
+
+ NetShareEnumResponse() {
+ }
+
+ int writeSetupWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeParametersWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeDataWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ int start = bufferIndex;
+
+ status = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ converter = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ entriesReturned = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ totalAvailableEntries = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+
+ return bufferIndex - start;
+ }
+ int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ int start = bufferIndex;
+
+ useUnicode = false;
+
+ results = new ShareInfo1[entriesReturned];
+ for( int i = 0; i < entriesReturned; i++ ) {
+ results[i] = new ShareInfo1();
+ results[i].netName = new String( buffer, bufferIndex,
+ readStringLength( buffer, bufferIndex, 13 ));
+ bufferIndex += 14;
+ results[i].type = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ int off = readInt4( buffer, bufferIndex );
+ bufferIndex += 4;
+ off = ( off & 0xFFFF ) - converter;
+ off = start + off;
+ results[i].remark = new String( buffer, off,
+ readStringLength( buffer, off, 48 ));
+Log.println( Log.DEBUGGING, "smb warning", results[i] );
+ }
+
+ return bufferIndex - start;
+ }
+ public String toString() {
+ return new String( "NetShareEnumResponse[" +
+ super.toString() +
+ ",status=" + status +
+ ",converter=" + converter +
+ ",entriesReturned=" + entriesReturned +
+ ",totalAvailableEntries=" + totalAvailableEntries + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import jcifs.Config;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.TimeZone;
+import java.util.Calendar;
+import java.util.Date;
+
+abstract class ServerMessageBlock {
+
+ static final int FLAGS_NONE = 0x00;
+ static final int FLAGS_LOCK_AND_READ_WRITE_AND_UNLOCK = 0x01;
+ static final int FLAGS_RECEIVE_BUFFER_POSTED = 0x02;
+ static final int FLAGS_PATH_NAMES_CASELESS = 0x08;
+ static final int FLAGS_PATH_NAMES_CANONICALIZED = 0x10;
+ static final int FLAGS_OPLOCK_REQUESTED_OR_GRANTED = 0x20;
+ static final int FLAGS_NOTIFY_OF_MODIFY_ACTION = 0x40;
+ static final int FLAGS_RESPONSE = 0x80;
+
+ static final int FLAGS2_NONE = 0x0000;
+ static final int FLAGS2_LONG_FILENAMES = 0x0001;
+ static final int FLAGS2_EXTENDED_ATTRIBUTES = 0x0002;
+ static final int FLAGS2_SECURITY_SIGNATURES = 0x0004;
+ static final int FLAGS2_EXTENDED_SECURITY_NEGOTIATION = 0x0800;
+ static final int FLAGS2_RESOLVE_PATHS_IN_DFS = 0x1000;
+ static final int FLAGS2_PERMIT_READ_IF_EXECUTE_PERM = 0x2000;
+ static final int FLAGS2_STATUS32 = 0x4000;
+ static final int FLAGS2_UNICODE = 0x8000;
+
+ static final int CAP_NONE = 0x0000;
+ static final int CAP_RAW_MODE = 0x0001;
+ static final int CAP_MPX_MODE = 0x0002;
+ static final int CAP_UNICODE = 0x0004;
+ static final int CAP_LARGE_FILES = 0x0008;
+ static final int CAP_NT_SMBS = 0x0010;
+ static final int CAP_RPC_REMOTE_APIS = 0x0020;
+ static final int CAP_STATUS32 = 0x0040;
+ static final int CAP_LEVEL_II_OPLOCKS = 0x0080;
+ static final int CAP_LOCK_AND_READ = 0x0100;
+ static final int CAP_NT_FIND = 0x0200;
+ static final int CAP_DFS = 0x1000;
+
+ // file attribute encoding
+ static final int ATTR_READONLY = 0x01;
+ static final int ATTR_HIDDEN = 0x02;
+ static final int ATTR_SYSTEM = 0x04;
+ static final int ATTR_VOLUME = 0x08;
+ static final int ATTR_DIRECTORY = 0x10;
+ static final int ATTR_ARCHIVE = 0x20;
+
+ // extended file attribute encoding(others same as above)
+ static final int ATTR_COMPRESSED = 0x800;
+ static final int ATTR_NORMAL = 0x080;
+ static final int ATTR_TEMPORARY = 0x100;
+
+ // flags for move and copy
+ static final int FLAGS_TARGET_MUST_BE_FILE = 0x0001;
+ static final int FLAGS_TARGET_MUST_BE_DIRECTORY = 0x0002;
+ static final int FLAGS_COPY_TARGET_MODE_ASCII = 0x0004;
+ static final int FLAGS_COPY_SOURCE_MODE_ASCII = 0x0008;
+ static final int FLAGS_VERIFY_ALL_WRITES = 0x0010;
+ static final int FLAGS_TREE_COPY = 0x0020;
+
+ // open function
+ static final int OPEN_FUNCTION_FAIL_IF_EXISTS = 0x0000;
+ static final int OPEN_FUNCTION_OVERWRITE_IF_EXISTS = 0x0020;
+
+ static final int PID = (int)( Math.random() * 65536d );
+
+ static final int SECURITY_SHARE = 0x00;
+ static final int SECURITY_USER = 0x01;
+
+ static final int CMD_OFFSET = 4;
+ static final int ERROR_CODE_OFFSET = 5;
+ static final int FLAGS_OFFSET = 9;
+ static final int TID_OFFSET = 24;
+ static final int HEADER_LENGTH = 32;
+
+ static final long MILLISECONDS_BETWEEN_1970_AND_1601 = 11644473600000L;
+ static final TimeZone TZ = TimeZone.getDefault();
+
+ static boolean useBatching = Config.getBoolean( "jcifs.smb.client.useBatching", true );
+
+ static final byte[] header = {
+ (byte)0xFF, (byte)'S', (byte)'M', (byte)'B',
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00
+ };
+
+ static void writeInt2( long val, byte[] dst, int dstIndex ) {
+ dst[dstIndex++] = (byte)((int)(val >>> 0) & 0xFF);
+ dst[dstIndex++] = (byte)((int)(val >>> 8) & 0xFF);
+ }
+ static void writeInt4( long val, byte[] dst, int dstIndex ) {
+ dst[dstIndex++] = (byte)((int)(val >>> 0) & 0xFF);
+ dst[dstIndex++] = (byte)((int)(val >>> 8) & 0xFF);
+ dst[dstIndex++] = (byte)((int)(val >>> 16) & 0xFF);
+ dst[dstIndex++] = (byte)((int)(val >>> 24) & 0xFF);
+ }
+ static int readInt2( byte[] src, int srcIndex ) {
+ return ( src[srcIndex] & 0xFF ) +
+ (( src[srcIndex + 1] & 0xFF ) << 8 );
+ }
+ static int readInt4( byte[] src, int srcIndex ) {
+ return ( src[srcIndex] & 0xFF ) +
+ (( src[srcIndex + 1] & 0xFF ) << 8 ) +
+ (( src[srcIndex + 2] & 0xFF ) << 16 ) +
+ (( src[srcIndex + 3] & 0xFF ) << 24 );
+ }
+ static long readLong( byte[] src, int srcIndex ) {
+ return (readInt4( src, srcIndex ) & 0xFFFFFFFFL) +
+ ((long)(readInt4( src, srcIndex + 4 )) << 32);
+ }
+ static void writeLong( long val, byte[] dst, int dstIndex ) {
+ dst[dstIndex++] = (byte)((int)(val >>> 0) & 0xFF);
+ dst[dstIndex++] = (byte)((int)(val >>> 8) & 0xFF);
+ dst[dstIndex++] = (byte)((int)(val >>> 16) & 0xFF);
+ dst[dstIndex++] = (byte)((int)(val >>> 24) & 0xFF);
+ dst[dstIndex++] = (byte)((int)(val >>> 32) & 0xFF);
+ dst[dstIndex++] = (byte)((int)(val >>> 40) & 0xFF);
+ dst[dstIndex++] = (byte)((int)(val >>> 48) & 0xFF);
+ dst[dstIndex++] = (byte)((int)(val >>> 56) & 0xFF);
+ }
+ static long readTime( byte[] src, int srcIndex ) {
+ int low = readInt4( src, srcIndex );
+ int hi = readInt4( src, srcIndex + 4 );
+ long t = ((long)hi << 32 ) | ( (long)low & 0xFFFFFFFFL );
+ t = ( t / 10000L - MILLISECONDS_BETWEEN_1970_AND_1601 );
+
+ synchronized( TZ ) {
+ if( TZ.inDaylightTime( new Date() )) {
+ // in dst
+ if( TZ.inDaylightTime( new Date( t ))) {
+ // t also in dst so no correction
+ return t;
+ }
+ // t not in dst so add 1 hour
+ return t + 3600000;
+ } else {
+ // not in dst
+ if( TZ.inDaylightTime( new Date( t ))) {
+ // t is in dst so subtract 1 hour
+ return t - 3600000;
+ }
+ // t isn't in dst either
+ return t;
+ }
+ }
+ }
+ static long readUTime( byte[] buffer, int bufferIndex ) {
+ return readInt4( buffer, bufferIndex ) * 1000L;
+ }
+
+
+ /*
+ * These are all the smbs supported by this library. This includes requests
+ * and well as their responses for each type however the actuall implementations
+ * of the readXxxWireFormat and writeXxxWireFormat methods may not be in
+ * place. For example at the time of this writing the readXxxWireFormat
+ * for requests and the writeXxxWireFormat for responses are not implemented
+ * and simply return 0. These would need to be completed for a server
+ * implementation.
+ */
+
+ static final byte SMB_COM_CREATE_DIRECTORY = (byte)0x00;
+ static final byte SMB_COM_DELETE_DIRECTORY = (byte)0x01;
+ static final byte SMB_COM_CLOSE = (byte)0x04;
+ static final byte SMB_COM_DELETE = (byte)0x06;
+ static final byte SMB_COM_RENAME = (byte)0x07;
+ static final byte SMB_COM_QUERY_INFORMATION = (byte)0x08;
+ static final byte SMB_COM_CHECK_DIRECTORY = (byte)0x10;
+ static final byte SMB_COM_TRANSACTION = (byte)0x25;
+ static final byte SMB_COM_TRANSACTION_SECONDARY = (byte)0x26;
+ static final byte SMB_COM_COPY = (byte)0x29;
+ static final byte SMB_COM_MOVE = (byte)0x2A;
+ static final byte SMB_COM_ECHO = (byte)0x2B;
+ static final byte SMB_COM_OPEN_ANDX = (byte)0x2D;
+ static final byte SMB_COM_READ_ANDX = (byte)0x2E;
+ static final byte SMB_COM_WRITE_ANDX = (byte)0x2F;
+ static final byte SMB_COM_TRANSACTION2 = (byte)0x32;
+ static final byte SMB_COM_FIND_CLOSE2 = (byte)0x34;
+ static final byte SMB_COM_TREE_DISCONNECT = (byte)0x71;
+ static final byte SMB_COM_NEGOTIATE = (byte)0x72;
+ static final byte SMB_COM_SESSION_SETUP_ANDX = (byte)0x73;
+ static final byte SMB_COM_LOGOFF_ANDX = (byte)0x74;
+ static final byte SMB_COM_TREE_CONNECT_ANDX = (byte)0x75;
+ static final byte SMB_COM_NT_CREATE_ANDX = (byte)0xA2;
+
+ /*
+ * Some fields specify the offset from the beginning of the header. This
+ * field should be used for calculating that. This would likely be zero
+ * but an implemantation that encorporates the transport header(for
+ * efficiency) might use a different initial bufferIndex. For example,
+ * to eliminate copying data when writing NbtSession data one might
+ * manage that 4 byte header specifically and therefore the initial
+ * bufferIndex, and thus headerStart, would be 4).(NOTE: If one where
+ * looking for a way to improve perfomance this is precisly what you
+ * would want to do as the jcifs.netbios.SocketXxxputStream classes
+ * arraycopy all data read or written into a new buffer shifted over 4!)
+ */
+
+ byte command, flags;
+ int headerStart,
+ length,
+ batchLevel,
+ errorCode,
+ flags2,
+ tid, pid, uid, mid,
+ wordCount, byteCount;
+ boolean useUnicode, received;
+ long responseTimeout = 1;
+
+ ServerMessageBlock() {
+ flags = (byte)( FLAGS_PATH_NAMES_CASELESS | FLAGS_PATH_NAMES_CANONICALIZED );
+ pid = PID;
+ batchLevel = 0;
+ }
+
+ int writeString( String str, byte[] dst, int dstIndex ) {
+ return writeString( str, dst, dstIndex, useUnicode );
+ }
+ int writeString( String str, byte[] dst, int dstIndex, boolean useUnicode ) {
+ int start = dstIndex;
+
+ if( useUnicode ) {
+ try {
+ // Unicode requires word alignment
+ if((( dstIndex - headerStart ) % 2 ) != 0 ) {
+ dst[dstIndex++] = (byte)'\0';
+ }
+ System.arraycopy( str.getBytes( "UnicodeLittleUnmarked" ), 0,
+ dst, dstIndex, str.length() * 2 );
+ dstIndex += str.length() * 2;
+ } catch( UnsupportedEncodingException uee ) {
+ Log.printStackTrace( "smb exception", uee );
+ }
+ dst[dstIndex++] = (byte)'\0';
+ dst[dstIndex++] = (byte)'\0';
+ } else {
+ System.arraycopy( str.getBytes(), 0, dst, dstIndex, str.length() );
+ dstIndex += str.length();
+ dst[dstIndex++] = (byte)'\0';
+ }
+
+ return dstIndex - start;
+ }
+ String readString( byte[] src, int srcIndex ) {
+ int len = 0;
+ String str = null;
+ if( useUnicode ) {
+ // Unicode requires word alignment
+ if((( srcIndex - headerStart ) % 2 ) != 0 ) {
+ srcIndex++;
+ }
+ while( src[srcIndex + len] != (byte)0x00 ||
+ src[srcIndex + len + 1] != (byte)0x00 ) {
+ len += 2;
+ if( len > 256 ) {
+ throw new RuntimeException( "zero termination not found" );
+ }
+ }
+ try {
+ str = new String( src, srcIndex, len, "UnicodeLittle" );
+ } catch( UnsupportedEncodingException uee ) {
+ Log.printStackTrace( "smb exception", uee );
+ }
+ } else {
+ while( src[srcIndex + len] != (byte)0x00 ) {
+ len++;
+ if( len > 256 ) {
+ throw new RuntimeException( "zero termination not found" );
+ }
+ }
+ str = new String( src, srcIndex, len );
+ }
+ return str;
+ }
+ int stringWireLength( String str, int offset ) {
+ int len = str.length() + 1;
+ if( useUnicode ) {
+ len = str.length() * 2 + 2;
+ len = ( offset % 2 ) != 0 ? len + 1 : len;
+ }
+ return len;
+ }
+ int readStringLength( byte[] src, int srcIndex, int max ) {
+ int len = 0;
+ while( src[srcIndex + len] != (byte)0x00 ) {
+ if( len++ > max ) {
+ throw new RuntimeException( "zero termination not found" );
+ }
+ }
+ return len;
+ }
+ int writeWireFormat( byte[] dst, int dstIndex ) {
+ int start = headerStart = dstIndex;
+
+ dstIndex += writeHeaderWireFormat( dst, dstIndex );
+ wordCount = writeParameterWordsWireFormat( dst, dstIndex + 1 );
+ dst[dstIndex++] = (byte)(( wordCount / 2 ) & 0xFF );
+ dstIndex += wordCount;
+ wordCount /= 2;
+ byteCount = writeBytesWireFormat( dst, dstIndex + 2 );
+ dst[dstIndex++] = (byte)( byteCount & 0xFF );
+ dst[dstIndex++] = (byte)(( byteCount >> 8 ) & 0xFF );
+ dstIndex += byteCount;
+
+ length = dstIndex - start;
+ return length;
+ }
+ int readWireFormat( InputStream in,
+ byte[] buffer,
+ int bufferIndex )
+ throws IOException {
+
+ int start = headerStart = bufferIndex;
+
+ /*
+ * read header
+ */
+
+ if( in.read( buffer, bufferIndex, HEADER_LENGTH ) != HEADER_LENGTH ) {
+ throw new IOException( "unexpected EOF reading smb header" );
+ }
+ bufferIndex += readHeaderWireFormat( buffer, bufferIndex );
+
+ /*
+ * read wordCount
+ */
+
+ if(( wordCount = in.read() ) == -1 ) {
+ throw new IOException( "unexpected EOF reading smb wordCount" );
+ }
+ buffer[bufferIndex++] = (byte)( wordCount & 0xFF );
+
+ /*
+ * read parameter words
+ */
+
+ if( wordCount != 0 ) {
+ if( in.read( buffer, bufferIndex, wordCount * 2 ) != wordCount * 2 ) {
+ throw new IOException( "unexpected EOF reading smb parameter words" );
+ }
+ int n;
+ if(( n = readParameterWordsWireFormat( buffer, bufferIndex )) != wordCount * 2 ) {
+ Log.println( Log.WARNINGS, "smb packet format warning", "wordCount * 2=" +
+ ( wordCount * 2 ) +
+ " but readParameterWordsWireFormat returned " + n );
+ }
+ bufferIndex += wordCount * 2;
+ }
+
+ /*
+ * read byteCount
+ */
+
+ if( in.read( buffer, bufferIndex, 2 ) != 2 ) {
+ throw new IOException( "unexpected EOF reading smb byteCount" );
+ }
+ byteCount = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+
+ /*
+ * read bytes
+ */
+
+ if( byteCount != 0 ) {
+ if( in.read( buffer, bufferIndex, byteCount ) != byteCount ) {
+ throw new IOException( "unexpected EOF reading smb" );
+ }
+ int n;
+ if(( n = readBytesWireFormat( buffer, bufferIndex )) != byteCount ) {
+ Log.println( Log.WARNINGS, "smb packet format warning", "byteCount=" +
+ byteCount + " but readBytesWireFormat returned " + n );
+ }
+ // Don't think we can rely on n being correct here. Must use byteCount.
+ // Last paragraph of section 3.13.3 eludes to this.
+
+ bufferIndex += byteCount;
+ }
+
+ length = bufferIndex - start;
+ return length;
+ }
+ int writeHeaderWireFormat( byte[] dst, int dstIndex ) {
+ System.arraycopy( header, 0, dst, dstIndex, header.length );
+ dst[dstIndex + CMD_OFFSET] = command;
+ dst[dstIndex + FLAGS_OFFSET] = flags;
+ writeInt2( flags2, dst, dstIndex + FLAGS_OFFSET + 1 );
+ dstIndex += TID_OFFSET;
+ writeInt2( tid, dst, dstIndex );
+ writeInt2( pid, dst, dstIndex + 2 );
+ writeInt2( uid, dst, dstIndex + 4 );
+ writeInt2( mid, dst, dstIndex + 6 );
+ return HEADER_LENGTH;
+ }
+ int readHeaderWireFormat( byte[] buffer, int bufferIndex ) throws IOException {
+ command = buffer[bufferIndex + CMD_OFFSET];
+ errorCode = readInt4( buffer, bufferIndex + ERROR_CODE_OFFSET );
+ flags = buffer[bufferIndex + FLAGS_OFFSET];
+ flags2 = readInt2( buffer, bufferIndex + FLAGS_OFFSET + 1 );
+ tid = readInt2( buffer, bufferIndex + TID_OFFSET );
+ pid = readInt2( buffer, bufferIndex + TID_OFFSET + 2 );
+ uid = readInt2( buffer, bufferIndex + TID_OFFSET + 4 );
+ mid = readInt2( buffer, bufferIndex + TID_OFFSET + 6 );
+ return HEADER_LENGTH;
+ }
+ boolean isResponse() {
+ return ( flags & FLAGS_RESPONSE ) == FLAGS_RESPONSE;
+ }
+
+ /*
+ * For this packet deconstruction technique to work for
+ * other networking protocols the InputStream may need
+ * to be passed to the readXxxWireFormat methods. This is
+ * actually purer. However, in the case of smb we know the
+ * wordCount and byteCount. And since every subclass of
+ * ServerMessageBlock would have to perform the same read
+ * operation on the input stream, we might as will pull that
+ * common functionality into the superclass and read wordCount
+ * and byteCount worth of data.
+ *
+ * We will still use the readXxxWireFormat return values to
+ * indicate how many bytes(note: readParameterWordsWireFormat
+ * returns bytes read and not the number of words(but the
+ * wordCount member DOES store the number of words)) we
+ * actually read. Incedentally this is important to the
+ * AndXServerMessageBlock class that needs to potentially
+ * read in another smb's parameter words and bytes based on
+ * information in it's andxCommand, andxOffset, ...etc.
+ */
+
+ abstract int writeParameterWordsWireFormat( byte[] dst, int dstIndex );
+ abstract int writeBytesWireFormat( byte[] dst, int dstIndex );
+ abstract int readParameterWordsWireFormat( byte[] buffer,
+ int bufferIndex )
+ throws IOException;
+ abstract int readBytesWireFormat( byte[] buffer,
+ int bufferIndex )
+ throws IOException;
+
+ public String toString() {
+ String c;
+ switch( command ) {
+ case SMB_COM_NEGOTIATE:
+ c = "SMB_COM_NEGOTIATE";
+ break;
+ case SMB_COM_SESSION_SETUP_ANDX:
+ c = "SMB_COM_SESSION_SETUP_ANDX";
+ break;
+ case SMB_COM_TREE_CONNECT_ANDX:
+ c = "SMB_COM_TREE_CONNECT_ANDX";
+ break;
+ case SMB_COM_QUERY_INFORMATION:
+ c = "SMB_COM_QUERY_INFORMATION";
+ break;
+ case SMB_COM_CHECK_DIRECTORY:
+ c = "SMB_COM_CHECK_DIRECTORY";
+ break;
+ case SMB_COM_TRANSACTION:
+ c = "SMB_COM_TRANSACTION";
+ break;
+ case SMB_COM_TRANSACTION2:
+ c = "SMB_COM_TRANSACTION2";
+ break;
+ case SMB_COM_TRANSACTION_SECONDARY:
+ c = "SMB_COM_TRANSACTION_SECONDARY";
+ break;
+ case SMB_COM_FIND_CLOSE2:
+ c = "SMB_COM_FIND_CLOSE2";
+ break;
+ case SMB_COM_TREE_DISCONNECT:
+ c = "SMB_COM_TREE_DISCONNECT";
+ break;
+ case SMB_COM_LOGOFF_ANDX:
+ c = "SMB_COM_LOGOFF_ANDX";
+ break;
+ case SMB_COM_ECHO:
+ c = "SMB_COM_ECHO";
+ break;
+ case SMB_COM_MOVE:
+ c = "SMB_COM_MOVE";
+ break;
+ case SMB_COM_RENAME:
+ c = "SMB_COM_RENAME";
+ break;
+ case SMB_COM_COPY:
+ c = "SMB_COM_COPY";
+ break;
+ case SMB_COM_DELETE:
+ c = "SMB_COM_DELETE";
+ break;
+ case SMB_COM_DELETE_DIRECTORY:
+ c = "SMB_COM_DELETE_DIRECTORY";
+ break;
+ case SMB_COM_NT_CREATE_ANDX:
+ c = "SMB_COM_NT_CREATE_ANDX";
+ break;
+ case SMB_COM_OPEN_ANDX:
+ c = "SMB_COM_OPEN_ANDX";
+ break;
+ case SMB_COM_READ_ANDX:
+ c = "SMB_COM_READ_ANDX";
+ break;
+ case SMB_COM_CLOSE:
+ c = "SMB_COM_CLOSE";
+ break;
+ case SMB_COM_WRITE_ANDX:
+ c = "SMB_COM_WRITE_ANDX";
+ break;
+ case SMB_COM_CREATE_DIRECTORY:
+ c = "SMB_COM_CREATE_DIRECTORY";
+ break;
+ default:
+ c = "UNKNOWN";
+ }
+ return new String(
+ "command=" + c +
+ ",received=" + received +
+ ",errorCode=" + SmbException.getErrorString( errorCode ) +
+ ",flags=0x" + Log.getHexString( flags & 0xFF, 4 ) +
+ ",flags2=0x" + Log.getHexString( flags2, 4 ) +
+ ",tid=" + tid +
+ ",pid=" + pid +
+ ",uid=" + uid +
+ ",mid=" + mid +
+ ",wordCount=" + wordCount +
+ ",byteCount=" + byteCount );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+class SmbComBlankResponse extends ServerMessageBlock {
+
+ SmbComBlankResponse() {
+ }
+
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ public String toString() {
+ return new String( "SmbComBlankResponse[" +
+ super.toString() + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+class SmbComCheckDirectory extends ServerMessageBlock {
+
+ String directoryPath;
+
+ SmbComCheckDirectory( String directoryPath ) {
+ command = SMB_COM_CHECK_DIRECTORY;
+ this.directoryPath = directoryPath;
+ }
+
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+
+ dst[dstIndex++] = (byte)0x04;
+ dstIndex += writeString( directoryPath, dst, dstIndex );
+
+ return dstIndex - start;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ public String toString() {
+ return new String( "SmbComCheckDirectory[" +
+ super.toString() +
+ ",directoryPath=" + directoryPath + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import java.util.Date;
+
+class SmbComClose extends ServerMessageBlock {
+
+ int fid, lastWriteTime;
+
+ SmbComClose( int fid ) {
+ this.fid = fid;
+ command = SMB_COM_CLOSE;
+ }
+
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ writeInt2( fid, dst, dstIndex );
+ dstIndex += 2;
+ lastWriteTime = 0xFFFFFFFF;
+ writeInt4( lastWriteTime, dst, dstIndex );
+ return 6;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ public String toString() {
+ return new String( "SmbComClose[" +
+ super.toString() +
+ ",fid=" + fid +
+ ",lastWriteTime=" + ( new Date( lastWriteTime )) + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+class SmbComCopy extends ServerMessageBlock {
+
+ String sourceFileName;
+ String targetFileName;
+ int tid2;
+ int openFunction;
+ int flags;
+
+ SmbComCopy( String sourceFileName, String targetFileName, int tid2 ) {
+ this.sourceFileName = sourceFileName;
+ this.targetFileName = targetFileName;
+ this.tid2 = tid2 > 0 ? tid2 : -1;
+ command = SMB_COM_COPY;
+ openFunction = OPEN_FUNCTION_FAIL_IF_EXISTS;
+ flags = FLAGS_TARGET_MUST_BE_FILE;
+ }
+
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ writeInt2( tid2, dst, dstIndex );
+ dstIndex += 2;
+ writeInt2( openFunction, dst, dstIndex );
+ dstIndex += 2;
+ writeInt2( flags, dst, dstIndex );
+ return 6;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+
+ dst[dstIndex++] = (byte)0x04;
+ dstIndex += writeString( sourceFileName, dst, dstIndex );
+ dst[dstIndex++] = (byte)0x04;
+ dstIndex += writeString( targetFileName, dst, dstIndex );
+
+ return dstIndex - start;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ public String toString() {
+ return new String( "SmbComCopy[" +
+ super.toString() +
+ ",sourceFileName=" + sourceFileName +
+ ",targetFileName=" + targetFileName + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+class SmbComCopyResponse extends ServerMessageBlock {
+
+ int count;
+ String errorFileName;
+
+ SmbComCopyResponse() {
+ count = 0;
+ errorFileName = "";
+ }
+
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ count = readInt2( buffer, bufferIndex );
+ return 2;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ bufferIndex++;
+ errorFileName = readString( buffer, bufferIndex );
+ return stringWireLength( errorFileName, bufferIndex );
+ }
+ public String toString() {
+ return new String( "SmbComCopyResponse[" +
+ super.toString() +
+ ",count=" + count +
+ ",errorFileName=" + errorFileName + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+class SmbComCreateDirectory extends ServerMessageBlock {
+
+ String directoryName;
+
+ SmbComCreateDirectory( String directoryName ) {
+ this.directoryName = directoryName;
+ command = SMB_COM_CREATE_DIRECTORY;
+ }
+
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+
+ dst[dstIndex++] = (byte)0x04;
+ dstIndex += writeString( directoryName, dst, dstIndex );
+
+ return dstIndex - start;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ public String toString() {
+ return new String( "SmbComCreateDirectory[" +
+ super.toString() +
+ ",directoryName=" + directoryName + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+class SmbComDelete extends ServerMessageBlock {
+
+ int searchAttributes;
+ String fileName;
+
+ SmbComDelete( String fileName ) {
+ this.fileName = fileName;
+ command = SMB_COM_DELETE;
+ searchAttributes = ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY;
+ }
+
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ writeInt2( searchAttributes, dst, dstIndex );
+ return 2;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+
+ dst[dstIndex++] = (byte)0x04;
+ dstIndex += writeString( fileName, dst, dstIndex );
+
+ return dstIndex - start;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ public String toString() {
+ return new String( "SmbComDelete[" +
+ super.toString() +
+ ",searchAttributes=0x" + Log.getHexString( searchAttributes, 4 ) +
+ ",fileName=" + fileName + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+class SmbComDeleteDirectory extends ServerMessageBlock {
+
+ String directoryName;
+
+ SmbComDeleteDirectory( String directoryName ) {
+ this.directoryName = directoryName;
+ command = SMB_COM_DELETE_DIRECTORY;
+ }
+
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+
+ dst[dstIndex++] = (byte)0x04;
+ dstIndex += writeString( directoryName, dst, dstIndex );
+
+ return dstIndex - start;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ public String toString() {
+ return new String( "SmbComDeleteDirectory[" +
+ super.toString() +
+ ",directoryName=" + directoryName + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+class SmbComEcho extends ServerMessageBlock {
+
+ int echoCount;
+
+ SmbComEcho( int echoCount ) {
+ command = SMB_COM_ECHO;
+ this.echoCount = echoCount;
+ }
+
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ writeInt2( echoCount, dst, dstIndex );
+ return 2;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ dst[dstIndex] = (byte)'M';
+ return 1;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ public String toString() {
+ return new String( "SmbComEcho[" +
+ super.toString() +
+ ",echoCount=" + echoCount + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+class SmbComEchoResponse extends ServerMessageBlock {
+
+ int sequenceNumber;
+
+ SmbComEchoResponse() {
+ }
+
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ sequenceNumber = readInt2( buffer, bufferIndex );
+ return 2;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 1;
+ }
+ public String toString() {
+ return new String( "SmbComEchoResponse[" +
+ super.toString() + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+class SmbComFindClose2 extends ServerMessageBlock {
+
+ int sid;
+
+ SmbComFindClose2( int sid ) {
+ this.sid = sid;
+ command = SMB_COM_FIND_CLOSE2;
+ }
+
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ writeInt2( sid, dst, dstIndex );
+ return 2;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ public String toString() {
+ return new String( "SmbComFindClose2[" +
+ super.toString() +
+ ",sid=" + sid + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+class SmbComLogoffAndX extends AndXServerMessageBlock {
+
+ SmbComLogoffAndX( ServerMessageBlock andx ) {
+ super( andx );
+ command = SMB_COM_LOGOFF_ANDX;
+ }
+
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesDirectWireFormat( InputStream in, int byteCount ) throws IOException {
+ return 0;
+ }
+ public String toString() {
+ return new String( "SmbComLogoffAndX[" +
+ super.toString() + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+class SmbComMove extends ServerMessageBlock {
+
+ String oldFileName;
+ String newFileName;
+ int tid2;
+ int openFunction;
+ int flags;
+
+ SmbComMove( String oldFileName, String newFileName, int tid2 ) {
+ command = SMB_COM_MOVE;
+ this.oldFileName = oldFileName;
+ this.newFileName = newFileName;
+ this.tid2 = tid2 == 0 ? -1 : tid2;
+
+ // these will need to be adjusted
+ openFunction = OPEN_FUNCTION_FAIL_IF_EXISTS;
+ flags = FLAGS_TARGET_MUST_BE_FILE;
+ }
+
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ writeInt2( tid2, dst, dstIndex );
+ dstIndex += 2;
+ writeInt2( openFunction, dst, dstIndex );
+ dstIndex += 2;
+ writeInt2( flags, dst, dstIndex );
+ return 6;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+
+ dst[dstIndex++] = (byte)0x04;
+ dstIndex += writeString( oldFileName, dst, dstIndex );
+ dst[dstIndex++] = (byte)0x04;
+ dstIndex += writeString( newFileName, dst, dstIndex );
+
+ return dstIndex - start;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ public String toString() {
+ return new String( "SmbComMove[" +
+ super.toString() +
+ ",oldFileName=" + oldFileName +
+ ",newFileName=" + newFileName +
+ ",tid2=" + tid2 +
+ ",openFunction=" + openFunction +
+ ",flags=" + flags + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+class SmbComMoveResponse extends ServerMessageBlock {
+
+ int count;
+ String errorFileName;
+
+ SmbComMoveResponse() {
+ count = 0;
+ errorFileName = "";
+ }
+
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ count = readInt2( buffer, bufferIndex );
+ return 2;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ bufferIndex++;
+ errorFileName = readString( buffer, bufferIndex );
+ return stringWireLength( errorFileName, bufferIndex );
+ }
+ public String toString() {
+ return new String( "SmbComMoveResponse[" +
+ super.toString() +
+ ",count=" + count +
+ ",errorFileName=" + errorFileName + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+class SmbComNTCreateAndX extends AndXServerMessageBlock {
+
+ // access mask encoding
+ static final int FILE_READ_DATA = 0x00000001; // 1
+ static final int FILE_WRITE_DATA = 0x00000002; // 2
+ static final int FILE_APPEND_DATA = 0x00000004; // 3
+ static final int FILE_READ_EA = 0x00000008; // 4
+ static final int FILE_WRITE_EA = 0x00000010; // 5
+ static final int FILE_EXECUTE = 0x00000020; // 6
+ static final int FILE_DELETE = 0x00000040; // 7
+ static final int FILE_READ_ATTRIBUTES = 0x00000080; // 8
+ static final int FILE_WRITE_ATTRIBUTES = 0x00000100; // 9
+ static final int DELETE = 0x00010000; // 16
+ static final int READ_CONTROL = 0x00020000; // 17
+ static final int WRITE_DAC = 0x00040000; // 18
+ static final int WRITE_OWNER = 0x00080000; // 19
+ static final int SYNCHRONIZE = 0x00100000; // 20
+ static final int GENERIC_ALL = 0x10000000; // 28
+ static final int GENERIC_EXECUTE = 0x20000000; // 29
+ static final int GENERIC_WRITE = 0x40000000; // 30
+ static final int GENERIC_READ = 0x80000000; // 31
+
+ // share access
+ static final int FILE_NO_SHARE = 0x00;
+ static final int FILE_SHARE_READ = 0x01;
+ static final int FILE_SHARE_WRITE = 0x02;
+ static final int FILE_SHARE_DELETE = 0x04;
+
+ // create disposition
+
+ /* Creates a new file or supersedes the existing one
+ */
+
+ static final int FILE_SUPERSEDE = 0x0;
+
+ /* Open the file or fail if it does not exist
+ * aka OPEN_EXISTING
+ */
+
+ static final int FILE_OPEN = 0x1;
+
+ /* Create the file or fail if it does not exist
+ * aka CREATE_NEW
+ */
+
+ static final int FILE_CREATE = 0x2;
+
+ /* Open the file or create it if it does not exist
+ * aka OPEN_ALWAYS
+ */
+
+ static final int FILE_OPEN_IF = 0x3;
+
+ /* Open the file and overwrite it's contents or fail if it does not exist
+ * aka TRUNCATE_EXISTING
+ */
+
+ static final int FILE_OVERWRITE = 0x4;
+
+ /* Open the file and overwrite it's contents or create it if it does not exist
+ * aka CREATE_ALWAYS (according to the wire when calling CreateFile)
+ */
+
+ static final int FILE_OVERWRITE_IF = 0x5;
+
+
+ // create options
+ static final int FILE_WRITE_THROUGH = 0x00000002;
+ static final int FILE_SEQUENTIAL_ONLY = 0x00000004;
+ static final int FILE_SYNCHRONOUS_IO_ALERT = 0x00000010;
+ static final int FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020;
+
+ // security flags
+ static final int SECURITY_CONTEXT_TRACKING = 0x01;
+ static final int SECURITY_EFFECTIVE_ONLY = 0x02;
+
+ String name;
+ int flags,
+ rootDirectoryFid,
+ desiredAccess,
+ extFileAttributes,
+ shareAccess,
+ createDisposition,
+ createOptions,
+ impersonationLevel;
+ long allocationSize;
+ byte securityFlags;
+
+ SmbComNTCreateAndX( String name, int flags, ServerMessageBlock andx ) {
+ super( andx );
+ this.name = name;
+ command = SMB_COM_NT_CREATE_ANDX;
+
+ // desiredAccess
+ desiredAccess = ( flags >>> 16 ) & 0xFFFF;
+ desiredAccess |= FILE_READ_EA | FILE_READ_ATTRIBUTES;
+
+ // extFileAttributes
+ extFileAttributes = ATTR_NORMAL;
+
+ // shareAccess
+ shareAccess = FILE_SHARE_READ;
+
+ // createDisposition
+ if(( flags & SmbFile.O_TRUNC ) == SmbFile.O_TRUNC ) {
+ // truncate the file
+ if(( flags & SmbFile.O_CREAT ) == SmbFile.O_CREAT ) {
+ // create it if necessary
+ createDisposition = FILE_OVERWRITE_IF;
+ } else {
+ createDisposition = FILE_OVERWRITE;
+ }
+ } else {
+ // don't truncate the file
+ if(( flags & SmbFile.O_CREAT ) == SmbFile.O_CREAT ) {
+ // create it if necessary
+ if ((flags & SmbFile.O_EXCL ) == SmbFile.O_EXCL ) {
+ // fail if already exists
+ createDisposition = FILE_CREATE;
+ } else {
+ createDisposition = FILE_OPEN_IF;
+ }
+ } else {
+ createDisposition = FILE_OPEN;
+ }
+ }
+
+ createOptions = 0x0040; // see netmon
+ impersonationLevel = 0x02; // As seen on NT :~)
+ securityFlags = (byte)0x03; // SECURITY_CONTEXT_TRACKING | SECURITY_EFFECTIVE_ONLY
+ }
+
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+
+ dst[dstIndex++] = (byte)0x00;
+ // name length without counting null termination
+ writeInt2( ( useUnicode ? name.length() * 2 : name.length() ), dst, dstIndex );
+ dstIndex += 2;
+ writeInt4( flags, dst, dstIndex );
+ dstIndex += 4;
+ writeInt4( rootDirectoryFid, dst, dstIndex );
+ dstIndex += 4;
+ writeInt4( desiredAccess, dst, dstIndex );
+ dstIndex += 4;
+ writeLong( allocationSize, dst, dstIndex );
+ dstIndex += 8;
+ writeInt4( extFileAttributes, dst, dstIndex );
+ dstIndex += 4;
+ writeInt4( shareAccess, dst, dstIndex );
+ dstIndex += 4;
+ writeInt4( createDisposition, dst, dstIndex );
+ dstIndex += 4;
+ writeInt4( createOptions, dst, dstIndex );
+ dstIndex += 4;
+ writeInt4( impersonationLevel, dst, dstIndex );
+ dstIndex += 4;
+ dst[dstIndex++] = securityFlags;
+
+ return dstIndex - start;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ return writeString( name, dst, dstIndex );
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesDirectWireFormat( InputStream in, int byteCount ) throws IOException {
+ return 0;
+ }
+ public String toString() {
+ return new String( "SmbComNTCreateAndX[" +
+ super.toString() +
+ ",flags=0x" + Log.getHexString( flags, 2 ) +
+ ",rootDirectoryFid=" + rootDirectoryFid +
+ ",desiredAccess=0x" + Log.getHexString( desiredAccess, 4 ) +
+ ",allocationSize=" + allocationSize +
+ ",extFileAttributes=0x" + Log.getHexString( extFileAttributes, 4 ) +
+ ",shareAccess=0x" + Log.getHexString( shareAccess, 4 ) +
+ ",createDisposition=0x" + Log.getHexString( createDisposition, 4 ) +
+ ",createOptions=0x" + Log.getHexString( createOptions, 8 ) +
+ ",impersonationLevel=0x" + Log.getHexString( impersonationLevel, 4 ) +
+ ",securityFlags=0x" + Log.getHexString( securityFlags, 2 ) +
+ ",name=" + name + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import java.util.Date;
+import java.io.IOException;
+import java.io.InputStream;
+
+class SmbComNTCreateAndXResponse extends AndXServerMessageBlock {
+
+ static final int EXCLUSIVE_OPLOCK_GRANTED = 1;
+ static final int BATCH_OPLOCK_GRANTED = 2;
+ static final int LEVEL_II_OPLOCK_GRANTED = 3;
+
+ byte oplockLevel;
+ int fid,
+ createAction,
+ extFileAttributes,
+ fileType,
+ deviceState;
+ long creationTime,
+ lastAccessTime,
+ lastWriteTime,
+ changeTime,
+ allocationSize,
+ endOfFile;
+ boolean directory;
+
+ SmbComNTCreateAndXResponse() {
+ }
+
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ int start = bufferIndex;
+
+ oplockLevel = buffer[bufferIndex++];
+ fid = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ createAction = readInt4( buffer, bufferIndex );
+ bufferIndex += 4;
+ creationTime = readTime( buffer, bufferIndex );
+ bufferIndex += 8;
+ lastAccessTime = readTime( buffer, bufferIndex );
+ bufferIndex += 8;
+ lastWriteTime = readTime( buffer, bufferIndex );
+ bufferIndex += 8;
+ changeTime = readTime( buffer, bufferIndex );
+ bufferIndex += 8;
+ allocationSize = readLong( buffer, bufferIndex );
+ bufferIndex += 8;
+ endOfFile = readLong( buffer, bufferIndex );
+ bufferIndex += 8;
+ fileType = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ deviceState = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ directory = ( buffer[bufferIndex++] & 0xFF ) > 0;
+
+ return bufferIndex - start;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesDirectWireFormat( InputStream in, int byteCount ) throws IOException {
+ return 0;
+ }
+ public String toString() {
+ return new String( "SmbComNTCreateAndXResponse[" +
+ super.toString() +
+ ",oplockLevel=" + oplockLevel +
+ ",fid=" + fid +
+ ",createAction=0x" + Log.getHexString( createAction, 4 ) +
+ ",creationTime=" + new Date( creationTime ) +
+ ",lastAccessTime=" + new Date( lastAccessTime ) +
+ ",lastWriteTime=" + new Date( lastWriteTime ) +
+ ",changeTime=" + new Date( changeTime ) +
+ ",extFileAttributes=0x" + Log.getHexString( extFileAttributes, 4 ) +
+ ",allocationSize=" + allocationSize +
+ ",endOfFile=" + endOfFile +
+ ",fileType=" + fileType +
+ ",deviceState=" + deviceState +
+ ",directory=" + directory + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+class SmbComNegotiate extends ServerMessageBlock {
+
+ static final byte[] dialects = new String(
+ '\2' + "NT LM 0.12" + '\0' ).getBytes();
+
+ SmbComNegotiate() {
+ command = SMB_COM_NEGOTIATE;
+ }
+
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ System.arraycopy( dialects, 0, dst, dstIndex, dialects.length );
+ return dialects.length;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ public String toString() {
+ return new String( "SmbComNegotiate[" +
+ super.toString() +
+ ",wordCount=" + wordCount +
+ ",byteCount=" + dialects.length +
+ ",dialects=NT LM 0.12]" );
+ }
+}
+
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import java.util.Date;
+import java.io.UnsupportedEncodingException;
+
+class SmbComNegotiateResponse extends ServerMessageBlock {
+
+ int dialectIndex,
+ securityMode,
+ security,
+ maxMpxCount,
+ maxNumberVcs,
+ maxBufferSize,
+ maxRawSize,
+ sessionKey,
+ capabilities,
+ serverTimeZone,
+ encryptionKeyLength;
+ boolean encryptedPasswords,
+ signaturesEnabled,
+ signaturesRequired;
+ long serverTime;
+ byte[] encryptionKey;
+ String oemDomainName;
+
+ SmbComNegotiateResponse() {
+ }
+
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readParameterWordsWireFormat( byte[] buffer,
+ int bufferIndex ) {
+ int start = bufferIndex;
+ dialectIndex = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ if( dialectIndex > 10 ) {
+ return bufferIndex - start;
+ }
+ securityMode = buffer[bufferIndex++] & 0xFF;
+ security = securityMode & 0x01;
+ encryptedPasswords = ( securityMode & 0x02 ) == 0x02 ? true : false;
+ signaturesEnabled = ( securityMode & 0x04 ) == 0x04 ? true : false;
+ signaturesRequired = ( securityMode & 0x08 ) == 0x08 ? true : false;
+ maxMpxCount = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ maxNumberVcs = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ maxBufferSize = readInt4( buffer, bufferIndex );
+ bufferIndex += 4;
+ maxRawSize = readInt4( buffer, bufferIndex );
+ bufferIndex += 4;
+ sessionKey = readInt4( buffer, bufferIndex );
+ bufferIndex += 4;
+ capabilities = readInt4( buffer, bufferIndex );
+ bufferIndex += 4;
+ serverTime = readTime( buffer, bufferIndex );
+ bufferIndex += 8;
+ serverTimeZone = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ encryptionKeyLength = buffer[bufferIndex++] & 0xFF;
+ return bufferIndex - start;
+ }
+ int readBytesWireFormat( byte[] buffer,
+ int bufferIndex ) {
+ int start = bufferIndex;
+ encryptionKey = new byte[encryptionKeyLength];
+ System.arraycopy( buffer, bufferIndex,
+ encryptionKey, 0, encryptionKeyLength );
+ bufferIndex += encryptionKeyLength;
+
+ int len = 0;
+ if(( flags2 & FLAGS2_UNICODE ) == FLAGS2_UNICODE ) {
+ while( buffer[bufferIndex + len] != (byte)0x00 ||
+ buffer[bufferIndex + len + 1] != (byte)0x00 ) {
+ len += 2;
+ if( len > 256 ) {
+ throw new RuntimeException( "zero termination not found" );
+ }
+ }
+ try {
+ oemDomainName = new String( buffer, bufferIndex, len, "UnicodeLittle" );
+ } catch( UnsupportedEncodingException uee ) {
+ Log.printStackTrace( "smb exception", uee );
+ }
+ } else {
+ while( buffer[bufferIndex + len] != (byte)0x00 ) {
+ len++;
+ if( len > 256 ) {
+ throw new RuntimeException( "zero termination not found" );
+ }
+ }
+ oemDomainName = new String( buffer, bufferIndex, len );
+ }
+ bufferIndex += len;
+
+ return bufferIndex - start;
+ }
+ public String toString() {
+ return new String( "SmbComNegotiateResponse[" +
+ super.toString() +
+ ",wordCount=" + wordCount +
+ ",dialectIndex=" + dialectIndex +
+ ",securityMode=0x" + Log.getHexString( securityMode, 1 ) +
+ ",security=" + ( security == SECURITY_SHARE ? "share" : "user" ) +
+ ",encryptedPasswords=" + encryptedPasswords +
+ ",maxMpxCount=" + maxMpxCount +
+ ",maxNumberVcs=" + maxNumberVcs +
+ ",maxBufferSize=" + maxBufferSize +
+ ",maxRawSize=" + maxRawSize +
+ ",sessionKey=0x" + jcifs.util.Log.getHexString( sessionKey, 8 ) +
+ ",capabilities=0x" + jcifs.util.Log.getHexString( capabilities, 8 ) +
+ ",serverTime=" + new Date( serverTime ) +
+ ",serverTimeZone=" + serverTimeZone +
+ ",encryptionKeyLength=" + encryptionKeyLength +
+ ",byteCount=" + byteCount +
+ ",encryptionKey=0x" + Log.getHexString( encryptionKey,
+ 0,
+ encryptionKeyLength * 2 ) +
+ ",oemDomainName=" + oemDomainName + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import jcifs.Config;
+import java.util.Date;
+import java.io.IOException;
+import java.io.InputStream;
+
+class SmbComOpenAndX extends AndXServerMessageBlock {
+
+ // flags (not the same as flags constructor argument)
+ static final int FLAGS_RETURN_ADDITIONAL_INFO = 0x01;
+ static final int FLAGS_REQUEST_OPLOCK = 0x02;
+ static final int FLAGS_REQUEST_BATCH_OPLOCK = 0x04;
+
+ // Access Mode Encoding for desiredAccess
+ static final int SHARING_COMPATIBILITY = 0x00;
+ static final int SHARING_DENY_READ_WRITE_EXECUTE = 0x10;
+ static final int SHARING_DENY_WRITE = 0x20;
+ static final int SHARING_DENY_READ_EXECUTE = 0x30;
+ static final int SHARING_DENY_NONE = 0x40;
+
+ static final int DO_NOT_CACHE = 0x1000; // bit 12
+ static final int WRITE_THROUGH = 0x4000; // bit 14
+
+ static final int OPEN_FN_CREATE = 0x10;
+ static final int OPEN_FN_FAIL_IF_EXISTS = 0x00;
+ static final int OPEN_FN_OPEN = 0x01;
+ static final int OPEN_FN_TRUNC = 0x02;
+
+ static final int BATCH_LIMIT = Config.getInt( "jcifs.smb.client.OpenAndX.ReadAndX", 1 );
+
+ int flags,
+ desiredAccess,
+ searchAttributes,
+ fileAttributes,
+ creationTime,
+ openFunction,
+ allocationSize;
+ String fileName;
+
+ // flags is NOT the same as flags member
+
+ SmbComOpenAndX( String fileName, int flags, ServerMessageBlock andx ) {
+ super( andx );
+ this.fileName = fileName;
+ command = SMB_COM_OPEN_ANDX;
+
+ // flags
+//why!! flags = 0;
+
+ // desiredAccess
+ desiredAccess = ( flags >>> 16 ) & 0x3;
+ if( desiredAccess == 0x3 ) {
+ desiredAccess = 0x4;
+ }
+ desiredAccess |= SHARING_DENY_NONE;
+ desiredAccess &= ~0x1; // Win98 doesn't like GENERIC_READ ?! -- get Access Denied.
+
+ // searchAttributes
+ searchAttributes = ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM;
+
+ // fileAttributes
+ fileAttributes = 0;
+
+ // openFunction
+ if(( flags & SmbFile.O_TRUNC ) == SmbFile.O_TRUNC ) {
+ // truncate the file
+ if(( flags & SmbFile.O_CREAT ) == SmbFile.O_CREAT ) {
+ // create it if necessary
+ openFunction = OPEN_FN_TRUNC | OPEN_FN_CREATE;
+ } else {
+ openFunction = OPEN_FN_TRUNC;
+ }
+ } else {
+ // don't truncate the file
+ if(( flags & SmbFile.O_CREAT ) == SmbFile.O_CREAT ) {
+ // create it if necessary
+ if(( flags & SmbFile.O_EXCL ) == SmbFile.O_EXCL ) {
+ // fail if already exists
+ openFunction = OPEN_FN_CREATE | OPEN_FN_FAIL_IF_EXISTS;
+ } else {
+ openFunction = OPEN_FN_CREATE | OPEN_FN_OPEN;
+ }
+ } else {
+ openFunction = OPEN_FN_OPEN;
+ }
+ }
+ }
+
+ int getBatchLimit( byte command ) {
+ return command == SMB_COM_READ_ANDX ? BATCH_LIMIT : 0;
+ }
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+
+ writeInt2( flags, dst, dstIndex );
+ dstIndex += 2;
+ writeInt2( desiredAccess, dst, dstIndex );
+ dstIndex += 2;
+ writeInt2( searchAttributes, dst, dstIndex );
+ dstIndex += 2;
+ writeInt2( fileAttributes, dst, dstIndex );
+ dstIndex += 2;
+ creationTime = 0;
+ writeInt4( creationTime, dst, dstIndex );
+ dstIndex += 4;
+ writeInt2( openFunction, dst, dstIndex );
+ dstIndex += 2;
+ writeInt4( allocationSize, dst, dstIndex );
+ dstIndex += 4;
+ for( int i = 0; i < 8; i++ ) {
+ dst[dstIndex++] = 0x00;
+ }
+
+ return dstIndex - start;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+
+ if( useUnicode ) {
+ dst[dstIndex++] = (byte)'\0';
+ }
+ dstIndex += writeString( fileName, dst, dstIndex );
+
+ return dstIndex - start;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesDirectWireFormat( InputStream in, int byteCount ) throws IOException {
+ return 0;
+ }
+ public String toString() {
+ return new String( "SmbComOpenAndX[" +
+ super.toString() +
+ ",flags=0x" + Log.getHexString( flags, 2 ) +
+ ",desiredAccess=0x" + Log.getHexString( desiredAccess, 4 ) +
+ ",searchAttributes=0x" + Log.getHexString( searchAttributes, 4 ) +
+ ",fileAttributes=0x" + Log.getHexString( fileAttributes, 4 ) +
+ ",creationTime=" + new Date( creationTime ) +
+ ",openFunction=0x" + Log.getHexString( openFunction, 2 ) +
+ ",allocationSize=" + allocationSize +
+ ",fileName=" + fileName + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+class SmbComOpenAndXResponse extends AndXServerMessageBlock {
+
+ int fid,
+ fileAttributes,
+ dataSize,
+ grantedAccess,
+ fileType,
+ deviceState,
+ action,
+ serverFid;
+ long lastWriteTime;
+
+ SmbComOpenAndXResponse() {
+ }
+
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ int start = bufferIndex;
+
+ fid = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ fileAttributes = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ lastWriteTime = readUTime( buffer, bufferIndex );
+ bufferIndex += 4;
+ dataSize = readInt4( buffer, bufferIndex );
+ bufferIndex += 4;
+ grantedAccess = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ fileType = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ deviceState = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ action = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ serverFid = readInt4( buffer, bufferIndex );
+ bufferIndex += 6;
+
+ return bufferIndex - start;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesDirectWireFormat( InputStream in, int byteCount ) throws IOException {
+ return 0;
+ }
+ public String toString() {
+ return new String( "SmbComOpenAndXResponse[" +
+ super.toString() +
+ ",fid=" + fid +
+ ",fileAttributes=" + fileAttributes +
+ ",lastWriteTime=" + lastWriteTime +
+ ",dataSize=" + dataSize +
+ ",grantedAccess=" + grantedAccess +
+ ",fileType=" + fileType +
+ ",deviceState=" + deviceState +
+ ",action=" + action +
+ ",serverFid=" + serverFid + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+class SmbComQueryInformation extends ServerMessageBlock {
+
+ String filename;
+
+ SmbComQueryInformation( String filename ) {
+ this.filename = filename;
+ command = SMB_COM_QUERY_INFORMATION;
+ }
+
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+ dst[dstIndex++] = (byte)0x04;
+ dstIndex += writeString( filename, dst, dstIndex );
+ return dstIndex - start;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ public String toString() {
+ return new String( "SmbComQueryInformation[" +
+ super.toString() +
+ ",filename=" + filename + "]" );
+ }
+}
+
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import java.util.Date;
+
+class SmbComQueryInformationResponse extends ServerMessageBlock implements Info {
+
+ int fileAttributes = 0x0000;
+ long lastWriteTime = 0, serverTimeZoneOffset;
+ int fileSize = 0;
+
+ SmbComQueryInformationResponse( long serverTimeZoneOffset ) {
+ this.serverTimeZoneOffset = serverTimeZoneOffset;
+ command = SMB_COM_QUERY_INFORMATION;
+ }
+
+ public int getAttributes() {
+ return fileAttributes;
+ }
+ public long getLastWriteTime() {
+ return lastWriteTime + serverTimeZoneOffset;
+ }
+ public long getSize() {
+ return fileSize;
+ }
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ if( wordCount == 0 ) {
+ return 0;
+ }
+ fileAttributes = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ lastWriteTime = readUTime( buffer, bufferIndex );
+ bufferIndex += 4;
+ fileSize = readInt4( buffer, bufferIndex );
+ return 20;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ public String toString() {
+ return new String( "SmbComQueryInformationResponse[" +
+ super.toString() +
+ ",fileAttributes=0x" + Log.getHexString( fileAttributes, 4 ) +
+ ",lastWriteTime=" + new Date( lastWriteTime ) +
+ ",fileSize=" + fileSize + "]" );
+ }
+}
+
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import jcifs.Config;
+import java.io.InputStream;
+import java.io.IOException;
+
+class SmbComReadAndX extends AndXServerMessageBlock {
+
+ static final int BATCH_LIMIT = Config.getInt( "jcifs.smb.client.ReadAndX.Close", 1 );
+
+ int fid,
+ offset,
+ maxCount,
+ minCount,
+ openTimeout,
+ remaining;
+
+ SmbComReadAndX( int fid, int offset, int maxCount, ServerMessageBlock andx ) {
+ super( andx );
+ this.fid = fid;
+ this.offset = offset;
+ this.maxCount = minCount = maxCount;
+ command = SMB_COM_READ_ANDX;
+ openTimeout = 0xFFFFFFFF;
+ }
+
+ int getBatchLimit( byte command ) {
+ return command == SMB_COM_CLOSE ? BATCH_LIMIT : 0;
+ }
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+
+ writeInt2( fid, dst, dstIndex );
+ dstIndex += 2;
+ writeInt4( offset, dst, dstIndex );
+ dstIndex += 4;
+ writeInt2( maxCount, dst, dstIndex );
+ dstIndex += 2;
+ writeInt2( minCount, dst, dstIndex );
+ dstIndex += 2;
+ writeInt4( openTimeout, dst, dstIndex );
+ dstIndex += 4;
+ writeInt2( remaining, dst, dstIndex );
+ dstIndex += 2;
+ writeInt4( 0, dst, dstIndex );
+ dstIndex += 4;
+
+ return dstIndex - start;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesDirectWireFormat( InputStream in, int byteCount ) throws IOException {
+ return 0;
+ }
+ public String toString() {
+ return new String( "SmbComReadAndX[" +
+ super.toString() +
+ ",fid=" + fid +
+ ",offset=" + offset +
+ ",maxCount=" + maxCount +
+ ",minCount=" + minCount +
+ ",openTimeout=" + openTimeout +
+ ",remaining=" + remaining +
+ ",offset=" + maxCount +
+ "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+class SmbComReadAndXResponse extends AndXServerMessageBlock {
+
+ byte[] b;
+ int dataCompactionMode,
+ dataLength,
+ dataOffset,
+ off;
+
+ SmbComReadAndXResponse( byte[] b, int off ) {
+ this.b = b;
+ this.off = off;
+ }
+
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ int start = bufferIndex;
+
+ bufferIndex += 2; // reserved
+ dataCompactionMode = readInt2( buffer, bufferIndex );
+ bufferIndex += 4; // 2 reserved
+ dataLength = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ dataOffset = readInt2( buffer, bufferIndex );
+ bufferIndex += 12; // 10 reserved
+
+ return bufferIndex - start;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesDirectWireFormat( InputStream in, int byteCount ) throws IOException {
+
+ int pad = dataOffset - ( HEADER_LENGTH + 3 + wordCount * 2 );
+ in.skip( pad );
+ in.read( b, off, dataLength );
+ return pad + dataLength;
+ }
+ public String toString() {
+ return new String( "SmbComReadAndXResponse[" +
+ super.toString() +
+ ",dataCompactionMode=" + dataCompactionMode +
+ ",dataLength=" + dataLength +
+ ",dataOffset=" + dataOffset + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+class SmbComRename extends ServerMessageBlock {
+
+ int searchAttributes;
+ String oldFileName;
+ String newFileName;
+
+ SmbComRename( String oldFileName, String newFileName ) {
+ command = SMB_COM_RENAME;
+ this.oldFileName = oldFileName;
+ this.newFileName = newFileName;
+ searchAttributes = ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY;
+ }
+
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ writeInt2( searchAttributes, dst, dstIndex );
+ return 2;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+
+ dst[dstIndex++] = (byte)0x04;
+ dstIndex += writeString( oldFileName, dst, dstIndex );
+ dst[dstIndex++] = (byte)0x04;
+ if( useUnicode ) {
+ dst[dstIndex++] = (byte)'\0';
+ }
+ dstIndex += writeString( newFileName, dst, dstIndex );
+
+ return dstIndex - start;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ public String toString() {
+ return new String( "SmbComRename[" +
+ super.toString() +
+ ",searchAttributes=0x" + Log.getHexString( searchAttributes, 4 ) +
+ ",oldFileName=" + oldFileName +
+ ",newFileName=" + newFileName + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import jcifs.Config;
+import java.io.IOException;
+import java.io.InputStream;
+
+class SmbComSessionSetupAndX extends AndXServerMessageBlock {
+
+ static final int BATCH_LIMIT =
+ Config.getInt( "jcifs.smb.client.SessionSetupAndX.TreeConnectAndX", 1 );
+
+ byte[] accountPassword, unicodePassword;
+ int passwordLength, unicodePasswordLength;
+ int negotiatedMaxBufferSize,
+ negotiatedMaxMpxCount,
+ vcNumber,
+ sessionKey;
+ String accountName,
+ primaryDomain,
+ nativeOs,
+ nativeLanMan;
+
+ SmbSession session;
+
+ SmbComSessionSetupAndX( SmbSession session, ServerMessageBlock andx ) {
+ super( andx );
+ command = SMB_COM_SESSION_SETUP_ANDX;
+ this.session = session;
+ }
+
+ int getBatchLimit( byte command ) {
+ return command == SMB_COM_TREE_CONNECT_ANDX ? BATCH_LIMIT : 0;
+ }
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+
+ if( session.transport.server.security == SECURITY_USER &&
+ session.password.length() != 0 ) {
+ if( session.transport.server.encryptedPasswords ) {
+ // encrypted
+ accountPassword = SmbSession.getPreNTLMResponse( session.password,
+ session.transport.server.encryptionKey );
+ unicodePassword = SmbSession.getNTLMResponse( session.password,
+ session.transport.server.encryptionKey );
+ passwordLength = unicodePasswordLength = 24;
+ } else {
+ // plain text
+ throw new RuntimeException( "plain text passwords not implemented" );
+ }
+ } else {
+ // no password in session setup
+ passwordLength = unicodePasswordLength = 0;
+ }
+
+ negotiatedMaxBufferSize = session.transport.negotiatedMaxBufferSize;
+ negotiatedMaxMpxCount = session.transport.negotiatedMaxMpxCount;
+ vcNumber = session.transport.client.vcNumber;
+ sessionKey = session.transport.client.sessionKey;
+
+ writeInt2( negotiatedMaxBufferSize, dst, dstIndex );
+ dstIndex += 2;
+ writeInt2( negotiatedMaxMpxCount, dst, dstIndex );
+ dstIndex += 2;
+ writeInt2( vcNumber, dst, dstIndex );
+ dstIndex += 2;
+ writeInt4( sessionKey, dst, dstIndex );
+ dstIndex += 4;
+ writeInt2( passwordLength, dst, dstIndex );
+ dstIndex += 2;
+ writeInt2( unicodePasswordLength, dst, dstIndex );
+ dstIndex += 2;
+ dst[dstIndex++] = (byte)0x00;
+ dst[dstIndex++] = (byte)0x00;
+ dst[dstIndex++] = (byte)0x00;
+ dst[dstIndex++] = (byte)0x00;
+ writeInt4( session.transport.client.capabilities, dst, dstIndex );
+ dstIndex += 4;
+
+ return dstIndex - start;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+
+ accountName = session.username;
+ primaryDomain = session.domain;
+ nativeOs = session.transport.client.nativeOs;
+ nativeLanMan = session.transport.client.nativeLanMan;
+
+ if( session.transport.server.security == SECURITY_USER &&
+ session.password.length() != 0 ) {
+ System.arraycopy( accountPassword, 0, dst, dstIndex, passwordLength );
+ dstIndex += passwordLength;
+ System.arraycopy( unicodePassword, 0, dst, dstIndex, unicodePasswordLength );
+ dstIndex += unicodePasswordLength;
+ }
+ if( useUnicode ) {
+ // at least NT 4 observed needing this only with unicode
+ dst[dstIndex++] = (byte)'\0';
+ }
+
+ dstIndex += writeString( accountName, dst, dstIndex );
+ dstIndex += writeString( primaryDomain, dst, dstIndex );
+ dstIndex += writeString( nativeOs, dst, dstIndex );
+/*
+ // at least NT 4 observed with 2 zero bytes here
+ dst[dstIndex++] = (byte)0x00;
+ dst[dstIndex++] = (byte)0x00;
+This still isn't quite right.
+*/
+ dstIndex += writeString( nativeLanMan, dst, dstIndex );
+
+ return dstIndex - start;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesDirectWireFormat( InputStream in, int byteCount ) throws IOException {
+ return 0;
+ }
+ public String toString() {
+ String result = new String( "SmbComSessionSetupAndX[" +
+ super.toString() +
+ ",maxBufferSize=" + negotiatedMaxBufferSize +
+ ",maxMpxCount=" + negotiatedMaxMpxCount +
+ ",vcNumber=" + vcNumber +
+ ",sessionKey=" + sessionKey +
+ ",passwordLength=" + passwordLength +
+ ",unicodePasswordLength=" + unicodePasswordLength +
+ ",capabilities=" + session.transport.client.capabilities +
+ ",accountPassword=" + accountPassword +
+ ",accountName=" + accountName +
+ ",primaryDomain=" + primaryDomain +
+ ",nativeOs=" + nativeOs +
+ ",nativeLanMan=" + nativeLanMan + "]" );
+ return result;
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+class SmbComSessionSetupAndXResponse extends AndXServerMessageBlock {
+
+ boolean isLoggedInAsGuest;
+ String nativeOs = "";
+ String nativeLanMan = "";
+ String primaryDomain = "";
+
+ SmbComSessionSetupAndXResponse( ServerMessageBlock andx ) {
+ super( andx );
+ }
+
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ isLoggedInAsGuest = ( buffer[bufferIndex] & 0x01 ) == 0x01 ? true : false;
+ return 2;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ int start = bufferIndex;
+
+ nativeOs = readString( buffer, bufferIndex );
+ bufferIndex += stringWireLength( nativeOs, bufferIndex );
+ nativeLanMan = readString( buffer, bufferIndex );
+ bufferIndex += stringWireLength( nativeLanMan, bufferIndex );
+ primaryDomain = readString( buffer, bufferIndex );
+ bufferIndex += stringWireLength( primaryDomain, bufferIndex );
+
+ return bufferIndex - start;
+ }
+ int readBytesDirectWireFormat( InputStream in, int byteCount ) throws IOException {
+ return 0;
+ }
+ public String toString() {
+ String result = new String( "SmbComSessionSetupAndXResponse[" +
+ super.toString() +
+ ",isLoggedInAsGuest=" + isLoggedInAsGuest +
+ ",nativeOs=" + nativeOs +
+ ",nativeLanMan=" + nativeLanMan +
+ ",primaryDomain=" + primaryDomain + "]" );
+ return result;
+ }
+}
+
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import java.util.Enumeration;
+import jcifs.Config;
+
+abstract class SmbComTransaction extends ServerMessageBlock implements Enumeration {
+
+ static final byte TRANS2_FIND_FIRST2 = (byte)0x01;
+ static final byte TRANS2_FIND_NEXT2 = (byte)0x02;
+ static final byte TRANS2_QUERY_FS_INFORMATION = (byte)0x03;
+ static final byte TRANS2_QUERY_PATH_INFORMATION = (byte)0x05;
+
+ static final int NET_SHARE_ENUM = 0x0000;
+ static final int NET_SERVER_ENUM2 = 0x0068;
+
+ static final byte TRANS_WAIT_NAMED_PIPE = (byte)0x53;
+ static final byte TRANS_CALL_NAMED_PIPE = (byte)0x54;
+ static final byte TRANS_TRANSACT_NAMED_PIPE = (byte)0x26;
+
+ // relative to headerStart
+ static final int PRIMARY_SETUP_OFFSET = 61;
+ static final int SECONDARY_PARAMETER_OFFSET = 51;
+
+ static final int DISCONNECT_TID = 0x01;
+ static final int ONE_WAY_TRANSACTION = 0x02;
+
+ static final int PADDING_SIZE = 2;
+
+ static final int DEFAULT_TRANSACTION_BUF_SIZE = 0xFFFF;
+
+ int totalParameterCount;
+ int totalDataCount;
+ int maxParameterCount;
+ int maxDataCount;
+ byte maxSetupCount;
+ int flags = 0x00;
+ int timeout = 0;
+ int parameterCount;
+ int parameterOffset;
+ int parameterDisplacement;
+ int dataCount;
+ int dataOffset;
+ int dataDisplacement;
+ int fid;
+ int setupCount = 1;
+ byte subCommand;
+ String name = "";
+ int pad = 0;
+ int pad1 = 0;
+ boolean hasMore = true;
+ boolean isPrimary = true;
+ int maxBufferSize; // set in SmbTransport.sendTransaction() before nextElement called
+
+ byte[] buf = new byte[DEFAULT_TRANSACTION_BUF_SIZE]; // yuck
+ int bufParameterOffset;
+ int bufDataOffset;
+
+ SmbComTransaction() {
+ maxParameterCount = 1024;
+ // subtract 512 just to be safe
+ maxDataCount = Config.getInt( "jcifs.smb.client.transaction_buf_size",
+ SmbComTransactionResponse.DEFAULT_TRANSACTION_BUF_SIZE ) - 512;
+ }
+
+ public boolean hasMoreElements() {
+ return hasMore;
+ }
+ public Object nextElement() {
+ if( isPrimary ) {
+ isPrimary = false;
+
+ parameterOffset = PRIMARY_SETUP_OFFSET + ( setupCount * 2 ) + 2;
+ if( command == SMB_COM_TRANSACTION && isResponse() == false ) {
+ parameterOffset += stringWireLength( name, parameterOffset );
+ }
+ pad = parameterOffset % PADDING_SIZE;
+ pad = pad == 0 ? 0 : PADDING_SIZE - pad;
+ parameterOffset += pad;
+
+ totalParameterCount = writeParametersWireFormat( buf, bufParameterOffset );
+ bufDataOffset = totalParameterCount; // data comes right after data
+
+ int available = maxBufferSize - parameterOffset;
+ parameterCount = Math.min( totalParameterCount, available );
+ available -= parameterCount;
+
+ dataOffset = parameterOffset + parameterCount;
+ pad1 = dataOffset % PADDING_SIZE;
+ pad1 = pad1 == 0 ? 0 : PADDING_SIZE - pad1;
+ dataOffset += pad1;
+
+ totalDataCount = writeDataWireFormat( buf, bufDataOffset );
+
+ dataCount = Math.min( totalDataCount, available );
+ } else {
+ command = SMB_COM_TRANSACTION_SECONDARY;
+ // totalParameterCount and totalDataCount are set ok from primary
+
+ parameterOffset = SECONDARY_PARAMETER_OFFSET;
+ if(( totalParameterCount - parameterDisplacement ) > 0 ) {
+ pad = parameterOffset % PADDING_SIZE;
+ pad = pad == 0 ? 0 : PADDING_SIZE - pad;
+ parameterOffset += pad;
+ }
+
+ // caclulate parameterDisplacement before calculating new parameterCount
+ parameterDisplacement += parameterCount;
+
+ int available = maxBufferSize - parameterOffset - pad;
+ parameterCount = Math.min( totalParameterCount - parameterDisplacement, available);
+ available -= parameterCount;
+
+ dataOffset = parameterOffset + parameterCount;
+ pad1 = dataOffset % PADDING_SIZE;
+ pad1 = pad1 == 0 ? 0 : PADDING_SIZE - pad1;
+ dataOffset += pad1;
+
+ dataDisplacement += dataCount;
+
+ available -= pad1;
+ dataCount = Math.min( totalDataCount - dataDisplacement, available );
+ }
+ if(( parameterDisplacement + parameterCount ) >= totalParameterCount &&
+ ( dataDisplacement + dataCount ) >= totalDataCount ) {
+ hasMore = false;
+ }
+ return this;
+ }
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+
+ writeInt2( totalParameterCount, dst, dstIndex );
+ dstIndex += 2;
+ writeInt2( totalDataCount, dst, dstIndex );
+ dstIndex += 2;
+ if( command != SMB_COM_TRANSACTION_SECONDARY ) {
+ writeInt2( maxParameterCount, dst, dstIndex );
+ dstIndex += 2;
+ writeInt2( maxDataCount, dst, dstIndex );
+ dstIndex += 2;
+ dst[dstIndex++] = maxSetupCount;
+ dst[dstIndex++] = (byte)0x00; // Reserved1
+ writeInt2( flags, dst, dstIndex );
+ dstIndex += 2;
+ writeInt4( timeout, dst, dstIndex );
+ dstIndex += 4;
+ dst[dstIndex++] = (byte)0x00; // Reserved2
+ dst[dstIndex++] = (byte)0x00;
+ }
+ writeInt2( parameterCount, dst, dstIndex );
+ dstIndex += 2;
+ writeInt2(( parameterCount == 0 ? 0 : parameterOffset ), dst, dstIndex );
+ dstIndex += 2;
+ if( command == SMB_COM_TRANSACTION_SECONDARY ) {
+ writeInt2( parameterDisplacement, dst, dstIndex );
+ dstIndex += 2;
+ }
+ writeInt2( dataCount, dst, dstIndex );
+ dstIndex += 2;
+ writeInt2(( dataCount == 0 ? 0 : dataOffset ), dst, dstIndex );
+ dstIndex += 2;
+ if( command == SMB_COM_TRANSACTION_SECONDARY ) {
+ writeInt2( dataDisplacement, dst, dstIndex );
+ dstIndex += 2;
+ } else {
+ dst[dstIndex++] = (byte)setupCount;
+ dst[dstIndex++] = (byte)0x00; // Reserved3
+ dstIndex += writeSetupWireFormat( dst, dstIndex );
+ }
+
+ return dstIndex - start;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+ int p = pad;
+
+ if( command == SMB_COM_TRANSACTION && isResponse() == false ) {
+ dstIndex += writeString( name, dst, dstIndex );
+ }
+
+ if( parameterCount > 0 ) {
+ while( p-- > 0 ) {
+ dst[dstIndex++] = (byte)0x00; // Pad
+ }
+
+ System.arraycopy( buf, bufParameterOffset, dst, dstIndex, parameterCount );
+ dstIndex += parameterCount;
+ }
+
+ if( dataCount > 0 ) {
+ p = pad1;
+ while( p-- > 0 ) {
+ dst[dstIndex++] = (byte)0x00; // Pad1
+ }
+ System.arraycopy( buf, bufDataOffset, dst, dstIndex, dataCount );
+ bufDataOffset += dataCount;
+ dstIndex += dataCount;
+ }
+
+ return dstIndex - start;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+
+ abstract int writeSetupWireFormat( byte[] dst, int dstIndex );
+ abstract int writeParametersWireFormat( byte[] dst, int dstIndex );
+ abstract int writeDataWireFormat( byte[] dst, int dstIndex );
+ abstract int readSetupWireFormat( byte[] buffer, int bufferIndex, int len );
+ abstract int readParametersWireFormat( byte[] buffer, int bufferIndex, int len );
+ abstract int readDataWireFormat( byte[] buffer, int bufferIndex, int len );
+
+ public String toString() {
+ return new String( super.toString() +
+ ",totalParameterCount=" + totalParameterCount +
+ ",totalDataCount=" + totalDataCount +
+ ",maxParameterCount=" + maxParameterCount +
+ ",maxDataCount=" + maxDataCount +
+ ",maxSetupCount=" + (int)maxSetupCount +
+ ",flags=0x" + Log.getHexString( flags, 2 ) +
+ ",timeout=" + timeout +
+ ",parameterCount=" + parameterCount +
+ ",parameterOffset=" + parameterOffset +
+ ",parameterDisplacement=" + parameterDisplacement +
+ ",dataCount=" + dataCount +
+ ",dataOffset=" + dataOffset +
+ ",dataDisplacement=" + dataDisplacement +
+ ",setupCount=" + setupCount +
+ ",pad=" + pad +
+ ",pad1=" + pad1 );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import java.util.Enumeration;
+import jcifs.Config;
+
+abstract class SmbComTransactionResponse extends ServerMessageBlock implements Enumeration {
+
+ // relative to headerStart
+ static final int SETUP_OFFSET = 61;
+
+ static final int DISCONNECT_TID = 0x01;
+ static final int ONE_WAY_TRANSACTION = 0x02;
+
+ static final int DEFAULT_TRANSACTION_BUF_SIZE = 0xFFFF;
+
+ int totalParameterCount;
+ int totalDataCount;
+ int parameterCount;
+ int parameterOffset;
+ int parameterDisplacement;
+ int dataCount;
+ int dataOffset;
+ int dataDisplacement;
+ int setupCount;
+ byte subCommand;
+ int pad;
+ int pad1;
+ boolean hasMore = true;
+ boolean isPrimary = true;
+
+ int data_rcv_buf_size;
+ byte[] buf;
+ int bufParameterStart;
+ int bufDataStart;
+
+ SmbComTransactionResponse() {
+ data_rcv_buf_size = Config.getInt( "jcifs.smb.client.transaction_buf_size",
+ DEFAULT_TRANSACTION_BUF_SIZE );
+ buf = new byte[data_rcv_buf_size]; // OUCH !!
+ }
+
+ public boolean hasMoreElements() {
+ return hasMore;
+ }
+ public Object nextElement() {
+ if( isPrimary ) {
+ isPrimary = false;
+ }
+ return this;
+ }
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ int start = bufferIndex;
+
+ totalParameterCount = readInt2( buffer, bufferIndex );
+ if( bufDataStart == 0 ) {
+ bufDataStart = totalParameterCount;
+ }
+ bufferIndex += 2;
+ totalDataCount = readInt2( buffer, bufferIndex );
+ bufferIndex += 4; // Reserved
+ parameterCount = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ parameterOffset = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ parameterDisplacement = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ dataCount = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ dataOffset = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ dataDisplacement = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ setupCount = buffer[bufferIndex] & 0xFF;
+ bufferIndex += 2;
+ if( setupCount != 0 ) {
+ Log.println( Log.WARNINGS, "smb transaction response",
+ "setupCount is not zero: " + setupCount );
+ }
+
+ return bufferIndex - start;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ pad = pad1 = 0;
+ int n;
+
+ if( parameterCount > 0 ) {
+ bufferIndex += pad = parameterOffset - ( bufferIndex - headerStart );
+ System.arraycopy( buffer, bufferIndex, buf,
+ bufParameterStart + parameterDisplacement, parameterCount );
+ bufferIndex += parameterCount;
+ }
+ if( dataCount > 0 ) {
+ bufferIndex += pad1 = dataOffset - ( bufferIndex - headerStart );
+ System.arraycopy( buffer, bufferIndex, buf,
+ bufDataStart + dataDisplacement, dataCount );
+ bufferIndex += dataCount;
+ }
+
+ /* Check to see if the entire transaction has been
+ * read. If so call the read methods.
+ */
+
+ if(( parameterDisplacement + parameterCount ) == totalParameterCount &&
+ ( dataDisplacement + dataCount ) == totalDataCount ) {
+ hasMore = false;
+ readParametersWireFormat( buf, bufParameterStart, totalParameterCount );
+ readDataWireFormat( buf, bufDataStart, totalDataCount );
+ }
+
+ return pad + parameterCount + pad1 + dataCount;
+ }
+
+ abstract int writeSetupWireFormat( byte[] dst, int dstIndex );
+ abstract int writeParametersWireFormat( byte[] dst, int dstIndex );
+ abstract int writeDataWireFormat( byte[] dst, int dstIndex );
+ abstract int readSetupWireFormat( byte[] buffer, int bufferIndex, int len );
+ abstract int readParametersWireFormat( byte[] buffer, int bufferIndex, int len );
+ abstract int readDataWireFormat( byte[] buffer, int bufferIndex, int len );
+
+ public String toString() {
+ return new String( super.toString() +
+ ",totalParameterCount=" + totalParameterCount +
+ ",totalDataCount=" + totalDataCount +
+ ",parameterCount=" + parameterCount +
+ ",parameterOffset=" + parameterOffset +
+ ",parameterDisplacement=" + parameterDisplacement +
+ ",dataCount=" + dataCount +
+ ",dataOffset=" + dataOffset +
+ ",dataDisplacement=" + dataDisplacement +
+ ",setupCount=" + setupCount +
+ ",pad=" + pad +
+ ",pad1=" + pad1 );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import jcifs.Config;
+import jcifs.util.PropertiesTree;
+import java.io.IOException;
+import java.io.InputStream;
+
+class SmbComTreeConnectAndX extends AndXServerMessageBlock {
+
+ SmbSession session;
+ boolean disconnectTid = false;
+ String path, service;
+ byte[] password;
+ int passwordLength;
+
+ /* batchLimits indecies
+ *
+ * 0 = SMB_COM_CHECK_DIRECTORY
+ * 1 = SMB_COM_COPY
+ * 2 = SMB_COM_CREATE_DIRECTORY
+ * 3 = SMB_COM_DELETE
+ * 4 = SMB_COM_DELETE_DIRECTORY
+ * 5 = SMB_COM_OPEN_ANDX
+ * 6 = SMB_COM_RENAME
+ * 7 = SMB_COM_TRANSACTION
+ * 8 = SMB_COM_QUERY_INFORMATION
+ */
+
+ /* All batch limits are single batch only until further notice
+ */
+
+ static byte[] batchLimits = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 0
+ };
+
+ static {
+ PropertiesTree pt = (PropertiesTree)Config.get( "jcifs.smb.client.TreeConnectAndX" );
+ String s;
+
+ if( pt != null ) {
+ if(( s = pt.getProperty( "CheckDirectory" )) != null ) {
+ batchLimits[0] = Byte.parseByte( s );
+ }
+ if(( s = pt.getProperty( "Copy" )) != null ) {
+ batchLimits[1] = Byte.parseByte( s );
+ }
+ if(( s = pt.getProperty( "CreateDirectory" )) != null ) {
+ batchLimits[2] = Byte.parseByte( s );
+ }
+ if(( s = pt.getProperty( "Delete" )) != null ) {
+ batchLimits[3] = Byte.parseByte( s );
+ }
+ if(( s = pt.getProperty( "DeleteDirectory" )) != null ) {
+ batchLimits[4] = Byte.parseByte( s );
+ }
+ if(( s = pt.getProperty( "OpenAndX" )) != null ) {
+ batchLimits[5] = Byte.parseByte( s );
+ }
+ if(( s = pt.getProperty( "Rename" )) != null ) {
+ batchLimits[6] = Byte.parseByte( s );
+ }
+ if(( s = pt.getProperty( "Transaction" )) != null ) {
+ batchLimits[7] = Byte.parseByte( s );
+ }
+ if(( s = pt.getProperty( "QueryInformation" )) != null ) {
+ batchLimits[8] = Byte.parseByte( s );
+ }
+ }
+ }
+
+ SmbComTreeConnectAndX( SmbSession session, String path,
+ String service, ServerMessageBlock andx ) {
+ super( andx );
+ this.session = session;
+ this.path = path;
+ this.service = service;
+ command = SMB_COM_TREE_CONNECT_ANDX;
+ }
+
+ int getBatchLimit( byte command ) {
+ int c = (int)( command & 0xFF );
+ switch( c ) {
+ case SMB_COM_CHECK_DIRECTORY:
+ return batchLimits[0];
+ case SMB_COM_COPY:
+ return batchLimits[1];
+ case SMB_COM_CREATE_DIRECTORY:
+ return batchLimits[2];
+ case SMB_COM_DELETE:
+ return batchLimits[3];
+ case SMB_COM_DELETE_DIRECTORY:
+ return batchLimits[4];
+ case SMB_COM_OPEN_ANDX:
+ return batchLimits[5];
+ case SMB_COM_RENAME:
+ return batchLimits[6];
+ case SMB_COM_TRANSACTION:
+ return batchLimits[7];
+ case SMB_COM_QUERY_INFORMATION:
+ return batchLimits[8];
+ }
+ return 0;
+ }
+
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+
+ if( session.transport.server.security == SECURITY_SHARE &&
+ session.password.length() != 0 ) {
+ if( session.transport.server.encryptedPasswords ) {
+ // encrypted
+ password = SmbSession.getPreNTLMResponse( session.password,
+ session.transport.server.encryptionKey );
+ passwordLength = 24;
+ } else {
+ // plain text
+ throw new RuntimeException( "plain text passwords not implemented" );
+ }
+ } else {
+ // no password in tree connect
+ passwordLength = 1;
+ }
+
+ dst[dstIndex++] = (byte)0x00;
+ dst[dstIndex++] = disconnectTid ? (byte)0x01 : (byte)0x00;
+ writeInt2( passwordLength, dst, dstIndex );
+ return 4;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+
+ if( session.transport.server.security == SECURITY_SHARE &&
+ session.password.length() != 0 ) {
+ if( session.transport.server.encryptedPasswords ) {
+ // encrypted
+ System.arraycopy( password, 0, dst, dstIndex, passwordLength );
+ dstIndex += passwordLength;
+ } else {
+ // plain text
+ throw new RuntimeException( "plain text passwords not implemented" );
+ }
+ } else {
+ // no password in tree connect
+ dst[dstIndex++] = (byte)0x00;
+ }
+ dstIndex += writeString( path, dst, dstIndex );
+ System.arraycopy( service.getBytes(), 0, dst, dstIndex, service.length() );
+ dstIndex += service.length();
+ dst[dstIndex++] = (byte)'\0';
+
+ return dstIndex - start;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesDirectWireFormat( InputStream in, int byteCount ) throws IOException {
+ return 0;
+ }
+ public String toString() {
+ String result = new String( "SmbComTreeConnectAndX[" +
+ super.toString() +
+ ",disconnectTid=" + disconnectTid +
+ ",passwordLength=" + passwordLength +
+ ",password=" + Log.getHexString(
+ password, passwordLength, 0 ) +
+ ",path=" + path +
+ ",service=" + service + "]" );
+ return result;
+ }
+}
+
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+class SmbComTreeConnectAndXResponse extends AndXServerMessageBlock {
+
+ static final int SMB_SUPPORT_SEARCH_BITS = 0x0001;
+ static final int SMB_SHARE_IS_IN_DFS = 0x0002;
+
+ boolean supportSearchBits, shareIsInDfs;
+ String service, nativeFileSystem = "";
+
+ SmbComTreeConnectAndXResponse( ServerMessageBlock andx ) {
+ super( andx );
+ }
+
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ supportSearchBits = ( buffer[bufferIndex] & SMB_SUPPORT_SEARCH_BITS ) ==
+ SMB_SUPPORT_SEARCH_BITS ? true : false;
+ shareIsInDfs = ( buffer[bufferIndex] & SMB_SHARE_IS_IN_DFS ) ==
+ SMB_SHARE_IS_IN_DFS ? true : false;
+ return 2;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ int start = bufferIndex;
+
+ int len = readStringLength( buffer, bufferIndex, 32 );
+ service = new String( buffer, bufferIndex, len );
+ bufferIndex += len + 1;
+ // win98 observed not returning nativeFileSystem
+ if( byteCount > bufferIndex - start ) {
+ nativeFileSystem = readString( buffer, bufferIndex );
+ bufferIndex += stringWireLength( nativeFileSystem, bufferIndex );
+ }
+
+ return bufferIndex - start;
+ }
+ int readBytesDirectWireFormat( InputStream in, int byteCount ) throws IOException {
+ return 0;
+ }
+ public String toString() {
+ String result = new String( "SmbComTreeConnectAndXResponse[" +
+ super.toString() +
+ ",supportSearchBits=" + supportSearchBits +
+ ",shareIsInDfs=" + shareIsInDfs +
+ ",service=" + service +
+ ",nativeFileSystem=" + nativeFileSystem + "]" );
+ return result;
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+class SmbComTreeDisconnect extends ServerMessageBlock {
+
+ SmbComTreeDisconnect() {
+ command = SMB_COM_TREE_DISCONNECT;
+ }
+
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ public String toString() {
+ return new String( "SmbComTreeDisconnect[" +
+ super.toString() + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import jcifs.Config;
+import java.io.IOException;
+import java.io.InputStream;
+
+class SmbComWriteAndX extends AndXServerMessageBlock {
+
+ static final int READ_ANDX_BATCH_LIMIT =
+ Config.getInt( "jcifs.smb.client.WriteAndX.ReadAndX", 1 );
+ static final int CLOSE_BATCH_LIMIT =
+ Config.getInt( "jcifs.smb.client.WriteAndX.Close", 1 );
+
+ int fid,
+ offset,
+ writeMode,
+ remaining,
+ dataLength,
+ dataOffset,
+ off,
+ pad;
+ byte[] b;
+
+ SmbComWriteAndX( int fid, int offset, int remaining,
+ byte[] b, int off, int len, ServerMessageBlock andx ) {
+ super( andx );
+ this.fid = fid;
+ this.offset = offset;
+ this.remaining = remaining;
+ this.b = b;
+ this.off = off;
+ dataLength = len;
+ command = SMB_COM_WRITE_ANDX;
+ }
+
+ int getBatchLimit( byte command ) {
+ if( command == SMB_COM_READ_ANDX ) {
+ return READ_ANDX_BATCH_LIMIT;
+ }
+ if( command == SMB_COM_CLOSE ) {
+ return CLOSE_BATCH_LIMIT;
+ }
+ return 0;
+ }
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+
+ dataOffset = dstIndex + 22; // 22 = off from here to pad
+ pad = ( dataOffset - headerStart ) % 4;
+ pad = pad == 0 ? 0 : 4 - pad;
+ dataOffset += pad;
+
+ writeInt2( fid, dst, dstIndex );
+ dstIndex += 2;
+ writeInt4( offset, dst, dstIndex );
+ dstIndex += 4;
+ for( int i = 0; i < 4; i++ ) {
+ dst[dstIndex++] = (byte)0x00;
+ }
+ writeInt2( writeMode, dst, dstIndex );
+ dstIndex += 2;
+ writeInt2( remaining, dst, dstIndex );
+ dstIndex += 2;
+ dst[dstIndex++] = (byte)0x00;
+ dst[dstIndex++] = (byte)0x00;
+ writeInt2( dataLength, dst, dstIndex );
+ dstIndex += 2;
+ writeInt2( dataOffset, dst, dstIndex );
+ dstIndex += 2;
+ // offsetHigh another day
+
+ return dstIndex - start;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+
+ while( pad-- > 0 ) {
+ dst[dstIndex++] = (byte)0x00;
+ }
+ System.arraycopy( b, off, dst, dstIndex, dataLength );
+ dstIndex += dataLength;
+
+ return dstIndex - start;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesDirectWireFormat( InputStream in, int byteCount ) throws IOException {
+ return 0;
+ }
+ public String toString() {
+ return new String( "SmbComWriteAndX[" +
+ super.toString() +
+ ",fid=" + fid +
+ ",offset=" + offset +
+ ",writeMode=" + writeMode +
+ ",remaining=" + remaining +
+ ",dataLength=" + dataLength +
+ ",dataOffset=" + dataOffset + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+class SmbComWriteAndXResponse extends AndXServerMessageBlock {
+
+ int count;
+
+ SmbComWriteAndXResponse() {
+ }
+
+ int writeParameterWordsWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeBytesWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readParameterWordsWireFormat( byte[] buffer, int bufferIndex ) {
+ count = readInt2( buffer, bufferIndex );
+ return 8;
+ }
+ int readBytesWireFormat( byte[] buffer, int bufferIndex ) {
+ return 0;
+ }
+ int readBytesDirectWireFormat( InputStream in, int byteCount ) throws IOException {
+ return 0;
+ }
+ public String toString() {
+ return new String( "SmbComWriteAndXResponse[" +
+ super.toString() +
+ ",count=" + count + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import java.io.IOException;
+
+class SmbException extends IOException {
+
+ // error classes
+ static final int SUCCESS = 0;
+ static final int ERRDOS = 0x01;
+ static final int ERRSRV = 0x02;
+ static final int ERRHRD = 0x03;
+ static final int ERRCMD = 0xFF;
+
+ // dos error codes
+ static final int ERRbadfunc = 1;
+ static final int ERRbadfile = 2;
+ static final int ERRbadpath = 3;
+ static final int ERRnoaccess = 5;
+ static final int ERRbadfid = 6;
+ static final int ERRbadshare = 32;
+ static final int ERRbadnetname = 67;
+ static final int ERRbadparm = 87;
+ static final int ERRfilexists = 80;
+ static final int ERRbrokenpipe = 109;
+ static final int ERRinvname = 123;
+ static final int ERRpipebusy = 231;
+ static final int ERRnodata = 232;
+
+ // srv error codes
+ static final int ERRerror = 1;
+ static final int ERRbadpw = 2;
+ static final int ERRaccess = 4;
+ static final int ERRinvnid = 5;
+ static final int ERRinvnetname = 6;
+ static final int ERRbaduid = 91;
+ static final int ERRaccountExpired = 2239;
+ static final int ERRbadClient = 2240;
+ static final int ERRbadLogonTime = 2241;
+ static final int ERRpasswordExpired = 2242;
+
+ // hrd error codes
+ static final int ERRnowrite = 19;
+ static final int ERRnotready = 21;
+
+ int errorClass;
+ int errorCode;
+
+ static String getErrorString( int errorClass, int errorCode ) {
+ String result = "";
+ switch( errorClass ) {
+ case SUCCESS:
+ result += "SUCCESS";
+ break;
+ case ERRDOS:
+ result += "ERRDOS/";
+ switch( errorCode ) {
+ case ERRbadfunc:
+ result += "ERRbadfunc: Invalid function";
+ break;
+ case ERRbadfile:
+ result += "ERRbadfile: File not found";
+ break;
+ case ERRbadpath:
+ result += "ERRbadpath: Directory invalid";
+ break;
+ case ERRnoaccess:
+ result += "ERRnoaccess: Access denied";
+ break;
+ case ERRbadparm:
+ result += "ERRbadparm: Invalid parameter";
+ break;
+ case ERRinvname:
+ result += "ERRinvname: Invalid name";
+ break;
+ case ERRfilexists:
+ result += "ERRfilexists: File exists";
+ break;
+ case ERRbadfid:
+ result += "ERRbadfid: Invalid file handle";
+ break;
+ case ERRbadshare:
+ result += "ERRbadshare: The file is being used by another process";
+ break;
+ case ERRnotready:
+ result += "ERRnotready: The device is not ready";
+ break;
+ case ERRbadnetname:
+ result += "ERRbadnetname: The network name cannot be found.";
+ break;
+ case ERRpipebusy:
+ result += "ERRpipebusy: All pipe instances are busy.";
+ break;
+ case ERRnodata:
+ result += "ERRnodata: The pipe is being closed.";
+ break;
+ case ERRbrokenpipe:
+ result += "ERRbrokenpipe: The pipe has been ended.";
+ break;
+ default:
+ result += "Ehh, one of the other ones. Please update " +
+ "getErrorString for errorCode=" + errorCode;
+ }
+ break;
+ case ERRSRV:
+ result += "ERRSRV/";
+ switch( errorCode ) {
+ case ERRerror:
+ result += "ERRerror: Non-specific error code";
+ break;
+ case ERRbadpw:
+ result += "ERRbadpw: Bad password";
+ break;
+ case ERRinvnid:
+ result += "ERRinvnid: The Tid specified was invalid";
+ break;
+ case ERRinvnetname:
+ result += "ERRinvnetname: Invalid network name in tree connect, " +
+ "service not found";
+ break;
+ case ERRbaduid:
+ result += "ERRbaduid: The UID is not known as a valid user " +
+ "identifier on this session";
+ break;
+ case ERRaccess:
+ result += "ERRaccess: The client does not have the necessary " +
+ "access rights for the requested function";
+ break;
+ case ERRaccountExpired:
+ result += "ERRaccountExpired: The user account has expired";
+ break;
+ case ERRbadClient:
+ result += "ERRbadClient: The user is not allowed to access " +
+ "this server from this client";
+ break;
+ case ERRbadLogonTime:
+ result += "ERRbadLogonTime: The user is not permitted to access " +
+ "the server at this time";
+ break;
+ case ERRpasswordExpired:
+ result += "ERRpasswordExpired: The password of the user has " +
+ "expired. Please change your password.";
+ break;
+ default:
+ result += "Ehh, one of the other ones. Please update " +
+ "getErrorString for errorCode=" + errorCode;
+ }
+ break;
+ case ERRHRD:
+ result += "ERRHRD/";
+ switch( errorCode ) {
+ case ERRnowrite:
+ result += "ERRnowrite: Attempt to write on write-protected media";
+ break;
+ case ERRnotready:
+ result += "ERRnotready: The device is not ready";
+ break;
+ default:
+ result += "Ehh, one of the other ones. Please update " +
+ "getErrorString for errorCode=" + errorCode;
+ }
+ break;
+ case ERRCMD:
+ result += "ERRCMD: Command was not in the \"SMB\" format";
+ break;
+ default:
+ result += "unknown error class: " + errorClass;
+ }
+ return result;
+ }
+ static String getErrorString( int code ) {
+ if( code == 0 ) {
+ return "0x00000000";
+ }
+ return getErrorString( code & 0xFF, ( code >> 16 ) & 0xFFFF );
+ }
+
+ public SmbException() {
+ }
+ public SmbException( int code ) {
+ super( getErrorString( code & 0xFF, ( code >> 16 ) & 0xFFFF ));
+ errorClass = code & 0xFF;
+ errorCode = ( code >> 16 ) & 0xFFFF;
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import jcifs.netbios.NbtAddress;
+import java.net.MalformedURLException;
+import java.net.UnknownHostException;
+import java.net.URL;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * This class represents a resource on an SMB network. Mainly these
+ * resources are files and directories however an <code>SmbFile</code>
+ * may also refer to servers and workgroups. If the resource is a file or
+ * directory the methods of <code>SmbFile</code> follow the behavior of
+ * the well known {@link java.io.File} class. One fundamental difference
+ * is the usage of a URL scheme<b>*</b> to specify the target file or
+ * directory. SmbFile URLs have the following syntax:
+ *
+ * <blockquote><pre>
+ * smb://[[[domain;]username[:password]@]server[:port][/share[/path]]]
+ * </pre></blockquote>
+ *
+ * This example:
+ *
+ * <blockquote><pre>
+ * smb://storage15/public/foo.txt
+ * </pre></blockquote>
+ *
+ * would referece the file <code>foo.txt</code> in the share
+ * <code>public</code> on the server <code>storage15</code>. In addition
+ * to referencing files and directories, jCIFS can also address servers,
+ * and workgroups. When used in conjunction with the <code>list</code>
+ * method, this functionality can be usefull for network diagnostics
+ * tools or "Network Neighborhood" like functionality. The server
+ * component may a traditional NetBIOS name, a DNS name, or IP
+ * address. These name resolution mechanisms and their resolution order
+ * can be changed (See <a href="../../../resolver.html">Setting Name
+ * Resolution Properties</a>). The servername and path components are
+ * not case sensitive but the domain, username, and password components
+ * are. It is also likely that properties must be specified for jcifs
+ * to function (See <a href="../../overview-summary.html#scp">Setting
+ * JCIFS Properties</a>). Here are some examples of SMB URLs with brief
+ * descriptions of what they do:
+ *
+ * <p><b>*</b> This URL scheme conforms to the <a target="_top"
+ * href="http://www.ietf.org/internet-drafts/draft-crhertel-smb-url-00.txt">SMB
+ * Filesharing URL Scheme</a> IETF draft.
+ *
+ * <p><table border="1" cellpadding="3" cellspacing="0" width="100%">
+ * <tr bgcolor="#ccccff">
+ * <td colspan="2"><b>SMB URL Examples</b></td>
+ * <tr><td width="20%"><b>URL</b></td><td><b>Description</b></td></tr>
+ *
+ * <tr><td width="20%"><code>smb://users-nyc;miallen:mypass@angus/tmp</code></td><td>
+ * This URL references a share called <code>tmp</code> on the server
+ * <code>angus</code> as user <code>miallen</code> who's password is
+ * <code>mypass</code>.
+ * </td></tr>
+ *
+ * <tr><td width="20%">
+ * <code>smb://Administrator:P@ss@msmith1/c/WINDOWS/Desktop/foo.txt</code></td><td>
+ * A relativly sophisticated example that references a file
+ * <code>msmith1</code>'s desktop as user <code>Administrator</code>.
+ * </td></tr>
+ *
+ * <tr><td width="20%"><code>smb://angus</code></td><td>
+ * This references only a server. The behavior of some methods is different
+ * in this context(e.g. you cannot <code>delete</code> a server) however
+ * as you might expect the <code>list</code> method will list the available
+ * shares on this server.
+ * </td></tr>
+ *
+ * <tr><td width="20%"><code>smb://myworkgroup</code></td><td>
+ * This syntactically is identical to the above example. However if
+ * <code>myworkgroup</code> happends to be a workgroup(which is indeed
+ * suggested by the name) the <code>list</code> method will return
+ * a list of servers that have registered themselves as members of
+ * <code>myworkgroup</code>.
+ * </td></tr>
+ *
+ * <tr><td width="20%"><code>smb://</code></td><td>
+ * Just as <code>smb://server</code> lists shares and
+ * <code>smb://workgroup</code> lists servers, the <code>smb://</code>
+ * URL lists all available workgroups on a netbios LAN. Again,
+ * in this context many methods are not valid and return default
+ * values(e.g. <code>isHidden</code> and <code>renameTo</code> will always
+ * return false).
+ * </td></tr>
+ *
+ * <tr><td width="20%"><code>smb://angus.foo.net/d/jcifs/pipes.doc</code></td><td>
+ * The server name may also be a DNS name as it is in this example. See
+ * <a href="../../../resolver.html">Setting Name Resolution Properties</a>
+ * for details.
+ * </td></tr>
+ *
+ * <tr><td width="20%"><code>smb://192.168.1.15/ADMIN$</code></td><td>
+ * The server name may also be an IP address. See <a
+ * href="../../../resolver.html">Setting Name Resolution Properties</a>
+ * for details.
+ * </td></tr>
+ *
+ * <tr><td width="20%">
+ * <code>smb://domain;username:password@server/share/path/to/file.txt</code></td><td>
+ * A prototypical example that uses all the fields.
+ * </td></tr>
+ *
+ * <tr><td width="20%"><code>smb://myworkgroup/angus <-- ILLEGAL </code></td><td>
+ * Despite the hierarchial relationship between workgroups, servers, and
+ * filesystems this example is not valid.
+ * </td></tr>
+ *
+ * </table>
+ *
+ * <p>A second constructor argument may be specified to augment the URL
+ * for better programmatic control when processing many files under
+ * a common base. This is slightly different from the corresponding
+ * <code>java.io.File</code> usage; a '/' at the beginning of the second
+ * parameter will still use the server component of the first parameter. The
+ * examples below illustrate the resulting URLs when this second contructor
+ * argument is used.
+ *
+ * <p><table border="1" cellpadding="3" cellspacing="0" width="100%">
+ * <tr bgcolor="#ccccff">
+ * <td colspan="3">
+ * <b>Examples Of SMB URLs When Augmented With A Second Constructor Parameter</b></td>
+ * <tr><td width="20%">
+ * <b>First Parameter</b></td><td><b>Second Parameter</b></td><td><b>Result</b></td></tr>
+ *
+ * <tr><td width="20%"><code>
+ * smb://host/share/a/b
+ * </code></td><td width="20%"><code>
+ * c/d
+ * </code></td><td><code>
+ * smb://host/share/a/b/c/d
+ * </code></td></tr>
+ *
+ * <tr><td width="20%"><code>
+ * smb://host/share/foo/bar
+ * </code></td><td width="20%"><code>
+ * /share2/zig/zag
+ * </code></td><td><code>
+ * smb://host/share2/zig/zag
+ * </code></td></tr>
+ *
+ * <tr><td width="20%"><code>
+ * smb://host/share/foo/bar
+ * </code></td><td width="20%"><code>
+ * ../zip
+ * </code></td><td><code>
+ * smb://host/share/foo/zip
+ * </code></td></tr>
+ *
+ * <tr><td width="20%"><code>
+ * smb://host/share/zig/zag
+ * </code></td><td width="20%"><code>
+ * smb://foo/bar
+ * </code></td><td><code>
+ * smb://foo/bar
+ * </code></td></tr>
+ *
+ * <tr><td width="20%"><code>
+ * smb://host/share/foo
+ * </code></td><td width="20%"><code>
+ * ../.././.././../foo
+ * </code></td><td><code>
+ * smb://foo
+ * </code></td></tr>
+ *
+ * <tr><td width="20%"><code>
+ * smb://host/share/zig/zag
+ * </code></td><td width="20%"><code>
+ * null
+ * </code></td><td><code>
+ * smb://host/share/zig/zag
+ * </code></td></tr>
+ *
+ * <tr><td width="20%"><code>
+ * smb://host/share/zig/zag
+ * </code></td><td width="20%"><code>
+ * /
+ * </code></td><td><code>
+ * smb://host
+ * </code></td></tr>
+ *
+ * <tr><td width="20%"><code>
+ * smb://server
+ * </code></td><td width="20%"><code>
+ * ..
+ * </code></td><td><code>
+ * smb://
+ * </code></td></tr>
+ *
+ * <tr><td width="20%"><code>
+ * smb://
+ * </code></td><td width="20%"><code>
+ * myworkgroup
+ * </code></td><td><code>
+ * smb://myworkgroup
+ * </code></td></tr>
+ *
+ * <tr><td width="20%"><code>
+ * smb://myworkgroup
+ * </code></td><td width="20%"><code>
+ * angus
+ * </code></td><td><code>
+ * smb://angus
+ * </code></td></tr>
+ *
+ * </table>
+ *
+ * <p>Notice there are two exceptional examples where the workgroup
+ * resource <code>smb://myworkgroup</code> and server <code>angus</code>
+ * are combined to produce just <code>smb://angus</code> and not
+ * <code>smb://myworkgroup/angus</code>. Similarly, when combining
+ * <code>smb://angus</code> with <code>..</code>,
+ * angus' workgroup resource <code>smb://myworkgroup</code> is <i>not</i>
+ * returned. This is by design and in accordance with the <a target="_top"
+ * href="http://www.ietf.org/internet-drafts/draft-crhertel-smb-url-00.txt">SMB
+ * Filesharing URL Scheme</a> IETF draft.
+ *
+ * <p>Instances of the <code>SmbFile</code> class are immutable; that is,
+ * once created, the abstract pathname represented by an SmbFile object
+ * will never change.
+ *
+ * @see java.io.File
+ * @since jcifs-0.4
+ */
+
+public class SmbFile {
+
+ // these are shifted for use in flags
+ static final int O_RDONLY = 0x010000;
+ static final int O_WRONLY = 0x020000;
+ static final int O_RDWR = 0x030000;
+ static final int O_APPEND = 0x040000;
+
+ // Open Function Encoding
+ // create if the file does not exist
+ static final int O_CREAT = 0x0010;
+ // fail if the file exists
+ static final int O_EXCL = 0x0001;
+ // truncate if the file exists
+ static final int O_TRUNC = 0x0002;
+
+ // file attribute encoding
+ static final int ATTR_READONLY = 0x01;
+ static final int ATTR_HIDDEN = 0x02;
+ static final int ATTR_SYSTEM = 0x04;
+ static final int ATTR_VOLUME = 0x08;
+ static final int ATTR_DIRECTORY = 0x10;
+ static final int ATTR_ARCHIVE = 0x20;
+
+ static {
+ // is this needed ??
+ try {
+ Class.forName( "jcifs.Config" );
+ } catch( ClassNotFoundException cnfe ) {
+ cnfe.printStackTrace();
+ }
+ }
+
+ SmbURL url;
+ String path;
+ SmbTree tree;
+ int fid, tid, hash;
+ int attributes = ATTR_READONLY | ATTR_DIRECTORY;
+ long lastModified, size;
+ boolean opened, isPipe;
+ NbtAddress address;
+
+/**
+ * Constructs an SmbFile representing a resource on an SMB network such as
+ * a file or directory. See the description and examples of smb URLs above.
+ *
+ * @param url A URL string
+ * @throws MalformedURLException
+ * If the <code>parent</code> and <code>child</code> parameters
+ * do not follow the prescribed syntax
+ * @throws UnknownHostException
+ * If the name of a server specified cannot be resolved using
+ * the configured name resolution methods
+ */
+
+ public SmbFile( String url ) throws MalformedURLException, UnknownHostException {
+ this( url, null );
+ }
+
+/**
+ * Constructs an SmbFile representing a resource on an SMB network such
+ * as a file or directory. The second parameter is a relative path from
+ * the <code>parent SmbFile</code>. See the description above for examples
+ * of using the second <code>name</code> parameter.
+ *
+ * @param parent A base <code>SmbFile</code>
+ * @param child A path string relative to the <code>parent</code> paremeter
+ * @throws MalformedURLException
+ * If the <code>parent</code> and <code>child</code> parameters
+ * do not follow the prescribed syntax
+ * @throws UnknownHostException
+ * If the name of a server specified cannot be resolved using
+ * the configured name resolution methods
+ */
+
+ public SmbFile( SmbFile parent, String child ) throws MalformedURLException,
+ UnknownHostException {
+ this( parent.getCanonicalPath(), child );
+ }
+
+/**
+ * Constructs an SmbFile representing a resource on an SMB network such
+ * as a file or directory. The second parameter is a relative path from
+ * the <code>parent</code>. See the description above for examples of
+ * using the second <code>chile</code> parameter.
+ *
+ * @param parent A URL string
+ * @param child A path string relative to the <code>parent</code> paremeter
+ * @throws MalformedURLException
+ * If the <code>parent</code> and <code>child</code> parameters
+ * do not follow the prescribed syntax
+ * @throws UnknownHostException
+ * If the name of a server specified cannot be resolved using
+ * the configured name resolution methods
+ */
+
+ public SmbFile( String parent, String child ) throws MalformedURLException,
+ UnknownHostException {
+ String share = "IPC$";
+ String unc;
+ String username = "";
+ String password = "";
+ String domain = "";
+ SmbTransport trans;
+ SmbSession ssn;
+
+ url = new SmbURL( parent, child );
+
+ if( url.isWorkgroup ) {
+ address = NbtAddress.getByName( url.server, 0x1d, null );
+ // Cannot est. session using name WORKGROUP<1D> so convert to IP<20> to force rev. lookup
+ address = NbtAddress.getByName( address.getHostAddress(), 0x20, null );
+ } else if( url.server != null && url.share != null ) {
+ address = NbtAddress.getByName( url.server, 0x20, null );
+ username = url.username;
+ password = url.password;
+ domain = url.domain;
+ share = url.share;
+ } else if( url.server != null ) {
+ address = NbtAddress.getByName( url.server, 0x20, null );
+ username = url.username;
+ password = url.password;
+ domain = url.domain;
+ } else {
+ address = NbtAddress.getByName( NbtAddress.MASTER_BROWSER_NAME, 0x01, null );
+ // Cannot est. session using name __MSBROWSE__<01> so convert to IP<20> to force rev. lookup
+ address = NbtAddress.getByName( address.getHostAddress(), 0x20, null );
+ }
+
+ trans = SmbTransport.getSmbTransport( address, url.port );
+ ssn = trans.getSmbSession( username, password, domain );
+ unc = new String( "\\\\" + address.getHostName() + "\\" + share ).toUpperCase();
+ tree = ssn.getSmbTree( unc, null );
+
+ if( url.canonicalPath == null ) {
+ path = "\\";
+ } else {
+ path = url.canonicalPath.replace( '/', '\\' );
+ }
+ opened = false;
+ }
+
+ boolean isOpen() {
+ if( opened && tree.treeConnected && tid == tree.tid ) {
+ return true;
+ }
+ return false;
+ }
+ void open( int flags ) throws IOException {
+ if( isOpen() ) {
+ return;
+ }
+ fid = tree.open( path, flags );
+ tid = tree.tid;
+ opened = true;
+ }
+ void close() throws IOException {
+ if( isOpen() == false ) {
+ return;
+ }
+ opened = false;
+
+ Log.println( Log.WARNINGS, "smb close warning",
+ " fid=" + fid );
+
+ /*
+ * Close Request / Response
+ */
+
+ tree.send( new SmbComClose( fid ), new SmbComBlankResponse() );
+ }
+
+
+/**
+ * Returns the last component of the target URL. This will
+ * effectively be the name of the file or directory represented by this
+ * <code>SmbFile</code> or in the case of URLs that only specify a server
+ * or workgroup, the server or workgroup will be returned. The name of
+ * the root URL <code>smb://</code> is also <code>smb://</code>.
+ *
+ * @return The last component of the URL associated with this SMB
+ * resource or <code>smb://</code> if the resource is <code>smb://</code>
+ * itself.
+ */
+
+ public String getName() {
+ String result;
+ int p;
+
+ if( url.server == null ) {
+ return "smb://";
+ }
+ result = url.toString();
+ p = result.lastIndexOf( '/' );
+ return result.substring( p + 1 );
+ }
+
+/**
+ * Everything but the last component of the URL representing this SMB
+ * resource is effectivly it's parent. The root URL <code>smb://</code>
+ * does not have a parent. In this case <code>smb://</code> is returned.
+ *
+ * @return The parent directory of this SMB resource or
+ * <code>smb://</code> if the resource refers to the root of the URL
+ * hierarchy which incedentally is also <code>smb://</code>.
+ */
+
+ public String getParent() {
+ String result;
+ int p;
+
+ if( url.share == null ) {
+ return "smb://";
+ }
+ result = url.toString();
+ p = result.lastIndexOf( '/' );
+ return result.substring( 0, p );
+ }
+
+/**
+ * Returns the full uncanonicalized URL of this SMB resource. An
+ * <code>SmbFile</code> constructed with the result of this method will
+ * result in an <code>SmbFile</code> that is equal to the original.
+ *
+ * @return The uncanonicalized full URL of this SMB resource.
+ */
+
+ public String getPath() {
+ return url.toString();
+ }
+
+/**
+ * Returns the full URL of this SMB resource with '.' and '..' components
+ * factored out. An <code>SmbFile</code> constructed with the result of
+ * this method will result in an <code>SmbFile</code> that is equal to
+ * the original.
+ *
+ * @return The canonicalized URL of this SMB resource.
+ */
+
+ public String getCanonicalPath() {
+ return url.getCanonicalPath();
+ }
+
+/**
+ * Retrieves the share associated with this SMB resource. In
+ * the case of <code>smb://</code>, <code>smb://workgroup</code>,
+ * and <code>smb://server</code> URLs which do not specify a share,
+ * <code>null</code> will be returned.
+ *
+ * @return The share component or <code>null</code> if there is no share
+ */
+
+ public String getShare() {
+ return url.share;
+ }
+
+/**
+ * Retrieve the hostname of the server for this SMB resource. If this
+ * <code>SmbFile</code> references a workgroup, the name of the workgroup
+ * is returned. If this <code>SmbFile</code> refers to the root of this
+ * SMB network hierarchy, <code>null</code> is returned.
+ *
+ * @return The server or workgroup name or <code>null</code> if this
+ * <code>SmbFile</code> refers to the root <code>smb://</code> resource.
+ */
+
+ public String getServer() {
+ return url.server;
+ }
+
+/**
+ * Determines wheather or not this resource is a workgroup by querying
+ * the NetBIOS name service. Only a URL of the form <code>smb://name</code>
+ * has the capacity to be a workgroup.
+ *
+ * @return <code>true</code> if this <code>SmbFile</code> refers to a
+ * workgroup and <code>false</code> otherwise.
+ */
+
+ public boolean isWorkgroup() {
+ return url.isWorkgroup;
+ }
+
+/**
+ * Tests to see if the SMB resource exists. If the resource refers
+ * only to a server, this method determines if the server exists on the
+ * network and is advertising SMB services. If this resource refers to
+ * a workgroup, this method determines if the workgroup name is valid on
+ * the local SMB network. If this <code>SmbFile</code> refers to the root
+ * <code>smb://</code> resource <code>true</code> is always returned. If
+ * this <code>SmbFile</code> is a traditional file or directory, it will
+ * be queried for on the specified server as expected.
+ *
+ * @return <code>true</code> if the resource exists or is alive or
+ * <code>false</code> otherwise
+ */
+
+ public boolean exists() {
+ attributes = ATTR_READONLY | ATTR_DIRECTORY;
+ lastModified = 0L;
+ try {
+ if( url.server == null ) {
+ } else if( url.share == null ) {
+ try {
+ if( url.isWorkgroup ) {
+ NbtAddress.getByName( url.server, 0x1d, null );
+ } else {
+ NbtAddress.getByName( url.server, 0x20, null );
+ }
+ } catch( UnknownHostException uhe ) {
+ return false;
+ }
+ } else {
+ if( url.share.equalsIgnoreCase( "IPC$" )) {
+ String[] shares = tree.netShareEnum();
+ for( int s = 0; s < shares.length; s++ ) {
+ if( shares[s].equalsIgnoreCase( "IPC$" )) {
+ return true;
+ }
+ }
+ return false;
+ }
+ if( path.equals( "\\" )) {
+ String[] shares = tree.netShareEnum();
+ for( int s = 0; s < shares.length; s++ ) {
+ if( shares[s].equalsIgnoreCase( url.share )) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ Info info = tree.queryPath( path,
+ Trans2QueryPathInformationResponse.SMB_QUERY_FILE_BASIC_INFO );
+ if( info == null ) {
+ return false;
+ }
+ attributes = info.getAttributes();
+ lastModified = info.getLastWriteTime();
+ }
+ return true;
+ } catch( Exception e ) {
+ Log.printStackTrace( Log.NON_CRITICAL_EXCEPTIONS, "SmbFile exception", e );
+ }
+ return false;
+ }
+
+/**
+ * Tests to see if the file this <code>SmbFile</code> represents can be
+ * read. Because any file, directory, or other resource can be read if it
+ * exists, this method simply calls the <code>exists</code> method.
+ *
+ * @return <code>true</code> if the file is read-only
+ */
+
+ public boolean canRead() {
+ return exists();
+ }
+
+/**
+ * Tests to see if the file this <code>SmbFile</code> represents
+ * exists and is not marked read-only. By default, resources are
+ * considered to be read-only and therefore for <code>smb://</code>,
+ * <code>smb://workgroup</code>, and <code>smb://server</code> resources
+ * will be read-only.
+ *
+ * @return <code>true</code> if the resource exists is not marked
+ * read-only
+ */
+
+ public boolean canWrite() {
+ if( isPipe ) {
+ return true;
+ }
+ return exists() && ( attributes & ATTR_READONLY ) == 0;
+ }
+
+/**
+ * Tests to see if the file this <code>SmbFile</code> represents is a directory.
+ *
+ * @return <code>true</code> if this <code>SmbFile</code> is a directory
+ */
+
+ public boolean isDirectory() {
+ return exists() && ( attributes & ATTR_DIRECTORY ) == ATTR_DIRECTORY;
+ }
+
+/**
+ * Tests to see if the file this <code>SmbFile</code> represents is not a directory.
+ *
+ * @return <code>true</code> if this <code>SmbFile</code> is not a directory
+ */
+
+ public boolean isFile() {
+ return exists() && ( attributes & ATTR_DIRECTORY ) == 0;
+ }
+
+/**
+ * Tests to see if the file this SmbFile represents is marked as hidden.
+ *
+ * @return <code>true</code> if the <code>SmbFile</code> is marked as being hidden
+ */
+
+ public boolean isHidden() {
+ if( url.share == null ) {
+ return false;
+ } else if( path.length() == 1 ) {
+ if( url.share.endsWith( "$" )) {
+ return true;
+ }
+ return false;
+ }
+ exists();
+ return ( attributes & ATTR_HIDDEN ) == ATTR_HIDDEN;
+ }
+
+/**
+ * Retrieve the last time the file represented by this
+ * <code>SmbFile</code> was modified. The value returned is suitable
+ * for constructing a {@link java.util.Date} object and is adjusted for
+ * the servers timezone differential. Times should be the same as those
+ * reported using the properties dialog of the Windows Explorer program.
+ *
+ * @return The number of milliseconds since the 00:00:00 GMT, January 1,
+ * 1970 as a <code>long</code> value
+ */
+
+ public long lastModified() {
+ exists();
+ return lastModified;
+ }
+
+/**
+ * List the contents of this SMB resource. The list returned by this method will be;
+ *
+ * <ul>
+ * <li> files and directories contained within this resource if the resource is a normal disk file directory,
+ * <li> all available NetBIOS workgroups or domains if this resource is the top level URL <code>smb://</code>,
+ * <li> all servers registered as members of a NetBIOS workgroup if this resource refers to a workgroup in a <code>smb://workgroup</code> URL,
+ * <li> all browseable shares of a server including printers, IPC services, or disk volumes if this resource is a server URL in the form <code>smb://server</code>,
+ * <li> or <code>null</code> if the resource cannot be resolved.
+ * </ul>
+ *
+ * @return A <code>String</code> array of file and directories, workgroups, servers, or shares depending on the context of the resource URL
+ */
+
+ public String[] list() {
+ try {
+ if( url.server == null ) {
+ try {
+ SmbTree.setLmbTree( this );
+ } catch( IOException ioe ) {
+ Log.printStackTrace(
+ "smb exception contacting local master browser", ioe );
+ return null;
+ }
+ return tree.domainEnum();
+ } else if( url.share == null ) {
+ if( url.isWorkgroup ) {
+ return tree.netServerEnum2( url.server );
+ } else {
+ return tree.netShareEnum();
+ }
+ }
+ return tree.find( path );
+ } catch( Exception e ) {
+ Log.printStackTrace( Log.NON_CRITICAL_EXCEPTIONS, "SmbFile exception", e );
+ }
+ return null;
+ }
+
+/**
+ * Changes the name of the file this <code>SmbFile</code> represents to the name
+ * designated by the <code>SmbFile</code> argument(Remember:
+ * <code>SmbFile</code>s are immutible
+ * and therefore the path associated with this <code>SmbFile</code> object will not
+ * change).
+ *
+ * @param dest An <code>SmbFile</code> that represents the new pathname
+ * @return <code>true</code> if the file or directory was successfully renamed
+ * @throws NullPointerException
+ * If the <code>dest</code> argument is <code>null</code>
+ */
+
+ public boolean renameTo( SmbFile dest ) {
+ try {
+ if( dest.exists() ) {
+ // otherwise we get Access Denied
+ if(( dest.attributes & ATTR_DIRECTORY ) == ATTR_DIRECTORY ) {
+ Log.println( Log.WARNINGS, "SmbFile warning",
+ " cannot renameTo() a directory that exists: " + dest.getName() );
+ return false;
+ }
+ if( dest.delete() == false ) {
+ return false;
+ }
+ }
+ return tree.rename( path, dest.path );
+ } catch( Exception e ) {
+ Log.printStackTrace( Log.NON_CRITICAL_EXCEPTIONS, "SmbFile exception", e );
+ }
+ return false;
+ }
+
+/**
+ * This method will delete the file or directory specified by this
+ * <code>SmbFile</code>. If the target is a directory, the contents of
+ * the directory will be deleted as well.
+ *
+ * @return <code>true</code> if the delete operation was successfull and
+ * <code>false</code> otherwise
+ */
+
+ public boolean delete() {
+ if( path.length() > 1 ) {
+ if( exists() ) {
+ try {
+ return tree.delete( path, ( attributes & ATTR_DIRECTORY ) == ATTR_DIRECTORY );
+ } catch( Exception e ) {
+ Log.printStackTrace( Log.NON_CRITICAL_EXCEPTIONS, "SmbFile exception", e );
+ }
+ }
+ } else {
+ Log.println( Log.WARNINGS, "SmbFile warning",
+ " cannot delete servers, workgroups, or shares" );
+ }
+ return false;
+ }
+
+/**
+ * Returns the length in bytes of this file represented by this
+ * <code>SmbFile</code>. The <code>SmbFile</code> must not be a directory.
+ *
+ * @return The length of the file in bytes
+ */
+
+ public long length() {
+ Info info = null;
+ if( path.length() > 1 ) {
+ try {
+ int infoLevel =
+ Trans2QueryPathInformationResponse.SMB_QUERY_FILE_STANDARD_INFO;
+ info = tree.queryPath( path, infoLevel );
+ } catch( Exception e ) {
+ info = null;
+ Log.printStackTrace( Log.NON_CRITICAL_EXCEPTIONS, "SmbFile exception", e );
+ }
+ if( info != null && ( info.getAttributes() & ATTR_DIRECTORY ) == 0 ) {
+ // will do long a little later. not hard.
+ size = info.getSize();
+ return size;
+ }
+ }
+ return 0L;
+ }
+
+/**
+ * Creates a directory with the path specified by this
+ * <code>SmbFile</code>. For this method to be successfull, the target
+ * must not already exist. This method will return false when
+ * used with <code>smb://</code>, <code>smb://workgroup</code>,
+ * <code>smb://server</code>, or <code>smb://server/share</code> URLs
+ * because workgroups, servers, and shares cannot be dynamically created.
+ *
+ * @return <code>true</code> if the file was successfully created or
+ * <code>false</code> otherwise
+ */
+
+ public boolean mkdir() {
+ if( path.length() > 1 ) {
+ try {
+ return tree.createDirectory( path );
+ } catch( Exception e ) {
+ Log.printStackTrace( Log.NON_CRITICAL_EXCEPTIONS, "SmbFile exception", e );
+ }
+ } else {
+ Log.println( Log.WARNINGS, "SmbFile warning",
+ " cannot create servers, workgroups, or shares with mkdir" );
+ }
+ return false;
+ }
+
+/**
+ * Returns a {@link java.net.URL} for this <code>SmbFile</code>. The
+ * <code>URL</code> may be used as any other <code>URL</code> might to
+ * access an smb resource. Currently only retrieving data and information
+ * is supported.
+ *
+ * @return A new <code>URL</code> for this <code>SmbFile</code>
+ */
+
+ public URL toURL() throws MalformedURLException {
+ return new URL( url.toString() );
+ }
+
+/**
+ * Computes a hashCode for this file based on the URL string and IP
+ * address if the server. The hashing function uses the hashcode of the
+ * server address, the canonical representation of the URL, and does not
+ * compare authentication information. In essance, two
+ * <code>SmbFile</code> objects that refer to
+ * the same file should generate the same hashcode provided it is possible
+ * to make such a determination.
+ *
+ * @return A hashcode for this abstract file
+ */
+
+ public int hashCode() {
+ if( hash == 0 ) {
+ hash = address.hashCode();
+ if( url.port != 0 && url.port != 139 ) {
+ hash += 65621 * url.port;
+ }
+ if( url.share != null ) {
+ hash += 65521 * url.share.toUpperCase().hashCode();
+ if( url.canonicalPath != null ) {
+ hash += 65521 * url.canonicalPath.toUpperCase().hashCode();
+ }
+ }
+ }
+ return hash;
+ }
+
+/**
+ * Tests to see if two <code>SmbFile</code> objects are equal. Two
+ * SmbFile objects are equal when they reference the same SMB
+ * resource. More specifically, two <code>SmbFile</code> objects are
+ * equals if their server IP addresses are equal and the canonicalized
+ * representation of their URLs, minus authentication parameters, are
+ * case insensitivly and lexographically equal. For example, assuming the
+ * server <code>angus</code> resolves to the <code>192.168.1.15</code>
+ * IP address, the below URLs would result in <code>SmbFile</code>s
+ * that are equal.
+ *
+ * <p><blockquote><pre>
+ * smb://192.168.1.15/share/DIR/foo.txt
+ * smb://angus/share/data/../dir/foo.txt
+ * </pre></blockquote>
+ *
+ * @param obj Another <code>SmbFile</code> object to compare for equality
+ * @return <code>true</code> if the two objects refer to the same SMB resource
+ * and <code>false</code> otherwise
+ */
+
+ public boolean equals( Object obj ) {
+ return obj instanceof SmbFile && obj.hashCode() == hashCode();
+ }
+
+/**
+ * Returns the string representation of this SmbFile object. This will
+ * be the same as the URL used to construct this <code>SmbFile</code>. The
+ * path will not be canonicalized. This method will return the same value
+ * as <code>getPath</code>.
+ *
+ * @return The URL representation of this SMB resource
+ */
+
+ public String toString() {
+ return url.toString();
+ }
+
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * This InputStream can read bytes from a file on an SMB file server.
+ */
+
+public class SmbFileInputStream extends InputStream {
+
+ private SmbFile file;
+ private int fp, off, readSize, openFlags;
+ private byte[] tmp = new byte[1];
+
+/**
+ * Creates an {@link java.io.InputStream} for reading bytes from a file on
+ * an SMB server addressed by the <code>url</code> parameter. See {@link
+ * jcifs.smb.SmbFile} for a detailed description and examples of the smb
+ * URL syntax.
+ *
+ * @param url An smb URL string representing the file to read from
+ * @return A new <code>InputStream</code> for the specified <code>SmbFile</code>
+ * @throws IOException if a network error occurs
+ */
+
+ public SmbFileInputStream( String url ) throws IOException {
+ this( new SmbFile( url ));
+ }
+
+/**
+ * Creates an {@link java.io.InputStream} for reading bytes from a file on
+ * an SMB server represented by the {@link jcifs.smb.SmbFile} parameter. See
+ * {@link jcifs.smb.SmbFile} for a detailed description and examples of
+ * the smb URL syntax.
+ *
+ * @param url An smb URL string representing the file to write to
+ * @return A new <code>InputStream</code> for the specified <code>SmbFile</code>
+ * @throws IOException if a network error occurs
+ */
+
+ public SmbFileInputStream( SmbFile file ) throws IOException {
+ this( file, SmbFile.O_RDONLY );
+ }
+
+ SmbFileInputStream( SmbFile file, int openFlags ) throws IOException {
+ this.file = file;
+ this.openFlags = openFlags;
+ file.open( openFlags );
+ readSize = Math.min( file.tree.session.transport.rcv_buf_size - 70,
+ file.tree.session.transport.server.maxBufferSize - 70 );
+ }
+
+/**
+ * Closes this input stream and releases any system resources associated with the stream.
+ *
+ * @throws IOException if a network error occurs
+ */
+
+ public void close() throws IOException {
+ file.close();
+ }
+
+/**
+ * Reads a byte of data from this input stream.
+ *
+ * @throws IOException if a network error occurs
+ */
+
+ public int read() throws IOException {
+ // need oplocks to cache otherwise use BufferedInputStream
+ if( read( tmp, 0, 1 ) == -1 ) {
+ return -1;
+ }
+ return tmp[0] & 0xFF;
+ }
+
+/**
+ * Reads up to b.length bytes of data from this input stream into an array of bytes.
+ *
+ * @throws IOException if a network error occurs
+ */
+
+ public int read( byte[] b ) throws IOException {
+ return read( b, 0, b.length );
+ }
+
+/**
+ * Reads up to len bytes of data from this input stream into an array of bytes.
+ *
+ * @throws IOException if a network error occurs
+ */
+
+ public int read( byte[] b, int off, int len ) throws IOException {
+ if( len <= 0 ) {
+ return 0;
+ }
+ int start = fp;
+
+ // ensure file is open
+ if( file.isOpen() == false ) {
+ file.open( openFlags );
+ }
+
+ Log.println( Log.WARNINGS, "smb read warning",
+ " fid=" + file.fid + ",off=" + off + ",len=" + len );
+
+ /*
+ * Read AndX Request / Response
+ */
+
+ SmbComReadAndXResponse response = new SmbComReadAndXResponse( b, off );
+
+ if( file.isPipe ) {
+ response.responseTimeout = 0;
+ }
+
+ int r, n;
+ do {
+ r = len > readSize ? readSize : len;
+//System.out.println( "len=" + len + ",r=" + r + ",fp=" + fp );
+ try {
+ file.tree.send( new SmbComReadAndX( file.fid, fp, r, null ), response );
+ } catch( SmbException se ) {
+ if( file.isPipe && se.errorClass == SmbException.ERRDOS &&
+ se.errorCode == SmbException.ERRbrokenpipe ) {
+ return -1;
+ }
+ throw se;
+ }
+ if(( n = response.dataLength ) <= 0 ) {
+ return -1;
+ }
+//System.out.println( "n=" + n );
+ fp += n;
+ len -= n;
+ response.off += n;
+ } while( len > 0 && n == r );
+
+ return fp - start;
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import java.io.OutputStream;
+import java.io.IOException;
+
+/**
+ * This <code>OutputStream</code> can write bytes to a file on an SMB file server.
+ */
+
+public class SmbFileOutputStream extends OutputStream {
+
+ private SmbFile file;
+ private boolean append;
+ private int openFlags, fp, writeSize;
+ private byte[] tmp = new byte[1];
+
+/**
+ * Creates an {@link java.io.OutputStream} for writing to a file
+ * on an SMB server addressed by the URL parameter. See {@link
+ * jcifs.smb.SmbFile} for a detailed description and examples of
+ * the smb URL syntax.
+ *
+ * @param url An smb URL string representing the file to write to
+ * @return A new <code>OutputStream</code> for the specified file
+ * @throws IOException if a network error occurs
+ */
+
+ public SmbFileOutputStream( String url ) throws IOException {
+ this( url, false );
+ }
+
+/**
+ * Creates an {@link java.io.OutputStream} for writing bytes to a file on
+ * an SMB server represented by the {@link jcifs.smb.SmbFile} parameter. See
+ * {@link jcifs.smb.SmbFile} for a detailed description and examples of
+ * the smb URL syntax.
+ *
+ * @param url An <code>SmbFile</code> specifying the file to write to
+ * @return A new <code>OutputStream</code> for the specified <code>SmbFile</code>
+ * @throws IOException if a network error occurs
+ */
+
+ public SmbFileOutputStream( SmbFile file ) throws IOException {
+ this( file, false );
+ }
+
+/**
+ * Creates an {@link java.io.OutputStream} for writing bytes to a file on an
+ * SMB server addressed by the URL parameter. See {@link jcifs.smb.SmbFile}
+ * for a detailed description and examples of the smb URL syntax. If the
+ * second argument is <code>true</code>, then bytes will be written to the
+ * end of the file rather than the beginning.
+ *
+ * @param url An smb URL string representing the file to write to
+ * @return A new <code>OutputStream</code> for the specified <code>url</code>
+ * @throws IOException if a network error occurs
+ */
+
+ public SmbFileOutputStream( String url, boolean append ) throws IOException {
+ this( new SmbFile( url ), append );
+ }
+
+/**
+ * Creates an {@link java.io.OutputStream} for writing bytes to a file
+ * on an SMB server addressed by the <code>SmbFile</code> parameter. See
+ * {@link jcifs.smb.SmbFile} for a detailed description and examples of
+ * the smb URL syntax. If the second argument is <code>true</code>, then
+ * bytes will be written to the end of the file rather than the beginning.
+ *
+ * @param url An <code>SmbFile</code> representing the file to write to
+ * @return A new <code>OutputStream</code> for the specified <code>SmbFile</code>
+ * @throws IOException if a network error occurs
+ */
+
+ public SmbFileOutputStream( SmbFile file, boolean append ) throws IOException {
+ this( file, append, append ? SmbFile.O_CREAT | SmbFile.O_WRONLY | SmbFile.O_APPEND :
+ SmbFile.O_CREAT | SmbFile.O_WRONLY | SmbFile.O_TRUNC );
+ }
+
+ SmbFileOutputStream( SmbFile file, boolean append, int openFlags ) throws IOException {
+ this.file = file;
+ this.append = append;
+ this.openFlags = openFlags;
+ if( append ) {
+ fp = (int)file.length();
+ }
+ file.open( openFlags );
+ writeSize = Math.min( file.tree.session.transport.snd_buf_size - 70,
+ file.tree.session.transport.server.maxBufferSize - 70 );
+ }
+
+/**
+ * Closes this output stream and releases any system resources associated
+ * with it.
+ *
+ * @throws IOException if a network error occurs
+ */
+
+ public void close() throws IOException {
+ file.close();
+ }
+
+/**
+ * Writes the specified byte to this file output stream.
+ *
+ * @throws IOException if a network error occurs
+ */
+
+ public void write( int b ) throws IOException {
+ tmp[0] = (byte)b;
+ write( tmp, 0, 1 );
+ }
+
+/**
+ * Writes b.length bytes from the specified byte array to this
+ * file output stream.
+ *
+ * @throws IOException if a network error occurs
+ */
+
+ public void write( byte[] b ) throws IOException {
+ write( b, 0, b.length );
+ }
+
+/**
+ * Writes len bytes from the specified byte array starting at
+ * offset off to this file output stream.
+ *
+ * @param b The array
+ * @throws IOException if a network error occurs
+ */
+
+ public void write( byte[] b, int off, int len ) throws IOException {
+ if( len <= 0 ) {
+ return;
+ }
+
+ // ensure file is open
+ if( file.isOpen() == false ) {
+ file.open( openFlags );
+ if( append ) {
+ fp = (int)file.length();
+ }
+ }
+
+ Log.println( Log.WARNINGS, "smb write warning",
+ " fid=" + file.fid + ",off=" + off + ",len=" + len );
+ int w;
+ do {
+ w = len > writeSize ? writeSize : len;
+ file.tree.send( new SmbComWriteAndX( file.fid, fp, len - w, b, off, w, null ),
+ new SmbComWriteAndXResponse() );
+ fp += w;
+ len -= w;
+ off += w;
+ } while( len > 0 );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ * "Paul Walker" <Paul.Walker@NBNZ.CO.NZ>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.UnknownHostException;
+
+/**
+ * This class will allow a Java program to read and write data to Named
+ * Pipes and Transact NamedPipes.
+ *
+ * <p>There are three Win32 function calls provided by the Windows SDK
+ * that are important in the context of using jCIFS. They are:
+ *
+ * <ul>
+ * <li> <code>CallNamedPipe</code> A message-type pipe call that opens,
+ * writes to, reads from, and closes the pipe in a single operation.
+ * <li> <code>TransactNamedPipe</code> A message-type pipe call that
+ * writes to and reads from an existing pipe descriptor in one operation.
+ * <li> <code>CreateFile</code>, <code>ReadFile</code>,
+ * <code>WriteFile</code>, and <code>CloseFile</code> A byte-type pipe can
+ * be opened, written to, read from and closed using the standard Win32
+ * file operations.
+ * </ul>
+ *
+ * <p>The jCIFS API maps all of these operations into the standard Java
+ * <code>XxxputStream</code> interface. A special <code>PIPE_TYPE</code>
+ * flags is necessary to distinguish which type of Named Pipe behavior
+ * is desired.
+ *
+ * <p><table border="1" cellpadding="3" cellspacing="0" width="100%">
+ * <tr bgcolor="#ccccff">
+ * <td colspan="2"><b><code>SmbNamedPipe</code> Constructor Examples</b></td>
+ * <tr><td width="20%"><b>Code Sample</b></td><td><b>Description</b></td></tr>
+ * <tr><td width="20%"><pre>
+ * new SmbNamedPipe( "smb://server/IPC$/PIPE/foo",
+ * SmbNamedPipe.PIPE_TYPE_RDWR |
+ * SmbNamedPipe.PIPE_TYPE_CALL );
+ * </pre></td><td>
+ * Open the Named Pipe foo for reading and writing. The pipe will behave like the <code>CallNamedPipe</code> interface.
+ * </td></tr>
+ * <tr><td width="20%"><pre>
+ * new SmbNamedPipe( "smb://server/IPC$/foo",
+ * SmbNamedPipe.PIPE_TYPE_RDWR |
+ * SmbNamedPipe.PIPE_TYPE_TRANSACT );
+ * </pre></td><td>
+ * Open the Named Pipe foo for reading and writing. The pipe will behave like the <code>TransactNamedPipe</code> interface.
+ * </td></tr>
+ * <tr><td width="20%"><pre>
+ * new SmbNamedPipe( "smb://server/IPC$/foo",
+ * SmbNamedPipe.PIPE_TYPE_RDWR );
+ * </pre></td><td>
+ * Open the Named Pipe foo for reading and writing. The pipe will
+ * behave as though the <code>CreateFile</code>, <code>ReadFile</code>,
+ * <code>WriteFile</code>, and <code>CloseFile</code> interface was
+ * being used.
+ * </td></tr>
+ * </table>
+ *
+ * <p>See <a href="../../../pipes.html">Using jCIFS to Connect to Win32
+ * Named Pipes</a> for a detailed description of how to use jCIFS with
+ * Win32 Named Pipe server processes.
+ *
+ * @since jcifs-0.5
+ */
+
+public class SmbNamedPipe extends SmbFile {
+
+ /**
+ * The pipe should be opened read-only.
+ */
+
+ public static final int PIPE_TYPE_RDONLY = O_RDONLY;
+
+ /**
+ * The pipe should be opened only for writing.
+ */
+
+ public static final int PIPE_TYPE_WRONLY = O_WRONLY;
+
+ /**
+ * The pipe should be opened for both reading and writing.
+ */
+
+ public static final int PIPE_TYPE_RDWR = O_RDWR;
+
+ /**
+ * Pipe operations should behave like the <code>CallNamedPipe</code> Win32 Named Pipe function.
+ */
+
+ public static final int PIPE_TYPE_CALL = 0x01;
+
+ /**
+ * Pipe operations should behave like the <code>TransactNamedPipe</code> Win32 Named Pipe function.
+ */
+
+ public static final int PIPE_TYPE_TRANSACT = 0x02;
+
+ InputStream pipeIn;
+ OutputStream pipeOut;
+ int pipeType;
+
+ /**
+ * Open the Named Pipe resource specified by the url
+ * parameter. The pipeType parameter should be at least one of
+ * the <code>PIPE_TYPE</code> flags combined with the bitwise OR
+ * operator <code>|</code>. See the examples listed above.
+ */
+
+ public SmbNamedPipe( String url, int pipeType )
+ throws MalformedURLException, UnknownHostException {
+ super( url );
+ this.pipeType = pipeType;
+ isPipe = true;
+ }
+
+ /**
+ * Return the <code>InputStream</code> used to read information
+ * from this pipe instance. Presumably data would first be written
+ * to the <code>OutputStream</code> associated with this Named
+ * Pipe instance although this is not a requirement (e.g. a
+ * read-only named pipe would write data to this stream on
+ * connection). Reading from this stream may block. Therefore it
+ * may be necessary that an addition thread be used to read and
+ * write to a Named Pipe.
+ */
+
+ public InputStream getNamedPipeInputStream() throws IOException {
+ if( pipeIn == null ) {
+ if(( pipeType & PIPE_TYPE_CALL ) == PIPE_TYPE_CALL ||
+ ( pipeType & PIPE_TYPE_TRANSACT ) == PIPE_TYPE_TRANSACT ) {
+ pipeIn = new TransactNamedPipeInputStream();
+ } else {
+ pipeIn = new SmbFileInputStream( this,
+ ( pipeType & 0xFF0000 ) | SmbFile.O_EXCL );
+ }
+ }
+ return pipeIn;
+ }
+
+ /**
+ * Return the <code>OutputStream</code> used to write
+ * information to this pipe instance. The act of writing data
+ * to this stream will result in response data recieved in the
+ * <code>InputStream</code> associated with this Named Pipe
+ * instance (unless of course it does not elicite a response or the pipe is write-only).
+ */
+
+ public OutputStream getNamedPipeOutputStream() throws IOException {
+ if( pipeOut == null ) {
+ if(( pipeType & PIPE_TYPE_CALL ) == PIPE_TYPE_CALL ||
+ ( pipeType & PIPE_TYPE_TRANSACT ) == PIPE_TYPE_TRANSACT ) {
+ pipeOut = new TransactNamedPipeOutputStream( this );
+ } else {
+ pipeOut = new SmbFileOutputStream( this, false,
+ ( pipeType & 0xFF0000 ) | SmbFile.O_EXCL );
+ }
+ }
+ return pipeOut;
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import jcifs.netbios.NbtAddress;
+import jcifs.util.DES;
+import jcifs.util.MD4;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.Hashtable;
+import java.util.Vector;
+import java.util.Enumeration;
+import java.net.InetAddress;
+
+class SmbSession {
+
+ // KGS!@#$%
+ static final byte[] S8 = {
+ (byte)0x4b, (byte)0x47, (byte)0x53, (byte)0x21,
+ (byte)0x40, (byte)0x23, (byte)0x24, (byte)0x25
+ };
+ static void E( byte[] key, byte[] data, byte[] e ) {
+ byte[] key7 = new byte[7];
+ byte[] e8 = new byte[8];
+
+ for( int i = 0; i < key.length / 7; i++ ) {
+ System.arraycopy( key, i * 7, key7, 0, 7 );
+ DES des = new DES( key7 );
+ des.encrypt( data, e8 );
+ System.arraycopy( e8, 0, e, i * 8, 8 );
+ }
+ }
+ static byte[] getPreNTLMResponse( String password, byte[] challenge ) {
+ byte[] p14 = new byte[14];
+ byte[] p21 = new byte[21];
+ byte[] p24 = new byte[24];
+
+ System.arraycopy( password.toUpperCase().getBytes(), 0, p14, 0, password.length() );
+ E( p14, S8, p21);
+ E( p21, challenge, p24);
+ return p24;
+ }
+ static byte[] getNTLMResponse( String password, byte[] challenge ) {
+ byte[] uni = null;
+ byte[] p21 = new byte[21];
+ byte[] p24 = new byte[24];
+
+ try {
+ uni = password.getBytes( "UnicodeLittleUnmarked" );
+ } catch( UnsupportedEncodingException uee ) {
+ Log.printStackTrace( "password encryption exception", uee );
+ }
+ MD4 md4 = new MD4();
+ md4.update( uni );
+ System.arraycopy( md4.digest(), 0, p21, 0, 16 );
+ E( p21, challenge, p24 );
+ return p24;
+ }
+
+ int uid;
+ String username, password, domain;
+ SmbTransport transport;
+ Vector trees;
+ boolean sessionSetup;
+ String passwordString = "*****";
+
+ SmbSession( SmbTransport transport, String username,
+ String password, String domain ) {
+ this.transport = transport;
+ this.username = username.toUpperCase();
+ this.password = password;
+ this.domain = domain.toUpperCase();
+ trees = new Vector();
+ sessionSetup = false;
+
+ if( password == null ) {
+ passwordString = "null";
+ } else if( password.length() == 0 ) {
+ passwordString = "";
+ }
+ }
+
+ synchronized SmbTree getSmbTree( String path, String service ) {
+ SmbTree t;
+ for( Enumeration e = trees.elements(); e.hasMoreElements(); ) {
+ t = (SmbTree)e.nextElement();
+ if( t.matches( path, service )) {
+ return t;
+ }
+ }
+ t = new SmbTree( this, path, service );
+ trees.addElement( t );
+ return t;
+ }
+ boolean matches( String username, String password, String domain ) {
+ return this.username.equals( username.toUpperCase() ) &&
+ this.password.equals( password ) &&
+ this.domain.equals( domain.toUpperCase() );
+ }
+ void sendTransaction( SmbComTransaction request,
+ SmbComTransactionResponse response ) throws IOException {
+ // transactions are not batchable
+ sessionSetup( null, null );
+ request.uid = uid;
+ transport.sendTransaction( request, response );
+ }
+ void send( ServerMessageBlock request,
+ ServerMessageBlock response ) throws IOException {
+ if( response != null ) {
+ response.received = false;
+ }
+ sessionSetup( request, response );
+ if( response != null && response.received ) {
+ return;
+ }
+ request.uid = uid;
+ transport.send( request, response );
+ }
+ synchronized void sessionSetup( ServerMessageBlock andx,
+ ServerMessageBlock andxResponse )
+ throws IOException {
+
+ if( sessionSetup ) {
+ return;
+ }
+
+ Log.println( Log.WARNINGS, "smb session setup warning",
+ " requesting session with accountName=" + username +
+ ",accountPassword=" + passwordString +
+ ",primaryDomain=" + domain );
+
+ /*
+ * Session Setup And X Request / Response
+ */
+
+ SmbComSessionSetupAndXResponse response =
+ new SmbComSessionSetupAndXResponse( andxResponse );
+ transport.send( new SmbComSessionSetupAndX( this, andx ), response );
+
+ uid = response.uid;
+ sessionSetup = true;
+ }
+ synchronized void logoff() throws IOException {
+ if( sessionSetup == false ) {
+ return;
+ }
+
+ for( Enumeration e = trees.elements(); e.hasMoreElements(); ) {
+ SmbTree t = (SmbTree)e.nextElement();
+ t.treeDisconnect();
+ }
+ sessionSetup = false;
+
+ if( transport.server.security == ServerMessageBlock.SECURITY_SHARE ) {
+ return;
+ }
+
+ /*
+ * Logoff And X Request / Response
+ */
+
+ SmbComLogoffAndX request = new SmbComLogoffAndX( null );
+ request.uid = uid;
+ transport.send( request, null );
+ }
+ public String toString() {
+ return "SmbSession[accountName=" + username +
+ ",accountPassword=" + passwordString +
+ ",primaryDomain=" + domain +
+ ",uid=" + uid + "]";
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import jcifs.netbios.NbtSocket;
+import jcifs.netbios.NbtException;
+import jcifs.netbios.NbtAddress;
+import jcifs.Config;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PushbackInputStream;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.InetAddress;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.Vector;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+class SmbTransport implements Runnable {
+
+ private static final int DEFAULT_MAX_MPX_COUNT = 10;
+ private static final int DEFAULT_RESPONSE_TIMEOUT = 10000;
+ private static final int DEFAULT_SO_TIMEOUT = 15000;
+ private static final int PUSHBACK_BUF_SIZE = 64;
+ private static final int DEFAULT_RCV_BUF_SIZE = 4096;
+ private static final int DEFAULT_SND_BUF_SIZE = 1300;
+
+ static final int MID_OFFSET = 30;
+ static final int HEADER_LENGTH = 32;
+ static final int FLAGS_OFFSET = 9;
+ static final int FLAGS_RESPONSE = 0x80;
+
+ private byte[] rcv_buf, snd_buf;
+
+ private NbtSocket socket;
+ private InputStream in;
+ private OutputStream out;
+ private int localPort, soTimeout, responseTimeout;
+ private long closeTime;
+ private InetAddress localAddr;
+ private Hashtable responseTable;
+ private Thread thread;
+ private Object outLock;
+
+ private static Vector connections = new Vector();
+ private static MpxControl mpxCtrl = new MpxControl();
+
+ Vector sessions;
+ boolean negotiated, useUnicode;
+
+ NbtAddress address;
+ int port, rcv_buf_size, snd_buf_size;
+
+ int negotiatedDialectIndex;
+ int negotiatedMaxMpxCount;
+ int negotiatedMaxBufferSize;
+ int negotiatedCapabilities;
+
+ ClientProperties client = new ClientProperties();
+ ServerProperties server = new ServerProperties();
+
+ class ClientProperties {
+ int maxMpxCount = Config.getInt( "jcifs.smb.client.maxMpxCount",
+ DEFAULT_MAX_MPX_COUNT );
+ int maxBufferSize = Config.getInt( "jcifs.smb.client.snd_buf_size",
+ DEFAULT_SND_BUF_SIZE );
+ int sessionKey = 0x00000000;
+ /* NT 4 Workstation client capabilities 0x00D4
+ * we don't do NT Status Codes or Level II oplocks
+ * but we could do raw and mpx
+ */
+ int flags2 = Config.getInt( "jcifs.smb.client.flags2",
+ ServerMessageBlock.FLAGS2_LONG_FILENAMES |
+ ServerMessageBlock.FLAGS2_UNICODE );
+ int capabilities = Config.getInt( "jcifs.smb.client.capabilities",
+ ServerMessageBlock.CAP_UNICODE | ServerMessageBlock.CAP_NT_SMBS );
+ String nativeOs = Config.getProperty( "jcifs.smb.client.nativeOs",
+ System.getProperty( "os.name" ));
+ String nativeLanMan = Config.getProperty( "jcifs.smb.client.nativeLanMan", "foo" );
+ int vcNumber = 1;
+ }
+ class ServerProperties {
+ byte flags;
+ int flags2;
+ int maxMpxCount;
+ int maxBufferSize;
+ int sessionKey;
+ // NT 4 Workstation is 0x43FD
+ int capabilities;
+ String oemDomainName;
+ String primaryDomain;
+ String nativeOs;
+ String nativeLanMan;
+
+ int securityMode;
+ int security;
+ boolean encryptedPasswords;
+ boolean signaturesEnabled;
+ boolean signaturesRequired;
+ int maxNumberVcs;
+ int maxRawSize;
+ long serverTime;
+ int serverTimeZone;
+ int encryptionKeyLength;
+ byte[] encryptionKey;
+ }
+
+ static synchronized SmbTransport getSmbTransport( NbtAddress address, int port ) {
+ return getSmbTransport( address, port,
+ Config.getInetAddress( "jcifs.smb.client.laddr", null ),
+ Config.getInt( "jcifs.smb.client.lport", 0 ));
+ }
+ static synchronized SmbTransport getSmbTransport( NbtAddress address, int port,
+ InetAddress localAddr, int localPort ) {
+ SmbTransport conn;
+ for( Enumeration e = connections.elements(); e.hasMoreElements(); ) {
+ conn = (SmbTransport)e.nextElement();
+ if( conn.matches( address, port, localAddr, localPort )) {
+ return conn;
+ }
+ }
+ conn = new SmbTransport( address, port, localAddr, localPort );
+ connections.addElement( conn );
+ return conn;
+ }
+
+ SmbTransport( NbtAddress address, int port, InetAddress localAddr, int localPort ) {
+ this.address = address;
+ this.port = port;
+ this.localAddr = localAddr;
+ this.localPort = localPort;
+
+ useUnicode = Config.getBoolean( "jcifs.smb.client.useUnicode", true );
+ if( useUnicode == false ) {
+ client.flags2 &= 0xFFFF ^ ServerMessageBlock.FLAGS2_UNICODE;
+ client.capabilities &= 0xFFFF ^ ServerMessageBlock.CAP_UNICODE;
+ }
+ if( Config.getBoolean( "jcifs.smb.client.useNTSmbs", false ) == true ) {
+ client.capabilities |= ServerMessageBlock.CAP_NT_SMBS;
+ }
+
+ soTimeout = Config.getInt( "jcifs.smb.client.soTimeout", DEFAULT_SO_TIMEOUT );
+ responseTimeout = Config.getInt( "jcifs.smb.client.responseTimeout",
+ DEFAULT_RESPONSE_TIMEOUT );
+ rcv_buf_size = Config.getInt( "jcifs.smb.client.rcv_buf_size", DEFAULT_RCV_BUF_SIZE );
+ snd_buf_size = client.maxBufferSize;
+ rcv_buf = new byte[rcv_buf_size];
+ snd_buf = new byte[snd_buf_size];
+ sessions = new Vector();
+ responseTable = new Hashtable();
+ outLock = new Object();
+ negotiated = false;
+ }
+
+ synchronized SmbSession getSmbSession() {
+ return getSmbSession( null, null, null );
+ }
+ synchronized SmbSession getSmbSession( String username, String password, String domain ) {
+ if( username == null ) {
+ username = Config.getProperty( "jcifs.smb.client.username", "guest" );
+ }
+ if( password == null ) {
+ password = Config.getProperty( "jcifs.smb.client.password", "" );
+ }
+ if( domain == null ) {
+ domain = Config.getProperty( "jcifs.smb.client.domain", "?" );
+ }
+ SmbSession ssn;
+ for( Enumeration e = sessions.elements(); e.hasMoreElements(); ) {
+ ssn = (SmbSession)e.nextElement();
+ if( ssn.matches( username, password, domain )) {
+ return ssn;
+ }
+ }
+ ssn = new SmbSession( this, username, password, domain );
+ sessions.addElement( ssn );
+ return ssn;
+ }
+ boolean matches( NbtAddress address, int port, InetAddress localAddr, int localPort ) {
+ InetAddress defaultLocal = null;
+ try {
+ defaultLocal = InetAddress.getLocalHost();
+ } catch( UnknownHostException uhe ) {
+ }
+ int p1 = ( port == 0 || port == 139 ) ? 0 : port;
+ int p2 = ( this.port == 0 || this.port == 139 ) ? 0 : this.port;
+ InetAddress la1 = localAddr == null ? defaultLocal : localAddr;
+ InetAddress la2 = this.localAddr == null ? defaultLocal : this.localAddr;
+ return address.equals( this.address ) &&
+ p1 == p2 &&
+ la1.equals( la2 ) &&
+ localPort == this.localPort;
+ }
+ void ensureOpen() throws IOException {
+ if( socket == null ) {
+ try {
+ socket = new NbtSocket( address, port, localAddr, localPort );
+ } catch( NbtException ne ) {
+ if( ne.errorClass == NbtException.ERR_SSN_SRVC &&
+ ( ne.errorCode == NbtException.CALLED_NOT_PRESENT ||
+ ne.errorCode == NbtException.NOT_LISTENING_CALLED )) {
+ Log.println( Log.WARNINGS, "smb warning",
+ " failed to establish netbios session: called name not " +
+ "present or not listening for called name, trying " +
+ "*SMBSERVER" );
+ socket = new NbtSocket( address, NbtAddress.SMBSERVER_NAME,
+ port, localAddr, localPort );
+ } else {
+ throw ne;
+ }
+ }
+ if( Config.getBoolean( "jcifs.smb.client.tcpNoDelay", false )) {
+ socket.setTcpNoDelay( true );
+ }
+ in = new PushbackInputStream( socket.getInputStream(), PUSHBACK_BUF_SIZE );
+ out = socket.getOutputStream();
+ thread = new Thread( this );
+ thread.setDaemon( true );
+ thread.start();
+ }
+ }
+ void tryClose() {
+ synchronized( outLock ) {
+ if( socket != null ) {
+ try {
+ for( Enumeration e = sessions.elements(); e.hasMoreElements(); ) {
+ ((SmbSession)e.nextElement()).logoff();
+ }
+ socket.close();
+ } catch( IOException ioe ) {
+ }
+ }
+ in = null;
+ out = null;
+ socket = null;
+ negotiated = false;
+ thread = null;
+ responseTable.clear();
+ }
+ }
+ public void run() {
+ int mid, l, b, n;
+ ServerMessageBlock response;
+
+ while( thread == Thread.currentThread() ) {
+ try {
+ socket.setSoTimeout( soTimeout );
+
+ if(( b = in.read() ) == -1) {
+ break;
+ }
+ if(( b & 0xFF ) != 0xFF ) {
+ continue;
+ }
+ rcv_buf[0] = (byte)0xFF;
+
+ if( in.read( rcv_buf, 1, HEADER_LENGTH - 1 ) != HEADER_LENGTH - 1 ) {
+ /* Read on a netbios SocketInputStream does not
+ * return until len bytes have been read or the stream is
+ * closed. This must be the latter case.
+ */
+ break;
+ }
+ ((PushbackInputStream)in).unread( rcv_buf, 0, HEADER_LENGTH );
+ if( rcv_buf[0] != (byte)0xFF ||
+ rcv_buf[1] != (byte)'S' ||
+ rcv_buf[2] != (byte)'M' ||
+ rcv_buf[3] != (byte)'B' ) {
+ Log.println( Log.WARNINGS, "smb warning",
+ "bad smb header, purging session message" );
+ in.skip( in.available() );
+ continue;
+ }
+ if(( rcv_buf[FLAGS_OFFSET] & FLAGS_RESPONSE ) == FLAGS_RESPONSE ) {
+ mid = ServerMessageBlock.readInt2( rcv_buf, MID_OFFSET );
+
+ response = (ServerMessageBlock)responseTable.get( new Integer( mid ));
+ if( response == null ) {
+ Log.println( Log.WARNINGS, "smb warning",
+ " no handler for mid=" + mid + ", purging session message" );
+ in.skip( in.available() );
+ continue;
+ }
+ synchronized( response ) {
+ response.useUnicode = useUnicode;
+ Log.println( Log.DEBUGGING, "smb debugging",
+ " new data read from socket" );
+
+ if( response instanceof SmbComTransactionResponse ) {
+ Enumeration e = (Enumeration)response;
+ if( e.hasMoreElements() ) {
+ e.nextElement();
+ } else {
+ Log.println( Log.WARNINGS, "smb warning",
+ "more responses to transaction than expected" );
+ continue;
+ }
+ response.readWireFormat( in, rcv_buf, 0 );
+ response.received = true;
+ Log.printMessageData( "smb received", response );
+
+ if( response.errorCode != 0 || e.hasMoreElements() == false ) {
+ ((SmbComTransactionResponse)response).hasMore = false;
+ response.notify();
+ } else {
+ ensureOpen();
+ }
+ } else {
+ response.readWireFormat( in, rcv_buf, 0 );
+ response.received = true;
+
+ Log.printMessageData( "smb received", response );
+ ServerMessageBlock smb = response;
+ while( smb instanceof AndXServerMessageBlock &&
+ ( smb = ((AndXServerMessageBlock)smb).andx ) != null ) {
+ Log.printMessageData( "smb andx data", smb );
+ }
+ Log.printHexDump( "smb received", rcv_buf, 0, response.length );
+
+ response.notify();
+ }
+ }
+ } else {
+ // it's a request(break oplock)
+ }
+ } catch( InterruptedIOException iioe ) {
+ if( responseTable.size() == 0 ) {
+ tryClose();
+ } else {
+ Log.println( Log.WARNINGS, "smb warning",
+ " soTimeout has occured but there are " +
+ responseTable.size() + " pending requests" );
+ }
+ } catch( IOException ioe ) {
+ Log.printStackTrace( "exception reading from socket input", ioe );
+ tryClose();
+ }
+ }
+ }
+ void send( ServerMessageBlock request,
+ ServerMessageBlock response ) throws IOException {
+ Integer mid = null;
+
+ negotiate();
+
+ request.flags2 = client.flags2;
+ request.mid = aquireMid();
+ request.useUnicode = useUnicode;
+
+ if( response == null ) {
+ try {
+ synchronized( outLock ) {
+ ensureOpen();
+ out.write( snd_buf, 0, request.writeWireFormat( snd_buf, 0 ));
+ out.flush();
+
+ Log.printMessageData( "smb sent", request );
+ ServerMessageBlock smb = request;
+ while( smb instanceof AndXServerMessageBlock &&
+ ( smb = ((AndXServerMessageBlock)smb).andx ) != null ) {
+ Log.printMessageData( "smb andx data", smb );
+ }
+ Log.printHexDump( "smb sent", snd_buf, 0, request.length );
+ }
+ } finally {
+ releaseMid( request.mid );
+ }
+
+ return;
+ }
+
+ // now for the normal case where response is not null
+
+ try {
+ synchronized( response ) {
+
+ response.received = false;
+ mid = new Integer( request.mid );
+ responseTable.put( mid, response );
+
+ synchronized( outLock ) {
+ ensureOpen();
+ out.write( snd_buf, 0, request.writeWireFormat( snd_buf, 0 ));
+ out.flush();
+
+ Log.printMessageData( "smb sent", request );
+ ServerMessageBlock smb = request;
+ while( smb instanceof AndXServerMessageBlock &&
+ ( smb = ((AndXServerMessageBlock)smb).andx ) != null ) {
+ Log.printMessageData( "smb andx data", smb );
+ }
+ Log.printHexDump( "smb sent", snd_buf, 0, request.length );
+ }
+
+ // default it 1 so that 0 can be used as forever
+ response.wait( response.responseTimeout == 1 ?
+ responseTimeout : response.responseTimeout );
+ }
+ } catch( InterruptedException ie ) {
+ } finally {
+ responseTable.remove( mid );
+ releaseMid( request.mid );
+ }
+
+ if( response.received == false ) {
+ throw new IOException(
+ "time out waiting for response from server: " + address );
+ }
+ if( response.errorCode != 0 ) {
+ throw new SmbException( response.errorCode );
+ }
+ }
+ void sendTransaction( SmbComTransaction request,
+ SmbComTransactionResponse response ) throws IOException {
+ Integer mid = null;
+
+ negotiate();
+
+ try {
+ request.flags2 = client.flags2;
+ request.mid = aquireMid();
+ mid = new Integer( request.mid );
+ request.useUnicode = useUnicode;
+ request.maxBufferSize = negotiatedMaxBufferSize;
+ response.received = false;
+ response.hasMore = true;
+ response.isPrimary = true;
+
+ request.nextElement();
+ if( request.hasMoreElements() ) {
+ // multi-part request
+
+ SmbComBlankResponse interimResponse = new SmbComBlankResponse();
+ synchronized( interimResponse ) {
+ responseTable.put( mid, interimResponse );
+ synchronized( outLock ) {
+ ensureOpen();
+ out.write( snd_buf, 0, request.writeWireFormat( snd_buf, 0 ));
+ out.flush();
+
+ Log.printMessageData( "smb sent", request );
+ Log.printHexDump( "smb sent", snd_buf, 0, request.length );
+ }
+ interimResponse.wait( responseTimeout );
+
+ if( interimResponse.received == false ) {
+ throw new IOException( "time out waiting for response from server" );
+ }
+ if( interimResponse.errorCode != 0 ) {
+ throw new SmbException( interimResponse.errorCode );
+ }
+ }
+ request.nextElement();
+ }
+
+ synchronized( response ) {
+ responseTable.put( mid, response );
+ do {
+ synchronized( outLock ) {
+ ensureOpen();
+ out.write( snd_buf, 0, request.writeWireFormat( snd_buf, 0 ));
+ out.flush();
+
+ Log.printMessageData( "smb sent", request );
+ Log.printHexDump( "smb sent", snd_buf, 0, request.length );
+ }
+ } while( request.hasMoreElements() && request.nextElement() != null );
+
+ do {
+ // default it 1 so that 0 can be used as forever
+ response.wait( response.responseTimeout == 1 ? responseTimeout : response.responseTimeout );
+ } while( response.received && response.hasMoreElements() );
+ }
+ } catch( InterruptedException ie ) {
+ } finally {
+ responseTable.remove( mid );
+ releaseMid( request.mid );
+ }
+
+ if( response.received == false ) {
+ throw new IOException( "time out waiting for response from server" );
+ }
+ if( response.errorCode != 0 ) {
+ throw new SmbException( response.errorCode );
+ }
+ }
+ synchronized void negotiate() throws IOException {
+
+ if( negotiated ) {
+ return;
+ }
+ /* we must set this here rather than later because this
+ * calls send which calls negotiate so we don't want to
+ * end up in a loop. The alternative would be to inline
+ * the send routine here but this seems okay for now
+ */
+ negotiated = true;
+
+ Log.println( Log.WARNINGS, "smb negotiation warning",
+ " requesting negotiation with " + address );
+
+ /*
+ * Negotiate Protocol Request / Response
+ */
+
+ SmbComNegotiateResponse response = new SmbComNegotiateResponse();
+ send( new SmbComNegotiate(), response );
+
+ if( response.dialectIndex > 10 ) {
+ throw new IOException( "smb failed to negotiate dialect" );
+ }
+
+ server.securityMode = response.securityMode;
+ server.security = response.security;
+ server.encryptedPasswords = response.encryptedPasswords;
+ server.signaturesEnabled = response.signaturesEnabled;
+ server.signaturesRequired = response.signaturesRequired;
+ negotiatedDialectIndex = response.dialectIndex;;
+ server.maxMpxCount = response.maxMpxCount;
+ negotiatedMaxMpxCount = client.maxMpxCount < server.maxMpxCount ?
+ client.maxMpxCount : server.maxMpxCount;
+ mpxCtrl.maxMpxCount = negotiatedMaxMpxCount < 1 ?
+ 1 : negotiatedMaxMpxCount;
+ server.maxNumberVcs = response.maxNumberVcs;
+ server.maxBufferSize = response.maxBufferSize;
+ negotiatedMaxBufferSize = client.maxBufferSize < server.maxBufferSize ?
+ client.maxBufferSize : server.maxBufferSize;
+ server.maxRawSize = response.maxRawSize;
+ server.sessionKey = response.sessionKey;
+ server.capabilities = response.capabilities;
+ negotiatedCapabilities = client.capabilities & server.capabilities;
+ if(( negotiatedCapabilities & ServerMessageBlock.CAP_UNICODE ) == 0 ) {
+ // server doesn't want unicode
+ if( Config.getBoolean( "jcifs.smb.client.useUnicode", false )) {
+ // force unicode
+ negotiatedCapabilities |= ServerMessageBlock.CAP_UNICODE;
+ } else {
+ // not explicitly set to true so flip unicode off as server requests
+ useUnicode = false;
+ client.flags2 &= 0xFFFF ^ ServerMessageBlock.FLAGS2_UNICODE;
+ }
+ }
+ server.serverTime = response.serverTime;
+ server.serverTimeZone = response.serverTimeZone;
+ server.encryptionKeyLength = response.encryptionKeyLength;
+ server.encryptionKey = response.encryptionKey;
+ server.oemDomainName = response.oemDomainName;
+ }
+ public String toString() {
+ return "SmbTransport[address=" + address +
+ ",port=" + socket.getPort() +
+ ",localAddr=" + socket.getLocalAddress() +
+ ",localPort=" + socket.getLocalPort() + "]";
+ }
+
+ static int aquireMid() throws IOException {
+ try {
+ return mpxCtrl.aquireMid();
+ } catch( InterruptedException ie ) {
+ throw new IOException( ie.getMessage() );
+ }
+ }
+ static void releaseMid( int mid ) {
+ mpxCtrl.releaseMid( mid );
+ }
+
+ static class MpxControl {
+ MpxListNode first, last;
+ class MpxListNode {
+ int i;
+ MpxListNode next;
+ MpxListNode( int id ) {
+ i = id;
+ next = null;
+ }
+ }
+ int nextMid, mpxCount, maxMpxCount;
+
+ MpxControl() {
+ nextMid = 0;
+ mpxCount = 0;
+ maxMpxCount = 1;
+ first = last = null;
+ }
+
+ synchronized void clear() {
+ nextMid = 0;
+ mpxCount = 0;
+ maxMpxCount = 1;
+ first = last = null;
+ }
+ synchronized int aquireMid() throws InterruptedException {
+ while( mpxCount >= maxMpxCount ) {
+ wait();
+ }
+ if(( ++nextMid % 0xFFFF ) == 0 ) {
+ nextMid = 1;
+ }
+ add( nextMid );
+ mpxCount++;
+ return nextMid;
+ }
+ synchronized void releaseMid( int i ) {
+ remove( i );
+ mpxCount--;
+ notify();
+ }
+ synchronized boolean contains( int i ) {
+ for( MpxListNode tmp = first; tmp != null; tmp = tmp.next ) {
+ if( tmp.i == i ) {
+ return true;
+ }
+ }
+ return false;
+ }
+ synchronized void add( int i ) {
+ if( contains( i )) {
+ return;
+ }
+ if( first == null ) {
+ first = last = new MpxListNode( i );
+ } else {
+ last = last.next = new MpxListNode( i );
+ }
+ }
+ synchronized void remove( int i ) {
+ if( first == null ) {
+ return;
+ } else if( first == last && first.i == i ) {
+ first = last = null;
+ return;
+ }
+ MpxListNode tmp, prev;
+ for( tmp = prev = first; tmp != null; tmp = tmp.next ) {
+ if( tmp.i == i ) {
+ if( tmp == first ) {
+ first = first.next;
+ }
+ if( tmp == last ) {
+ last = prev;
+ last.next = null;
+ }
+ }
+ prev = tmp;
+ }
+ }
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import java.io.IOException;
+import jcifs.netbios.NbtAddress;
+import java.net.UnknownHostException;
+
+class SmbTree {
+
+ int tid;
+ String path;
+ String service = jcifs.Config.getProperty( "jcifs.smb.client.serviceType", "?????" );
+ SmbSession session;
+ boolean treeConnected = false;
+
+ SmbTree( SmbSession session, String path, String service ) {
+ this.session = session;
+ this.path = path;
+ if( service != null && service.startsWith( "??" ) == false ) {
+ this.service = service;
+ }
+ }
+
+ boolean matches( String path, String service ) {
+ return this.path.equals( path ) &&
+ ( service == null || service.startsWith( "??" ) ||
+ this.service.equals( service ));
+ }
+ void sendTransaction( SmbComTransaction request,
+ SmbComTransactionResponse response ) throws IOException {
+ // transactions are not batchable
+ treeConnect( null, null );
+ request.tid = tid;
+ session.sendTransaction( request, response );
+ }
+ void send( ServerMessageBlock request,
+ ServerMessageBlock response ) throws IOException {
+ if( response != null ) {
+ response.received = false;
+ }
+ treeConnect( request, response );
+ if( response != null && response.received ) {
+ return;
+ }
+ request.tid = tid;
+ session.send( request, response );
+ }
+ synchronized void treeConnect( ServerMessageBlock andx, ServerMessageBlock andxResponse )
+ throws IOException {
+
+ if( treeConnected ) {
+ return;
+ }
+
+ Log.println( Log.WARNINGS, "smb tree connect warning",
+ " requesting tree connect with path=" + path +
+ ",service=" + service );
+
+ /*
+ * Tree Connect And X Request / Response
+ */
+
+ SmbComTreeConnectAndXResponse response =
+ new SmbComTreeConnectAndXResponse( andxResponse );
+ SmbComTreeConnectAndX request =
+ new SmbComTreeConnectAndX( session, path, service, andx );
+ session.send( request, response );
+
+ tid = response.tid;
+ service = response.service;
+ treeConnected = true;
+ }
+ synchronized void treeDisconnect() {
+ if( treeConnected == false ) {
+ return;
+ }
+ try {
+ send( new SmbComTreeDisconnect(), null );
+ } catch( IOException ioe ) {
+ Log.printStackTrace( "smb tree disconnect exception", ioe );
+ } finally {
+ treeConnected = false;
+ }
+ }
+
+//
+// Not used at the moment.
+//
+// boolean checkDirectory( String path ) throws IOException {
+//
+// Log.println( Log.WARNINGS, "smb check directory warning",
+// " checking directory with path=" + path );
+//
+// /*
+// * Check Directory Request / Response
+// */
+//
+// try {
+// send( new SmbComCheckDirectory( path ), new SmbComBlankResponse() );
+// } catch( SmbException se ) {
+// if( se.errorClass == SmbException.ERRDOS &&
+// se.errorCode == SmbException.ERRbadpath ) {
+// return false;
+// } else {
+// throw se;
+// }
+// }
+// return true;
+// }
+
+ Info queryPath( String path, int infoLevel ) throws IOException {
+
+ Log.println( Log.WARNINGS, "smb query path warning",
+ " querying path=" + path );
+
+ /* To query server capabilities we must ensure the negotiation has talken place
+ */
+
+ synchronized( this ) {
+ session.transport.negotiate();
+ }
+
+ /* normally we'd check the negotiatedCapabilities for CAP_NT_SMBS
+ * however I can't seem to get a good last modified time from
+ * SMB_COM_QUERY_INFORMATION so if NT_SMBs are requested
+ * by the server than in this case that's what it will get
+ * regardless of what jcifs.smb.client.useNTSmbs is set
+ * to(overrides negotiatedCapabilities).
+ */
+
+ Info result = null;
+ if(( session.transport.server.capabilities &
+ ServerMessageBlock.CAP_NT_SMBS ) ==
+ ServerMessageBlock.CAP_NT_SMBS ) {
+ /*
+ * Trans2 Query Path Information Request / Response
+ */
+
+ Trans2QueryPathInformationResponse response =
+ new Trans2QueryPathInformationResponse( infoLevel );
+ try {
+ sendTransaction( new Trans2QueryPathInformation( path, infoLevel ), response );
+ } catch( SmbException se ) {
+ if( se.errorClass == SmbException.ERRDOS &&
+ se.errorCode == SmbException.ERRbadfile ) {
+ return null;
+ } else {
+ throw se;
+ }
+ }
+ result = response.info;
+ } else {
+
+ /*
+ * Query Information Request / Response
+ */
+
+ SmbComQueryInformationResponse response =
+ new SmbComQueryInformationResponse(
+ session.transport.server.serverTimeZone * 1000 * 60L );
+ try {
+ send( new SmbComQueryInformation( path ), response );
+ } catch( SmbException se ) {
+ if( se.errorClass == SmbException.ERRDOS &&
+ se.errorCode == SmbException.ERRbadfile ) {
+ return null;
+ } else {
+ throw se;
+ }
+ }
+ result = response;
+ }
+ return result;
+ }
+ String[] find( String path ) throws IOException {
+ int sid, count, i, j;
+ String[] results;
+ String filename;
+
+ synchronized( this ) {
+ // Must ensure treeConnect has been issued to query the service type
+ treeConnect( null, null );
+ }
+
+ if( service.equals( "A:" ) == false ) {
+ // Cannot issue find on anything but a Disk Share
+ return new String[0];
+ }
+
+ if( path.equals( "\\" )) {
+ path = "\\*";
+ } else {
+ path += "\\*";
+ }
+
+ Log.println( Log.WARNINGS, "smb find warning",
+ " find with path=" + path );
+
+ Trans2FindFirst2Response response = new Trans2FindFirst2Response();
+ sendTransaction( new Trans2FindFirst2( path ), response );
+
+ sid = response.sid;
+ count = response.searchCount;
+ j = 0;
+
+ results = new String[Math.max( 10, count )];
+ /*
+ * using hashCode is much more efficient than
+ * filename.equals( "." ) || filename.equals( ".." )
+ */
+ int h1 = new String( "." ).hashCode();
+ int h2 = new String( ".." ).hashCode();
+ i = 0;
+ while( j < count ) {
+ filename = response.results[i++].filename;
+ if( filename.length() < 3 ) {
+ int h = filename.hashCode();
+ if( h == h1 || h == h2 ) {
+ count--;
+ continue;
+ }
+ }
+ results[j++] = filename;
+ }
+
+ // only difference between first2 and next2 responses is subCommand so let's recycle
+ response.subCommand = SmbComTransaction.TRANS2_FIND_NEXT2;
+
+ while( response.isEndOfSearch == false && response.searchCount > 0 ) {
+ sendTransaction( new Trans2FindNext2( sid, response.resumeKey,
+ response.lastName ), response );
+ count += response.searchCount;
+
+ if( count > results.length ) {
+ String[] tmp = results;
+ results = new String[Math.max( results.length * 2, count )];
+ System.arraycopy( tmp, 0, results, 0, j );
+ }
+ i = 0;
+ while( j < count ) {
+ filename = response.results[i++].filename;
+ if( filename.length() < 3 ) {
+ int h = filename.hashCode();
+ if( h == h1 || h == h2 ) {
+ count--;
+ continue;
+ }
+ }
+ results[j++] = filename;
+ }
+ }
+
+ try {
+ send( new SmbComFindClose2( sid ), new SmbComBlankResponse() );
+ } catch( SmbException se ) {
+ Log.printStackTrace( "smb find close response exception", se );
+ }
+
+ if( results.length != count ) {
+ String[] tmp = results;
+ results = new String[count];
+ System.arraycopy( tmp, 0, results, 0, count );
+ }
+
+ return results;
+ }
+ String[] netShareEnum() throws IOException {
+ String ipcPath = path.substring( 0, path.lastIndexOf( '\\' ) + 1 ) + "IPC$";
+ SmbTree t = session.getSmbTree( ipcPath, null );
+
+ NetShareEnumResponse response = new NetShareEnumResponse();
+ t.sendTransaction( new NetShareEnum(), response );
+
+ if( response.status != 0 &&
+ response.status != NetShareEnumResponse.ERROR_MORE_DATA ) {
+ throw new IOException( response.toString() );
+ }
+
+ String[] ret = new String[response.entriesReturned];
+ for( int i = 0; i < response.entriesReturned; i++ ) {
+ ret[i] = response.results[i].netName;
+ }
+
+ return ret;
+ }
+ static void setLmbTree( SmbFile file ) throws IOException {
+ NbtAddress lmb = NbtAddress.getByName( NbtAddress.MASTER_BROWSER_NAME, 0x01, null );
+ lmb = NbtAddress.getByName( lmb.getHostAddress() );
+ file.address = NbtAddress.getByName( lmb.getHostAddress(), 0x20, null );
+ SmbTransport trans = SmbTransport.getSmbTransport( file.address, 0 );
+ SmbSession ssn = trans.getSmbSession( "", "", "" );
+ String unc = new String( "\\\\" + file.address.getHostName() +
+ "\\IPC$" ).toUpperCase();
+ file.tree = ssn.getSmbTree( unc, null );
+ }
+ String[] domainEnum() throws IOException {
+ String ipcPath = path.substring( 0, path.lastIndexOf( '\\' ) + 1 ) + "IPC$";
+ SmbTree t = session.getSmbTree( ipcPath, null );
+
+ synchronized( this ) {
+ // to query oemDomainName megotiation must have occurred
+ t.session.transport.negotiate();
+ }
+
+ NetServerEnum2Response response = new NetServerEnum2Response();
+ t.sendTransaction( new NetServerEnum2( t.session.transport.server.oemDomainName,
+ NetServerEnum2.SV_TYPE_DOMAIN_ENUM ), response );
+
+ if( response.status != NetServerEnum2Response.NERR_Success &&
+ response.status != NetServerEnum2Response.ERROR_MORE_DATA ) {
+ throw new IOException( response.toString() );
+ }
+
+ String[] ret = new String[response.entriesReturned];
+ for( int i = 0; i < response.entriesReturned; i++ ) {
+ ret[i] = response.results[i].name;
+ }
+ return ret;
+ }
+ String[] netServerEnum2( String domain ) throws IOException {
+ NetServerEnum2Response response = new NetServerEnum2Response();
+ sendTransaction( new NetServerEnum2( domain, NetServerEnum2.SV_TYPE_ALL ), response );
+
+ if( response.status != NetServerEnum2Response.NERR_Success &&
+ response.status != NetServerEnum2Response.ERROR_MORE_DATA ) {
+ throw new IOException( response.toString() );
+ }
+
+ String[] ret = new String[response.entriesReturned];
+ for( int i = 0; i < response.entriesReturned; i++ ) {
+ ret[i] = response.results[i].name;
+ }
+ return ret;
+ }
+ boolean rename( String oldFileName, String newFileName ) throws IOException {
+
+ Log.println( Log.WARNINGS, "smb rename warning",
+ " oldFileName=" + oldFileName +
+ ",newFileName=" + newFileName );
+
+ /*
+ * Rename Request / Response
+ */
+
+ SmbComBlankResponse response = new SmbComBlankResponse();
+ try {
+ send( new SmbComRename( oldFileName, newFileName ), response );
+ } catch( SmbException se ) {
+ if( se.errorClass == SmbException.ERRDOS &&
+ ( se.errorCode == SmbException.ERRbadpath ||
+ se.errorCode == SmbException.ERRbadfile )) {
+ return false;
+ } else {
+ throw se;
+ }
+ }
+ return true;
+ }
+
+//
+// Not used at the moment.
+//
+// boolean copy( String sourceFileName, String targetFileName, int tid2 )
+// throws IOException {
+//
+// Log.println( Log.WARNINGS, "smb copy warning",
+// " sourceFileName=" + sourceFileName +
+// ",targetFileName=" + targetFileName );
+//
+// /*
+// * Copy Request / Response
+// */
+//
+// SmbComCopyResponse response = new SmbComCopyResponse();
+// try {
+// send( new SmbComCopy( sourceFileName, targetFileName, tid2 ), response );
+// } catch( SmbException se ) {
+// if( se.errorClass == SmbException.ERRDOS &&
+// ( se.errorCode == SmbException.ERRbadpath ||
+// se.errorCode == SmbException.ERRbadfile )) {
+// return false;
+// } else {
+// throw se;
+// }
+// }
+// return true;
+// }
+
+ boolean delete( String fileName, boolean isDirectory ) throws IOException {
+
+ Log.println( Log.WARNINGS, "smb delete warning",
+ " fileName=" + fileName );
+
+ /*
+ * Delete or Delete Directory Request / Response
+ */
+
+ ServerMessageBlock request;
+ if( isDirectory ) {
+
+ /* Recursively delete directory contents using post order DFS
+ */
+
+ String[] list = find( fileName );
+ for( int i = 0; i < list.length; i++ ) {
+ String p = fileName + "\\" + list[i];
+ int infoLevel = Trans2QueryPathInformationResponse.SMB_QUERY_FILE_BASIC_INFO;
+ Info info = queryPath( p, infoLevel );
+ boolean dir = ( info.getAttributes() & SmbFile.ATTR_DIRECTORY ) ==
+ SmbFile.ATTR_DIRECTORY;
+ delete( p, dir );
+ }
+
+ request = new SmbComDeleteDirectory( fileName );
+ } else {
+ request = new SmbComDelete( fileName );
+ }
+
+ try {
+ send( request, new SmbComBlankResponse() );
+ } catch( SmbException se ) {
+ if( se.errorClass == SmbException.ERRDOS &&
+ ( se.errorCode == SmbException.ERRbadpath ||
+ se.errorCode == SmbException.ERRbadfile )) {
+ return false;
+ } else {
+ throw se;
+ }
+ }
+ return true;
+ }
+ int open( String name, int flags ) throws IOException {
+
+ Log.println( Log.WARNINGS, "smb open warning", " name=" + name );
+
+ /*
+ * Open AndX Request / Response
+ */
+
+ /* To query server capabilities we must ensure the negotiation has talken place
+ */
+
+ synchronized( this ) {
+ session.transport.negotiate();
+ }
+
+ if(( session.transport.negotiatedCapabilities &
+ ServerMessageBlock.CAP_NT_SMBS ) ==
+ ServerMessageBlock.CAP_NT_SMBS ) {
+ SmbComNTCreateAndXResponse response = new SmbComNTCreateAndXResponse();
+ send( new SmbComNTCreateAndX( name, flags, null ), response );
+ return response.fid;
+ } else {
+ SmbComOpenAndXResponse response = new SmbComOpenAndXResponse();
+ send( new SmbComOpenAndX( name, flags, null ), response );
+ return response.fid;
+ }
+ }
+ boolean createDirectory( String directoryName ) throws IOException {
+
+ Log.println( Log.WARNINGS, "smb create directory warning",
+ " directoryName=" + directoryName );
+
+ /*
+ * Create Directory Request / Response
+ */
+
+ try {
+ send( new SmbComCreateDirectory( directoryName ), new SmbComBlankResponse() );
+ } catch( SmbException se ) {
+ if( se.errorClass == SmbException.ERRDOS &&
+ se.errorCode == SmbException.ERRnoaccess ) {
+ return false;
+ } else {
+ throw se;
+ }
+ }
+ return true;
+ }
+ public String toString() {
+ return "SmbTree[path=" + path +
+ ",service=" + service +
+ ",tid=" + tid + "]";
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import jcifs.netbios.NbtAddress;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.UnknownHostException;
+import java.util.Vector;
+import java.util.Enumeration;
+
+final class SmbURL {
+ String url;
+ String domain;
+ String username;
+ String password;
+ String server;
+ int port;
+ String share;
+ String canonicalPath;
+ String path;
+ String file;
+ boolean isWorkgroup;
+
+ static class QueryThread extends Thread {
+
+ Object lock;
+ String host, scope;
+ int type;
+ NbtAddress ans = null;
+ UnknownHostException uhe;
+
+ QueryThread( Object lock, String host, int type, String scope ) {
+ this.lock = lock;
+ this.host = host;
+ this.type = type;
+ this.scope = scope;
+ }
+ public void run() {
+ try {
+ ans = NbtAddress.getByName( host, type, scope );
+ } catch( UnknownHostException uhe ) {
+ this.uhe = uhe;
+ }
+ synchronized( lock ) {
+ lock.notify();
+ }
+ }
+ }
+ static NbtAddress lookupServerOrWorkgroup( String name ) throws UnknownHostException {
+ Object lock = new Object();
+ QueryThread q1d = new QueryThread( lock, name, 0x1d, null );
+ QueryThread q20 = new QueryThread( lock, name, 0x20, null );
+ q1d.setDaemon( true );
+ q20.setDaemon( true );
+ try {
+ synchronized( lock ) {
+ q1d.start();
+ q20.start();
+
+ int i = 2;
+ while( i-- > 0 && q1d.ans == null && q20.ans == null ) {
+ lock.wait();
+ }
+ }
+ } catch( InterruptedException ie ) {
+ throw new UnknownHostException( name );
+ }
+ if( q1d.ans != null ) {
+ return NbtAddress.getByName( q1d.ans.getHostAddress(), 0x1d, null );
+ } else if( q20.ans != null ) {
+ return q20.ans;
+ } else {
+ throw q1d.uhe;
+ }
+ }
+
+ /*
+ * smb://[[[ntdomain;]user[:password]@]server[:port][/share[/path]]]
+ *
+ * smb://hendrix/download/
+ * smb://nycdom;mike@angus/tmp/classes/Main.class
+ * smb://mike:sw@#ii@angus/tmp/classes
+ * smb://nycdom;mike:sw@#ii@hendrix/download/docs/index.html
+ */
+
+ SmbURL( String url ) throws MalformedURLException, UnknownHostException {
+ this( url, null, 4, url.length() );
+ }
+ SmbURL( String url, String name ) throws MalformedURLException, UnknownHostException {
+ this( url, name, 4, url.length() );
+ }
+ SmbURL( String url, String name, int start, int limit )
+ throws MalformedURLException, UnknownHostException {
+ int beg, end, c, at, srv, pat;
+
+ this.url = url;
+
+ try {
+ if( name != null ) {
+ if( name.regionMatches( true, 0, "smb://", 0, 6 )) {
+
+ /* If the secondard argument begins with
+ * 'smb://' then we simply replace the
+ * primary url argument with it and proceed
+ * as usuall.
+ */
+
+ url = name;
+ name = null;
+ start = 4;
+ limit = url.length();
+ } else if( url.equalsIgnoreCase( "smb://" )) {
+ url = "smb://" + name;
+ name = null;
+ start = 4;
+ limit = url.length();
+ }
+ }
+
+ beg = start + 2;
+ end = limit;
+ if( end > beg ) {
+ while( end > beg && url.charAt( end - 1 ) == '/' ) {
+ end--; // trim trailing slashes
+ }
+ while( beg < end && url.charAt( beg ) != '/' && url.charAt( beg ) != '@' ) {
+ beg++;
+ }
+ if( beg == end && Character.isDigit( url.charAt( start + 2 )) == false ) {
+ // Could be a workgroup. Need to query the network to find out.
+ NbtAddress ans = lookupServerOrWorkgroup( url.substring( 6, end ));
+ if( ans.getNameType() == 0x1d ) {
+ if( name != null ) {
+ url = "smb://" + name;
+ name = null;
+ start = 4;
+ limit = url.length();
+ } else {
+ isWorkgroup = true;
+ }
+ }
+ }
+ }
+
+ if( url.startsWith( "smb://" ) == false ) {
+ throw new MalformedURLException();
+ }
+
+ /* The java.net.URL parsing model always provides
+ * a start point of right after the ':'. So in the
+ * case of 'smb://' this would always be position
+ * 4. Because smb:// URLs always have 2 following
+ * slashes we can just bump-up start by 2 here
+ */
+
+ start += 2;
+ srv = start;
+
+ at = url.lastIndexOf( '@' );
+ if( at != -1 ) {
+ // server right after '@'
+ srv = at + 1;
+
+ // parse authentication info
+ int u = start;
+ int i = start;
+ for( i = start; i < at; i++ ) {
+ c = url.charAt( i );
+ if( c == ';' ) {
+ domain = url.substring( start, i );
+ u = i + 1;
+ } else if( c == ':' ) {
+ password = url.substring( i + 1, at );
+ break;
+ }
+ }
+ username = url.substring( u, i );
+ }
+
+ server = url.substring( srv );
+
+ /* For the moment the server variable will
+ * contain everything that follows as well for
+ * feeding to the canonicalization via make-shift
+ * stack routine below. After that, the server,
+ * share, path, etc will be isolated.
+ */
+
+ if( name != null && name.length() != 0 ) {
+
+ /* A secondary argument was provided. If
+ * it begins with '/' then we replace
+ * everything after the server with
+ * name. Otherwise we simply concatonate
+ * it onto the current path.
+ */
+
+ if( name.charAt( 0 ) == '/' ) {
+ int sha = url.indexOf( '/', srv );
+ if( sha < srv ) {
+ sha = limit;
+ }
+ server = url.substring( srv, sha ) + name;
+ } else {
+ if( server.length() == 0 || server.endsWith( "/" )) {
+ server += name;
+ } else {
+ server = server + '/' + name;
+ }
+ }
+ }
+ limit = server.length();
+
+ /* The path must preserve all that was provided in
+ * the primary url argument and possibly secondary
+ * argument such that it could be fed back into the
+ * constructor of an SmbURL and the results would
+ * be equal.
+ */
+
+ path = server;
+
+ Vector stk = new Vector();
+ String str;
+ for( int i = 0, s = 0; i <= limit; i++ ) {
+ if( i == limit || server.charAt( i ) == '/' ) {
+ if( i > s ) {
+ str = server.substring( s, i );
+ if( str.equals( ".." )) {
+ if( stk.isEmpty() == false ) {
+ stk.removeElementAt( stk.size() - 1 );
+ }
+ } else if( str.equals( "." )) {
+ } else {
+ stk.addElement( str );
+ }
+ }
+ s = i + 1;
+ }
+ }
+
+ server = null;
+ if( stk.isEmpty() == false ) {
+ Enumeration e = stk.elements();
+ server = (String)e.nextElement();
+
+ int p = server.indexOf( ':' );
+ if( p > 0 ) {
+ port = Integer.parseInt( server.substring( p + 1 ));
+ server = server.substring( 0, p );
+ }
+
+ file = server;
+ if( e.hasMoreElements() ) {
+ StringBuffer sb = new StringBuffer();
+
+ share = (String)e.nextElement();
+ file = share;
+
+ while( e.hasMoreElements() ) {
+ file = (String)e.nextElement();
+ sb.append( '/' ).append( file );
+ }
+
+ if( sb.length() > 0 ) {
+ canonicalPath = sb.toString();
+ }
+ }
+ }
+ } catch( UnknownHostException uhe ) {
+ throw uhe;
+ } catch( Exception e ) {
+ throw new MalformedURLException( url + ", " + name );
+ }
+ }
+
+ public boolean equals( Object obj ) {
+ return obj instanceof SmbURL && obj.hashCode() == hashCode();
+ }
+ public int hashCode() {
+ return toString().hashCode();
+ }
+ String getCanonicalPath() {
+ StringBuffer sb = new StringBuffer( "smb://" );
+ if( server == null ) {
+ return "smb://";
+ } else if( username != null ) {
+ if( domain != null ) {
+ sb.append( domain ).append( ';' );
+ }
+ sb.append( username );
+ if( password != null ) {
+ sb.append( ':' ).append( password );
+ }
+ sb.append( '@' );
+ }
+ sb.append( server );
+ // should probably not put the netbios session service
+ // port in here like this :~(
+ if( port != 0 && port != 139 ) {
+ sb.append( ":" ).append( port );
+ }
+ if( share != null ) {
+ sb.append( '/' ).append( share );
+ if( canonicalPath != null ) {
+ sb.append( canonicalPath );
+ }
+ }
+ return sb.toString();
+ }
+ public String toString() {
+ StringBuffer sb = new StringBuffer( "smb://" );
+ if( username != null ) {
+ if( domain != null ) {
+ sb.append( domain ).append( ';' );
+ }
+ sb.append( username );
+ if( password != null ) {
+ sb.append( ':' ).append( password );
+ }
+ sb.append( '@' );
+ }
+ if( server != null ) {
+ sb.append( path );
+ }
+ return sb.toString();
+ }
+}
+
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import java.net.URLConnection;
+import java.net.URL;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * This class represents a communications link between an application and
+ * an SMB resource represented by a {@link java.net.URL}. An object of this type will be
+ * returned by the <code>java.net.URL openConnection</code> method when an SMB URL is
+ * used. See the {@link jcifs.smb.SmbFile} class for a detailed decription of
+ * the smb URL syntax with examples.
+ *
+ * Before referencing a <code>java.net.URL</code> or code that uses one
+ * with SMB URLs, the <code>jcifs.Config</code> class must be loaded. It
+ * contains a static initializer that installs the SMB specific protocol
+ * handler. If this protocol handler is not loaded the following Exception
+ * will occur:
+ *
+ * <blockquote><pre>
+ * java.net.MalformedURLException: unknown protocol: smb
+ * </pre></blockquote>
+ *
+ * It may be loaded by simply using the <code>jcifs.Config</code> class
+ * or if for no other reason the following code will do:
+ *
+ * <blockquote><pre>
+ * Class.forName( "jcifs.Config" );
+ * </pre></blockquote>
+ *
+ * In general this class is deficient; it only supports downloading
+ * via an <code>InputStream</code>. Adding more functionality is strait
+ * forward. If you require more functionality please express your intrest
+ * to the jcifs@samba.org mailing list.
+ */
+
+public class SmbURLConnection extends URLConnection {
+
+ SmbURL url;
+ SmbFile file;
+
+ SmbURLConnection( URL u, SmbURL url ) {
+ super( u );
+ this.url = url;
+ }
+
+/**
+ * Issue the actual socket IO necesary to open a connection with the server
+ * hosting the target resource.
+ */
+
+ public void connect() throws IOException {
+ if( connected ) {
+ return;
+ }
+ file = new SmbFile( url.getCanonicalPath() );
+ }
+
+/**
+ * Return the length in bytes of the resource specified by the URL.
+ */
+
+ public int getContentLength() {
+ try {
+ connect();
+ return (int)file.length();
+ } catch( IOException ioe ) {
+ }
+ return 0;
+ }
+
+/**
+ * Retrieves the last modified time of the file or directory specified by
+ * the URL for this connection.
+ */
+
+ public long getDate() {
+ return getLastModified();
+ }
+
+/**
+ * Retrieves the last modified time of the file or directory specified by
+ * the URL for this connection.
+ */
+
+ public long getLastModified() {
+ try {
+ connect();
+ return file.lastModified();
+ } catch( IOException ioe ) {
+ }
+ return 0L;
+ }
+
+/**
+ * Create an <code>InputStream</code> from which bytes may be read from
+ * the taget specified by the URL of this connection.
+ */
+
+ public InputStream getInputStream() throws IOException {
+ connect();
+ return new SmbFileInputStream( file );
+ }
+
+/**
+ * Return a String representing this object.
+ */
+
+ public String toString() {
+ return new String( "SmbURLConnection[url=" + url.toString() + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import jcifs.Config;
+
+class Trans2FindFirst2 extends SmbComTransaction {
+
+
+ // information levels
+
+ static final int SMB_INFO_STANDARD = 1;
+ static final int SMB_INFO_QUERY_EA_SIZE = 2;
+ static final int SMB_INFO_QUERY_EAS_FROM_LIST = 3;
+ static final int SMB_FIND_FILE_DIRECTORY_INFO = 0x101;
+ static final int SMB_FIND_FILE_FULL_DIRECTORY_INFO = 0x102;
+ static final int SMB_FILE_NAMES_INFO = 0x103;
+ static final int SMB_FILE_BOTH_DIRECTORY_INFO = 0x104;
+
+ // flags
+
+ static final int FLAGS_CLOSE_AFTER_THIS_REQUEST = 0x01;
+ static final int FLAGS_CLOSE_IF_END_REACHED = 0x02;
+ static final int FLAGS_RETURN_RESUME_KEYS = 0x04;
+ static final int FLAGS_RESUME_FROM_PREVIOUS_END = 0x08;
+ static final int FLAGS_FIND_WITH_BACKUP_INTENT = 0x10;
+
+
+ static final int DEFAULT_MAX_DATA_COUNT = 1200;
+ static final int DEFAULT_SEARCH_COUNT = 15;
+
+ int searchAttributes;
+ int searchCount;
+ int flags;
+ int informationLevel;
+ int searchStorageType = 0;
+ String filename;
+
+ Trans2FindFirst2( String filename ) {
+ this.filename = filename;
+ command = SMB_COM_TRANSACTION2;
+ subCommand = TRANS2_FIND_FIRST2;
+
+ searchAttributes = ATTR_DIRECTORY | ATTR_HIDDEN | ATTR_SYSTEM;
+ searchCount = Config.getInt( "jcifs.smb.client.listCount", DEFAULT_SEARCH_COUNT );
+ flags = 0x00;
+ informationLevel = SMB_FILE_BOTH_DIRECTORY_INFO;
+
+ totalDataCount = 0;
+ maxParameterCount = 10;
+ maxDataCount = Config.getInt( "jcifs.smb.client.listSize", DEFAULT_MAX_DATA_COUNT );
+ maxSetupCount = 0;
+ }
+
+ int writeSetupWireFormat( byte[] dst, int dstIndex ) {
+ dst[dstIndex++] = subCommand;
+ dst[dstIndex++] = (byte)0x00;
+ return 2;
+ }
+ int writeParametersWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+
+ writeInt2( searchAttributes, dst, dstIndex );
+ dstIndex += 2;
+ writeInt2( searchCount, dst, dstIndex );
+ dstIndex += 2;
+ writeInt2( flags, dst, dstIndex );
+ dstIndex += 2;
+ writeInt2( informationLevel, dst, dstIndex );
+ dstIndex += 2;
+ writeInt4( searchStorageType, dst, dstIndex );
+ dstIndex += 4;
+ dstIndex += writeString( filename, dst, dstIndex );
+
+ return dstIndex - start;
+ }
+ int writeDataWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ public String toString() {
+ return new String( "Trans2FindFirst2[" + super.toString() +
+ ",searchAttributes=0x" + Log.getHexString( searchAttributes, 2 ) +
+ ",searchCount=" + searchCount +
+ ",flags=0x" + Log.getHexString( flags, 2 ) +
+ ",informationLevel=0x" + Log.getHexString( informationLevel, 3 ) +
+ ",searchStorageType=" + searchStorageType +
+ ",filename=" + filename + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Date;
+
+class Trans2FindFirst2Response extends SmbComTransactionResponse {
+
+ // information levels
+
+ static final int SMB_INFO_STANDARD = 1;
+ static final int SMB_INFO_QUERY_EA_SIZE = 2;
+ static final int SMB_INFO_QUERY_EAS_FROM_LIST = 3;
+ static final int SMB_FIND_FILE_DIRECTORY_INFO = 0x101;
+ static final int SMB_FIND_FILE_FULL_DIRECTORY_INFO = 0x102;
+ static final int SMB_FILE_NAMES_INFO = 0x103;
+ static final int SMB_FILE_BOTH_DIRECTORY_INFO = 0x104;
+
+ class SmbFindFileBothDirectoryInfo {
+ int nextEntryOffset;
+ int fileIndex;
+ long creationTime;
+ long lastAccessTime;
+ long lastWriteTime;
+ long changeTime;
+ long endOfFile;
+ long allocationSize;
+ int extFileAttributes;
+ int fileNameLength;
+ int eaSize;
+ int shortNameLength;
+ String shortName;
+ String filename;
+
+ public String toString() {
+ return new String( "SmbFindFileBothDirectoryInfo[" +
+ "nextEntryOffset=" + nextEntryOffset +
+ ",fileIndex=" + fileIndex +
+ ",creationTime=" + new Date( creationTime ) +
+ ",lastAccessTime=" + new Date( lastAccessTime ) +
+ ",lastWriteTime=" + new Date( lastWriteTime ) +
+ ",changeTime=" + new Date( changeTime ) +
+ ",endOfFile=" + endOfFile +
+ ",allocationSize=" + allocationSize +
+ ",extFileAttributes=" + extFileAttributes +
+ ",fileNameLength=" + fileNameLength +
+ ",eaSize=" + eaSize +
+ ",shortNameLength=" + shortNameLength +
+ ",shortName=" + shortName +
+ ",filename=" + filename + "]" );
+ }
+ }
+
+ int sid;
+ int searchCount;
+ boolean isEndOfSearch;
+ int eaErrorOffset;
+ int lastNameOffset, lastNameBufferIndex;
+ String lastName;
+ int resumeKey;
+
+ SmbFindFileBothDirectoryInfo[] results;
+
+ Trans2FindFirst2Response() {
+ command = SMB_COM_TRANSACTION2;
+ subCommand = SmbComTransaction.TRANS2_FIND_FIRST2;
+ }
+
+ String readString( byte[] src, int srcIndex, int len ) {
+ String str = null;
+ if( useUnicode ) {
+ // should Unicode alignment be corrected for here?
+ try {
+ str = new String( src, srcIndex, len, "UnicodeLittle" );
+ } catch( UnsupportedEncodingException uee ) {
+ Log.printStackTrace( "smb exception", uee );
+ }
+ } else {
+
+ /* On NT without Unicode the fileNameLength
+ * includes the '\0' whereas on win98 it doesn't. I
+ * guess most clients only support non-unicode so
+ * they don't run into this.
+ */
+
+/* UPDATE: Maybe not! Could this be a Unicode alignment issue. I hope
+ * so. We cannot just comment out this method and use readString of
+ * ServerMessageBlock.java because the arguments are different, however
+ * one might be able to reduce this.
+ */
+
+ if( len > 0 && src[srcIndex + len - 1] == '\0' ) {
+ len--;
+ }
+ str = new String( src, srcIndex, len );
+ }
+ return str;
+ }
+ int writeSetupWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeParametersWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeDataWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ int start = bufferIndex;
+
+ if( subCommand == SmbComTransaction.TRANS2_FIND_FIRST2 ) {
+ sid = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ }
+ searchCount = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ isEndOfSearch = ( buffer[bufferIndex] & 0x01 ) == 0x01 ? true : false;
+ bufferIndex += 2;
+ eaErrorOffset = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ lastNameOffset = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+
+ return bufferIndex - start;
+ }
+ int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ int start = bufferIndex;
+
+ lastNameBufferIndex = bufferIndex + lastNameOffset;
+
+ results = new SmbFindFileBothDirectoryInfo[searchCount];
+
+ for( int i = 0; i < searchCount; i++ ) {
+ results[i] = new SmbFindFileBothDirectoryInfo();
+
+ results[i].nextEntryOffset = readInt4( buffer, bufferIndex );
+ results[i].fileIndex = readInt4( buffer, bufferIndex + 4 );
+ results[i].creationTime = readTime( buffer, bufferIndex + 8 );
+ results[i].lastAccessTime = readTime( buffer, bufferIndex + 16 );
+ results[i].lastWriteTime = readTime( buffer, bufferIndex + 24 );
+ results[i].changeTime = readTime( buffer, bufferIndex + 32 );
+ results[i].endOfFile = readLong( buffer, bufferIndex + 40 );
+ results[i].allocationSize = readLong( buffer, bufferIndex + 48 );
+ results[i].extFileAttributes = readInt4( buffer, bufferIndex + 56 );
+ results[i].fileNameLength = readInt4( buffer, bufferIndex + 60 );
+ results[i].eaSize = readInt4( buffer, bufferIndex + 64 );
+ results[i].shortNameLength = buffer[bufferIndex + 68] & 0xFF;
+
+ /* With NT, the shortName is in Unicode regardless of what is negotiated.
+ */
+
+ results[i].shortName = readString( buffer, bufferIndex + 70,
+ results[i].shortNameLength );
+ results[i].filename = readString( buffer, bufferIndex + 94,
+ results[i].fileNameLength );
+
+//Log.println( Log.DEBUGGING, "Trans2FindFirst2/Next2Response debugging", "bufferIndex=" + bufferIndex + ",lastNameBufferIndex=" + lastNameBufferIndex + ",nextEntryOffet=" + ( bufferIndex + results[i].nextEntryOffset ));
+
+ /* lastNameOffset ends up pointing to either to
+ * the exact location of the filename(e.g. Win98)
+ * or to the start of the entry containing the
+ * filename(e.g. NT). Ahhrg! In either case the
+ * lastNameOffset falls between the start of the
+ * entry and the next entry.
+ */
+
+ if( lastNameBufferIndex >= bufferIndex &&
+ ( results[i].nextEntryOffset == 0 ||
+ lastNameBufferIndex < ( bufferIndex + results[i].nextEntryOffset ))) {
+ lastName = results[i].filename;
+ resumeKey = results[i].fileIndex;
+ }
+
+//Log.println( Log.DEBUGGING, "info entry", results[i].toString() );
+
+ bufferIndex += results[i].nextEntryOffset;
+ }
+
+
+ if( lastName == null ) {
+ Log.println( Log.DEBUGGING, "Trans2FindFirst2/Next2Response debugging",
+ "lastName was null!" );
+ }
+
+ /* last nextEntryOffset for NT 4(but not 98) is 0 so we must
+ * use dataCount or our accounting will report an error for NT :~(
+ */
+
+ //return bufferIndex - start;
+
+ return dataCount;
+ }
+ public String toString() {
+ String c;
+ if( subCommand == SmbComTransaction.TRANS2_FIND_FIRST2 ) {
+ c = "Trans2FindFirst2Response[";
+ } else {
+ c = "Trans2FindNext2Response[";
+ }
+ return new String( c + super.toString() +
+ ",sid=" + sid +
+ ",searchCount=" + searchCount +
+ ",isEndOfSearch=" + isEndOfSearch +
+ ",eaErrorOffset=" + eaErrorOffset +
+ ",lastNameOffset=" + lastNameOffset +
+ ",lastName=" + lastName + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import jcifs.Config;
+
+class Trans2FindNext2 extends SmbComTransaction {
+
+ int sid, searchCount, informationLevel, resumeKey, flags;
+ String filename;
+
+ Trans2FindNext2( int sid, int resumeKey, String filename ) {
+ this.sid = sid;
+ this.resumeKey = resumeKey;
+ this.filename = filename;
+ command = SMB_COM_TRANSACTION2;
+ subCommand = TRANS2_FIND_NEXT2;
+ searchCount = Config.getInt( "jcifs.smb.client.listCount",
+ Trans2FindFirst2.DEFAULT_SEARCH_COUNT );
+ informationLevel = Trans2FindFirst2.SMB_FILE_BOTH_DIRECTORY_INFO;
+ flags = 0x00;
+ maxParameterCount = 8;
+ maxDataCount = Config.getInt( "jcifs.smb.client.listSize",
+ Trans2FindFirst2.DEFAULT_MAX_DATA_COUNT );
+ maxSetupCount = 0;
+ }
+
+ int writeSetupWireFormat( byte[] dst, int dstIndex ) {
+ dst[dstIndex++] = subCommand;
+ dst[dstIndex++] = (byte)0x00;
+ return 2;
+ }
+ int writeParametersWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+
+ writeInt2( sid, dst, dstIndex );
+ dstIndex += 2;
+ writeInt2( searchCount, dst, dstIndex );
+ dstIndex += 2;
+ writeInt2( informationLevel, dst, dstIndex );
+ dstIndex += 2;
+ writeInt4( resumeKey, dst, dstIndex );
+ dstIndex += 4;
+ writeInt2( flags, dst, dstIndex );
+ dstIndex += 2;
+ dstIndex += writeString( filename, dst, dstIndex );
+
+ return dstIndex - start;
+ }
+ int writeDataWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ public String toString() {
+ return new String( "Trans2FindNext2[" + super.toString() +
+ ",sid=" + sid +
+ ",searchCount=" + searchCount +
+ ",informationLevel=0x" + Log.getHexString( informationLevel, 3 ) +
+ ",resumeKey=0x" + Log.getHexString( resumeKey, 4 ) +
+ ",flags=0x" + Log.getHexString( flags, 2 ) +
+ ",filename=" + filename + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+class Trans2QueryFSInformation extends SmbComTransaction {
+
+ int informationLevel;
+
+ Trans2QueryFSInformation() {
+ command = SMB_COM_TRANSACTION2;
+ subCommand = TRANS2_QUERY_FS_INFORMATION;
+ informationLevel = Trans2QueryFSInformationResponse.SMB_QUERY_FS_ATTRIBUTE_INFO;
+ totalParameterCount = 2;
+ totalDataCount = 0;
+ maxParameterCount = 0;
+ maxDataCount = 800;
+ maxSetupCount = 0;
+ }
+
+ int writeSetupWireFormat( byte[] dst, int dstIndex ) {
+ dst[dstIndex++] = subCommand;
+ dst[dstIndex++] = (byte)0x00;
+ return 2;
+ }
+ int writeParametersWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+
+ writeInt2( informationLevel, dst, dstIndex );
+ dstIndex += 2;
+
+ /* windows98 has what appears to be another 4 0's followed by the share
+ * name as a zero terminated ascii string "\TMP" + '\0'
+ *
+ * As is this works, but it deviates from the spec section 4.1.6.6 but
+ * maybe I should put it in. Wonder what NT does?
+ */
+
+ return dstIndex - start;
+ }
+ int writeDataWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ public String toString() {
+ return new String( "Trans2QueryFSInformation[" + super.toString() +
+ ",informationLevel=0x" + Log.getHexString( informationLevel, 3 ) + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import java.io.UnsupportedEncodingException;
+
+class Trans2QueryFSInformationResponse extends SmbComTransactionResponse {
+
+ // information levels
+ static final int SMB_QUERY_FS_ATTRIBUTE_INFO = 0x105;
+
+ class SmbQueryFSAttributeInfo implements Info {
+ int attributes;
+ int maxNameLength;
+ String name;
+
+ public int getAttributes() {
+ return attributes;
+ }
+ public long getLastWriteTime() {
+ return 0;
+ }
+ public long getSize() {
+ return 0;
+ }
+ public String toString() {
+ return new String( "SmbQueryFSAttributeInfo[" +
+ "attributes=0x" + Log.getHexString( attributes, 4 ) +
+ ",maxNameLength=" + maxNameLength +
+ ",name=" + name + "]" );
+ }
+ }
+
+ Info info;
+
+ Trans2QueryFSInformationResponse() {
+ command = SMB_COM_TRANSACTION2;
+ subCommand = SmbComTransaction.TRANS2_QUERY_FS_INFORMATION;
+ }
+
+ int writeSetupWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeParametersWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeDataWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ int start = bufferIndex;
+
+ SmbQueryFSAttributeInfo info = new SmbQueryFSAttributeInfo();
+ info.attributes = readInt4( buffer, bufferIndex );
+ bufferIndex += 4;
+ info.maxNameLength = readInt2( buffer, bufferIndex );
+ bufferIndex += 4;
+ int nameLength = readInt2( buffer, bufferIndex );
+ bufferIndex += 4;
+ try {
+ info.name = new String( buffer, bufferIndex, nameLength, "UnicodeLittle" );
+ } catch( UnsupportedEncodingException uee ) {
+ Log.printStackTrace( "", uee );
+ }
+ bufferIndex += nameLength;
+ this.info = info;
+
+ return bufferIndex - start;
+ }
+ public String toString() {
+ return new String( "Trans2QueryFSInformationResponse[" +
+ super.toString() + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+class Trans2QueryPathInformation extends SmbComTransaction {
+
+ int informationLevel;
+ String filename;
+
+ Trans2QueryPathInformation( String filename, int informationLevel ) {
+ this.filename = filename;
+ this.informationLevel = informationLevel;
+ command = SMB_COM_TRANSACTION2;
+ subCommand = TRANS2_QUERY_PATH_INFORMATION;
+ totalDataCount = 0;
+ maxParameterCount = 2;
+ maxDataCount = 40;
+ maxSetupCount = (byte)0x00;
+ }
+
+ int writeSetupWireFormat( byte[] dst, int dstIndex ) {
+ dst[dstIndex++] = subCommand;
+ dst[dstIndex++] = (byte)0x00;
+ return 2;
+ }
+ int writeParametersWireFormat( byte[] dst, int dstIndex ) {
+ int start = dstIndex;
+
+ writeInt2( informationLevel, dst, dstIndex );
+ dstIndex += 2;
+ dst[dstIndex++] = (byte)0x00;
+ dst[dstIndex++] = (byte)0x00;
+ dst[dstIndex++] = (byte)0x00;
+ dst[dstIndex++] = (byte)0x00;
+ dstIndex += writeString( filename, dst, dstIndex );
+
+ return dstIndex - start;
+ }
+ int writeDataWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ public String toString() {
+ return new String( "Trans2QueryPathInformation[" + super.toString() +
+ ",informationLevel=0x" + Log.getHexString( informationLevel, 3 ) +
+ ",filename=" + filename + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import java.util.Date;
+
+class Trans2QueryPathInformationResponse extends SmbComTransactionResponse {
+
+ // information levels
+ static final int SMB_QUERY_FILE_BASIC_INFO = 0x101;
+ static final int SMB_QUERY_FILE_STANDARD_INFO = 0x102;
+
+ class SmbQueryFileBasicInfo implements Info {
+ long creationTime;
+ long lastAccessTime;
+ long lastWriteTime;
+ long changeTime;
+ int attributes;
+
+ public int getAttributes() {
+ return attributes;
+ }
+ public long getLastWriteTime() {
+ return lastWriteTime;
+ }
+ public long getSize() {
+ return 0L;
+ }
+ public String toString() {
+ return new String( "SmbQueryFileBasicInfo[" +
+ "creationTime=" + new Date( creationTime ) +
+ ",lastAccessTime=" + new Date( lastAccessTime ) +
+ ",lastWriteTime=" + new Date( lastWriteTime ) +
+ ",changeTime=" + new Date( changeTime ) +
+ ",attributes=0x" + Log.getHexString( attributes, 4 ) + "]" );
+ }
+ }
+ class SmbQueryFileStandardInfo implements Info {
+ long allocationSize;
+ long endOfFile;
+ int numberOfLinks;
+ boolean deletePending;
+ boolean directory;
+
+ public int getAttributes() {
+ return 0;
+ }
+ public long getLastWriteTime() {
+ return 0;
+ }
+ public long getSize() {
+ return endOfFile;
+ }
+ public String toString() {
+ return new String( "SmbQueryInfoStandard[" +
+ "allocationSize=" + allocationSize +
+ ",endOfFile=" + endOfFile +
+ ",numberOfLinks=" + numberOfLinks +
+ ",deletePending=" + deletePending +
+ ",directory=" + directory + "]" );
+ }
+ }
+
+ int informationLevel;
+ Info info;
+
+ Trans2QueryPathInformationResponse( int informationLevel ) {
+ this.informationLevel = informationLevel;
+ subCommand = SmbComTransaction.TRANS2_QUERY_PATH_INFORMATION;
+ }
+
+ int writeSetupWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeParametersWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeDataWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ // observed two zero bytes here with at least win98
+ return 2;
+ }
+ int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ switch( informationLevel ) {
+ case SMB_QUERY_FILE_BASIC_INFO:
+ return readSmbQueryFileBasicInfoWireFormat( buffer, bufferIndex );
+ case SMB_QUERY_FILE_STANDARD_INFO:
+ return readSmbQueryFileStandardInfoWireFormat( buffer, bufferIndex );
+ default:
+ return 0;
+ }
+ }
+ int readSmbQueryFileStandardInfoWireFormat( byte[] buffer, int bufferIndex ) {
+ int start = bufferIndex;
+
+ SmbQueryFileStandardInfo info = new SmbQueryFileStandardInfo();
+ info.allocationSize = readLong( buffer, bufferIndex );
+ bufferIndex += 8;
+ info.endOfFile = readLong( buffer, bufferIndex );
+ bufferIndex += 8;
+ info.numberOfLinks = readInt4( buffer, bufferIndex );
+ bufferIndex += 4;
+ info.deletePending = ( buffer[bufferIndex++] & 0xFF ) > 0;
+ info.directory = ( buffer[bufferIndex++] & 0xFF ) > 0;
+ this.info = info;
+
+ return bufferIndex - start;
+ }
+ int readSmbQueryFileBasicInfoWireFormat( byte[] buffer, int bufferIndex ) {
+ int start = bufferIndex;
+
+ SmbQueryFileBasicInfo info = new SmbQueryFileBasicInfo();
+ info.creationTime = readTime( buffer, bufferIndex );
+ bufferIndex += 8;
+ info.lastAccessTime = readTime( buffer, bufferIndex );
+ bufferIndex += 8;
+ info.lastWriteTime = readTime( buffer, bufferIndex );
+ bufferIndex += 8;
+ info.changeTime = readTime( buffer, bufferIndex );
+ bufferIndex += 8;
+ info.attributes = readInt2( buffer, bufferIndex );
+ bufferIndex += 2;
+ this.info = info;
+
+ return bufferIndex - start;
+ }
+ public String toString() {
+ return new String( "Trans2QueryPathInformationResponse[" +
+ super.toString() + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+class TransCallNamedPipe extends SmbComTransaction {
+
+ byte[] pipeData;
+ int pipeDataOff, pipeDataLen;
+
+ TransCallNamedPipe( String pipeName, byte[] data, int off, int len ) {
+ name = pipeName;
+ pipeData = data;
+ pipeDataOff = off;
+ pipeDataLen = len;
+ command = SMB_COM_TRANSACTION;
+ subCommand = TRANS_CALL_NAMED_PIPE;
+ timeout = 0xFFFFFFFF;
+ maxParameterCount = 0;
+ maxDataCount = 0xFFFF;
+ maxSetupCount = (byte)0x00;
+ setupCount = 2;
+ }
+
+ int writeSetupWireFormat( byte[] dst, int dstIndex ) {
+ dst[dstIndex++] = subCommand;
+ dst[dstIndex++] = (byte)0x00;
+ // this says "Transaction priority" in netmon
+ dst[dstIndex++] = (byte)0x00; // no FID
+ dst[dstIndex++] = (byte)0x00;
+ return 4;
+ }
+ int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int writeParametersWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeDataWireFormat( byte[] dst, int dstIndex ) {
+ if(( dst.length - dstIndex ) < pipeDataLen ) {
+ Log.println( Log.WARNINGS, "smb warning",
+ "TransCallNamedPipe data too long for buffer" );
+ return 0;
+ }
+ System.arraycopy( pipeData, pipeDataOff, dst, dstIndex, pipeDataLen );
+ return pipeDataLen;
+ }
+ int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ public String toString() {
+ return new String( "TransCallNamedPipe[" + super.toString() +
+ ",pipeName=" + name + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+class TransCallNamedPipeResponse extends SmbComTransactionResponse {
+
+ SmbNamedPipe pipe;
+
+ TransCallNamedPipeResponse( SmbNamedPipe pipe ) {
+ this.pipe = pipe;
+ }
+
+ int writeSetupWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeParametersWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeDataWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ if( pipe.pipeIn != null ) {
+ TransactNamedPipeInputStream in = (TransactNamedPipeInputStream)pipe.pipeIn;
+ synchronized( in.lock ) {
+ in.receive( buffer, bufferIndex, len );
+ in.lock.notify();
+ }
+ }
+ return len;
+ }
+ public String toString() {
+ return new String( "TransCallNamedPipeResponse[" + super.toString() + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+class TransTransactNamedPipe extends SmbComTransaction {
+
+ byte[] pipeData;
+ int pipeFid, pipeDataOff, pipeDataLen;
+
+ TransTransactNamedPipe( int fid, byte[] data, int off, int len ) {
+ pipeFid = fid;
+ pipeData = data;
+ pipeDataOff = off;
+ pipeDataLen = len;
+ command = SMB_COM_TRANSACTION;
+ subCommand = TRANS_TRANSACT_NAMED_PIPE;
+ maxParameterCount = 0;
+ maxDataCount = 0xFFFF;
+ maxSetupCount = (byte)0x00;
+ setupCount = 2;
+ name = "\\PIPE\\";
+ }
+
+ int writeSetupWireFormat( byte[] dst, int dstIndex ) {
+ dst[dstIndex++] = subCommand;
+ dst[dstIndex++] = (byte)0x00;
+ writeInt2( pipeFid, dst, dstIndex );
+ dstIndex += 2;
+ return 4;
+ }
+ int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int writeParametersWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeDataWireFormat( byte[] dst, int dstIndex ) {
+ if(( dst.length - dstIndex ) < pipeDataLen ) {
+ Log.println( Log.WARNINGS, "smb warning",
+ "TransTransactNamedPipe data too long for buffer" );
+ return 0;
+ }
+ System.arraycopy( pipeData, pipeDataOff, dst, dstIndex, pipeDataLen );
+ return pipeDataLen;
+ }
+ int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ public String toString() {
+ return new String( "TransTransactNamedPipe[" + super.toString() +
+ ",pipeFid=" + pipeFid + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+class TransTransactNamedPipeResponse extends SmbComTransactionResponse {
+
+ SmbNamedPipe pipe;
+
+ TransTransactNamedPipeResponse( SmbNamedPipe pipe ) {
+ this.pipe = pipe;
+ }
+
+ int writeSetupWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeParametersWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeDataWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ if( pipe.pipeIn != null ) {
+ TransactNamedPipeInputStream in = (TransactNamedPipeInputStream)pipe.pipeIn;
+ synchronized( in.lock ) {
+ in.receive( buffer, bufferIndex, len );
+ in.lock.notify();
+ }
+ }
+ return len;
+ }
+ public String toString() {
+ return new String( "TransTransactNamedPipeResponse[" + super.toString() + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+class TransWaitNamedPipe extends SmbComTransaction {
+
+ TransWaitNamedPipe( String pipeName ) {
+ name = pipeName;
+ command = SMB_COM_TRANSACTION;
+ subCommand = TRANS_WAIT_NAMED_PIPE;
+ timeout = 0xFFFFFFFF;
+ maxParameterCount = 0;
+ maxDataCount = 0;
+ maxSetupCount = (byte)0x00;
+ setupCount = 2;
+ }
+
+ int writeSetupWireFormat( byte[] dst, int dstIndex ) {
+ dst[dstIndex++] = subCommand;
+ dst[dstIndex++] = (byte)0x00;
+ dst[dstIndex++] = (byte)0x00; // no FID
+ dst[dstIndex++] = (byte)0x00;
+ return 4;
+ }
+ int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int writeParametersWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeDataWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ public String toString() {
+ return new String( "TransWaitNamedPipe[" + super.toString() +
+ ",pipeName=" + name + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+class TransWaitNamedPipeResponse extends SmbComTransactionResponse {
+
+ // not much to this one is there :~)
+
+ TransWaitNamedPipeResponse() {
+ }
+
+ int writeSetupWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeParametersWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int writeDataWireFormat( byte[] dst, int dstIndex ) {
+ return 0;
+ }
+ int readSetupWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int readParametersWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ int readDataWireFormat( byte[] buffer, int bufferIndex, int len ) {
+ return 0;
+ }
+ public String toString() {
+ return new String( "TransWaitNamedPipeResponse[" + super.toString() + "]" );
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import java.io.InputStream;
+import java.io.IOException;
+
+class TransactNamedPipeInputStream extends InputStream {
+
+ static final int INIT_PIPE_SIZE = 4096;
+
+ byte[] pipe_buf = new byte[INIT_PIPE_SIZE];
+ int beg_idx, nxt_idx, used;
+ Object lock;
+
+ TransactNamedPipeInputStream() {
+ lock = new Object();
+ }
+ public void close() throws IOException {
+ }
+ public int read() throws IOException {
+ int result = -1;
+
+ synchronized( lock ) {
+ try {
+ while( used == 0 ) {
+ lock.wait();
+ }
+ } catch( InterruptedException ie ) {
+ throw new IOException( ie.getMessage() );
+ }
+ result = pipe_buf[beg_idx] & 0xFF;
+ beg_idx = ( beg_idx + 1 ) % pipe_buf.length;
+ }
+ return result;
+ }
+ public int read( byte[] b ) throws IOException {
+ return read( b, 0, b.length );
+ }
+ public int read( byte[] b, int off, int len ) throws IOException {
+ int result = -1;
+ int i;
+
+ if( len <= 0 ) {
+ return 0;
+ }
+ synchronized( lock ) {
+ try {
+ while( used == 0 ) {
+ lock.wait();
+ }
+ } catch( InterruptedException ie ) {
+ throw new IOException( ie.getMessage() );
+ }
+ i = pipe_buf.length - beg_idx;
+ result = len > used ? used : len;
+ if( used > i && result > i ) {
+ System.arraycopy( pipe_buf, beg_idx, b, off, i );
+ off += i;
+ System.arraycopy( pipe_buf, 0, b, off, result );
+ } else {
+ System.arraycopy( pipe_buf, beg_idx, b, off, result );
+ }
+ used -= result;
+ beg_idx = ( beg_idx + result ) % pipe_buf.length;
+ }
+ return result;
+ }
+
+ int receive( byte[] b, int off, int len ) {
+ int i;
+
+ if( len > ( pipe_buf.length - used )) {
+ byte[] tmp;
+ int new_size;
+
+ new_size = pipe_buf.length * 2;
+ if( len > ( new_size - used )) {
+ new_size = len + used;
+ }
+ tmp = pipe_buf;
+ pipe_buf = new byte[new_size];
+ i = pipe_buf.length - beg_idx;
+ if( used > i ) {
+ System.arraycopy( tmp, beg_idx, pipe_buf, 0, i );
+ System.arraycopy( tmp, 0, pipe_buf, i, used - i );
+ } else {
+ System.arraycopy( tmp, beg_idx, pipe_buf, 0, used );
+ }
+ beg_idx = 0;
+ tmp = null;
+ }
+
+ i = pipe_buf.length - nxt_idx;
+ if( len > i ) {
+ System.arraycopy( b, off, pipe_buf, nxt_idx, i );
+ off += i;
+ System.arraycopy( b, off, pipe_buf, 0, len - i );
+ } else {
+ System.arraycopy( b, off, pipe_buf, nxt_idx, len );
+ }
+ nxt_idx = ( nxt_idx + len ) % pipe_buf.length;
+ used += len;
+ return len;
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.smb;
+
+import java.io.OutputStream;
+import java.io.IOException;
+
+class TransactNamedPipeOutputStream extends OutputStream {
+
+ String path;
+ SmbNamedPipe pipe;
+ byte[] tmp = new byte[1];
+
+ TransactNamedPipeOutputStream( SmbNamedPipe pipe ) throws IOException {
+ this.pipe = pipe;
+ path = pipe.path.toUpperCase();
+ }
+
+ public void close() throws IOException {
+ }
+ public void write( int b ) throws IOException {
+ tmp[0] = (byte)b;
+ write( tmp, 0, 1 );
+ }
+ public void write( byte[] b ) throws IOException {
+ write( b, 0, b.length );
+ }
+ public void write( byte[] b, int off, int len ) throws IOException {
+ if( len < 0 ) {
+ len = 0;
+ }
+
+ if(( pipe.pipeType & SmbNamedPipe.PIPE_TYPE_CALL ) ==
+ SmbNamedPipe.PIPE_TYPE_CALL ) {
+ pipe.tree.sendTransaction( new TransWaitNamedPipe( path ),
+ new TransWaitNamedPipeResponse() );
+ pipe.tree.sendTransaction( new TransCallNamedPipe( path, b, off, len ),
+ new TransCallNamedPipeResponse( pipe ));
+ } else if(( pipe.pipeType & SmbNamedPipe.PIPE_TYPE_TRANSACT ) ==
+ SmbNamedPipe.PIPE_TYPE_TRANSACT ) {
+ pipe.open(( pipe.pipeType & 0xFF0000 ) | SmbFile.O_EXCL );
+ pipe.tree.sendTransaction( new TransTransactNamedPipe( pipe.fid, b, off, len ),
+ new TransTransactNamedPipeResponse( pipe ));
+ }
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.util;
+
+import java.util.Properties;
+import java.util.Enumeration;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/**
+ * This class uses a static {@link jcifs.util.PropertiesTree} to act
+ * as a cental repository of configuration information. It cannot be
+ * instantiated. Similar to <code>System</code> properties the namespace
+ * is global therefore property names should be unique. Before use,
+ * the <code>load</code> method should be called with the name of a
+ * <code>PropertiesTree</code> file(or <code>null</code> indicating no
+ * file) to initialize the <code>Config</code>. The <code>System</code>
+ * properties will then populate the <code>Config</code> as well potentially
+ * overwriting properties from the file. Thus properties provided on the
+ * commandline with the <code>-Dproperty.name=value</code> VM parameter
+ * will override properties from the configuration file.
+ */
+
+public class Config {
+
+ // supress javadoc constructor summary by removing 'protected'
+ Config() {}
+
+ /**
+ * The static <code>PropertiesTree</code>.
+ */
+
+ protected static PropertiesTree properties = new PropertiesTree();
+
+ /**
+ * Load the <code>Config</code> with properties from the stream
+ * <code>in</code> which should be in <code>PropertiesTree</code>
+ * format. See <a href="../../../properties.html">More About
+ * PropertiesTree and it's File Format</code>.
+ */
+
+ public static void load( InputStream in ) throws IOException {
+ Properties sys;
+
+ if( in != null ) {
+ properties.load( in );
+ }
+
+ sys = System.getProperties();
+ for( Enumeration e = sys.propertyNames(); e.hasMoreElements(); ) {
+ String key = (String)e.nextElement();
+ String val = (String)sys.getProperty( key );
+ if( key != null && val != null ) {
+ try {
+ properties.put( key, val );
+ } catch( IllegalArgumentException iae ) {
+ }
+ }
+ }
+ }
+
+ /**
+ * List the properties in the <code>Code</code>.
+ */
+
+ public static void list( PrintStream out ) throws IOException {
+ properties.list( out );
+ }
+
+ /**
+ * Add a property. If the property already
+ * exists and it is a <code>PropertiesTree</code> an
+ * <code>IllegalArgumentException</code> will be thrown to indicate
+ * that an entire branch of the tree cannot be overwritten. If
+ * however the node is a leaf property, it will be overwritten
+ * and the old value returned as a <code>String</code>.
+ */
+
+ public static String setProperty( String key, String value ) {
+ return (String)properties.put( key, value );
+ }
+
+ /**
+ * Retrieve a property as an <code>Object</code>. Possible
+ * types are <code>String</code> if the property is a leaf node,
+ * or a <code>PropertiesTree</code> if key resolves to a parent node,
+ * or <code>null</code> otherwise.
+ */
+
+ public static Object get( String key ) {
+ return properties.get( key );
+ }
+
+ /**
+ * Retrieve a <code>String</code>. If the key cannot be found,
+ * the provided <code>def</code> default parameter will be returned.
+ */
+
+ public static String getProperty( String key, String def ) {
+ String result = null;
+ Object obj = get( key );
+ if( obj != null && obj instanceof String ) {
+ result = (String)obj;
+ }
+ return obj == null ? def : result;
+ }
+
+ /**
+ * Retrieve a <code>String</code>. If the property is not found, <code>null</code> is returned.
+ */
+
+ public static String getProperty( String key ) {
+ String result = null;
+ Object obj = get( key );
+ if( obj != null && obj instanceof String ) {
+ result = (String)obj;
+ }
+ return result;
+ }
+
+ /**
+ * Retrieve an <code>int</code>. If the key does not exist or
+ * cannot be converted to an <code>int</code>, the provided default
+ * argument will be returned.
+ */
+
+ public static int getInt( String key, int def ) {
+ Object obj = get( key );
+ if( obj != null && obj instanceof String ) {
+ try {
+ def = Integer.parseInt( (String)obj );
+ } catch( NumberFormatException nfe ) {
+ Log.printStackTrace( "configuration warning", nfe );
+ }
+ }
+ return def;
+ }
+
+ /**
+ * Retrieve an <code>int</code>. If the property is not found, <code>-1</code> is returned.
+ */
+
+ public static int getInt( String key ) {
+ int result = -1;
+ Object obj = get( key );
+ if( obj != null && obj instanceof String ) {
+ try {
+ result = Integer.parseInt( (String)obj );
+ } catch( NumberFormatException nfe ) {
+ Log.printStackTrace( "configuration warning", nfe );
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Retrieve an <code>InetAddress</code>. If the address is not
+ * an IP address and cannot be resolved <code>null</code> will
+ * be returned.
+ */
+
+ public static InetAddress getInetAddress( String key, InetAddress def ) {
+ String addr = getProperty( key );
+ if( addr != null ) {
+ try {
+ def = InetAddress.getByName( addr );
+ } catch( UnknownHostException uhe ) {
+ }
+ }
+ return def;
+ }
+
+ /**
+ * Retrieve a boolean value. If the property is not found, the value of <code>def</code> is returned.
+ */
+
+ public static boolean getBoolean( String key, boolean def ) {
+ String b = getProperty( key );
+ if( b != null ) {
+ def = b.toLowerCase().equals( "true" );
+ }
+ return def;
+ }
+
+ /**
+ * Print all properties through the {@link jcifs.util.Log} class with the mask <code>Log.WARNINGS</code>.
+ */
+
+ public static void printProperties( String msg ) {
+ Log.printProperties( Log.WARNINGS, msg, properties );
+ }
+}
--- /dev/null
+// DesCipher - the DES encryption method
+//
+// The meat of this code is by Dave Zimmerman <dzimm@widget.com>, and is:
+//
+// Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved.
+//
+// Permission to use, copy, modify, and distribute this software
+// and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and
+// without fee is hereby granted, provided that this copyright notice is kept
+// intact.
+//
+// WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
+// OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+// TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+// PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE
+// FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+// DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
+//
+// THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
+// CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
+// PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
+// NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
+// SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
+// SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
+// PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). WIDGET WORKSHOP
+// SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR
+// HIGH RISK ACTIVITIES.
+//
+//
+// The rest is:
+//
+// Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
+//
+// Copyright (C) 1996 by Wolfgang Platzer
+// email: wplatzer@iaik.tu-graz.ac.at
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+// SUCH DAMAGE.
+//
+
+package jcifs.util;
+
+import java.io.*;
+
+/**
+ * This code is derived from the above source
+ * JCIFS API
+ * Norbert Hranitzky
+ *
+ * <p>and modified again by Michael B. Allen
+ */
+
+public class DES {
+
+
+ private int[] encryptKeys = new int[32];
+ private int[] decryptKeys = new int[32];
+
+ private int[] tempInts = new int[2];
+
+
+ public DES( ) {
+
+ }
+
+ // Constructor, byte-array key.
+ public DES( byte[] key ) {
+ if( key.length == 7 ) {
+ byte[] key8 = new byte[8];
+ makeSMBKey( key, key8 );
+ setKey( key8 );
+ } else {
+ setKey( key );
+ }
+ }
+
+
+ public static void makeSMBKey(byte[] key7, byte[] key8) {
+
+ int i;
+
+ key8[0] = (byte) ( ( key7[0] >> 1) & 0xff);
+ key8[1] = (byte)(( ((key7[0] & 0x01) << 6) | (((key7[1] & 0xff)>>2) & 0xff)) & 0xff );
+ key8[2] = (byte)(( ((key7[1] & 0x03) << 5) | (((key7[2] & 0xff)>>3) & 0xff)) & 0xff );
+ key8[3] = (byte)(( ((key7[2] & 0x07) << 4) | (((key7[3] & 0xff)>>4) & 0xff)) & 0xff );
+ key8[4] = (byte)(( ((key7[3] & 0x0F) << 3) | (((key7[4] & 0xff)>>5) & 0xff)) & 0xff );
+ key8[5] = (byte)(( ((key7[4] & 0x1F) << 2) | (((key7[5] & 0xff)>>6) & 0xff)) & 0xff );
+ key8[6] = (byte)(( ((key7[5] & 0x3F) << 1) | (((key7[6] & 0xff)>>7) & 0xff)) & 0xff );
+ key8[7] = (byte)(key7[6] & 0x7F);
+ for (i=0;i<8;i++) {
+ key8[i] = (byte)( key8[i] << 1);
+ }
+ }
+
+ /// Set the key.
+ public void setKey( byte[] key ) {
+
+ // CHECK PAROTY TBD
+ deskey( key, true, encryptKeys );
+ deskey( key, false, decryptKeys );
+ }
+
+ // Turn an 8-byte key into internal keys.
+ private void deskey( byte[] keyBlock, boolean encrypting, int[] KnL ) {
+
+ int i, j, l, m, n;
+ int[] pc1m = new int[56];
+ int[] pcr = new int[56];
+ int[] kn = new int[32];
+
+ for ( j = 0; j < 56; ++j ) {
+ l = pc1[j];
+ m = l & 07;
+ pc1m[j] = ( (keyBlock[l >>> 3] & bytebit[m]) != 0 )? 1: 0;
+ }
+
+ for ( i = 0; i < 16; ++i ) {
+
+ if ( encrypting )
+ m = i << 1;
+ else
+ m = (15-i) << 1;
+ n = m+1;
+ kn[m] = kn[n] = 0;
+ for ( j = 0; j < 28; ++j ) {
+ l = j+totrot[i];
+ if ( l < 28 )
+ pcr[j] = pc1m[l];
+ else
+ pcr[j] = pc1m[l-28];
+ }
+ for ( j=28; j < 56; ++j ) {
+ l = j+totrot[i];
+ if ( l < 56 )
+ pcr[j] = pc1m[l];
+ else
+ pcr[j] = pc1m[l-28];
+ }
+ for ( j = 0; j < 24; ++j ) {
+ if ( pcr[pc2[j]] != 0 )
+ kn[m] |= bigbyte[j];
+ if ( pcr[pc2[j+24]] != 0 )
+ kn[n] |= bigbyte[j];
+ }
+ }
+ cookey( kn, KnL );
+ }
+
+ private void cookey( int[] raw, int KnL[] ) {
+ int raw0, raw1;
+ int rawi, KnLi;
+ int i;
+
+ for ( i = 0, rawi = 0, KnLi = 0; i < 16; ++i ) {
+ raw0 = raw[rawi++];
+ raw1 = raw[rawi++];
+ KnL[KnLi] = (raw0 & 0x00fc0000) << 6;
+ KnL[KnLi] |= (raw0 & 0x00000fc0) << 10;
+ KnL[KnLi] |= (raw1 & 0x00fc0000) >>> 10;
+ KnL[KnLi] |= (raw1 & 0x00000fc0) >>> 6;
+ ++KnLi;
+ KnL[KnLi] = (raw0 & 0x0003f000) << 12;
+ KnL[KnLi] |= (raw0 & 0x0000003f) << 16;
+ KnL[KnLi] |= (raw1 & 0x0003f000) >>> 4;
+ KnL[KnLi] |= (raw1 & 0x0000003f);
+ ++KnLi;
+ }
+ }
+
+
+ /// Encrypt a block of eight bytes.
+ private void encrypt( byte[] clearText, int clearOff, byte[] cipherText, int cipherOff ) {
+
+ squashBytesToInts( clearText, clearOff, tempInts, 0, 2 );
+ des( tempInts, tempInts, encryptKeys );
+ spreadIntsToBytes( tempInts, 0, cipherText, cipherOff, 2 );
+ }
+
+ /// Decrypt a block of eight bytes.
+ private void decrypt( byte[] cipherText, int cipherOff, byte[] clearText, int clearOff ) {
+
+ squashBytesToInts( cipherText, cipherOff, tempInts, 0, 2 );
+ des( tempInts, tempInts, decryptKeys );
+ spreadIntsToBytes( tempInts, 0, clearText, clearOff, 2 );
+ }
+
+ // The DES function.
+ private void des( int[] inInts, int[] outInts, int[] keys ) {
+
+ int fval, work, right, leftt;
+ int round;
+ int keysi = 0;
+
+ leftt = inInts[0];
+ right = inInts[1];
+
+ work = ((leftt >>> 4) ^ right) & 0x0f0f0f0f;
+ right ^= work;
+ leftt ^= (work << 4);
+
+ work = ((leftt >>> 16) ^ right) & 0x0000ffff;
+ right ^= work;
+ leftt ^= (work << 16);
+
+ work = ((right >>> 2) ^ leftt) & 0x33333333;
+ leftt ^= work;
+ right ^= (work << 2);
+
+ work = ((right >>> 8) ^ leftt) & 0x00ff00ff;
+ leftt ^= work;
+ right ^= (work << 8);
+ right = (right << 1) | ((right >>> 31) & 1);
+
+ work = (leftt ^ right) & 0xaaaaaaaa;
+ leftt ^= work;
+ right ^= work;
+ leftt = (leftt << 1) | ((leftt >>> 31) & 1);
+
+ for ( round = 0; round < 8; ++round ) {
+ work = (right << 28) | (right >>> 4);
+ work ^= keys[keysi++];
+ fval = SP7[ work & 0x0000003f ];
+ fval |= SP5[(work >>> 8) & 0x0000003f ];
+ fval |= SP3[(work >>> 16) & 0x0000003f ];
+ fval |= SP1[(work >>> 24) & 0x0000003f ];
+ work = right ^ keys[keysi++];
+ fval |= SP8[ work & 0x0000003f ];
+ fval |= SP6[(work >>> 8) & 0x0000003f ];
+ fval |= SP4[(work >>> 16) & 0x0000003f ];
+ fval |= SP2[(work >>> 24) & 0x0000003f ];
+ leftt ^= fval;
+ work = (leftt << 28) | (leftt >>> 4);
+ work ^= keys[keysi++];
+ fval = SP7[ work & 0x0000003f ];
+ fval |= SP5[(work >>> 8) & 0x0000003f ];
+ fval |= SP3[(work >>> 16) & 0x0000003f ];
+ fval |= SP1[(work >>> 24) & 0x0000003f ];
+ work = leftt ^ keys[keysi++];
+ fval |= SP8[ work & 0x0000003f ];
+ fval |= SP6[(work >>> 8) & 0x0000003f ];
+ fval |= SP4[(work >>> 16) & 0x0000003f ];
+ fval |= SP2[(work >>> 24) & 0x0000003f ];
+ right ^= fval;
+ }
+
+ right = (right << 31) | (right >>> 1);
+ work = (leftt ^ right) & 0xaaaaaaaa;
+ leftt ^= work;
+ right ^= work;
+ leftt = (leftt << 31) | (leftt >>> 1);
+ work = ((leftt >>> 8) ^ right) & 0x00ff00ff;
+ right ^= work;
+ leftt ^= (work << 8);
+ work = ((leftt >>> 2) ^ right) & 0x33333333;
+ right ^= work;
+ leftt ^= (work << 2);
+ work = ((right >>> 16) ^ leftt) & 0x0000ffff;
+ leftt ^= work;
+ right ^= (work << 16);
+ work = ((right >>> 4) ^ leftt) & 0x0f0f0f0f;
+ leftt ^= work;
+ right ^= (work << 4);
+ outInts[0] = right;
+ outInts[1] = leftt;
+ }
+
+
+ /// Encrypt a block of bytes.
+ public void encrypt( byte[] clearText, byte[] cipherText ) {
+ encrypt( clearText, 0, cipherText, 0 );
+ }
+
+ /// Decrypt a block of bytes.
+ public void decrypt( byte[] cipherText, byte[] clearText ) {
+
+ decrypt( cipherText, 0, clearText, 0 );
+ }
+
+ /**
+ * encrypts an array where the length must be a multiple of 8
+ */
+ public byte[] encrypt(byte[] clearText) {
+
+ int length = clearText.length;
+
+ if (length % 8 != 0) {
+ System.out.println("Array must be a multiple of 8");
+ return null;
+ }
+
+ byte[] cipherText = new byte[length];
+ int count = length / 8;
+
+ for (int i=0; i<count; i++)
+ encrypt(clearText, i*8, cipherText, i*8);
+
+ return cipherText;
+ }
+
+ /**
+ * decrypts an array where the length must be a multiple of 8
+ */
+ public byte[] decrypt(byte[] cipherText) {
+
+ int length = cipherText.length;
+
+ if (length % 8 != 0) {
+ System.out.println("Array must be a multiple of 8");
+ return null;
+ }
+
+ byte[] clearText = new byte[length];
+ int count = length / 8;
+
+ for (int i=0; i<count; i++)
+ encrypt(cipherText, i*8, clearText, i*8);
+
+ return clearText;
+ }
+
+
+ // Tables, permutations, S-boxes, etc.
+
+ private static byte[] bytebit = {
+ (byte)0x80, (byte)0x40, (byte)0x20, (byte)0x10,
+ (byte)0x08, (byte)0x04, (byte)0x02, (byte)0x01
+ };
+ private static int[] bigbyte = {
+ 0x800000, 0x400000, 0x200000, 0x100000,
+ 0x080000, 0x040000, 0x020000, 0x010000,
+ 0x008000, 0x004000, 0x002000, 0x001000,
+ 0x000800, 0x000400, 0x000200, 0x000100,
+ 0x000080, 0x000040, 0x000020, 0x000010,
+ 0x000008, 0x000004, 0x000002, 0x000001
+ };
+ private static byte[] pc1 = {
+ (byte)56, (byte)48, (byte)40, (byte)32, (byte)24, (byte)16, (byte) 8,
+ (byte) 0, (byte)57, (byte)49, (byte)41, (byte)33, (byte)25, (byte)17,
+ (byte) 9, (byte) 1, (byte)58, (byte)50, (byte)42, (byte)34, (byte)26,
+ (byte)18, (byte)10, (byte) 2, (byte)59, (byte)51, (byte)43, (byte)35,
+ (byte)62, (byte)54, (byte)46, (byte)38, (byte)30, (byte)22, (byte)14,
+ (byte) 6, (byte)61, (byte)53, (byte)45, (byte)37, (byte)29, (byte)21,
+ (byte)13, (byte) 5, (byte)60, (byte)52, (byte)44, (byte)36, (byte)28,
+ (byte)20, (byte)12, (byte) 4, (byte)27, (byte)19, (byte)11, (byte)3
+ };
+ private static int[] totrot = {
+ 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28
+ };
+
+ private static byte[] pc2 = {
+ (byte)13, (byte)16, (byte)10, (byte)23, (byte) 0, (byte) 4,
+ (byte) 2, (byte)27, (byte)14, (byte) 5, (byte)20, (byte) 9,
+ (byte)22, (byte)18, (byte)11, (byte)3 , (byte)25, (byte) 7,
+ (byte)15, (byte) 6, (byte)26, (byte)19, (byte)12, (byte) 1,
+ (byte)40, (byte)51, (byte)30, (byte)36, (byte)46, (byte)54,
+ (byte)29, (byte)39, (byte)50, (byte)44, (byte)32, (byte)47,
+ (byte)43, (byte)48, (byte)38, (byte)55, (byte)33, (byte)52,
+ (byte)45, (byte)41, (byte)49, (byte)35, (byte)28, (byte)31,
+ };
+
+ private static int[] SP1 = {
+ 0x01010400, 0x00000000, 0x00010000, 0x01010404,
+ 0x01010004, 0x00010404, 0x00000004, 0x00010000,
+ 0x00000400, 0x01010400, 0x01010404, 0x00000400,
+ 0x01000404, 0x01010004, 0x01000000, 0x00000004,
+ 0x00000404, 0x01000400, 0x01000400, 0x00010400,
+ 0x00010400, 0x01010000, 0x01010000, 0x01000404,
+ 0x00010004, 0x01000004, 0x01000004, 0x00010004,
+ 0x00000000, 0x00000404, 0x00010404, 0x01000000,
+ 0x00010000, 0x01010404, 0x00000004, 0x01010000,
+ 0x01010400, 0x01000000, 0x01000000, 0x00000400,
+ 0x01010004, 0x00010000, 0x00010400, 0x01000004,
+ 0x00000400, 0x00000004, 0x01000404, 0x00010404,
+ 0x01010404, 0x00010004, 0x01010000, 0x01000404,
+ 0x01000004, 0x00000404, 0x00010404, 0x01010400,
+ 0x00000404, 0x01000400, 0x01000400, 0x00000000,
+ 0x00010004, 0x00010400, 0x00000000, 0x01010004
+ };
+ private static int[] SP2 = {
+ 0x80108020, 0x80008000, 0x00008000, 0x00108020,
+ 0x00100000, 0x00000020, 0x80100020, 0x80008020,
+ 0x80000020, 0x80108020, 0x80108000, 0x80000000,
+ 0x80008000, 0x00100000, 0x00000020, 0x80100020,
+ 0x00108000, 0x00100020, 0x80008020, 0x00000000,
+ 0x80000000, 0x00008000, 0x00108020, 0x80100000,
+ 0x00100020, 0x80000020, 0x00000000, 0x00108000,
+ 0x00008020, 0x80108000, 0x80100000, 0x00008020,
+ 0x00000000, 0x00108020, 0x80100020, 0x00100000,
+ 0x80008020, 0x80100000, 0x80108000, 0x00008000,
+ 0x80100000, 0x80008000, 0x00000020, 0x80108020,
+ 0x00108020, 0x00000020, 0x00008000, 0x80000000,
+ 0x00008020, 0x80108000, 0x00100000, 0x80000020,
+ 0x00100020, 0x80008020, 0x80000020, 0x00100020,
+ 0x00108000, 0x00000000, 0x80008000, 0x00008020,
+ 0x80000000, 0x80100020, 0x80108020, 0x00108000
+ };
+ private static int[] SP3 = {
+ 0x00000208, 0x08020200, 0x00000000, 0x08020008,
+ 0x08000200, 0x00000000, 0x00020208, 0x08000200,
+ 0x00020008, 0x08000008, 0x08000008, 0x00020000,
+ 0x08020208, 0x00020008, 0x08020000, 0x00000208,
+ 0x08000000, 0x00000008, 0x08020200, 0x00000200,
+ 0x00020200, 0x08020000, 0x08020008, 0x00020208,
+ 0x08000208, 0x00020200, 0x00020000, 0x08000208,
+ 0x00000008, 0x08020208, 0x00000200, 0x08000000,
+ 0x08020200, 0x08000000, 0x00020008, 0x00000208,
+ 0x00020000, 0x08020200, 0x08000200, 0x00000000,
+ 0x00000200, 0x00020008, 0x08020208, 0x08000200,
+ 0x08000008, 0x00000200, 0x00000000, 0x08020008,
+ 0x08000208, 0x00020000, 0x08000000, 0x08020208,
+ 0x00000008, 0x00020208, 0x00020200, 0x08000008,
+ 0x08020000, 0x08000208, 0x00000208, 0x08020000,
+ 0x00020208, 0x00000008, 0x08020008, 0x00020200
+ };
+ private static int[] SP4 = {
+ 0x00802001, 0x00002081, 0x00002081, 0x00000080,
+ 0x00802080, 0x00800081, 0x00800001, 0x00002001,
+ 0x00000000, 0x00802000, 0x00802000, 0x00802081,
+ 0x00000081, 0x00000000, 0x00800080, 0x00800001,
+ 0x00000001, 0x00002000, 0x00800000, 0x00802001,
+ 0x00000080, 0x00800000, 0x00002001, 0x00002080,
+ 0x00800081, 0x00000001, 0x00002080, 0x00800080,
+ 0x00002000, 0x00802080, 0x00802081, 0x00000081,
+ 0x00800080, 0x00800001, 0x00802000, 0x00802081,
+ 0x00000081, 0x00000000, 0x00000000, 0x00802000,
+ 0x00002080, 0x00800080, 0x00800081, 0x00000001,
+ 0x00802001, 0x00002081, 0x00002081, 0x00000080,
+ 0x00802081, 0x00000081, 0x00000001, 0x00002000,
+ 0x00800001, 0x00002001, 0x00802080, 0x00800081,
+ 0x00002001, 0x00002080, 0x00800000, 0x00802001,
+ 0x00000080, 0x00800000, 0x00002000, 0x00802080
+ };
+ private static int[] SP5 = {
+ 0x00000100, 0x02080100, 0x02080000, 0x42000100,
+ 0x00080000, 0x00000100, 0x40000000, 0x02080000,
+ 0x40080100, 0x00080000, 0x02000100, 0x40080100,
+ 0x42000100, 0x42080000, 0x00080100, 0x40000000,
+ 0x02000000, 0x40080000, 0x40080000, 0x00000000,
+ 0x40000100, 0x42080100, 0x42080100, 0x02000100,
+ 0x42080000, 0x40000100, 0x00000000, 0x42000000,
+ 0x02080100, 0x02000000, 0x42000000, 0x00080100,
+ 0x00080000, 0x42000100, 0x00000100, 0x02000000,
+ 0x40000000, 0x02080000, 0x42000100, 0x40080100,
+ 0x02000100, 0x40000000, 0x42080000, 0x02080100,
+ 0x40080100, 0x00000100, 0x02000000, 0x42080000,
+ 0x42080100, 0x00080100, 0x42000000, 0x42080100,
+ 0x02080000, 0x00000000, 0x40080000, 0x42000000,
+ 0x00080100, 0x02000100, 0x40000100, 0x00080000,
+ 0x00000000, 0x40080000, 0x02080100, 0x40000100
+ };
+ private static int[] SP6 = {
+ 0x20000010, 0x20400000, 0x00004000, 0x20404010,
+ 0x20400000, 0x00000010, 0x20404010, 0x00400000,
+ 0x20004000, 0x00404010, 0x00400000, 0x20000010,
+ 0x00400010, 0x20004000, 0x20000000, 0x00004010,
+ 0x00000000, 0x00400010, 0x20004010, 0x00004000,
+ 0x00404000, 0x20004010, 0x00000010, 0x20400010,
+ 0x20400010, 0x00000000, 0x00404010, 0x20404000,
+ 0x00004010, 0x00404000, 0x20404000, 0x20000000,
+ 0x20004000, 0x00000010, 0x20400010, 0x00404000,
+ 0x20404010, 0x00400000, 0x00004010, 0x20000010,
+ 0x00400000, 0x20004000, 0x20000000, 0x00004010,
+ 0x20000010, 0x20404010, 0x00404000, 0x20400000,
+ 0x00404010, 0x20404000, 0x00000000, 0x20400010,
+ 0x00000010, 0x00004000, 0x20400000, 0x00404010,
+ 0x00004000, 0x00400010, 0x20004010, 0x00000000,
+ 0x20404000, 0x20000000, 0x00400010, 0x20004010
+ };
+ private static int[] SP7 = {
+ 0x00200000, 0x04200002, 0x04000802, 0x00000000,
+ 0x00000800, 0x04000802, 0x00200802, 0x04200800,
+ 0x04200802, 0x00200000, 0x00000000, 0x04000002,
+ 0x00000002, 0x04000000, 0x04200002, 0x00000802,
+ 0x04000800, 0x00200802, 0x00200002, 0x04000800,
+ 0x04000002, 0x04200000, 0x04200800, 0x00200002,
+ 0x04200000, 0x00000800, 0x00000802, 0x04200802,
+ 0x00200800, 0x00000002, 0x04000000, 0x00200800,
+ 0x04000000, 0x00200800, 0x00200000, 0x04000802,
+ 0x04000802, 0x04200002, 0x04200002, 0x00000002,
+ 0x00200002, 0x04000000, 0x04000800, 0x00200000,
+ 0x04200800, 0x00000802, 0x00200802, 0x04200800,
+ 0x00000802, 0x04000002, 0x04200802, 0x04200000,
+ 0x00200800, 0x00000000, 0x00000002, 0x04200802,
+ 0x00000000, 0x00200802, 0x04200000, 0x00000800,
+ 0x04000002, 0x04000800, 0x00000800, 0x00200002
+ };
+ private static int[] SP8 = {
+ 0x10001040, 0x00001000, 0x00040000, 0x10041040,
+ 0x10000000, 0x10001040, 0x00000040, 0x10000000,
+ 0x00040040, 0x10040000, 0x10041040, 0x00041000,
+ 0x10041000, 0x00041040, 0x00001000, 0x00000040,
+ 0x10040000, 0x10000040, 0x10001000, 0x00001040,
+ 0x00041000, 0x00040040, 0x10040040, 0x10041000,
+ 0x00001040, 0x00000000, 0x00000000, 0x10040040,
+ 0x10000040, 0x10001000, 0x00041040, 0x00040000,
+ 0x00041040, 0x00040000, 0x10041000, 0x00001000,
+ 0x00000040, 0x10040040, 0x00001000, 0x00041040,
+ 0x10001000, 0x00000040, 0x10000040, 0x10040000,
+ 0x10040040, 0x10000000, 0x00040000, 0x10001040,
+ 0x00000000, 0x10041040, 0x00040040, 0x10000040,
+ 0x10040000, 0x10001000, 0x10001040, 0x00000000,
+ 0x10041040, 0x00041000, 0x00041000, 0x00001040,
+ 0x00001040, 0x00040040, 0x10000000, 0x10041000
+ };
+
+
+ /// Squash bytes down to ints.
+ public static void squashBytesToInts( byte[] inBytes, int inOff, int[] outInts,
+ int outOff, int intLen ) {
+
+ for ( int i = 0; i < intLen; ++i )
+ outInts[outOff + i] =
+ ( ( inBytes[inOff + i * 4 ] & 0xff ) << 24 ) |
+ ( ( inBytes[inOff + i * 4 + 1] & 0xff ) << 16 ) |
+ ( ( inBytes[inOff + i * 4 + 2] & 0xff ) << 8 ) |
+ ( inBytes[inOff + i * 4 + 3] & 0xff );
+ }
+
+ /// Spread ints into bytes.
+ public static void spreadIntsToBytes( int[] inInts, int inOff, byte[] outBytes,
+ int outOff, int intLen ) {
+
+ for ( int i = 0; i < intLen; ++i ) {
+
+ outBytes[outOff + i * 4 ] = (byte) ( inInts[inOff + i] >>> 24 );
+ outBytes[outOff + i * 4 + 1] = (byte) ( inInts[inOff + i] >>> 16 );
+ outBytes[outOff + i * 4 + 2] = (byte) ( inInts[inOff + i] >>> 8 );
+ outBytes[outOff + i * 4 + 3] = (byte) inInts[inOff + i];
+ }
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ * "Christopher R. Hertel" <crh@nts.umn.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.util;
+
+import java.io.Writer;
+import java.io.OutputStream;
+import java.util.Properties;
+
+/**
+ * This log utility uses a combination of bit mask control and io stream
+ * functionality. All methods check the mask with the mask passed as a
+ * parameter to see if any further worki (logging) should be performed. This
+ * provides explicit control at runtime over what is logged. The IO stream
+ * model allows the {@link java.io.PrintWriter} to be set and provides
+ * many of the common {@link java.io.PrintWriter} methods that are usefull
+ * for streams.
+ *
+ * <p>Three example log entries follow:
+ *
+ * <blockquote><pre>
+ * Jul 7 19:17:40.999 - smb tree connect warning
+ * path=\\140.240.194.37\IPC$
+ * Jul 7 19:17:41.069 - datagram packet sent to: cranes.campus.foo.br/140.240.194.37
+ * 00000: 00 06 01 10 00 01 00 00 00 00 00 00 20 43 4B 41 |............ CKA|
+ * 00010: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 |AAAAAAAAAAAAAAAA|
+ * 00020: 41 41 41 41 41 41 41 41 41 41 41 41 41 00 00 21 |AAAAAAAAAAAAA..!|
+ * 00030: 00 01 |.. |
+ * Jul 7 19:17:47.087 - SmbFile exception
+ * java.net.UnknownHostException: no name with type 0x20 with no scope for host 140.240.194.37
+ * at jcifs.netbios.NbtAddress.getAllByAddress(NbtAddress.java:618)
+ * at jcifs.smb.SmbFile.list(SmbFile.java:700)
+ * at List.main(List.java:30)
+ * </pre></blockquote>
+ *
+ * To use this logging facility simply add any
+ * <code>Log.println</code>, <code>Log.printHexDump</code>,
+ * <code>Log.printStackTrace</code>, or derived methods throughout
+ * your code and set a suitable mask with <code>Log.setMask</code>. For
+ * example the following mask might be set at the very beginning of your
+ * program:
+ *
+ * <p><blockquote><pre>
+ * Log.setMask(( Log.EXCEPTIONS | foo.Log.ALL ) & ~foo.Log.LOGINS );
+ * </pre></blockquote>
+ *
+ * This would write the stack traces from <code>Log.printStackTrace</code>
+ * calls and all logging for package <code>foo</code> with the exception
+ * of logging associated with the <code>LOGINS</code> mask. The following
+ * is an example of using the <code>Log.println</code> method:
+ *
+ * <p><blockquote><pre>
+ * Log.println( Log.WARNINGS, "smb tree connect warning", " path=" + path );
+ * </pre></blockquote>
+ *
+ * <p>Masks can be combined and subtracted with one another using
+ * bitwise operators. To combine two masks use the bitwise OR operator
+ * <code>|</code>. The bitwise AND operator <code>&</code> together with
+ * bitwise NOT <code>~</code> can be used to turn off masks.
+ *
+ * <p>If bit manipulation is not familiar, use the <code>addMask</code>
+ * and <code>subtractMask</code> methods. The equivalent of the first code
+ * sample would be:
+ *
+ * <p><blockquote><pre>
+ * Log.addMask( Log.EXCEPTIONS );
+ * Log.addMask( foo.Log.ALL );
+ * Log.subtractMask( foo.Log.LOGINS );
+ * </pre></blockquote>
+ *
+ * <p>Note: When defining a new mask, one must take care not to use bits
+ * that are already being used by another package. In the future, masks
+ * may be statically assigned during class initialization.
+ *
+ * @see jcifs.util.LogWriter
+ * @see jcifs.netbios.Log
+ * @see jcifs.smb.Log
+ * @since jcifs-0.1
+ */
+
+public class Log {
+
+ // supress javadoc constructor summary by removing 'protected'
+ protected Log() {}
+
+ private static final char[] hexChars = {
+ '0', '1', '2', '3', '4', '5',
+ '6', '7', '8', '9', 'A', 'B',
+ 'C', 'D', 'E', 'F'
+ };
+ private static final char[] spaceChars = {
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
+ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '
+ };
+
+/**
+ * The systems line separator.
+ */
+
+ public static final String NL = System.getProperty( "line.separator" );
+
+/**
+ * The systems line separator length.
+ */
+
+ public static final int NL_LENGTH = NL.length();
+
+/**
+ * Mask to indicate that no messages should be logged(not even exceptions).
+ */
+
+ public static final int NONE = 0x00000000;
+
+/**
+ * Log all messages.
+ */
+
+ public static final int ALL = 0xFFFFFFFF;
+
+/**
+ * This is the default mask. However, be aware that specifying a
+ * mask without adding this mask will result in exceptions not being
+ * logged. One should always add this EXCEPTIONS mask to the {@link
+ * jcifs.util.Log#setMask(int mask)} expression unless you are explicitly
+ * trying to suppress them. Of course only exceptions that go through
+ * the {@link jcifs.util.Log#printStackTrace(String desc, Throwable t )}
+ * facility can be filtered out.
+ */
+
+ public static final int EXCEPTIONS = 0x10000001;
+
+/**
+ * Log only critical exceptions. All exceptions logged with
+ * <code>printStackTrace</code> are considered critical. Exceptions are not
+ * critical if they are logged with the <code>NON_CRITICAL_EXCEPTIONS</code>
+ * mask.
+ */
+
+ public static final int CRITICAL_EXCEPTIONS = 0x00000001;
+
+/**
+ * Log non-critical exceptions. The <code>EXCEPTIONS</code> mask consists of both critical and non-critical exceptions.
+ */
+
+ public static final int NON_CRITICAL_EXCEPTIONS = 0x10000000;
+
+/**
+ * Log warning messages.
+ */
+
+ public static final int WARNINGS = 0x00000002;
+
+/**
+ * Use this mask while actively debugging your code. It is
+ * an alternative for the popular <code>System.out.println( "MADE
+ * IT!" )</code> statement but can be supressed.
+ */
+
+ public static final int DEBUGGING = 0x00000004;
+
+/**
+ * This controls wheather or not {@link jcifs.util.Log#printHexDump}
+ * messages are logged.
+ */
+
+ public static final int HEX_DUMPS = 0x00000008;
+
+/**
+ * The shared output stream of all <code>Log</code> classes. The
+ * defualt is <code>System.out</code>.
+ */
+
+ protected static LogWriter out = new LogWriter( System.out );
+
+/**
+ * This is the integer mask that controls what is logged. It is shared
+ * by all Log classes. The default mask is <code>EXCEPTIONS</code>
+ * which consists of <code>CRITICAL_EXCEPTIONS</code> and
+ * <code>NON_CRITICAL_EXCEPTIONS</code>.
+ */
+
+ protected static int mask = EXCEPTIONS;
+
+ // Setting Methods
+
+/**
+ * Specify an {@link java.io.OutputStream} to be used as the underlying
+ * stream.
+ *
+ * @param out the output stream
+ */
+
+ public static void setPrintWriter( OutputStream out ) {
+ Log.out = new LogWriter( out );
+ }
+
+/**
+ * This controls what is passed to {@link java.text.SimpleDateFormat} to
+ * control what the timestamp looks like in the log stream. For example, a
+ * format of <code>"EEE, MMM d, h:mm:ss a"</code> would generate timestamps
+ * that read <code>Tue, Mar 14, 4:57:02 PM</code>. This is a whistle.
+ *
+ * @param the format string
+ * @see java.util.SimpleDateFormat
+ */
+
+ public static void setDateFormat( String format ) {
+ out.setDateFormat( format );
+ }
+
+/**
+ * Set the mask used to screen all calls to logging methods. The idea
+ * here is that the mask can be specified as an arithmetic expression
+ * to perovide a crude but effective syslog style way to dictate what it
+ * logged. For example:
+ * <p><blockquote><pre>
+ * setMask( Log.EXCEPTIONS +
+ * Log.HEX_DUMPS +
+ * jcifs.netbios.Log.PACKET_DATA );
+ *
+ * setMask( Log.ALL - jcifs.netbios.Log.PACKET_DIAGRAMS );
+ * </pre></blockquote>
+ */
+
+ public static void setMask( int mask ) {
+ Log.mask = mask;
+ }
+ public static boolean isSet( int mask ) {
+ return ( Log.mask & mask ) == mask;
+ }
+ public static void addMask( int mask ) {
+ Log.mask |= mask;
+ }
+ public static void subtractMask( int mask ) {
+ Log.mask &= ~mask;
+ }
+
+/**
+ * Provides standard way to log any {@link java.lang.Throwable} object like
+ * an {@link java.lang.Exception}.
+ */
+
+ public static void printStackTrace( String desc, Throwable t ) {
+ if(( CRITICAL_EXCEPTIONS & mask ) != 0 )
+ out.printStackTrace( desc, t );
+ }
+ public static void printStackTrace( int type, String desc, Throwable t ) {
+ if(( type & mask ) != 0 )
+ out.printStackTrace( desc, t );
+ }
+
+ // Output Methods Used Only By This Package
+/**
+ * Hex dumps are ubiquitous enough to provide a standard and easy-to-use
+ * method for logging them. All that is required to use this is setting
+ * the mask for {@link jcifs.util.Log#HEX_DUMPS}. The hex dump output is
+ * represended in the standard form and is quite efficient. Many mega bytes
+ * of source data could be dumped to a file without worry.
+ *
+ * <p><blockquote><pre>
+ * 00000: 04 d2 29 00 00 01 00 00 00 00 00 01 20 45 47 46 |..)......... EGF|
+ * 00010: 43 45 46 45 45 43 41 43 41 43 41 43 41 43 41 43 |CEFEECACACACACAC|
+ * 00020: 41 43 41 43 41 43 41 43 41 43 41 41 44 00 00 20 |ACACACACACAAD.. |
+ * 00030: 00 01 c0 0c 00 20 00 01 00 00 00 00 00 06 20 00 |..... ........ .|
+ * 00040: ac 22 22 e1 |."". |
+ * </blockquote></pre>
+ */
+
+ public static void printHexDump( String desc, byte[] src ) {
+ printHexDump( desc, src, 0, src.length );
+ }
+ public static void printHexDump( String desc, byte[] src, int srcIndex, int length ) {
+ if(( HEX_DUMPS & mask ) == 0 || length == 0 ) {
+ return;
+ }
+ int s = length % 16;
+ int r = ( s == 0 ) ? length / 16 : length / 16 + 1;
+ char[] c = new char[r * (74 + NL_LENGTH)];
+ char[] d = new char[16];
+ int i;
+ int si = 0;
+ int ci = 0;
+ do {
+ toHexChars( si, c, ci, 5 );
+ ci += 5;
+ c[ci++] = ':';
+ do {
+ if( si == length ) {
+ int n = 16 - s;
+ System.arraycopy( spaceChars, 0, c, ci, n * 3 );
+ ci += n * 3;
+ System.arraycopy( spaceChars, 0, d, s, n );
+ break;
+ }
+ c[ci++] = ' ';
+ i = src[srcIndex + si] & 0xFF;
+ toHexChars( i, c, ci, 2 );
+ ci += 2;
+ if( i < 0 || Character.isISOControl( (char)i )) {
+ d[si % 16] = '.';
+ } else {
+ d[si % 16] = (char)i;
+ }
+ } while(( ++si % 16 ) != 0 );
+ c[ci++] = ' ';
+ c[ci++] = ' ';
+ c[ci++] = '|';
+ System.arraycopy( d, 0, c, ci, 16 );
+ ci += 16;
+ c[ci++] = '|';
+ NL.getChars( 0, NL_LENGTH, c, ci );
+ ci += NL_LENGTH;
+ } while( si < length );
+ out.println( desc, c );
+ }
+
+/**
+ * This is an alternative to the <code>java.lang.Integer.toHexString</cod>
+ * method. It is an efficient relative that also will pad the left side so
+ * that the result is <code>size</code> digits.
+ */
+
+ public static String getHexString( int val, int size ) {
+ char[] c = new char[size];
+ toHexChars( val, c, 0, size );
+ return new String( c );
+ }
+ public static String getHexString( long val, int size ) {
+ char[] c = new char[size];
+ toHexChars( val, c, 0, size );
+ return new String( c );
+ }
+
+ public static String getHexString( byte[] src, int srcIndex, int size ) {
+ char[] c = new char[size];
+ size = ( size % 2 == 0 ) ? size / 2 : size / 2 + 1;
+ for( int i = 0, j = 0; i < size; i++ ) {
+ c[j++] = hexChars[(src[i] >> 4 ) & 0x0F];
+ if( j == c.length ) {
+ break;
+ }
+ c[j++] = hexChars[src[i] & 0x0F];
+ }
+ return new String( c );
+ }
+
+/**
+ * This is the same as {@link jcifs.util.Log#getHexString(int val, int
+ * size)} but provides a more practical form when trying to avoid {@link
+ * java.lang.String} concatenation and {@link java.lang.StringBuffer}.
+ */
+
+ public static void toHexChars( int val, char dst[], int dstIndex, int size ) {
+ while( size > 0 ) {
+ dst[dstIndex + size - 1] = hexChars[val & 0x000F];
+ if( val != 0 ) {
+ val >>>= 4;
+ }
+ size--;
+ }
+ }
+ public static void toHexChars( long val, char dst[], int dstIndex, int size ) {
+ while( size > 0 ) {
+ dst[dstIndex + size - 1] = hexChars[(int)( val & 0x000FL )];
+ if( val != 0 ) {
+ val >>>= 4;
+ }
+ size--;
+ }
+ }
+
+/**
+ * Print an int. The bits of the integer <code>type</code> must match the
+ * {@link jcifs.util.Log#mask}.
+ */
+
+ public static void println( int type, String desc, int x ) {
+ if(( type & mask ) != 0 )
+ out.println( desc, x );
+ }
+
+/**
+ * Print a char[] array. The bits of the integer <code>type</code> must
+ * match the {@link jcifs.util.Log#mask}.
+ */
+
+ public static void println( int type, String desc, char x[] ) {
+ if(( type & mask ) != 0 )
+ out.println( desc, x );
+ }
+
+/**
+ * Print a {@link java.lang.String}. The bits of the integer
+ * <code>type</code> must match the {@link jcifs.util.Log#mask}.
+ */
+
+ public static void println( int type, String desc, String x ) {
+ if(( type & mask ) != 0 )
+ out.println( desc, x );
+ }
+
+/**
+ * Print an {@link java.lang.Object}. The bits of the integer
+ * <code>type</code> must match the {@link jcifs.util.Log#mask}.
+ */
+
+ public static void println( int type, String desc, Object x ) {
+ if(( type & mask ) != 0 )
+ out.println( desc, x );
+ }
+
+/**
+ * Print the contents of a {@link java.util.Properties} object to the
+ * log stream using the <code>store</code> method.
+ */
+
+ public static void printProperties( int type, String desc, Properties p ) {
+ if(( type & mask ) != 0 )
+ out.printProperties( desc, p );
+ }
+}
+
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+package jcifs.util;
+
+import java.io.*;
+import java.util.GregorianCalendar;
+import java.util.Date;
+import java.text.SimpleDateFormat;
+import java.util.Properties;
+
+/**
+ * This class is basically a {@link java.io.PrintWriter} that prepends
+ * a timestamp before each message is written to the underlying
+ * stream. The methods for printing are a pertainent subset from {@link
+ * java.io.PrintWriter}.
+ *
+ * @see jcifs.util.Log
+ */
+
+public class LogWriter {
+
+ private Writer out;
+ private OutputStream raw;
+ private PrintWriter eout;
+ private boolean trouble = false;
+ private String lineSeparator;
+
+/**
+ * The object used to synchronize operations on this stream
+ */
+
+ public Object lock;
+
+/**
+ * Create a new <code>LogWriter</code> instance that uses the specified
+ * output stream as it's underlying stream
+ */
+
+ public LogWriter( OutputStream out ) {
+ this.out = new OutputStreamWriter( out );
+ raw = out;
+ this.lock = this;
+ eout = new PrintWriter( out );
+ lineSeparator = System.getProperty( "line.separator" );
+ }
+
+ static String dateString;
+ static GregorianCalendar cal;
+ static SimpleDateFormat sdf;
+
+ static {
+ cal = new GregorianCalendar();
+ setDateFormat( "MMM d HH:mm:ss.SSS" );
+ }
+
+/**
+ * Set the date format used to render the timestamp written with each
+ * message.
+ *
+ * @param format the format string used
+ * @see java.text.SimpleDateFormat
+ */
+
+ public static void setDateFormat( String format ) {
+ sdf = new SimpleDateFormat( format );
+ sdf.setCalendar( cal );
+ }
+
+ private void ensureOpen() throws IOException {
+ if( out == null )
+ throw new IOException( "Stream closed" );
+ }
+
+/**
+ * Close the stream
+ */
+
+ public void close() {
+ try {
+ synchronized( lock ) {
+ if( out == null )
+ return;
+ out.close();
+ out = null;
+ }
+ } catch( IOException x ) {
+ trouble = true;
+ }
+ }
+
+/**
+ * Flush the stream and check error state
+ */
+
+ public boolean checkError() {
+ if( out != null ) {
+ try {
+ synchronized( lock ) {
+ ensureOpen();
+ out.flush();
+ }
+ } catch( IOException x ) {
+ trouble = true;
+ }
+ }
+ return trouble;
+ }
+
+/**
+ * Indicate that an error has occured
+ */
+
+ public void setError() {
+ trouble = true;
+ }
+
+/**
+ * This is a pervasive enough feature for a logging utility that it is
+ * built in.
+ *
+ * @param desc a brief description of the source of the message to follow
+ * @param t the <code>Exception</code> to obtain the message to be printed from
+ */
+
+ public void printStackTrace( String desc, Throwable t ) {
+ try {
+ synchronized( lock ) {
+ ensureOpen();
+ out.write( sdf.format( new Date() ));
+ out.write( " - " );
+ out.write( desc );
+ out.write( lineSeparator );
+ eout.flush();
+ out.flush();
+ t.printStackTrace( eout );
+ eout.flush();
+ out.flush();
+ }
+ } catch( InterruptedIOException x ) {
+ Thread.currentThread().interrupt();
+ } catch( IOException ioe ) {
+ trouble = true;
+ }
+ }
+
+
+
+/**
+ * Print an <code>int</code> to the log stream. Keep in mind that every
+ * call to a <code>PrintWriter</code> like method will print a new timestamp.
+ * Using several calls together will not concatonate several messages
+ * together under one timestamp.
+ *
+ * @param desc a brief description of the source of the message to follow
+ * @param i the <code>int</code> to print
+ */
+
+ public void println( String desc, int i ) {
+ try {
+ synchronized( lock ) {
+ ensureOpen();
+ out.write( sdf.format( new Date() ));
+ out.write( " - " );
+ out.write( desc );
+ out.write( lineSeparator );
+ out.write( Integer.toString( i ));
+ out.write( lineSeparator );
+ out.flush();
+ }
+ } catch( InterruptedIOException x ) {
+ Thread.currentThread().interrupt();
+ } catch( IOException ioe ) {
+ trouble = true;
+ }
+ }
+
+/**
+ * Print an array of <code>char</code> to the log.
+ *
+ * @param desc a brief description of the source of the message to follow
+ * @param c the message
+ */
+
+ public void println( String desc, char c[] ) {
+ try {
+ synchronized( lock ) {
+ ensureOpen();
+ out.write( sdf.format( new Date() ));
+ out.write( " - " );
+ out.write( desc );
+ out.write( lineSeparator );
+ out.write( c );
+ out.write( lineSeparator );
+ out.flush();
+ }
+ } catch( InterruptedIOException x ) {
+ Thread.currentThread().interrupt();
+ } catch( IOException ioe ) {
+ trouble = true;
+ }
+ }
+
+/**
+ * Print a <code>String</code> to the log.
+ *
+ * @param desc a brief description of the source of the message to follow
+ * @param s the string message
+ */
+
+ public void println( String desc, String s ) {
+ try {
+ synchronized( lock ) {
+ ensureOpen();
+ out.write( sdf.format( new Date() ));
+ out.write( " - " );
+ out.write( desc );
+ out.write( lineSeparator );
+ out.write( s );
+ out.write( lineSeparator );
+ out.flush();
+ }
+ } catch( InterruptedIOException x ) {
+ Thread.currentThread().interrupt();
+ } catch( IOException ioe ) {
+ trouble = true;
+ }
+ }
+
+/**
+ * Print the string representation of an <code>Object</code> to the screen.
+ *
+ * @param desc a general description of the source of the message
+ * @param o the <code>Object</code> to print
+ */
+
+ public void println( String desc, Object o ) {
+ try {
+ synchronized( lock ) {
+ ensureOpen();
+ out.write( sdf.format( new Date() ));
+ out.write( " - " );
+ out.write( desc );
+ out.write( lineSeparator );
+ out.write( String.valueOf( o ));
+ out.write( lineSeparator );
+ out.flush();
+ }
+ } catch( InterruptedIOException x ) {
+ Thread.currentThread().interrupt();
+ } catch( IOException ioe ) {
+ trouble = true;
+ }
+ }
+/**
+ * Print the contents of a {@link java.util.Properties} object to the
+ * log stream using the <code>store</code> method.
+ */
+
+ public void printProperties( String desc, Properties p ) {
+ try {
+ synchronized( lock ) {
+ ensureOpen();
+ p.save( raw, desc );
+ out.write( lineSeparator );
+ out.flush();
+ }
+ } catch( InterruptedIOException x ) {
+ Thread.currentThread().interrupt();
+ } catch( IOException ioe ) {
+ trouble = true;
+ }
+ }
+}
+
--- /dev/null
+// This file is currently unlocked (change this line if you lock the file)
+//
+// $Log: MD4.java,v $
+// Revision 1.2 1998/01/05 03:41:19 iang
+// Added references only.
+//
+// Revision 1.1.1.1 1997/11/03 22:36:56 hopwood
+// + Imported to CVS (tagged as 'start').
+//
+// Revision 0.1.0.0 1997/07/14 R. Naffah
+// + original version
+//
+// $Endlog$
+/*
+ * Copyright (c) 1997 Systemics Ltd
+ * on behalf of the Cryptix Development Team. All rights reserved.
+ */
+
+package jcifs.util;
+
+import java.security.MessageDigest;
+
+/**
+ * Implements the MD4 message digest algorithm in Java.
+ * <p>
+ * <b>References:</b>
+ * <ol>
+ * <li> Ronald L. Rivest,
+ * "<a href="http://www.roxen.com/rfc/rfc1320.html">
+ * The MD4 Message-Digest Algorithm</a>",
+ * IETF RFC-1320 (informational).
+ * </ol>
+ *
+ * <p><b>$Revision: 1.2 $</b>
+ * @author Raif S. Naffah
+ */
+public class MD4 extends MessageDigest implements Cloneable
+{
+// MD4 specific object variables
+//...........................................................................
+
+ /**
+ * The size in bytes of the input block to the tranformation algorithm.
+ */
+ private static final int BLOCK_LENGTH = 64; // = 512 / 8;
+
+ /**
+ * 4 32-bit words (interim result)
+ */
+ private int[] context = new int[4];
+
+ /**
+ * Number of bytes processed so far mod. 2 power of 64.
+ */
+ private long count;
+
+ /**
+ * 512 bits input buffer = 16 x 32-bit words holds until reaches 512 bits.
+ */
+ private byte[] buffer = new byte[BLOCK_LENGTH];
+
+ /**
+ * 512 bits work buffer = 16 x 32-bit words
+ */
+ private int[] X = new int[16];
+
+
+// Constructors
+//...........................................................................
+
+ public MD4 () {
+ super("MD4");
+ engineReset();
+ }
+
+ /**
+ * This constructor is here to implement cloneability of this class.
+ */
+ private MD4 (MD4 md) {
+ this();
+ context = (int[])md.context.clone();
+ buffer = (byte[])md.buffer.clone();
+ count = md.count;
+ }
+
+
+// Cloneable method implementation
+//...........................................................................
+
+ /**
+ * Returns a copy of this MD object.
+ */
+ public Object clone() { return new MD4(this); }
+
+
+// JCE methods
+//...........................................................................
+
+ /**
+ * Resets this object disregarding any temporary data present at the
+ * time of the invocation of this call.
+ */
+ public void engineReset () {
+ // initial values of MD4 i.e. A, B, C, D
+ // as per rfc-1320; they are low-order byte first
+ context[0] = 0x67452301;
+ context[1] = 0xEFCDAB89;
+ context[2] = 0x98BADCFE;
+ context[3] = 0x10325476;
+ count = 0L;
+ for (int i = 0; i < BLOCK_LENGTH; i++)
+ buffer[i] = 0;
+ }
+
+ /**
+ * Continues an MD4 message digest using the input byte.
+ */
+ public void engineUpdate (byte b) {
+ // compute number of bytes still unhashed; ie. present in buffer
+ int i = (int)(count % BLOCK_LENGTH);
+ count++; // update number of bytes
+ buffer[i] = b;
+ if (i == BLOCK_LENGTH - 1)
+ transform(buffer, 0);
+ }
+
+ /**
+ * MD4 block update operation.
+ * <p>
+ * Continues an MD4 message digest operation, by filling the buffer,
+ * transform(ing) data in 512-bit message block(s), updating the variables
+ * context and count, and leaving (buffering) the remaining bytes in buffer
+ * for the next update or finish.
+ *
+ * @param input input block
+ * @param offset start of meaningful bytes in input
+ * @param len count of bytes in input block to consider
+ */
+ public void engineUpdate (byte[] input, int offset, int len) {
+ // make sure we don't exceed input's allocated size/length
+ if (offset < 0 || len < 0 || (long)offset + len > input.length)
+ throw new ArrayIndexOutOfBoundsException();
+
+ // compute number of bytes still unhashed; ie. present in buffer
+ int bufferNdx = (int)(count % BLOCK_LENGTH);
+ count += len; // update number of bytes
+ int partLen = BLOCK_LENGTH - bufferNdx;
+ int i = 0;
+ if (len >= partLen) {
+ System.arraycopy(input, offset, buffer, bufferNdx, partLen);
+
+
+ transform(buffer, 0);
+
+ for (i = partLen; i + BLOCK_LENGTH - 1 < len; i+= BLOCK_LENGTH)
+ transform(input, offset + i);
+ bufferNdx = 0;
+ }
+ // buffer remaining input
+ if (i < len)
+ System.arraycopy(input, offset + i, buffer, bufferNdx, len - i);
+ }
+
+ /**
+ * Completes the hash computation by performing final operations such
+ * as padding. At the return of this engineDigest, the MD engine is
+ * reset.
+ *
+ * @return the array of bytes for the resulting hash value.
+ */
+ public byte[] engineDigest () {
+ // pad output to 56 mod 64; as RFC1320 puts it: congruent to 448 mod 512
+ int bufferNdx = (int)(count % BLOCK_LENGTH);
+ int padLen = (bufferNdx < 56) ? (56 - bufferNdx) : (120 - bufferNdx);
+
+ // padding is alwas binary 1 followed by binary 0s
+ byte[] tail = new byte[padLen + 8];
+ tail[0] = (byte)0x80;
+
+ // append length before final transform:
+ // save number of bits, casting the long to an array of 8 bytes
+ // save low-order byte first.
+ for (int i = 0; i < 8; i++)
+ tail[padLen + i] = (byte)((count * 8) >>> (8 * i));
+
+ engineUpdate(tail, 0, tail.length);
+
+ byte[] result = new byte[16];
+ // cast this MD4's context (array of 4 ints) into an array of 16 bytes.
+ for (int i = 0; i < 4; i++)
+ for (int j = 0; j < 4; j++)
+ result[i * 4 + j] = (byte)(context[i] >>> (8 * j));
+
+ // reset the engine
+ engineReset();
+ return result;
+ }
+
+
+// own methods
+//...........................................................................
+
+ /**
+ * MD4 basic transformation.
+ * <p>
+ * Transforms context based on 512 bits from input block starting
+ * from the offset'th byte.
+ *
+ * @param block input sub-array.
+ * @param offset starting position of sub-array.
+ */
+ private void transform (byte[] block, int offset) {
+
+ // encodes 64 bytes from input block into an array of 16 32-bit
+ // entities. Use A as a temp var.
+ for (int i = 0; i < 16; i++)
+ X[i] = (block[offset++] & 0xFF) |
+ (block[offset++] & 0xFF) << 8 |
+ (block[offset++] & 0xFF) << 16 |
+ (block[offset++] & 0xFF) << 24;
+
+
+ int A = context[0];
+ int B = context[1];
+ int C = context[2];
+ int D = context[3];
+
+ A = FF(A, B, C, D, X[ 0], 3);
+ D = FF(D, A, B, C, X[ 1], 7);
+ C = FF(C, D, A, B, X[ 2], 11);
+ B = FF(B, C, D, A, X[ 3], 19);
+ A = FF(A, B, C, D, X[ 4], 3);
+ D = FF(D, A, B, C, X[ 5], 7);
+ C = FF(C, D, A, B, X[ 6], 11);
+ B = FF(B, C, D, A, X[ 7], 19);
+ A = FF(A, B, C, D, X[ 8], 3);
+ D = FF(D, A, B, C, X[ 9], 7);
+ C = FF(C, D, A, B, X[10], 11);
+ B = FF(B, C, D, A, X[11], 19);
+ A = FF(A, B, C, D, X[12], 3);
+ D = FF(D, A, B, C, X[13], 7);
+ C = FF(C, D, A, B, X[14], 11);
+ B = FF(B, C, D, A, X[15], 19);
+
+ A = GG(A, B, C, D, X[ 0], 3);
+ D = GG(D, A, B, C, X[ 4], 5);
+ C = GG(C, D, A, B, X[ 8], 9);
+ B = GG(B, C, D, A, X[12], 13);
+ A = GG(A, B, C, D, X[ 1], 3);
+ D = GG(D, A, B, C, X[ 5], 5);
+ C = GG(C, D, A, B, X[ 9], 9);
+ B = GG(B, C, D, A, X[13], 13);
+ A = GG(A, B, C, D, X[ 2], 3);
+ D = GG(D, A, B, C, X[ 6], 5);
+ C = GG(C, D, A, B, X[10], 9);
+ B = GG(B, C, D, A, X[14], 13);
+ A = GG(A, B, C, D, X[ 3], 3);
+ D = GG(D, A, B, C, X[ 7], 5);
+ C = GG(C, D, A, B, X[11], 9);
+ B = GG(B, C, D, A, X[15], 13);
+
+ A = HH(A, B, C, D, X[ 0], 3);
+ D = HH(D, A, B, C, X[ 8], 9);
+ C = HH(C, D, A, B, X[ 4], 11);
+ B = HH(B, C, D, A, X[12], 15);
+ A = HH(A, B, C, D, X[ 2], 3);
+ D = HH(D, A, B, C, X[10], 9);
+ C = HH(C, D, A, B, X[ 6], 11);
+ B = HH(B, C, D, A, X[14], 15);
+ A = HH(A, B, C, D, X[ 1], 3);
+ D = HH(D, A, B, C, X[ 9], 9);
+ C = HH(C, D, A, B, X[ 5], 11);
+ B = HH(B, C, D, A, X[13], 15);
+ A = HH(A, B, C, D, X[ 3], 3);
+ D = HH(D, A, B, C, X[11], 9);
+ C = HH(C, D, A, B, X[ 7], 11);
+ B = HH(B, C, D, A, X[15], 15);
+
+ context[0] += A;
+ context[1] += B;
+ context[2] += C;
+ context[3] += D;
+ }
+
+ // The basic MD4 atomic functions.
+
+ private int FF (int a, int b, int c, int d, int x, int s) {
+ int t = a + ((b & c) | (~b & d)) + x;
+ return t << s | t >>> (32 - s);
+ }
+ private int GG (int a, int b, int c, int d, int x, int s) {
+ int t = a + ((b & (c | d)) | (c & d)) + x + 0x5A827999;
+ return t << s | t >>> (32 - s);
+ }
+ private int HH (int a, int b, int c, int d, int x, int s) {
+ int t = a + (b ^ c ^ d) + x + 0x6ED9EBA1;
+ return t << s | t >>> (32 - s);
+ }
+}
--- /dev/null
+/* jcifs smb client library in Java
+ * Copyright (C) 2000 "Michael B. Allen" <mballen@erols.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+package jcifs.util;
+
+import java.util.Properties;
+import java.util.Hashtable;
+import java.util.Vector;
+import java.util.Enumeration;
+import java.io.OutputStream;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.IOException;
+import java.util.Date;
+
+/**
+ *
+ *
+ * This class is backwords compatible with {@link java.util.Properties}
+ * however another dimension is added by using the customary dot '.' as
+ * an operator to alternativly represent properties as trees. In essance
+ * it gives meaning to the '.' used in keys of properties whereas with
+ * traditional properties usage of the dot '.' was mearly a convention. This
+ * allows applications to organize there data in new ways. The following
+ * is an example of the "tagged" output from a PropertiesTree along with
+ * traditional output from the same PropertiesTree to
+ * it's right. PropertiesTree can load and store
+ * both formats at runtime(e.g. load traditional and then store tagged).
+ *
+ * <p><table border="1" cellpadding="3" cellspacing="0" width="100%"><tr><td>
+ * <pre>
+ * #Feed Processor Config
+ * #Sun Dec 31 00:48:23 EST 2000
+ *
+ * proxy=192.168.1.15
+ * <net>
+ * username=joe
+ * <smb>
+ * host=doc-storage
+ * username=kelly
+ * </smb>
+ * <ftp>
+ * host=feed10.research.com
+ * </ftp>
+ * </net>
+ * </pre>
+ *
+ * </td><td>
+ *
+ * <pre>
+ * #Feed Processor Config
+ * #Sun Dec 31 00:59:31 EST 2000
+ *
+ * proxy=192.168.1.15
+ * net.username=joe
+ * net.smb.host=doc-storage
+ * net.smb.username=kelly
+ * net.ftp.host=feed10.research.com
+ * </pre>
+ *
+ * </td></tr></table>
+ *
+ * <p>In the above example, if <code>getProperty( "net.ftp.username" )</code>
+ * was called "joe" would be returned. The <code>get</code> method walks
+ * up the tree searching for the first match. So the following:
+ *
+ * <pre>
+ * net.ftp.username
+ * net.username
+ * username
+ * </pre>
+ *
+ * are basically equivalent and thus backwords compatible with
+ * java.util.Properties.
+ *
+ * <p>The benifit of using <code>PropertiesTree</code> as opposed to <code>Properties</code> is that a child property can mask a parent
+ * property resulting in sophisticated hierarchial relationships. This is true of the <code>net.smb.username</code> property.
+ * It might also be thought of as overloading <code>net.username</code>
+ * with <code>net.smb.username</code> but only for the smb branch.
+ *
+ * <p>See the <a href="../../../properties.html">More About PropertiesTree and it's File Format</a> for details.
+ */
+
+public class PropertiesTree extends Properties {
+
+ private static final String INDENT = " ";
+ private static final int TRUNC = 70;
+
+ String label;
+ private PropertiesTree parent;
+
+ private void listTagged( String indent, PrintStream out ) {
+ Vector sections = new Vector(0);
+ for( Enumeration e = keys(); e.hasMoreElements(); ) {
+ String key = (String)e.nextElement();
+ Object value = get( key );
+ if( value instanceof PropertiesTree ) {
+ sections.addElement( value );
+ } else {
+ String s;
+ s = indent + key + "=" + (String)value;
+ s = s.length() > TRUNC ? s.substring( 0, TRUNC - 3 ) + "..." : s;
+ out.println( s );
+ }
+ }
+ for( Enumeration e1 = sections.elements(); e1.hasMoreElements(); ) {
+ String s;
+ PropertiesTree p = (PropertiesTree)e1.nextElement();
+
+ s = indent + "<" + p.label + ">";
+ s = s.length() > TRUNC ? s.substring( 0, TRUNC - 3 ) + "..." : s;
+ out.println( s );
+
+ p.list0( indent + INDENT, out );
+
+ s = indent + "</" + p.label + ">";
+ s = s.length() > TRUNC ? s.substring( 0, TRUNC - 3 ) + "..." : s;
+ out.println( s );
+ }
+ }
+ private void list0( String prefix, PrintStream out ) {
+ Vector sections = new Vector(0);
+ for( Enumeration e = keys(); e.hasMoreElements(); ) {
+ String key = (String)e.nextElement();
+ Object value = get( key );
+ if( value == null ) {
+ } else if( value instanceof PropertiesTree ) {
+ sections.addElement( value );
+ } else {
+ if( prefix != null ) {
+ key = prefix + "." + key;
+ }
+ String s = (String)value;
+ s = s.length() > TRUNC ? s.substring( 0, TRUNC - 3 ) + "..." : s;
+ out.println( key + "=" + s );
+ }
+ }
+ for( Enumeration e1 = sections.elements(); e1.hasMoreElements(); ) {
+ PropertiesTree p = (PropertiesTree)e1.nextElement();
+ p.list0( prefix == null ? p.label : prefix + "." + p.label, out );
+ }
+ }
+ private synchronized void saveTagged( String indent, PrintWriter out ) {
+ Vector sections = new Vector(0);
+ for( Enumeration e = keys(); e.hasMoreElements(); ) {
+ String key = (String)e.nextElement();
+ Object value = get( key );
+ if( value == null ) {
+ value = "";
+ }
+ if( value instanceof PropertiesTree ) {
+ sections.addElement( value );
+ } else if( value instanceof String ) {
+ out.print( indent );
+ out.print( key );
+ out.write( '=' );
+
+ String val = (String)value;
+ int len = val.length();
+ boolean empty = false;
+
+ for (int i = 0 ; i < len ; i++) {
+ int ch = val.charAt(i);
+
+ switch (ch) {
+ case '\\': out.write('\\'); out.write('\\'); break;
+ case '\t': out.write('\\'); out.write('t'); break;
+ case '\n': out.write('\\'); out.write('n'); break;
+ case '\r': out.write('\\'); out.write('r'); break;
+
+ default:
+ if ((ch < ' ') || (ch >= 127) || (empty && (ch == ' '))) {
+ if( ch > 255 ) {
+ out.write(ch);
+ } else {
+ out.write('\\');
+ out.write('u');
+ out.write(toHex((ch >> 12) & 0xF));
+ out.write(toHex((ch >> 8) & 0xF));
+ out.write(toHex((ch >> 4) & 0xF));
+ out.write(toHex((ch >> 0) & 0xF));
+ }
+ } else {
+ out.write(ch);
+ }
+ }
+ empty = false;
+ }
+ out.write('\n');
+ out.flush();
+ } else {
+ System.out.println( "error: " + key + "=" + value );
+ }
+ }
+ for( Enumeration e1 = sections.elements(); e1.hasMoreElements(); ) {
+ PropertiesTree p = (PropertiesTree)e1.nextElement();
+ out.println( indent + "<" + p.label + ">" );
+ p.saveTagged( indent + INDENT, out );
+ out.println( indent + "</" + p.label + ">" );
+ }
+ }
+ private synchronized void save0( String prefix, PrintWriter out ) {
+ Vector sections = new Vector(0);
+ for( Enumeration e = keys(); e.hasMoreElements(); ) {
+ String key = (String)e.nextElement();
+ Object value = get( key );
+ if( value == null ) {
+ value = "";
+ }
+ if( value instanceof PropertiesTree ) {
+ sections.addElement( value );
+ } else if( value instanceof String ) {
+ if( prefix != null ) {
+ out.print( prefix );
+ out.write( '.' );
+ }
+ out.print( key );
+ out.write( '=' );
+
+ String val = (String)value;
+ int len = val.length();
+ boolean empty = false;
+
+ for (int i = 0 ; i < len ; i++) {
+ int ch = val.charAt(i);
+
+ switch (ch) {
+ case '\\': out.write('\\'); out.write('\\'); break;
+ case '\t': out.write('\\'); out.write('t'); break;
+ case '\n': out.write('\\'); out.write('n'); break;
+ case '\r': out.write('\\'); out.write('r'); break;
+
+ default:
+ if ((ch < ' ') || (ch >= 127) || (empty && (ch == ' '))) {
+ if( ch > 255 ) {
+ out.write(ch);
+ } else {
+ out.write('\\');
+ out.write('u');
+ out.write(toHex((ch >> 12) & 0xF));
+ out.write(toHex((ch >> 8) & 0xF));
+ out.write(toHex((ch >> 4) & 0xF));
+ out.write(toHex((ch >> 0) & 0xF));
+ }
+ } else {
+ out.write(ch);
+ }
+ }
+ empty = false;
+ }
+ out.write('\n');
+ out.flush();
+ } else {
+ System.out.println( "error: " + key + "=" + value );
+ }
+ }
+ for( Enumeration e1 = sections.elements(); e1.hasMoreElements(); ) {
+ PropertiesTree p = (PropertiesTree)e1.nextElement();
+ p.save0( prefix == null ? p.label : prefix + "." + p.label, out );
+ }
+ }
+ private static char toHex(int nibble) {
+ return hexDigit[(nibble & 0xF)];
+ }
+ private static char[] hexDigit = {
+ '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
+ };
+
+ /**
+ * Construct an empty properties tree with no values.
+ */
+
+ public PropertiesTree() {
+ this.label = null;
+ this.parent = null;
+ }
+
+ /**
+ * Put a key and value into the tree. If the key contains a dot
+ * '.', new tree nodes will be automatically created to accomodate.
+ */
+
+ public synchronized Object put( Object key, Object value ) {
+ String s = (String)key;
+ String l;
+ Object o;
+ PropertiesTree p;
+ int d;
+ if(( d = s.indexOf( '.' )) > -1 ) {
+ l = s.substring( 0, d );
+ o = super.get( l );
+ if( o != null && o instanceof PropertiesTree ) {
+ p = (PropertiesTree)o;
+ } else if( o != null ) {
+ throw new IllegalArgumentException( "property exists: " +
+ l + "=" + (String)o );
+ } else {
+ p = new PropertiesTree();
+ p.label = l;
+ p.parent = this;
+ super.put( l, p );
+ }
+ return p.put( s.substring( d + 1 ), value );
+ } else {
+ o = super.get( s );
+ if( o != null && o instanceof PropertiesTree ) {
+ throw new IllegalArgumentException( "property tree exists: " + s );
+ }
+ if( value instanceof PropertiesTree ) {
+ ((PropertiesTree)value).label = (String)key;
+ ((PropertiesTree)value).parent = this;
+ }
+ return super.put( key, value );
+ }
+ }
+
+ /**
+ * Retrieved the property specified by the key parameter, seraching parent
+ * nodes if necessary.
+ */
+
+ public synchronized Object get( Object key ) {
+ String s = (String)key;
+ int d;
+ if(( d = s.indexOf( '.' )) > 0 ) {
+ Object o = super.get( s.substring( 0, d ));
+ if( o == null ) {
+ return get( s.substring( d + 1 ));
+ } else if( o instanceof PropertiesTree ) {
+ return ((PropertiesTree)o).get( s.substring( d + 1 ));
+ }
+ } else {
+ Object o = super.get( s );
+ if( o == null && parent != null ) {
+ return parent.get( s );
+ } else if( o instanceof PropertiesTree ||
+ ( o instanceof String && ((String)o).length() > 0 )) {
+ return o;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Retrieve a property from the tree by searching parent nodes
+ * if necessary and return the value as a String.
+ */
+
+ public String getProperty( String key ) {
+ Object o = get( key );
+ return o == null ? null : (String)o;
+ }
+
+ /**
+ * Retrieve a property from the tree by searching parent nodes if necessary
+ * and return the value as a String. If the keys value is not found, the
+ * default parameter will be returned.
+ */
+
+ public String getProperty( String key, String defaultValue ) {
+ Object o = get( key );
+ return o == null ? defaultValue : (String)o;
+ }
+
+ /**
+ * List all properties in the traditional output format and truncated to
+ * ensure the contents fit within the display.
+ */
+
+ public void list( PrintStream out ) {
+ out.println("-- listing properties tree --");
+ list0( null, out );
+ }
+
+ /**
+ * Save this properties tree to the specified OutputStream. The header
+ * parameter will be printed at the top as a comment.
+ */
+
+ public synchronized void store( OutputStream out, String header ) {
+ store( out, header, false );
+ }
+
+ /**
+ * Write this properties tree to the specified OutputStream. The header
+ * parameter will be printed at the top as a comment. If the boolean
+ * parameter is true the output will be stored in tagged format as shown
+ * in the example at the top of this page.
+ */
+
+ public synchronized void store( OutputStream out, String header, boolean tagged ) {
+ PrintWriter prnt = new PrintWriter( out, true );
+ if( header != null ) {
+ prnt.write( '#' );
+ prnt.println( header );
+ }
+ prnt.write( '#' );
+ prnt.println( new Date() );
+ if( tagged ) {
+ saveTagged( "", prnt );
+ } else {
+ save0( null, prnt );
+ }
+ }
+
+ /**
+ * Load all properties from the provided InputStream. The text read may be
+ * either tagged format, traditional format, or a mixture of both.
+ */
+
+ public synchronized void load( InputStream in ) throws IOException {
+ int buflen = 80;
+ char[] buf = new char[buflen];
+ int bufindx = 0;
+ boolean intag = false;
+ String section = null;
+
+ int ch = in.read();
+ while( true ) {
+ switch( ch ) {
+ case -1:
+ if( section != null ) {
+ throw new IOException( "expecting end tag" );
+ }
+ return;
+ case '<':
+ intag = true;
+ ch = in.read();
+ continue;
+ case '#':
+ case ';':
+ do {
+ ch = in.read();
+ } while(( ch >= 0 ) && ( ch != '\n' ) && ( ch != '\r' ));
+ continue;
+
+ case '\n':
+ case '\r':
+ case ' ':
+ case '\t':
+ ch = in.read();
+ continue;
+ }
+
+ bufindx = 0;
+ while(( ch >= 0 ) && ( ch != '=' ) && ( ch != ':' ) && ( ch != ' ' ) &&
+ ( ch != '\t' ) && ( ch != '\n' ) && ( ch != '\r' )) {
+ if( intag && ch == '>' ) {
+ ch = in.read();
+ break;
+ }
+ if( bufindx >= buflen ) {
+ buflen *= 2;
+ char[] nbuf = new char[buflen];
+ System.arraycopy( buf, 0, nbuf, 0, buf.length );
+ buf = nbuf;
+ }
+ buf[bufindx++] = (char)ch;
+ ch = in.read();
+ }
+ String key = new String( buf, 0, bufindx );
+ if( intag ) {
+ if( key.startsWith( "/" )) {
+ int s;
+ // chop off end tag from current section
+ if( section != null && section.regionMatches(
+ ( s = section.lastIndexOf( '.' )) + 1, key, 1, key.length() - 1 )) {
+ section = s < 1 ? null : section.substring( 0, s );
+ } else {
+ throw new IOException( "unexpected end tag: </" + key + ">" );
+ }
+ } else {
+ section = section == null ? key : section + "." + key;
+ }
+ intag = false;
+ continue;
+ }
+
+ while(( ch == ' ' ) || ( ch == '\t' )) {
+ ch = in.read();
+ }
+ if(( ch == '=' ) || ( ch == ':' )) {
+ ch = in.read();
+ }
+ while(( ch == ' ' ) || ( ch == '\t' )) {
+ ch = in.read();
+ }
+
+ bufindx = 0;
+ while(( ch >= 0 ) && ( ch != '\n' ) && ( ch != '\r' )) {
+ int next = 0;
+ if( ch == '\\' ) {
+ switch( ch = in.read() ) {
+ case '\r':
+ if((( ch = in.read() ) == '\n' ) ||
+ ( ch == ' ' ) || ( ch == '\t' )) {
+ } else continue;
+ case '\n':
+ while((( ch = in.read() ) == ' ') || ( ch == '\t' ));
+ continue;
+ case 't': ch = '\t'; next = in.read(); break;
+ case 'n': ch = '\n'; next = in.read(); break;
+ case 'r': ch = '\r'; next = in.read(); break;
+ case 'u': {
+ while ((ch = in.read()) == 'u');
+ int d = 0;
+ loop:
+ for (int i = 0 ; i < 4 ; i++) {
+ next = in.read();
+ switch (ch) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ d = (d << 4) + ch - '0';
+ break;
+ case 'a': case 'b': case 'c':
+ case 'd': case 'e': case 'f':
+ d = (d << 4) + 10 + ch - 'a';
+ break;
+ case 'A': case 'B': case 'C':
+ case 'D': case 'E': case 'F':
+ d = (d << 4) + 10 + ch - 'A';
+ break;
+ default:
+ break loop;
+ }
+ ch = next;
+ }
+ ch = d;
+ break;
+ }
+ default:
+ next = in.read();
+ break;
+ }
+ } else {
+ next = in.read();
+ }
+ if (bufindx >= buflen) {
+ buflen *= 2;
+ char[] nbuf = new char[buflen];
+ System.arraycopy(buf, 0, nbuf, 0, buf.length);
+ buf = nbuf;
+ }
+ buf[bufindx++] = (char)ch;
+ ch = next;
+ }
+ String val = new String(buf, 0, bufindx);
+
+ if( section != null ) {
+ put( section + '.' + key, val );
+ } else {
+ put( key, val );
+ }
+ }
+ }
+}