Import smbfs-1.4.1.

This is Boris Popov's SMB/CIFS file system implementation for FreeBSD.

Obtained from:	Boris Popov via ftp://ftp.butya.kz/pub/smbfs/
This commit is contained in:
Sheldon Hearn 2001-12-14 11:06:03 +00:00
commit f1b9d12761
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/smbfs/dist/; revision=87866
svn path=/vendor/smbfs/1.4.1/; revision=87868; tag=vendor/smbfs/1.4.1
52 changed files with 7041 additions and 0 deletions

29
contrib/smbfs/COPYRIGHT Normal file
View file

@ -0,0 +1,29 @@
Copyright (c) 2000, 2001 Boris Popov
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.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by Boris Popov.
4. Neither the name of the author nor the names of any co-contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
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.

10
contrib/smbfs/CREDITS Normal file
View file

@ -0,0 +1,10 @@
In the development process next sources were used:
Various documents from the Microsoft ftp site.
HTML docs published by Thursby Software.
Special thanks to the Samba team for permission to use their source
code as reference.
Author - Boris Popov <bp@butya.kz>, <bp@freebsd.org>

130
contrib/smbfs/HISTORY Normal file
View file

@ -0,0 +1,130 @@
16.04.2001 1.4.1
- Kernel side of smbfs committed in the FreeBSD-current. It controlled
by following options: LIBMCHAIN, LIBICONV, NETSMB, NETSMBCRYPTO and SMBFS.
- Removed static dependency on the libiconv library, option WITH_ICONV
removed as well. If you use libiconv support, make sure that the latest
port is installed.
- Multiple mount/umount operations called in parallel can cause kernel
panic - fixed.
- Misc code cleanups.
26.02.2001 1.3.6
- Names of some options is the config.mk.in file are changed. The old ones
are still supported.
- Synch with changes in the recent -current (you'll need kernel compiled
from sources at least as of Feb 24).
- In all previous versions of smbfs signals weren't properly masked,
which caused erratical behavior of some programs (ftp(1) for example).
- Mounted shares may become "frozen" (no timeout occurs) if server died or
disconnected for some reason - fixed.
09.02.2001 1.3.5
- The user and server names was swapped in the "TreeConnect"
request (fixed by Jonathan Hanna).
- smb requester could cause a panic if there is no free mbufs - fixed.
- It is possible to use smbfs with devfs now, but it wasn't tested under
SMP. Also note that device permissions will be wrong, because devfs
do not allow passing of credentials to the cloning function.
- nsmbX device moved from the /dev/net directory to /dev directory.
31.01.2001 1.3.4
- Maintance: synch with changes in the recent -current
28.01.2001 1.3.3
- Connection handling engine rewritten in order to reduce number of
possible deadlocks during reconnect operations.
- Directory traversals should be faster on large directories.
- smbfs now can talk to the NetApp servers (thanks to Jonathan Hanna).
- smbfs.sh.sample script updated (ideas from Nikolai Saoukh).
- Minor bug fixes.
19.11.2000 1.3.2
- synch with changes in the recent -current
- nail down a nasty bug which may cause incorrect values supplied as
domain name (reported by Harald Weis).
- There was a bug in the directory listing code which caused long directory
traversals to fail (reported by A G F Keahan).
29.10.2000 1.3.1
- An attempt was made to get rid from the possible kernel stack overflow.
- Now connection will be restored properly under -stable.
NOTE: NT servers have an 'AutoDisconnect' feature which will drop client
connection after some time of idleing. smbfs will restore connection on
the next request, but one may wish to setup a cron job with a simple
'ls /ntmount' command.
20.10.2000 1.3.0
- Network IO engine significantly reworked. Now it uses kernel threads
to implement 'smbiod' process which handles network traffic for each VC.
Previous model were incapable to serve large number of mount points and
didn't work well with intensive IO operations performed on a different
files on the same mount point. Special care was taken on better
usage of MP systems.
Unfortunately, kernel threads aren't supported by FreeBSD 3.X and for
now it is excluded from the list of supported systems.
- Reduce overhead caused by using single hash table for each mount point.
26.09.2000 1.2.8 (never released)
- More SMP related bugs are fixed.
- Make smbfs compatible with the Linux emulator.
- smbfs now known to work with IBM LanManager (special thanks to
Eugen Averin <mad@euinf.dp.ua>)
- Fix problem with files bigger than 2GB (reported by Lee McKenna)
- Please note that smbfs may not work properly with FreeBSD 3.X.
16.08.2000 1.2.7
- Maintance: use better algorithm to detect SYSCTL_HANDLER_ARGS changes
to avoid compilation problems on various versions of FreeBSD.
07.08.2000 1.2.6
- Fix iconv support, was broken in the 1.2.5
- Minor corrections to 'smbutil view' command.
- Fix kernel memory leak caused by two subsequent and identical
'smbutil login' commands.
25.07.2000 1.2.5
- NetBIOS name resolver added. '-I' option still supported. WINS server
can be specified in the nsmbrc file (nbns variable). To use resolver
with Win9X machines you have to specify WINS server in the config file.
12.07.2000 1.2.4
- Variable SRCTREE in the config.mk replaced with SYSDIR and should
point to the sys directory. '/usr/src/sys' for example.
- Correct problem with the keep-alive packets
04.07.2000 1.2.3
- Killed some bugs related to the out-of-mbufs condition.
- new keyword 'addr' added to the config file to specify server address.
- Another attempt to make reconnection procedure more stable.
21.06.2000 1.2.2
- Device handles wasn't freed under FreeBSD 3.4 - fixed.
Implement correct handling of multiple connections to the same NT
server (thanks to kit <kit.mitchell@team.xtra.co.nz>) for report.
More misc fixes for an NT servers.
11.06.2000 1.2.1
- More bug fixes in the connection handling mechanism.
mount_smbfs(8) manpage has now proper description for an '-N' option.
smbutil supports new commands:
'print' - send file to the remote printer
'view' - list shares available on the specified host
'login' - create permanent connection to remote host
'logout'- counterpart of 'login'
'crypt' - produce an encrypted password to store in the .nsmbrc file.
01.06.2000 1.1.2
- Support for FreeBSD 3.4 added (see INSTALL file for details).
Add advisory locking support in order to make fcntl(2), flock(2)
system calls actually work on smbfs.
Few non-serious bugs fixed.
16.05.2000 1.0.5
- fix authentication code, this caused troubles with NT server.
(Thanks to Neil Blakey-Milner and Andrew Zavjalov for testing)
Some documentation changes.
14.05.2000 1.0.2
- first public release
Boris Popov <bp@butya.kz>

68
contrib/smbfs/INSTALL Normal file
View file

@ -0,0 +1,68 @@
1. Building
===========
Copy config.in file to the config.local and edit it for your needs. Build
process requires kernel sources in order to compile KLD module. If you want
to use encrypted passwords you'll need an src/sys/crypto directory (sys-crypto
cvsup collection) because encryption process involves DES algorithm.
Note for FreeBSD-current: it have kernel module sources in the base
tree and requires options LIBMCHAIN and LIBICONV included in the kernel
config file. smbfs can be either compiled in the kernel or loaded as module.
If FreeBSD machine and SMB server uses different character sets you
may consider install ports/converters/iconv package (version 2.0 required).
Type 'make' to compile.
If you're running any previous version of smbfs, unmount all mounted
shares and unload an old module via 'kldunload smbfs' command.
2. Installing
=============
'make install' command will copy compiled binaries to /usr/local/bin
directory and KLD module into /modules directory.
If you're running smbfs for the first time, it is also necessary to
run 'make makedev' command in order to create /dev/nsmb0 device.
3. Configuring
==============
KLD module can be loaded either manually:
kldload smbfs.ko
or via loader.conf(5) file:
smbfs_load="YES"
However it is not strictly necessary because mount_smbfs(8) command
will load it automatically.
Copy ./examples/dot.nsmbrc file into your home directory with ./.nsmbrc
name and edit it for your needs.
4. Running
==========
Please read mount_smbfs man page to get overview of command options.
Here is a quick example:
mount_smbfs -I hostname //bp@myserver/myshare /mnt
If something goes wrong, please try to find a problem and, if it is a bug
send me detailed description or patch. Before complaining about a bug, please
check the same operations with smbclient program included in the Samba package.
5. Deinstalling
===============
All files can be completly removed by typing 'make deinstall' in the
working directory.

87
contrib/smbfs/Makefile Normal file
View file

@ -0,0 +1,87 @@
# $Id: Makefile,v 1.12 2001/04/16 04:34:26 bp Exp $
#
# Valid targets:
# install installs binaries and man pages
# deinstall undo install (except man pages)
# install-src copy .h files in /usr/local/include
# install-lib copy lib files in /usr/lib
# deinstall-lib,
# deinstall-src undo corresponding install-* target
# clean cleanup source tree
.if ${MACHINE_ARCH} != "i386"
. error "only IA32 machines supported"
.endif
CONFIG_INT?= config.int
CONFIG_MK?= config.mk
CFGDEPEND=
.ifmake !configure && !clean
. if !exists(${CONFIG_INT})
. error "Run 'make configure' before build"
. else
. include "${CONFIG_INT}"
. endif
.else
. if exists(${CONFIG_MK})
CFGDEPEND= ${CONFIG_MK}
${CONFIG_MK}: config.mk.in
@echo Your ${CONFIG_MK} file is older than the config.mk.in file
@echo Please check for possible changes
@false
. include "${CONFIG_MK}"
. endif
.endif
BUILDKLD?=yes
PREFIX?=/usr/local
SYSDIR?=/usr/src/sys
configure::
.if ${CFGDEPEND} == ${CONFIG_MK}
@echo Using ${CFGDEPEND} file...
.endif
echo PREFIX= ${PREFIX} > ${CONFIG_INT}
echo SYSDIR=${SYSDIR} >> ${CONFIG_INT}
echo KMODDIR=${KMODDIR} >> ${CONFIG_INT}
echo SINGLEKLD=yes >> ${CONFIG_INT}
.if !defined(WITHOUT_CRYPT)
echo ENCRYPTED_PASSWD=yes >> ${CONFIG_INT}
.endif
.if defined(SMP_SUPPORT) || defined(SMP)
echo SMP=yes >> ${CONFIG_INT}
.endif
SUBDIR=
.if defined(COMPLETEBUILD) || (${BUILDKLD} == yes && !exists(${SYSDIR}/netsmb/smb.h))
SUBDIR+= kernel/modules
.endif
SUBDIR+= lib
SUBDIR+= mount_smbfs smbutil
install-src install-lib deinstall-lib deinstall-src:
cd kernel && make ${.TARGET}
cd lib && make ${.TARGET}
makedev:
@-( if [ `mount -t devfs | wc -l` = 0 ]; then \
cd /dev && && rm -f nsmb* && mknod nsmb0 c 144 0; \
else \
echo This operation is not required with devfs; \
fi; \
)
cleandepend deinstall: _SUBDIRUSE
clean: _SUBDIRUSE
rm -f ${CONFIG_INT}
.include <bsd.subdir.mk>

View file

@ -0,0 +1,43 @@
# $Id: Makefile.inc,v 1.9 2001/04/16 04:34:26 bp Exp $
.ifmake !clean && !cleandepend
.if !defined(PREFIX)
.include "config.int"
.endif
.endif
BINDIR?=${PREFIX}/bin
SMBSBINDIR=${PREFIX}/sbin
MANDIR=${PREFIX}/man/man
CFLAGS += -Wall -I../kernel/mysys
.include <bsd.libnames.mk>
.if !defined(LIBSMB) || defined(COMPLETEBUILD)
CFLAGS += -L../lib/smb -L../lib/nb
CFLAGS += -I../include
LIBSMB = ../lib/smb/libsmb.a
.endif
.if !exists(${SYSDIR}/netsmb/smb.h)
CFLAGS += -I../kernel
.endif
.if defined(SMBGDB)
CFLAGS+= -ggdb
.endif
deinstall:
@(if test -f ${BINDIR}/${PROG}; then \
echo removing ${BINDIR}/${PROG}; \
rm -f ${BINDIR}/${PROG}; \
fi;)
@(if test -f ${MANDIR}1/${MAN1}.gz ; then \
echo removing ${MANDIR}1/${MAN1}.gz; \
rm -f ${MANDIR}1/${MAN1}.gz; \
fi;)
@(if test -f ${MANDIR}8/${MAN8}.gz ; then \
echo removing ${MANDIR}8/${MAN8}.gz; \
rm -f ${MANDIR}8/${MAN8}.gz; \
fi;)

50
contrib/smbfs/README Normal file
View file

@ -0,0 +1,50 @@
SMB/CIFS protocol and SMB/CIFS file system implementation
for FreeBSD, version 1.4.
This is native SMB/CIFS filesystem (smbfs for short) for FreeBSD.
It is a complete, kernel side implementation of SMB requester and filesystem.
Supportted platforms:
FreeBSD 4.X
FreeBSD-current kernel module is included in the base source
tree.
I'm would be very grateful for any feedback, bug reports etc.
Supported SMB servers:
Samba
Windows 95/98/ME/2000/NT4.0 (SPs 4, 5, 6)
IBM LanManager
NetApp
An updated versions of this package can be retrieved from ftp server:
ftp://ftp.butya.kz/pub/smbfs/smbfs.tar.gz
Perfomance
==========
There is some perfomance benchmarks over 10Mbit network:
Win95 machine as server:
IOZONE: auto-test mode
MB reclen bytes/sec written bytes/sec read
1 512 339791 323416
1 1024 481067 431568
1 2048 648394 588674
1 4096 630130 583555
1 8192 671088 618514
Samba 2.0.6 as server:
IOZONE: auto-test mode
MB reclen bytes/sec written bytes/sec read
1 512 409200 437191
1 1024 545600 596523
1 2048 729444 798915
1 4096 871543 919299
1 8192 900790 1024562
Author: Boris Popov <bp@freebsd.org>

View file

@ -0,0 +1,37 @@
# SMBFS build configuration
# copy this file to config.mk and edit as needed.
# If you want to disable an option just comment it with '#' char.
#
# $Id: config.mk.in,v 1.16 2001/04/16 04:34:26 bp Exp $
# Where your kernel source tree located (/usr/src/sys for example)
SYSDIR=/usr/src/sys
# Where the kernel module gets installed
KMODDIR=/modules
# Where all files get installed
PREFIX?=/usr/local
# Build shared smb library, or link all executables statically
USE_SHAREDLIBS=no
# Comment this to disable support for encrypted passwords (requires
# src/sys/crypto directory). By default, NT and Win* machines use encrypted
# passwords.
ENCRYPTED_PASSWD=yes
# Uncomment this option if kernel compiled with SMP suppport.
# SMP_SUPPORT=
# This turns on debug logging, be careful - it produces a lot of kernel
# messages.
#KDEBUG+= -DSMB_SOCKET_DEBUG
#KDEBUG+= -DSMB_SOCKETDATA_DEBUG
#KDEBUG+= -DSMB_VNODE_DEBUG
# Compile binaries with debugging symbols
#SMBGDB=yes
# Build kernel module (don't touch that)
SINGLEKLD=yes

3
contrib/smbfs/configure vendored Executable file
View file

@ -0,0 +1,3 @@
#!/bin/sh
make configure $*

View file

@ -0,0 +1,57 @@
# $Id: dot.nsmbrc,v 1.6 2000/07/16 01:52:06 bp Exp $
#
# Example for .nsmbrc file
#
# smbfs lookups configuration files in next order:
# 1. ~/.nsmbrc
# 2. /usr/local/etc/nsmb.conf - if this file found it will
# override values with same keys from user files.
#
#
# This file consist from a set of sections. Each section started by section name
# surrounded with square brackets:
# [section_name]
#
# End of the section marked either by new section or by the end of file.
# Each section can contain zero or more parameters:
# [section_name]
# key=value
#
# where 'key' represents parameter name and 'value' a value assigned
# to this parameter.
#
# SMB library uses next forms of section names:
# A) [default]
# B) [SERVER]
# C) [SERVER:USER]
# D) [SERVER:USER:SHARE]
#
# Here is the map of possible keywords:
#
# keyword/section A B C D Comment
#
# addr - + - - IP or IPX address of SMB server
# charsets - + + + local:remote charset pair
# nbns + + - - address of NetBIOS name server (WINS)
# nbscope + + - - NetBIOS scope
# nbtimeout + + - - timeout for NetBIOS name servers
# password - - + + a plain text password used to access to the given share
# retry_count + + - - number of retries before connection marked as broken
# timeout + + - - SMB request timeout
# workgroup + + + + name of workgroup
#
# A simple configuration example:
# First, define a workgroup.
[default]
workgroup=SALES
# The 'FSERVER' is an NT server.
[FSERVER]
charsets=koi8-r:cp866
addr=fserv.coolcorp.com
[FSERVER:JOE]
# use persistent password cache for user 'joe'
password=$$1767877DF

View file

@ -0,0 +1,22 @@
#!/bin/sh
# Sample input filter to print on HP Laser Jet printers
# Installed in /usr/local/libexec/hp6l
DEVICE="ljet3"
PAPERSIZE="a4"
printf "\033&k2G" || exit 2
read first_line
first_two_chars=`expr "$first_line" : '\(..\)'`
if [ "$first_two_chars" = "%!" ]; then
exec 3>&1 1>&2
/usr/local/bin/gs -sPAPERSIZE=${PAPERSIZE} -dSAFER -dNOPAUSE -q -sDEVICE=${DEVICE} \
-sOutputFile=/dev/fd/3 - && exit 0
else
echo $first_line && cat && printf "\033&l0H" && exit 0
fi
exit 2

View file

@ -0,0 +1,4 @@
#!/bin/sh
/usr/local/libexec/lj6l | /usr/local/libexec/tolj && exit 0
exit 2

View file

@ -0,0 +1,7 @@
# $Id: printcap.sample,v 1.1 2000/06/11 08:13:28 bp Exp $
# Sample printcap entry for NetWare printer
fserverlj|LJ6L on the fserver:\
:sh:lp=/dev/null:\
:if=/usr/local/libexec/ljspool: \
:sd=/var/spool/output/nwhost:lf=/var/log/lpd-errs:

View file

@ -0,0 +1,5 @@
#!/bin/sh
QUEUE="//joe@fserver/lj"
/usr/local/bin/smbutil print ${QUEUE} -

View file

@ -0,0 +1,37 @@
#!/bin/sh
#
# $Id: smbfs.sh.sample,v 1.3 2001/01/13 04:50:36 bp Exp $
#
# Location: /usr/local/etc/rc.d/smbfs.sh
#
# Simple script to mount smbfs file systems at startup.
# It assumes that all mount points described in fstab file and password
# entries listed in /root/.nsmbrc file. See mount_smbfs(8) for details.
#
mount="/sbin/mount -o -N"
umount=/sbin/umount
HOME=/root; export HOME
vols=`awk -- '/^\/.*[[:space:]]+smbfs[[:space:]]+/ { print $2 }' /etc/fstab`
case "$1" in
start)
echo -n "smbfs: "
for vol in ${vols}; do
$mount $vol
echo -n "$vol "
done
;;
stop)
echo -n "unmounting smbfs mount points: "
for vol in ${vols}; do
$umount $vol
echo -n "$vol "
done
;;
*)
echo "Usage: `basename $0` {start|stop}" >&2
exit 64
esac
echo "Done"

View file

@ -0,0 +1,86 @@
/*
* Copyright (c) 2000, Boris Popov
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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.
*
* $Id: cflib.h,v 1.3 2000/07/11 01:51:49 bp Exp $
*/
#ifndef _zzzzzz_RCFILE_H_
#define _zzzzzz_RCFILE_H_
struct rcfile;
/*
* A unified options parser
*/
enum opt_argtype {OPTARG_STR, OPTARG_INT, OPTARG_BOOL};
struct opt_args;
typedef int opt_callback_t (struct opt_args*);
#define OPTFL_NONE 0x0000
#define OPTFL_HAVEMIN 0x0001
#define OPTFL_HAVEMAX 0x0002
#define OPTFL_MINMAX NAFL_HAVEMIN | NAFL_HAVEMAX
struct opt_args {
enum opt_argtype type;
int opt; /* command line option */
char * name; /* rc file equiv */
int flag; /* OPTFL_* */
int ival; /* int/bool values, or max len for str value */
char * str; /* string value */
int min; /* min for ival */
int max; /* max for ival */
opt_callback_t *fn; /* call back to validate */
};
extern int cf_opterr, cf_optind, cf_optopt, cf_optreset;
extern const char *cf_optarg;
__BEGIN_DECLS
int opt_args_parse(struct rcfile *, struct opt_args *, const char *,
opt_callback_t *);
int opt_args_parseopt(struct opt_args *, int, char *, opt_callback_t *);
int cf_getopt(int, char * const *, const char *);
int rc_open(const char *, const char *, struct rcfile **);
int rc_close(struct rcfile *);
int rc_merge(const char *, struct rcfile **);
int rc_getstringptr(struct rcfile *, const char *, const char *, char **);
int rc_getstring(struct rcfile *, const char *, const char *, size_t, char *);
int rc_getint(struct rcfile *, const char *, const char *, int *);
int rc_getbool(struct rcfile *, const char *, const char *, int *);
__END_DECLS
#endif /* _zzzzzz_RCFILE_H_ */

View file

@ -0,0 +1,147 @@
/*
* Copyright (c) 2000, Boris Popov
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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.
*
* $Id: nb_lib.h,v 1.2 2000/07/17 01:49:27 bp Exp $
*/
#ifndef _NETSMB_NB_LIB_H_
#define _NETSMB_NB_LIB_H_
/*
* Error codes
*/
#define NBERR_INVALIDFORMAT 0x0001
#define NBERR_SRVFAILURE 0x0002
#define NBERR_NAMENOTFOUND 0x0003
#define NBERR_IMP 0x0004
#define NBERR_REFUSED 0x0005
#define NBERR_ACTIVE 0x0006
#define NBERR_HOSTNOTFOUND 0x0101
#define NBERR_TOOMANYREDIRECTS 0x0102
#define NBERR_INVALIDRESPONSE 0x0103
#define NBERR_NAMETOOLONG 0x0104
#define NBERR_NOBCASTIFS 0x0105
#define NBERR_MAX 0x0106
#define NBERROR(e) ((e) | SMB_NB_ERROR)
#define NBCF_RESOLVED 0x0001
/*
* nb environment
*/
struct nb_ctx {
int nb_flags;
int nb_timo;
char * nb_scope; /* NetBIOS scope */
char * nb_nsname; /* name server */
struct sockaddr_in nb_ns; /* ip addr of name server */
struct sockaddr_in nb_lastns;
};
/*
* resource record
*/
struct nbns_rr {
u_char * rr_name; /* compressed NETBIOS name */
u_int16_t rr_type;
u_int16_t rr_class;
u_int32_t rr_ttl;
u_int16_t rr_rdlength;
u_char * rr_data;
};
#define NBRQF_BROADCAST 0x0001
/*
* nbns request
*/
struct nbns_rq {
int nr_opcode;
int nr_nmflags;
int nr_rcode;
int nr_qdcount;
int nr_ancount;
int nr_nscount;
int nr_arcount;
struct nb_name* nr_qdname;
u_int16_t nr_qdtype;
u_int16_t nr_qdclass;
struct sockaddr_in nr_dest; /* receiver of query */
struct sockaddr_in nr_sender; /* sender of response */
int nr_rpnmflags;
int nr_rprcode;
u_int16_t nr_rpancount;
u_int16_t nr_rpnscount;
u_int16_t nr_rparcount;
u_int16_t nr_trnid;
struct nb_ctx * nr_nbd;
struct mbdata nr_rq;
struct mbdata nr_rp;
struct nb_ifdesc *nr_if;
int nr_flags;
int nr_fd;
};
struct nb_ifdesc {
int id_flags;
struct in_addr id_addr;
struct in_addr id_mask;
char id_name[16]; /* actually IFNAMSIZ */
struct nb_ifdesc * id_next;
};
struct sockaddr;
__BEGIN_DECLS
int nb_name_len(struct nb_name *);
int nb_name_encode(struct nb_name *, u_char *);
int nb_encname_len(const char *);
int nb_snballoc(int namelen, struct sockaddr_nb **);
void nb_snbfree(struct sockaddr*);
int nb_sockaddr(struct sockaddr *, struct nb_name *, struct sockaddr_nb **);
int nb_resolvehost_in(const char *, struct sockaddr **);
int nbns_resolvename(const char *, struct nb_ctx *, struct sockaddr **);
int nb_getlocalname(char *name);
int nb_enum_if(struct nb_ifdesc **, int);
const char *nb_strerror(int error);
int nb_ctx_create(struct nb_ctx **);
void nb_ctx_done(struct nb_ctx *);
int nb_ctx_setns(struct nb_ctx *, const char *);
int nb_ctx_setscope(struct nb_ctx *, const char *);
int nb_ctx_resolve(struct nb_ctx *);
int nb_ctx_readrcsection(struct rcfile *, struct nb_ctx *, const char *, int);
__END_DECLS
#endif /* !_NETSMB_NB_LIB_H_ */

View file

@ -0,0 +1,256 @@
/*
* Copyright (c) 2000-2001 Boris Popov
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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.
*
* $Id: smb_lib.h,v 1.22 2001/04/10 05:37:22 bp Exp $
*/
#ifndef _NETSMB_SMB_LIB_H_
#define _NETSMB_SMB_LIB_H_
#include <netsmb/smb.h>
#include <netsmb/smb_dev.h>
#define SMB_CFG_FILE "/usr/local/etc/nsmb.conf"
#define STDPARAM_ARGS 'A':case 'B':case 'C':case 'E':case 'I': \
case 'L':case 'M': \
case 'N':case 'U':case 'R':case 'S':case 'T': \
case 'W':case 'O':case 'P'
#define STDPARAM_OPT "A:BCE:I:L:M:NO:P:U:R:S:T:W:"
/*
* bits to indicate the source of error
*/
#define SMB_ERRTYPE_MASK 0xf0000
#define SMB_SYS_ERROR 0x00000
#define SMB_RAP_ERROR 0x10000
#define SMB_NB_ERROR 0x20000
#ifndef min
#define min(a,b) (((a)<(b)) ? (a) : (b))
#endif
#define getb(buf,ofs) (((const u_int8_t *)(buf))[ofs])
#define setb(buf,ofs,val) (((u_int8_t*)(buf))[ofs])=val
#define getbw(buf,ofs) ((u_int16_t)(getb(buf,ofs)))
#define getw(buf,ofs) (*((u_int16_t*)(&((u_int8_t*)(buf))[ofs])))
#define getdw(buf,ofs) (*((u_int32_t*)(&((u_int8_t*)(buf))[ofs])))
#if (BYTE_ORDER == LITTLE_ENDIAN)
#define getwle(buf,ofs) (*((u_int16_t*)(&((u_int8_t*)(buf))[ofs])))
#define getdle(buf,ofs) (*((u_int32_t*)(&((u_int8_t*)(buf))[ofs])))
#define getwbe(buf,ofs) (ntohs(getwle(buf,ofs)))
#define getdbe(buf,ofs) (ntohl(getdle(buf,ofs)))
#define setwle(buf,ofs,val) getwle(buf,ofs)=val
#define setwbe(buf,ofs,val) getwle(buf,ofs)=htons(val)
#define setdle(buf,ofs,val) getdle(buf,ofs)=val
#define setdbe(buf,ofs,val) getdle(buf,ofs)=htonl(val)
#else /* (BYTE_ORDER == LITTLE_ENDIAN) */
#error "Macros for Big-Endians are incomplete"
#define getwle(buf,ofs) ((u_int16_t)(getb(buf, ofs) | (getb(buf, ofs + 1) << 8)))
#define getdle(buf,ofs) ((u_int32_t)(getb(buf, ofs) | \
(getb(buf, ofs + 1) << 8) | \
(getb(buf, ofs + 2) << 16) | \
(getb(buf, ofs + 3) << 24)))
#define getwbe(buf,ofs) (*((u_int16_t*)(&((u_int8_t*)(buf))[ofs])))
#define getdbe(buf,ofs) (*((u_int32_t*)(&((u_int8_t*)(buf))[ofs])))
/*
#define setwle(buf,ofs,val) getwle(buf,ofs)=val
#define setdle(buf,ofs,val) getdle(buf,ofs)=val
*/
#define setwbe(buf,ofs,val) getwle(buf,ofs)=val
#define setdbe(buf,ofs,val) getdle(buf,ofs)=val
#endif /* (BYTE_ORDER == LITTLE_ENDIAN) */
/*
* SMB work context. Used to store all values which is necessary
* to establish connection to an SMB server.
*/
struct smb_ctx {
int ct_flags; /* SMBCF_ */
int ct_fd; /* handle of connection */
int ct_parsedlevel;
int ct_minlevel;
int ct_maxlevel;
char * ct_srvaddr; /* hostname or IP address of server */
char ct_locname[SMB_MAXUSERNAMELEN + 1];
const char * ct_uncnext;
struct nb_ctx * ct_nb;
struct smbioc_ossn ct_ssn;
struct smbioc_oshare ct_sh;
};
#define SMBCF_NOPWD 0x0001 /* don't ask for a password */
#define SMBCF_SRIGHTS 0x0002 /* share access rights was supplied */
#define SMBCF_LOCALE 0x0004 /* use current locale */
#define SMBCF_RESOLVED 0x8000 /* structure has been verified */
/*
* request handling structures
*/
struct mbuf {
int m_len;
int m_maxlen;
char * m_data;
struct mbuf * m_next;
};
struct mbdata {
struct mbuf * mb_top;
struct mbuf * mb_cur;
char * mb_pos;
int mb_count;
};
#define M_ALIGNFACTOR (sizeof(long))
#define M_ALIGN(len) (((len) + M_ALIGNFACTOR - 1) & ~(M_ALIGNFACTOR - 1))
#define M_BASESIZE (sizeof(struct mbuf))
#define M_MINSIZE (256 - M_BASESIZE)
#define M_TOP(m) ((char*)(m) + M_BASESIZE)
#define mtod(m,t) ((t)(m)->m_data)
#define M_TRAILINGSPACE(m) ((m)->m_maxlen - (m)->m_len)
struct smb_rq {
u_char rq_cmd;
struct mbdata rq_rq;
struct mbdata rq_rp;
struct smb_ctx *rq_ctx;
int rq_wcount;
int rq_bcount;
};
struct smb_bitname {
u_int bn_bit;
char *bn_name;
};
extern struct rcfile *smb_rc;
__BEGIN_DECLS
struct sockaddr;
int smb_lib_init(void);
int smb_open_rcfile(void);
void smb_error(const char *, int,...);
char *smb_printb(char *, int, const struct smb_bitname *);
void *smb_dumptree(void);
/*
* Context management
*/
int smb_ctx_init(struct smb_ctx *, int, char *[], int, int, int);
void smb_ctx_done(struct smb_ctx *);
int smb_ctx_parseunc(struct smb_ctx *, const char *, int, const char **);
int smb_ctx_setcharset(struct smb_ctx *, const char *);
int smb_ctx_setserver(struct smb_ctx *, const char *);
int smb_ctx_setuser(struct smb_ctx *, const char *);
int smb_ctx_setshare(struct smb_ctx *, const char *, int);
int smb_ctx_setscope(struct smb_ctx *, const char *);
int smb_ctx_setworkgroup(struct smb_ctx *, const char *);
int smb_ctx_setpassword(struct smb_ctx *, const char *);
int smb_ctx_setsrvaddr(struct smb_ctx *, const char *);
int smb_ctx_opt(struct smb_ctx *, int, const char *);
int smb_ctx_lookup(struct smb_ctx *, int, int);
int smb_ctx_login(struct smb_ctx *);
int smb_ctx_readrc(struct smb_ctx *);
int smb_ctx_resolve(struct smb_ctx *);
int smb_ctx_setflags(struct smb_ctx *, int, int, int);
int smb_smb_open_print_file(struct smb_ctx *, int, int, const char *, smbfh*);
int smb_smb_close_print_file(struct smb_ctx *, smbfh);
int smb_read(struct smb_ctx *, smbfh, off_t, size_t, char *);
int smb_write(struct smb_ctx *, smbfh, off_t, size_t, const char *);
#define smb_rq_getrequest(rqp) (&(rqp)->rq_rq)
#define smb_rq_getreply(rqp) (&(rqp)->rq_rp)
int smb_rq_init(struct smb_ctx *, u_char, size_t, struct smb_rq **);
void smb_rq_done(struct smb_rq *);
void smb_rq_wend(struct smb_rq *);
int smb_rq_simple(struct smb_rq *);
int smb_rq_dmem(struct mbdata *, const char *, size_t);
int smb_rq_dstring(struct mbdata *, const char *);
int smb_t2_request(struct smb_ctx *, int, int, const char *,
int, void *, int, void *, int *, void *, int *, void *);
void smb_simplecrypt(char *dst, const char *src);
int smb_simpledecrypt(char *dst, const char *src);
int m_getm(struct mbuf *, size_t, struct mbuf **);
int m_lineup(struct mbuf *, struct mbuf **);
int mb_init(struct mbdata *, size_t);
int mb_initm(struct mbdata *, struct mbuf *);
int mb_done(struct mbdata *);
int mb_fit(struct mbdata *mbp, size_t size, char **pp);
int mb_put_uint8(struct mbdata *, u_int8_t);
int mb_put_uint16be(struct mbdata *, u_int16_t);
int mb_put_uint16le(struct mbdata *, u_int16_t);
int mb_put_uint32be(struct mbdata *, u_int32_t);
int mb_put_uint32le(struct mbdata *, u_int32_t);
int mb_put_int64be(struct mbdata *, int64_t);
int mb_put_int64le(struct mbdata *, int64_t);
int mb_put_mem(struct mbdata *, const char *, size_t);
int mb_put_pstring(struct mbdata *mbp, const char *s);
int mb_put_mbuf(struct mbdata *, struct mbuf *);
int mb_get_uint8(struct mbdata *, u_int8_t *);
int mb_get_uint16(struct mbdata *, u_int16_t *);
int mb_get_uint16le(struct mbdata *, u_int16_t *);
int mb_get_uint16be(struct mbdata *, u_int16_t *);
int mb_get_uint32(struct mbdata *, u_int32_t *);
int mb_get_uint32be(struct mbdata *, u_int32_t *);
int mb_get_uint32le(struct mbdata *, u_int32_t *);
int mb_get_int64(struct mbdata *, int64_t *);
int mb_get_int64be(struct mbdata *, int64_t *);
int mb_get_int64le(struct mbdata *, int64_t *);
int mb_get_mem(struct mbdata *, char *, size_t);
extern u_char nls_lower[256], nls_upper[256];
int nls_setrecode(const char *, const char *);
int nls_setlocale(const char *);
char* nls_str_toext(char *, const char *);
char* nls_str_toloc(char *, const char *);
void* nls_mem_toext(void *, const void *, int);
void* nls_mem_toloc(void *, const void *, int);
char* nls_str_upper(char *, const char *);
char* nls_str_lower(char *, const char *);
__END_DECLS
#endif /* _NETSMB_SMB_LIB_H_ */

View file

@ -0,0 +1,74 @@
/*
* Copyright (c) 2000-2001, Boris Popov
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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.
*
* $Id: smb_rap.h,v 1.3 2001/04/10 05:37:22 bp Exp $
*/
#ifndef _NETSMB_SMB_RAP_H_
#define _NETSMB_SMB_RAP_H_
struct smb_rap {
char * r_sparam;
char * r_nparam;
char * r_sdata;
char * r_ndata;
char * r_pbuf; /* rq parameters */
int r_plen; /* rq param len */
char * r_npbuf;
char * r_dbuf; /* rq data */
int r_dlen; /* rq data len */
char * r_ndbuf;
u_int32_t r_result;
char * r_rcvbuf;
int r_rcvbuflen;
int r_entries;
};
struct smb_share_info_1 {
char shi1_netname[13];
char shi1_pad;
u_int16_t shi1_type;
u_int32_t shi1_remark; /* char * */
};
__BEGIN_DECLS
int smb_rap_create(int, const char *, const char *, struct smb_rap **);
void smb_rap_done(struct smb_rap *);
int smb_rap_request(struct smb_rap *, struct smb_ctx *);
int smb_rap_setNparam(struct smb_rap *, long);
int smb_rap_setPparam(struct smb_rap *, void *);
int smb_rap_error(struct smb_rap *, int);
int smb_rap_NetShareEnum(struct smb_ctx *, int, void *, int, int *, int *);
__END_DECLS
#endif /* _NETSMB_SMB_RAP_H_ */

View file

@ -0,0 +1,21 @@
# $Id: Makefile,v 1.5 2001/02/24 15:56:04 bp Exp $
.ifmake !clean && !cleandepend
.include "../config.int"
.endif
#.if defined(COMPLETEBUILD) || !exists(/usr/lib/libnls.a)
#SUBDIR+= nls
#.endif
#.if defined(COMPLETEBUILD) || !exists(/usr/lib/libnb.a)
#SUBDIR+= nb
#.endif
.if defined(COMPLETEBUILD) || !exists(/usr/lib/libsmb.a)
SUBDIR+= smb
.endif
deinstall install-lib deinstall-lib install-src deinstall-src: _SUBDIRUSE
.include <bsd.subdir.mk>

View file

@ -0,0 +1,18 @@
#
CFLAGS+= -I${.CURDIR}/../../include
CFLAGS+= -I${.CURDIR}/../../kernel/mysys
CFLAGS+= -Wall ${BPCFLAGS}
.if !exists(${SYSDIR}/netsmb/smb.h)
CFLAGS+= -I${.CURDIR}/../../kernel
.endif
.if defined(SMBGDB)
CFLAGS+= -ggdb
.endif
CLEANFILES+=.depend
deinstall: deinstall-lib deinstall-src

View file

@ -0,0 +1,50 @@
# $Id: Makefile,v 1.12 2001/04/16 14:27:35 bp Exp $
LIB= smb
NOPROFILE= yes
#SHLIB_MAJOR= 1
#SHLIB_MINOR= 0
NOMAN=
SRCS= rcfile.c ctx.c cfopt.c subr.c nls.c rap.c mbuf.c rq.c file.c \
print.c \
kiconv.c \
nb.c nb_name.c nb_net.c nbns_rq.c
.ifmake !clean && !cleandepend
.if !defined(PREFIX)
.include "../../config.int"
.endif
.endif
DESTDIR=${PREFIX}/
LIBDIR=lib
.if !defined(USE_SHAREDLIBS)
NOPIC= yes
.endif
install-src: install-lib
deinstall-src: deinstall-lib
.include <bsd.lib.mk>
install-lib: afterinstall _SUBDIR
.if !defined(NOMAN)
afterinstall: realinstall maninstall
.else
afterinstall: realinstall
.endif
deinstall-lib:
rm -f ${DESTDIR}/${LIBDIR}/lib${LIB}.a
.if defined(SHLIB_NAME)
rm -f ${DESTDIR}/${SHLIBDIR}/${SHLIB_NAME}
.endif
.if defined(SHLIB_LINK)
rm -f ${DESTDIR}/${SHLIBDIR}/${SHLIB_LINK}
.endif

View file

@ -0,0 +1,123 @@
/*
* Copyright (c) 2000, Boris Popov
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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.
*
* $Id: cfopt.c,v 1.3 2000/07/11 01:51:49 bp Exp $
*/
#include <sys/param.h>
#include <stdio.h>
#include <string.h>
#include <cflib.h>
extern char *__progname;
int cf_opterr = 1, /* if error message should be printed */
cf_optind = 1, /* index into parent argv vector */
cf_optopt, /* character checked for validity */
cf_optreset; /* reset getopt */
const char* cf_optarg; /* argument associated with option */
#define BADCH (int)'?'
#define BADARG (int)':'
#define EMSG ""
int
cf_getopt(nargc, nargv, ostr)
int nargc;
char * const *nargv;
const char *ostr;
{
static const char *place = EMSG; /* option letter processing */
char *oli; /* option letter list index */
int tmpind;
if (cf_optreset || !*place) { /* update scanning pointer */
cf_optreset = 0;
tmpind = cf_optind;
while (1) {
if (tmpind >= nargc) {
place = EMSG;
return (-1);
}
if (*(place = nargv[tmpind]) != '-') {
tmpind++;
continue; /* lookup next option */
}
if (place[1] && *++place == '-') { /* found "--" */
cf_optind = ++tmpind;
place = EMSG;
return (-1);
}
cf_optind = tmpind;
break;
}
} /* option letter okay? */
if ((cf_optopt = (int)*place++) == (int)':' ||
!(oli = strchr(ostr, cf_optopt))) {
/*
* if the user didn't specify '-' as an option,
* assume it means -1.
*/
if (cf_optopt == (int)'-')
return (-1);
if (!*place)
++cf_optind;
if (cf_opterr && *ostr != ':')
(void)fprintf(stderr,
"%s: illegal option -- %c\n", __progname, cf_optopt);
return (BADCH);
}
if (*++oli != ':') { /* don't need argument */
cf_optarg = NULL;
if (!*place)
++cf_optind;
}
else { /* need an argument */
if (*place) /* no white space */
cf_optarg = place;
else if (nargc <= ++cf_optind) { /* no arg */
place = EMSG;
if (*ostr == ':')
return (BADARG);
if (cf_opterr)
(void)fprintf(stderr,
"%s: option requires an argument -- %c\n",
__progname, cf_optopt);
return (BADCH);
}
else /* white space */
cf_optarg = nargv[cf_optind];
place = EMSG;
++cf_optind;
}
return (cf_optopt); /* dump back option letter */
}

773
contrib/smbfs/lib/smb/ctx.c Normal file
View file

@ -0,0 +1,773 @@
/*
* Copyright (c) 2000, Boris Popov
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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.
*
* $Id: ctx.c,v 1.21 2001/04/06 15:47:14 bp Exp $
*/
#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/mount.h>
#include <fcntl.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pwd.h>
#include <grp.h>
#include <unistd.h>
#include <sys/iconv.h>
#define NB_NEEDRESOLVER
#include <netsmb/smb_lib.h>
#include <netsmb/netbios.h>
#include <netsmb/nb_lib.h>
#include <netsmb/smb_conn.h>
#include <cflib.h>
/*
* Prescan command line for [-U user] argument
* and fill context with defaults
*/
int
smb_ctx_init(struct smb_ctx *ctx, int argc, char *argv[],
int minlevel, int maxlevel, int sharetype)
{
int opt, error = 0;
const char *arg, *cp;
bzero(ctx,sizeof(*ctx));
error = nb_ctx_create(&ctx->ct_nb);
if (error)
return error;
ctx->ct_fd = -1;
ctx->ct_parsedlevel = SMBL_NONE;
ctx->ct_minlevel = minlevel;
ctx->ct_maxlevel = maxlevel;
ctx->ct_ssn.ioc_opt = SMBVOPT_CREATE;
ctx->ct_ssn.ioc_timeout = 15;
ctx->ct_ssn.ioc_retrycount = 4;
ctx->ct_ssn.ioc_owner = SMBM_ANY_OWNER;
ctx->ct_ssn.ioc_group = SMBM_ANY_GROUP;
ctx->ct_ssn.ioc_mode = SMBM_EXEC;
ctx->ct_ssn.ioc_rights = SMBM_DEFAULT;
ctx->ct_sh.ioc_opt = SMBVOPT_CREATE;
ctx->ct_sh.ioc_owner = SMBM_ANY_OWNER;
ctx->ct_sh.ioc_group = SMBM_ANY_GROUP;
ctx->ct_sh.ioc_mode = SMBM_EXEC;
ctx->ct_sh.ioc_rights = SMBM_DEFAULT;
ctx->ct_sh.ioc_owner = SMBM_ANY_OWNER;
ctx->ct_sh.ioc_group = SMBM_ANY_GROUP;
nb_ctx_setscope(ctx->ct_nb, "");
smb_ctx_setuser(ctx, getpwuid(geteuid())->pw_name);
endpwent();
if (argv == NULL)
return 0;
for (opt = 1; opt < argc; opt++) {
cp = argv[opt];
if (strncmp(cp, "//", 2) != 0)
continue;
error = smb_ctx_parseunc(ctx, cp, sharetype, (const char**)&cp);
if (error)
return error;
ctx->ct_uncnext = cp;
break;
}
while (error == 0 && (opt = cf_getopt(argc, argv, ":E:L:U:")) != -1) {
arg = cf_optarg;
switch (opt) {
case 'E':
error = smb_ctx_setcharset(ctx, arg);
if (error)
return error;
break;
case 'L':
error = nls_setlocale(optarg);
if (error)
break;
break;
case 'U':
error = smb_ctx_setuser(ctx, arg);
break;
}
}
cf_optind = cf_optreset = 1;
return error;
}
void
smb_ctx_done(struct smb_ctx *ctx)
{
if (ctx->ct_ssn.ioc_server)
nb_snbfree(ctx->ct_ssn.ioc_server);
if (ctx->ct_ssn.ioc_local)
nb_snbfree(ctx->ct_ssn.ioc_local);
if (ctx->ct_srvaddr)
free(ctx->ct_srvaddr);
if (ctx->ct_nb)
nb_ctx_done(ctx->ct_nb);
}
static int
getsubstring(const char *p, u_char sep, char *dest, int maxlen, const char **next)
{
int len;
maxlen--;
for (len = 0; len < maxlen && *p != sep; p++, len++, dest++) {
if (*p == 0)
return EINVAL;
*dest = *p;
}
*dest = 0;
*next = *p ? p + 1 : p;
return 0;
}
/*
* Here we expect something like "[proto:]//[user@]host[/share][/path]"
*/
int
smb_ctx_parseunc(struct smb_ctx *ctx, const char *unc, int sharetype,
const char **next)
{
const char *p = unc;
char *p1;
char tmp[1024];
int error ;
ctx->ct_parsedlevel = SMBL_NONE;
if (*p++ != '/' || *p++ != '/') {
smb_error("UNC should start with '//'", 0);
return EINVAL;
}
p1 = tmp;
error = getsubstring(p, '@', p1, sizeof(tmp), &p);
if (!error) {
if (ctx->ct_maxlevel < SMBL_VC) {
smb_error("no user name required", 0);
return EINVAL;
}
if (*p1 == 0) {
smb_error("empty user name", 0);
return EINVAL;
}
error = smb_ctx_setuser(ctx, tmp);
if (error)
return error;
ctx->ct_parsedlevel = SMBL_VC;
}
error = getsubstring(p, '/', p1, sizeof(tmp), &p);
if (error) {
error = getsubstring(p, '\0', p1, sizeof(tmp), &p);
if (error) {
smb_error("no server name found", 0);
return error;
}
}
if (*p1 == 0) {
smb_error("empty server name", 0);
return EINVAL;
}
error = smb_ctx_setserver(ctx, tmp);
if (error)
return error;
if (sharetype == SMB_ST_NONE) {
*next = p;
return 0;
}
if (*p != 0 && ctx->ct_maxlevel < SMBL_SHARE) {
smb_error("no share name required", 0);
return EINVAL;
}
error = getsubstring(p, '/', p1, sizeof(tmp), &p);
if (error) {
error = getsubstring(p, '\0', p1, sizeof(tmp), &p);
if (error) {
smb_error("unexpected end of line", 0);
return error;
}
}
if (*p1 == 0 && ctx->ct_minlevel >= SMBL_SHARE) {
smb_error("empty share name", 0);
return EINVAL;
}
*next = p;
if (*p1 == 0)
return 0;
error = smb_ctx_setshare(ctx, p1, sharetype);
return error;
}
int
smb_ctx_setcharset(struct smb_ctx *ctx, const char *arg)
{
char *cp, *servercs, *localcs;
int cslen = sizeof(ctx->ct_ssn.ioc_localcs);
int scslen, lcslen, error;
cp = strchr(arg, ':');
lcslen = cp ? (cp - arg) : 0;
if (lcslen == 0 || lcslen >= cslen) {
smb_error("invalid local charset specification (%s)", 0, arg);
return EINVAL;
}
scslen = (size_t)strlen(++cp);
if (scslen == 0 || scslen >= cslen) {
smb_error("invalid server charset specification (%s)", 0, arg);
return EINVAL;
}
localcs = memcpy(ctx->ct_ssn.ioc_localcs, arg, lcslen);
localcs[lcslen] = 0;
servercs = strcpy(ctx->ct_ssn.ioc_servercs, cp);
error = nls_setrecode(localcs, servercs);
if (error == 0)
return 0;
smb_error("can't initialize iconv support (%s:%s)",
error, localcs, servercs);
localcs[0] = 0;
servercs[0] = 0;
return error;
}
int
smb_ctx_setserver(struct smb_ctx *ctx, const char *name)
{
if (strlen(name) >= SMB_MAXSRVNAMELEN) {
smb_error("server name '%s' too long", 0, name);
return ENAMETOOLONG;
}
nls_str_upper(ctx->ct_ssn.ioc_srvname, name);
return 0;
}
int
smb_ctx_setuser(struct smb_ctx *ctx, const char *name)
{
if (strlen(name) >= SMB_MAXUSERNAMELEN) {
smb_error("user name '%s' too long", 0, name);
return ENAMETOOLONG;
}
nls_str_upper(ctx->ct_ssn.ioc_user, name);
return 0;
}
int
smb_ctx_setworkgroup(struct smb_ctx *ctx, const char *name)
{
if (strlen(name) >= SMB_MAXUSERNAMELEN) {
smb_error("workgroup name '%s' too long", 0, name);
return ENAMETOOLONG;
}
nls_str_upper(ctx->ct_ssn.ioc_workgroup, name);
return 0;
}
int
smb_ctx_setpassword(struct smb_ctx *ctx, const char *passwd)
{
if (passwd == NULL)
return EINVAL;
if (strlen(passwd) >= SMB_MAXPASSWORDLEN) {
smb_error("password too long", 0);
return ENAMETOOLONG;
}
if (strncmp(passwd, "$$1", 3) == 0)
smb_simpledecrypt(ctx->ct_ssn.ioc_password, passwd);
else
strcpy(ctx->ct_ssn.ioc_password, passwd);
strcpy(ctx->ct_sh.ioc_password, ctx->ct_ssn.ioc_password);
return 0;
}
int
smb_ctx_setshare(struct smb_ctx *ctx, const char *share, int stype)
{
if (strlen(share) >= SMB_MAXSHARENAMELEN) {
smb_error("share name '%s' too long", 0, share);
return ENAMETOOLONG;
}
nls_str_upper(ctx->ct_sh.ioc_share, share);
if (share[0] != 0)
ctx->ct_parsedlevel = SMBL_SHARE;
ctx->ct_sh.ioc_stype = stype;
return 0;
}
int
smb_ctx_setsrvaddr(struct smb_ctx *ctx, const char *addr)
{
if (addr == NULL || addr[0] == 0)
return EINVAL;
if (ctx->ct_srvaddr)
free(ctx->ct_srvaddr);
if ((ctx->ct_srvaddr = strdup(addr)) == NULL)
return ENOMEM;
return 0;
}
static int
smb_parse_owner(char *pair, uid_t *uid, gid_t *gid)
{
struct group *gr;
struct passwd *pw;
char *cp;
cp = strchr(pair, ':');
if (cp) {
*cp++ = '\0';
if (*cp) {
gr = getgrnam(cp);
if (gr) {
*gid = gr->gr_gid;
} else
smb_error("Invalid group name %s, ignored",
0, cp);
}
}
if (*pair) {
pw = getpwnam(pair);
if (pw) {
*uid = pw->pw_uid;
} else
smb_error("Invalid user name %s, ignored", 0, pair);
}
endpwent();
return 0;
}
int
smb_ctx_opt(struct smb_ctx *ctx, int opt, const char *arg)
{
int error = 0;
char *p, *cp;
switch(opt) {
case 'U':
break;
case 'I':
error = smb_ctx_setsrvaddr(ctx, arg);
break;
case 'M':
ctx->ct_ssn.ioc_rights = strtol(arg, &cp, 8);
if (*cp == '/') {
ctx->ct_sh.ioc_rights = strtol(cp + 1, &cp, 8);
ctx->ct_flags |= SMBCF_SRIGHTS;
}
break;
case 'N':
ctx->ct_flags |= SMBCF_NOPWD;
break;
case 'O':
p = strdup(arg);
cp = strchr(p, '/');
if (cp) {
*cp++ = '\0';
error = smb_parse_owner(cp, &ctx->ct_sh.ioc_owner,
&ctx->ct_sh.ioc_group);
}
if (*p && error == 0) {
error = smb_parse_owner(cp, &ctx->ct_ssn.ioc_owner,
&ctx->ct_ssn.ioc_group);
}
free(p);
break;
case 'P':
/* ctx->ct_ssn.ioc_opt |= SMBCOPT_PERMANENT;*/
break;
case 'R':
ctx->ct_ssn.ioc_retrycount = atoi(arg);
break;
case 'T':
ctx->ct_ssn.ioc_timeout = atoi(arg);
break;
case 'W':
error = smb_ctx_setworkgroup(ctx, arg);
break;
}
return error;
}
#if 0
static void
smb_hexdump(const u_char *buf, int len) {
int ofs = 0;
while (len--) {
if (ofs % 16 == 0)
printf("\n%02X: ", ofs);
printf("%02x ", *buf++);
ofs++;
}
printf("\n");
}
#endif
static int
smb_addiconvtbl(const char *to, const char *from, const u_char *tbl)
{
int error;
error = kiconv_add_xlat_table(to, from, tbl);
if (error && error != EEXIST) {
smb_error("can not setup kernel iconv table (%s:%s)", error,
from, to);
return error;
}
return 0;
}
/*
* Verify context before connect operation(s),
* lookup specified server and try to fill all forgotten fields.
*/
int
smb_ctx_resolve(struct smb_ctx *ctx)
{
struct smbioc_ossn *ssn = &ctx->ct_ssn;
struct smbioc_oshare *sh = &ctx->ct_sh;
struct nb_name nn;
struct sockaddr *sap;
struct sockaddr_nb *salocal, *saserver;
char *cp;
u_char cstbl[256];
u_int i;
int error = 0;
ctx->ct_flags &= ~SMBCF_RESOLVED;
if (ssn->ioc_srvname[0] == 0) {
smb_error("no server name specified", 0);
return EINVAL;
}
if (ssn->ioc_user[0] == 0) {
smb_error("no user name specified for server %s",
0, ssn->ioc_srvname);
return EINVAL;
}
if (ctx->ct_minlevel >= SMBL_SHARE && sh->ioc_share[0] == 0) {
smb_error("no share name specified for %s@%s",
0, ssn->ioc_user, ssn->ioc_srvname);
return EINVAL;
}
error = nb_ctx_resolve(ctx->ct_nb);
if (error)
return error;
if (ssn->ioc_localcs[0] == 0)
strcpy(ssn->ioc_localcs, "default"); /* XXX: locale name ? */
error = smb_addiconvtbl("tolower", ssn->ioc_localcs, nls_lower);
if (error)
return error;
error = smb_addiconvtbl("toupper", ssn->ioc_localcs, nls_upper);
if (error)
return error;
if (ssn->ioc_servercs[0] != 0) {
for(i = 0; i < sizeof(cstbl); i++)
cstbl[i] = i;
nls_mem_toext(cstbl, cstbl, sizeof(cstbl));
error = smb_addiconvtbl(ssn->ioc_servercs, ssn->ioc_localcs, cstbl);
if (error)
return error;
for(i = 0; i < sizeof(cstbl); i++)
cstbl[i] = i;
nls_mem_toloc(cstbl, cstbl, sizeof(cstbl));
error = smb_addiconvtbl(ssn->ioc_localcs, ssn->ioc_servercs, cstbl);
if (error)
return error;
}
if (ctx->ct_srvaddr) {
error = nb_resolvehost_in(ctx->ct_srvaddr, &sap);
} else {
error = nbns_resolvename(ssn->ioc_srvname, ctx->ct_nb, &sap);
}
if (error) {
smb_error("can't get server address", error);
return error;
}
nn.nn_scope = ctx->ct_nb->nb_scope;
nn.nn_type = NBT_SERVER;
strcpy(nn.nn_name, ssn->ioc_srvname);
error = nb_sockaddr(sap, &nn, &saserver);
nb_snbfree(sap);
if (error) {
smb_error("can't allocate server address", error);
return error;
}
ssn->ioc_server = (struct sockaddr*)saserver;
if (ctx->ct_locname[0] == 0) {
error = nb_getlocalname(ctx->ct_locname);
if (error) {
smb_error("can't get local name", error);
return error;
}
nls_str_upper(ctx->ct_locname, ctx->ct_locname);
}
strcpy(nn.nn_name, ctx->ct_locname);
nn.nn_type = NBT_WKSTA;
nn.nn_scope = ctx->ct_nb->nb_scope;
error = nb_sockaddr(NULL, &nn, &salocal);
if (error) {
nb_snbfree((struct sockaddr*)saserver);
smb_error("can't allocate local address", error);
return error;
}
ssn->ioc_local = (struct sockaddr*)salocal;
ssn->ioc_lolen = salocal->snb_len;
ssn->ioc_svlen = saserver->snb_len;
if (ssn->ioc_password[0] == 0 && (ctx->ct_flags & SMBCF_NOPWD) == 0) {
cp = getpass("Password:");
error = smb_ctx_setpassword(ctx, cp);
if (error)
return error;
}
ctx->ct_flags |= SMBCF_RESOLVED;
return 0;
}
static int
smb_ctx_gethandle(struct smb_ctx *ctx)
{
int fd, i;
char buf[20];
/*
* First try to open as clone
*/
fd = open("/dev/"NSMB_NAME, O_RDWR);
if (fd >= 0) {
ctx->ct_fd = fd;
return 0;
}
/*
* well, no clone capabilities available - we have to scan
* all devices in order to get free one
*/
for (i = 0; i < 1024; i++) {
snprintf(buf, sizeof(buf), "/dev/%s%d", NSMB_NAME, i);
fd = open(buf, O_RDWR);
if (fd >= 0) {
ctx->ct_fd = fd;
return 0;
}
}
/*
* This is a compatibility with old /dev/net/nsmb device
*/
for (i = 0; i < 1024; i++) {
snprintf(buf, sizeof(buf), "/dev/net/%s%d", NSMB_NAME, i);
fd = open(buf, O_RDWR);
if (fd >= 0) {
ctx->ct_fd = fd;
return 0;
}
if (errno == ENOENT)
return ENOENT;
}
return ENOENT;
}
int
smb_ctx_lookup(struct smb_ctx *ctx, int level, int flags)
{
struct smbioc_lookup rq;
int error;
if ((ctx->ct_flags & SMBCF_RESOLVED) == 0) {
smb_error("smb_ctx_lookup() data is not resolved", 0);
return EINVAL;
}
if (ctx->ct_fd != -1) {
close(ctx->ct_fd);
ctx->ct_fd = -1;
}
error = smb_ctx_gethandle(ctx);
if (error) {
smb_error("can't get handle to requester (no /dev/net/nsmb* device)", 0);
return EINVAL;
}
bzero(&rq, sizeof(rq));
bcopy(&ctx->ct_ssn, &rq.ioc_ssn, sizeof(struct smbioc_ossn));
bcopy(&ctx->ct_sh, &rq.ioc_sh, sizeof(struct smbioc_oshare));
rq.ioc_flags = flags;
rq.ioc_level = level;
if (ioctl(ctx->ct_fd, SMBIOC_LOOKUP, &rq) == -1) {
error = errno;
if (flags & SMBLK_CREATE)
smb_error("unable to open connection", error);
return error;
}
return 0;
}
int
smb_ctx_login(struct smb_ctx *ctx)
{
struct smbioc_ossn *ssn = &ctx->ct_ssn;
struct smbioc_oshare *sh = &ctx->ct_sh;
int error;
if ((ctx->ct_flags & SMBCF_RESOLVED) == 0) {
smb_error("smb_ctx_resolve() should be called first", 0);
return EINVAL;
}
if (ctx->ct_fd != -1) {
close(ctx->ct_fd);
ctx->ct_fd = -1;
}
error = smb_ctx_gethandle(ctx);
if (error) {
smb_error("can't get handle to requester", 0);
return EINVAL;
}
if (ioctl(ctx->ct_fd, SMBIOC_OPENSESSION, ssn) == -1) {
error = errno;
smb_error("can't open session to server %s", error, ssn->ioc_srvname);
return error;
}
if (sh->ioc_share[0] == 0)
return 0;
if (ioctl(ctx->ct_fd, SMBIOC_OPENSHARE, sh) == -1) {
error = errno;
smb_error("can't connect to share //%s/%s", error,
ssn->ioc_srvname, sh->ioc_share);
return error;
}
return 0;
}
int
smb_ctx_setflags(struct smb_ctx *ctx, int level, int mask, int flags)
{
struct smbioc_flags fl;
if (ctx->ct_fd == -1)
return EINVAL;
fl.ioc_level = level;
fl.ioc_mask = mask;
fl.ioc_flags = flags;
if (ioctl(ctx->ct_fd, SMBIOC_SETFLAGS, &fl) == -1)
return errno;
return 0;
}
/*
* level values:
* 0 - default
* 1 - server
* 2 - server:user
* 3 - server:user:share
*/
static int
smb_ctx_readrcsection(struct smb_ctx *ctx, const char *sname, int level)
{
char *p;
int error;
if (level > 0) {
rc_getstringptr(smb_rc, sname, "charsets", &p);
if (p) {
error = smb_ctx_setcharset(ctx, p);
if (error)
smb_error("charset specification in the section '%s' ignored", error, sname);
}
}
if (level <= 1) {
rc_getint(smb_rc, sname, "timeout", &ctx->ct_ssn.ioc_timeout);
rc_getint(smb_rc, sname, "retry_count", &ctx->ct_ssn.ioc_retrycount);
}
if (level == 1) {
rc_getstringptr(smb_rc, sname, "addr", &p);
if (p) {
error = smb_ctx_setsrvaddr(ctx, p);
if (error) {
smb_error("invalid address specified in the section %s", 0, sname);
return error;
}
}
}
if (level >= 2) {
rc_getstringptr(smb_rc, sname, "password", &p);
if (p)
smb_ctx_setpassword(ctx, p);
}
rc_getstringptr(smb_rc, sname, "workgroup", &p);
if (p)
smb_ctx_setworkgroup(ctx, p);
return 0;
}
/*
* read rc file as follows:
* 1. read [default] section
* 2. override with [server] section
* 3. override with [server:user:share] section
* Since abcence of rcfile is not fatal, silently ignore this fact.
* smb_rc file should be closed by caller.
*/
int
smb_ctx_readrc(struct smb_ctx *ctx)
{
char sname[SMB_MAXSRVNAMELEN + SMB_MAXUSERNAMELEN + SMB_MAXSHARENAMELEN + 4];
/* char *p;*/
if (smb_open_rcfile() != 0)
return 0;
if (ctx->ct_ssn.ioc_user[0] == 0 || ctx->ct_ssn.ioc_srvname[0] == 0)
return 0;
smb_ctx_readrcsection(ctx, "default", 0);
nb_ctx_readrcsection(smb_rc, ctx->ct_nb, "default", 0);
smb_ctx_readrcsection(ctx, ctx->ct_ssn.ioc_srvname, 1);
nb_ctx_readrcsection(smb_rc, ctx->ct_nb, ctx->ct_ssn.ioc_srvname, 1);
/*
* SERVER:USER parameters
*/
snprintf(sname, sizeof(sname), "%s:%s", ctx->ct_ssn.ioc_srvname,
ctx->ct_ssn.ioc_user);
smb_ctx_readrcsection(ctx, sname, 2);
if (ctx->ct_sh.ioc_share[0] != 0) {
/*
* SERVER:USER:SHARE parameters
*/
snprintf(sname, sizeof(sname), "%s:%s:%s", ctx->ct_ssn.ioc_srvname,
ctx->ct_ssn.ioc_user, ctx->ct_sh.ioc_share);
smb_ctx_readrcsection(ctx, sname, 3);
}
return 0;
}

View file

@ -0,0 +1,80 @@
/*
* Copyright (c) 2000, Boris Popov
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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.
*
* $Id: file.c,v 1.2 2001/04/16 04:33:01 bp Exp $
*/
#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/mount.h>
#include <fcntl.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pwd.h>
#include <grp.h>
#include <unistd.h>
#include <netsmb/smb_lib.h>
#include <netsmb/smb_conn.h>
#include <cflib.h>
int
smb_read(struct smb_ctx *ctx, smbfh fh, off_t offset, size_t count, char *dst)
{
struct smbioc_rw rwrq;
rwrq.ioc_fh = fh;
rwrq.ioc_base = dst;
rwrq.ioc_cnt = count;
rwrq.ioc_offset = offset;
if (ioctl(ctx->ct_fd, SMBIOC_READ, &rwrq) == -1)
return -1;
return rwrq.ioc_cnt;
}
int
smb_write(struct smb_ctx *ctx, smbfh fh, off_t offset, size_t count,
const char *src)
{
struct smbioc_rw rwrq;
rwrq.ioc_fh = fh;
(const char*)rwrq.ioc_base = src;
rwrq.ioc_cnt = count;
rwrq.ioc_offset = offset;
if (ioctl(ctx->ct_fd, SMBIOC_WRITE, &rwrq) == -1)
return -1;
return rwrq.ioc_cnt;
}

View file

@ -0,0 +1,61 @@
/*
* Copyright (c) 2000-2001, Boris Popov
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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.
*
* $Id: kiconv.c,v 1.2 2001/04/16 04:33:01 bp Exp $
*/
#include <sys/types.h>
#include <sys/iconv.h>
#include <sys/sysctl.h>
#include <ctype.h>
#include <errno.h>
int
kiconv_add_xlat_table(const char *to, const char *from, const u_char *table)
{
struct iconv_add_in din;
struct iconv_add_out dout;
int olen;
if (strlen(from) > ICONV_CSNMAXLEN || strlen(to) > ICONV_CSNMAXLEN)
return EINVAL;
din.ia_version = ICONV_ADD_VER;
strcpy(din.ia_converter, "xlat");
strcpy(din.ia_from, from);
strcpy(din.ia_to, to);
din.ia_data = table;
din.ia_datalen = 256;
olen = sizeof(dout);
if (sysctlbyname("kern.iconv.add", &dout, &olen, &din, sizeof(din)) == -1)
return errno;
return 0;
}

View file

@ -0,0 +1,467 @@
/*
* Copyright (c) 2000, Boris Popov
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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.
*
* $Id: mbuf.c,v 1.6 2001/02/24 15:56:04 bp Exp $
*/
#include <sys/types.h>
#include <sys/mchain.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netsmb/smb_lib.h>
#define MBERROR(format, args...) printf("%s(%d): "format, __FUNCTION__ , \
__LINE__ ,## args)
static int
m_get(size_t len, struct mbuf **mpp)
{
struct mbuf *m;
len = M_ALIGN(len);
if (len < M_MINSIZE)
len = M_MINSIZE;
m = malloc(M_BASESIZE + len);
if (m == NULL)
return ENOMEM;
bzero(m, M_BASESIZE + len);
m->m_maxlen = len;
m->m_data = M_TOP(m);
*mpp = m;
return 0;
}
static void
m_free(struct mbuf *m)
{
free(m);
}
static void
m_freem(struct mbuf *m0)
{
struct mbuf *m;
while (m0) {
m = m0->m_next;
m_free(m0);
m0 = m;
}
}
static size_t
m_totlen(struct mbuf *m0)
{
struct mbuf *m = m0;
int len = 0;
while (m) {
len += m->m_len;
m = m->m_next;
}
return len;
}
int
m_lineup(struct mbuf *m0, struct mbuf **mpp)
{
struct mbuf *nm, *m;
char *dp;
size_t len;
int error;
if (m0->m_next == NULL) {
*mpp = m0;
return 0;
}
if ((error = m_get(m_totlen(m0), &nm)) != 0)
return error;
dp = mtod(nm, char *);
while (m0) {
len = m0->m_len;
bcopy(m0->m_data, dp, len);
dp += len;
m = m0->m_next;
m_free(m0);
m0 = m;
}
*mpp = nm;
return 0;
}
int
mb_init(struct mbdata *mbp, size_t size)
{
struct mbuf *m;
int error;
if ((error = m_get(size, &m)) != 0)
return error;
return mb_initm(mbp, m);
}
int
mb_initm(struct mbdata *mbp, struct mbuf *m)
{
bzero(mbp, sizeof(*mbp));
mbp->mb_top = mbp->mb_cur = m;
mbp->mb_pos = mtod(m, char *);
return 0;
}
int
mb_done(struct mbdata *mbp)
{
if (mbp->mb_top) {
m_freem(mbp->mb_top);
mbp->mb_top = NULL;
}
return 0;
}
/*
int
mb_fixhdr(struct mbdata *mbp)
{
struct mbuf *m = mbp->mb_top;
int len = 0;
while (m) {
len += m->m_len;
m = m->m_next;
}
mbp->mb_top->m_pkthdr.len = len;
return len;
}
*/
int
m_getm(struct mbuf *top, size_t len, struct mbuf **mpp)
{
struct mbuf *m, *mp;
int error;
for (mp = top; ; mp = mp->m_next) {
len -= M_TRAILINGSPACE(mp);
if (mp->m_next == NULL)
break;
}
if (len > 0) {
if ((error = m_get(len, &m)) != 0)
return error;
mp->m_next = m;
}
*mpp = top;
return 0;
}
/*
* Routines to put data in a buffer
*/
#define MB_PUT(t) int error; t *p; \
if ((error = mb_fit(mbp, sizeof(t), (char**)&p)) != 0) \
return error
/*
* Check if object of size 'size' fit to the current position and
* allocate new mbuf if not. Advance pointers and increase length of mbuf(s).
* Return pointer to the object placeholder or NULL if any error occured.
*/
int
mb_fit(struct mbdata *mbp, size_t size, char **pp)
{
struct mbuf *m, *mn;
int error;
m = mbp->mb_cur;
if (M_TRAILINGSPACE(m) < (int)size) {
if ((error = m_get(size, &mn)) != 0)
return error;
mbp->mb_pos = mtod(mn, char *);
mbp->mb_cur = m->m_next = mn;
m = mn;
}
m->m_len += size;
*pp = mbp->mb_pos;
mbp->mb_pos += size;
mbp->mb_count += size;
return 0;
}
int
mb_put_uint8(struct mbdata *mbp, u_int8_t x)
{
MB_PUT(u_int8_t);
*p = x;
return 0;
}
int
mb_put_uint16be(struct mbdata *mbp, u_int16_t x)
{
MB_PUT(u_int16_t);
setwbe(p, 0, x);
return 0;
}
int
mb_put_uint16le(struct mbdata *mbp, u_int16_t x)
{
MB_PUT(u_int16_t);
setwle(p, 0, x);
return 0;
}
int
mb_put_uint32be(struct mbdata *mbp, u_int32_t x)
{
MB_PUT(u_int32_t);
setdbe(p, 0, x);
return 0;
}
int
mb_put_uint32le(struct mbdata *mbp, u_int32_t x)
{
MB_PUT(u_int32_t);
setdle(p, 0, x);
return 0;
}
int
mb_put_int64be(struct mbdata *mbp, int64_t x)
{
MB_PUT(int64_t);
*p = htobeq(x);
return 0;
}
int
mb_put_int64le(struct mbdata *mbp, int64_t x)
{
MB_PUT(int64_t);
*p = htoleq(x);
return 0;
}
int
mb_put_mem(struct mbdata *mbp, const char *source, size_t size)
{
struct mbuf *m;
char * dst;
size_t cplen;
int error;
if (size == 0)
return 0;
m = mbp->mb_cur;
if ((error = m_getm(m, size, &m)) != 0)
return error;
while (size > 0) {
cplen = M_TRAILINGSPACE(m);
if (cplen == 0) {
m = m->m_next;
continue;
}
if (cplen > size)
cplen = size;
dst = mtod(m, char *) + m->m_len;
if (source) {
bcopy(source, dst, cplen);
source += cplen;
} else
bzero(dst, cplen);
size -= cplen;
m->m_len += cplen;
mbp->mb_count += cplen;
}
mbp->mb_pos = mtod(m, char *) + m->m_len;
mbp->mb_cur = m;
return 0;
}
int
mb_put_mbuf(struct mbdata *mbp, struct mbuf *m)
{
mbp->mb_cur->m_next = m;
while (m) {
mbp->mb_count += m->m_len;
if (m->m_next == NULL)
break;
m = m->m_next;
}
mbp->mb_pos = mtod(m, char *) + m->m_len;
mbp->mb_cur = m;
return 0;
}
int
mb_put_pstring(struct mbdata *mbp, const char *s)
{
int error, len = strlen(s);
if (len > 255) {
len = 255;
}
if ((error = mb_put_uint8(mbp, len)) != 0)
return error;
return mb_put_mem(mbp, s, len);
}
/*
* Routines for fetching data from an mbuf chain
*/
#define mb_left(m,p) (mtod(m, char *) + (m)->m_len - (p))
int
mb_get_uint8(struct mbdata *mbp, u_int8_t *x)
{
return mb_get_mem(mbp, x, 1);
}
int
mb_get_uint16(struct mbdata *mbp, u_int16_t *x)
{
return mb_get_mem(mbp, (char *)x, 2);
}
int
mb_get_uint16le(struct mbdata *mbp, u_int16_t *x)
{
u_int16_t v;
int error = mb_get_uint16(mbp, &v);
*x = letohs(v);
return error;
}
int
mb_get_uint16be(struct mbdata *mbp, u_int16_t *x) {
u_int16_t v;
int error = mb_get_uint16(mbp, &v);
*x = betohs(v);
return error;
}
int
mb_get_uint32(struct mbdata *mbp, u_int32_t *x)
{
return mb_get_mem(mbp, (char *)x, 4);
}
int
mb_get_uint32be(struct mbdata *mbp, u_int32_t *x)
{
u_int32_t v;
int error;
error = mb_get_uint32(mbp, &v);
*x = betohl(v);
return error;
}
int
mb_get_uint32le(struct mbdata *mbp, u_int32_t *x)
{
u_int32_t v;
int error;
error = mb_get_uint32(mbp, &v);
*x = letohl(v);
return error;
}
int
mb_get_int64(struct mbdata *mbp, int64_t *x)
{
return mb_get_mem(mbp, (char *)x, 8);
}
int
mb_get_int64be(struct mbdata *mbp, int64_t *x)
{
int64_t v;
int error;
error = mb_get_int64(mbp, &v);
*x = betohq(v);
return error;
}
int
mb_get_int64le(struct mbdata *mbp, int64_t *x)
{
int64_t v;
int error;
error = mb_get_int64(mbp, &v);
*x = letohq(v);
return error;
}
int
mb_get_mem(struct mbdata *mbp, char * target, size_t size)
{
struct mbuf *m = mbp->mb_cur;
u_int count;
while (size > 0) {
if (m == NULL) {
MBERROR("incomplete copy\n");
return EBADRPC;
}
count = mb_left(m, mbp->mb_pos);
if (count == 0) {
mbp->mb_cur = m = m->m_next;
if (m)
mbp->mb_pos = mtod(m, char *);
continue;
}
if (count > size)
count = size;
size -= count;
if (target) {
if (count == 1) {
*target++ = *mbp->mb_pos;
} else {
bcopy(mbp->mb_pos, target, count);
target += count;
}
}
mbp->mb_pos += count;
}
return 0;
}

191
contrib/smbfs/lib/smb/nb.c Normal file
View file

@ -0,0 +1,191 @@
/*
* Copyright (c) 2000, 2001 Boris Popov
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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.
*
* $Id: nb.c,v 1.4 2001/04/16 04:33:01 bp Exp $
*/
#include <sys/param.h>
#include <sys/socket.h>
#include <ctype.h>
#include <netdb.h>
#include <err.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <cflib.h>
#include <netsmb/netbios.h>
#include <netsmb/smb_lib.h>
#include <netsmb/nb_lib.h>
int
nb_ctx_create(struct nb_ctx **ctxpp)
{
struct nb_ctx *ctx;
ctx = malloc(sizeof(struct nb_ctx));
if (ctx == NULL)
return ENOMEM;
bzero(ctx, sizeof(struct nb_ctx));
*ctxpp = ctx;
return 0;
}
void
nb_ctx_done(struct nb_ctx *ctx)
{
if (ctx == NULL)
return;
if (ctx->nb_scope)
free(ctx->nb_scope);
}
int
nb_ctx_setns(struct nb_ctx *ctx, const char *addr)
{
if (addr == NULL || addr[0] == 0)
return EINVAL;
if (ctx->nb_nsname)
free(ctx->nb_nsname);
if ((ctx->nb_nsname = strdup(addr)) == NULL)
return ENOMEM;
return 0;
}
int
nb_ctx_setscope(struct nb_ctx *ctx, const char *scope)
{
size_t slen = strlen(scope);
if (slen >= 128) {
smb_error("scope '%s' is too long", 0, scope);
return ENAMETOOLONG;
}
if (ctx->nb_scope)
free(ctx->nb_scope);
ctx->nb_scope = malloc(slen + 1);
if (ctx->nb_scope == NULL)
return ENOMEM;
nls_str_upper(ctx->nb_scope, scope);
return 0;
}
int
nb_ctx_resolve(struct nb_ctx *ctx)
{
struct sockaddr *sap;
int error;
ctx->nb_flags &= ~NBCF_RESOLVED;
if (ctx->nb_nsname == NULL) {
ctx->nb_ns.sin_addr.s_addr = htonl(INADDR_BROADCAST);
} else {
error = nb_resolvehost_in(ctx->nb_nsname, &sap);
if (error) {
smb_error("can't resolve %s", error, ctx->nb_nsname);
return error;
}
if (sap->sa_family != AF_INET) {
smb_error("unsupported address family %d", 0, sap->sa_family);
return EINVAL;
}
bcopy(sap, &ctx->nb_ns, sizeof(ctx->nb_ns));
free(sap);
}
ctx->nb_ns.sin_port = htons(137);
ctx->nb_ns.sin_family = AF_INET;
ctx->nb_ns.sin_len = sizeof(ctx->nb_ns);
ctx->nb_flags |= NBCF_RESOLVED;
return 0;
}
/*
* used level values:
* 0 - default
* 1 - server
*/
int
nb_ctx_readrcsection(struct rcfile *rcfile, struct nb_ctx *ctx,
const char *sname, int level)
{
char *p;
int error;
if (level > 1)
return EINVAL;
rc_getint(rcfile, sname, "nbtimeout", &ctx->nb_timo);
rc_getstringptr(rcfile, sname, "nbns", &p);
if (p) {
error = nb_ctx_setns(ctx, p);
if (error) {
smb_error("invalid address specified in the section %s", 0, sname);
return error;
}
}
rc_getstringptr(rcfile, sname, "nbscope", &p);
if (p)
nb_ctx_setscope(ctx, p);
return 0;
}
static const char *nb_err_rcode[] = {
"bad request/response format",
"NBNS server failure",
"no such name",
"unsupported request",
"request rejected",
"name already registered"
};
static const char *nb_err[] = {
"host not found",
"too many redirects",
"invalid response",
"NETBIOS name too long",
"no interface to broadcast on and no NBNS server specified"
};
const char *
nb_strerror(int error)
{
if (error == 0)
return NULL;
if (error <= NBERR_ACTIVE)
return nb_err_rcode[error - 1];
else if (error >= NBERR_HOSTNOTFOUND && error < NBERR_MAX)
return nb_err[error - NBERR_HOSTNOTFOUND];
else
return NULL;
}

View file

@ -0,0 +1,198 @@
/*
* Copyright (c) 2000, Boris Popov
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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.
*
* $Id: nb_name.c,v 1.1 2000/07/16 01:52:07 bp Exp $
*/
#include <sys/param.h>
#include <sys/socket.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netsmb/netbios.h>
#include <netsmb/smb_lib.h>
#include <netsmb/nb_lib.h>
int
nb_snballoc(int namelen, struct sockaddr_nb **dst)
{
struct sockaddr_nb *snb;
int slen;
slen = namelen + sizeof(*snb) - sizeof(snb->snb_name);
snb = malloc(slen);
if (snb == NULL)
return ENOMEM;
bzero(snb, slen);
snb->snb_family = AF_NETBIOS;
snb->snb_len = slen;
*dst = snb;
return 0;
}
void
nb_snbfree(struct sockaddr *snb)
{
free(snb);
}
/*
* Create a full NETBIOS address
*/
int
nb_sockaddr(struct sockaddr *peer, struct nb_name *np,
struct sockaddr_nb **dst)
{
struct sockaddr_nb *snb;
int nmlen, error;
if (peer && (peer->sa_family != AF_INET && peer->sa_family != AF_IPX))
return EPROTONOSUPPORT;
nmlen = nb_name_len(np);
if (nmlen < NB_ENCNAMELEN)
return EINVAL;
error = nb_snballoc(nmlen, &snb);
if (error)
return error;
if (nmlen != nb_name_encode(np, snb->snb_name))
printf("a bug somewhere in the nb_name* code\n");
if (peer)
memcpy(&snb->snb_tran, peer, peer->sa_len);
*dst = snb;
return 0;
}
int
nb_name_len(struct nb_name *np)
{
u_char *name;
int len, sclen;
len = 1 + NB_ENCNAMELEN;
if (np->nn_scope == NULL)
return len + 1;
sclen = 0;
for (name = np->nn_scope; *name; name++) {
if (*name == '.') {
sclen = 0;
} else {
if (sclen < NB_MAXLABLEN) {
sclen++;
len++;
}
}
}
return len + 1;
}
int
nb_encname_len(const char *str)
{
const u_char *cp = (const u_char *)str;
int len, blen;
if ((cp[0] & 0xc0) == 0xc0)
return -1; /* first two bytes are offset to name */
len = 1;
for (;;) {
blen = *cp;
if (blen++ == 0)
break;
len += blen;
cp += blen;
}
return len;
}
#define NBENCODE(c) ((u_short)(((u_char)(c) >> 4) | \
(((u_char)(c) & 0xf) << 8)) + 0x4141)
static void
memsetw(char *dst, int n, u_short word)
{
while (n--) {
*(u_short*)dst = word;
dst += 2;
}
}
int
nb_name_encode(struct nb_name *np, u_char *dst)
{
u_char *name, *plen;
u_char *cp = dst;
int i, lblen;
*cp++ = NB_ENCNAMELEN;
name = np->nn_name;
if (name[0] == '*' && name[1] == 0) {
*(u_short*)cp = NBENCODE('*');
memsetw(cp + 2, NB_NAMELEN - 1, NBENCODE(' '));
cp += NB_ENCNAMELEN;
} else {
for (i = 0; *name && i < NB_NAMELEN; i++, cp += 2, name++)
*(u_short*)cp = NBENCODE(toupper(*name));
i = NB_NAMELEN - i - 1;
if (i > 0) {
memsetw(cp, i, NBENCODE(' '));
cp += i * 2;
}
*(u_short*)cp = NBENCODE(np->nn_type);
cp += 2;
}
*cp = 0;
if (np->nn_scope == NULL)
return nb_encname_len(dst);
plen = cp++;
lblen = 0;
for (name = np->nn_scope; ; name++) {
if (*name == '.' || *name == 0) {
*plen = lblen;
plen = cp++;
*plen = 0;
if (*name == 0)
break;
} else {
if (lblen < NB_MAXLABLEN) {
*cp++ = *name;
lblen++;
}
}
}
return nb_encname_len(dst);
}

View file

@ -0,0 +1,201 @@
/*
* Copyright (c) 2000, Boris Popov
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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.
*
* $Id: nb_net.c,v 1.4 2001/02/16 02:46:12 bp Exp $
*/
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <ctype.h>
#include <netdb.h>
#include <err.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <netsmb/netbios.h>
#include <netsmb/smb_lib.h>
#include <netsmb/nb_lib.h>
int
nb_getlocalname(char *name)
{
char buf[1024], *cp;
if (gethostname(buf, sizeof(buf)) != 0)
return errno;
cp = strchr(buf, '.');
if (cp)
*cp = 0;
strcpy(name, buf);
return 0;
}
int
nb_resolvehost_in(const char *name, struct sockaddr **dest)
{
struct hostent* h;
struct sockaddr_in *sinp;
int len;
h = gethostbyname(name);
if (!h) {
warnx("can't get server address `%s': ", name);
herror(NULL);
return ENETDOWN;
}
if (h->h_addrtype != AF_INET) {
warnx("address for `%s' is not in the AF_INET family", name);
return EAFNOSUPPORT;
}
if (h->h_length != 4) {
warnx("address for `%s' has invalid length", name);
return EAFNOSUPPORT;
}
len = sizeof(struct sockaddr_in);
sinp = malloc(len);
if (sinp == NULL)
return ENOMEM;
bzero(sinp, len);
sinp->sin_len = len;
sinp->sin_family = h->h_addrtype;
memcpy(&sinp->sin_addr.s_addr, h->h_addr, 4);
sinp->sin_port = htons(SMB_TCP_PORT);
*dest = (struct sockaddr*)sinp;
return 0;
}
int
nb_enum_if(struct nb_ifdesc **iflist, int maxif)
{
struct ifconf ifc;
struct ifreq *ifrqp;
struct nb_ifdesc *ifd;
struct in_addr iaddr, imask;
char *ifrdata, *iname;
int s, rdlen, ifcnt, error, iflags, i;
*iflist = NULL;
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s == -1)
return errno;
rdlen = maxif * sizeof(struct ifreq);
ifrdata = malloc(rdlen);
if (ifrdata == NULL) {
error = ENOMEM;
goto bad;
}
ifc.ifc_len = rdlen;
ifc.ifc_buf = ifrdata;
if (ioctl(s, SIOCGIFCONF, &ifc) != 0) {
error = errno;
goto bad;
}
ifrqp = ifc.ifc_req;
ifcnt = ifc.ifc_len / sizeof(struct ifreq);
error = 0;
for (i = 0; i < ifcnt; i++, ifrqp++) {
if (ioctl(s, SIOCGIFFLAGS, ifrqp) != 0)
continue;
iflags = ifrqp->ifr_flags;
if ((iflags & IFF_UP) == 0 || (iflags & IFF_BROADCAST) == 0)
continue;
if (ioctl(s, SIOCGIFADDR, ifrqp) != 0 ||
ifrqp->ifr_addr.sa_family != AF_INET)
continue;
iname = ifrqp->ifr_name;
if (strlen(iname) >= sizeof(ifd->id_name))
continue;
iaddr = (*(struct sockaddr_in *)&ifrqp->ifr_addr).sin_addr;
if (ioctl(s, SIOCGIFNETMASK, ifrqp) != 0)
continue;
imask = ((struct sockaddr_in *)&ifrqp->ifr_addr)->sin_addr;
ifd = malloc(sizeof(struct nb_ifdesc));
if (ifd == NULL)
return ENOMEM;
bzero(ifd, sizeof(struct nb_ifdesc));
strcpy(ifd->id_name, iname);
ifd->id_flags = iflags;
ifd->id_addr = iaddr;
ifd->id_mask = imask;
ifd->id_next = *iflist;
*iflist = ifd;
}
bad:
free(ifrdata);
close(s);
return error;
}
/*ARGSUSED*/
/*int
nbns_resolvename(const char *name, struct sockaddr **dest)
{
printf("NetBIOS name resolver is not included in this distribution.\n");
printf("Please use '-I' option to specify an IP address of server.\n");
return EHOSTUNREACH;
}*/
/*
int
nb_hostlookup(struct nb_name *np, const char *server, const char *hint,
struct sockaddr_nb **dst)
{
struct sockaddr_nb *snb;
int error;
error = nb_sockaddr(NULL, np, &snb);
if (error)
return error;
do {
if (hint) {
error = nb_resolvehost_in(host, snb);
if (error)
break;
} else {
error = nb_resolvename(server);
}
} while(0);
if (!error) {
*dst = snb;
} else
nb_snbfree(snb);
return error;
}
*/

View file

@ -0,0 +1,380 @@
/*
* Copyright (c) 2000, Boris Popov
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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.
*
* $Id: nbns_rq.c,v 1.5 2001/02/17 03:07:24 bp Exp $
*/
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <ctype.h>
#include <netdb.h>
#include <err.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#define NB_NEEDRESOLVER
#include <netsmb/netbios.h>
#include <netsmb/smb_lib.h>
#include <netsmb/nb_lib.h>
static int nbns_rq_create(int opcode, struct nb_ctx *ctx, struct nbns_rq **rqpp);
static void nbns_rq_done(struct nbns_rq *rqp);
static int nbns_rq_getrr(struct nbns_rq *rqp, struct nbns_rr *rrp);
static int nbns_rq_prepare(struct nbns_rq *rqp);
static int nbns_rq(struct nbns_rq *rqp);
static struct nb_ifdesc *nb_iflist;
int
nbns_resolvename(const char *name, struct nb_ctx *ctx, struct sockaddr **adpp)
{
struct nbns_rq *rqp;
struct nb_name nn;
struct nbns_rr rr;
struct sockaddr_in *dest;
int error, rdrcount, len;
if (strlen(name) > NB_NAMELEN)
return NBERROR(NBERR_NAMETOOLONG);
error = nbns_rq_create(NBNS_OPCODE_QUERY, ctx, &rqp);
if (error)
return error;
bzero(&nn, sizeof(nn));
strcpy(nn.nn_name, name);
nn.nn_scope = ctx->nb_scope;
nn.nn_type = NBT_SERVER;
rqp->nr_nmflags = NBNS_NMFLAG_RD;
rqp->nr_qdname = &nn;
rqp->nr_qdtype = NBNS_QUESTION_TYPE_NB;
rqp->nr_qdclass = NBNS_QUESTION_CLASS_IN;
rqp->nr_qdcount = 1;
dest = &rqp->nr_dest;
*dest = ctx->nb_ns;
dest->sin_family = AF_INET;
dest->sin_len = sizeof(*dest);
if (dest->sin_port == 0)
dest->sin_port = htons(137);
if (dest->sin_addr.s_addr == INADDR_ANY)
dest->sin_addr.s_addr = htonl(INADDR_BROADCAST);
if (dest->sin_addr.s_addr == INADDR_BROADCAST)
rqp->nr_flags |= NBRQF_BROADCAST;
error = nbns_rq_prepare(rqp);
if (error) {
nbns_rq_done(rqp);
return error;
}
rdrcount = NBNS_MAXREDIRECTS;
for (;;) {
error = nbns_rq(rqp);
if (error)
break;
if ((rqp->nr_rpnmflags & NBNS_NMFLAG_AA) == 0) {
if (rdrcount-- == 0) {
error = NBERROR(NBERR_TOOMANYREDIRECTS);
break;
}
error = nbns_rq_getrr(rqp, &rr);
if (error)
break;
error = nbns_rq_getrr(rqp, &rr);
if (error)
break;
bcopy(rr.rr_data, &dest->sin_addr, 4);
rqp->nr_flags &= ~NBRQF_BROADCAST;
continue;
}
if (rqp->nr_rpancount == 0) {
error = NBERROR(NBERR_HOSTNOTFOUND);
break;
}
error = nbns_rq_getrr(rqp, &rr);
if (error)
break;
len = sizeof(struct sockaddr_in);
dest = malloc(len);
if (dest == NULL)
return ENOMEM;
bzero(dest, len);
dest->sin_len = len;
dest->sin_family = AF_INET;
bcopy(rr.rr_data + 2, &dest->sin_addr.s_addr, 4);
dest->sin_port = htons(SMB_TCP_PORT);
*adpp = (struct sockaddr*)dest;
ctx->nb_lastns = rqp->nr_sender;
break;
}
nbns_rq_done(rqp);
return error;
}
int
nbns_rq_create(int opcode, struct nb_ctx *ctx, struct nbns_rq **rqpp)
{
struct nbns_rq *rqp;
static u_int16_t trnid;
int error;
rqp = malloc(sizeof(*rqp));
if (rqp == NULL)
return ENOMEM;
bzero(rqp, sizeof(*rqp));
error = mb_init(&rqp->nr_rq, NBDG_MAXSIZE);
if (error) {
free(rqp);
return error;
}
rqp->nr_opcode = opcode;
rqp->nr_nbd = ctx;
rqp->nr_trnid = trnid++;
*rqpp = rqp;
return 0;
}
void
nbns_rq_done(struct nbns_rq *rqp)
{
if (rqp == NULL)
return;
if (rqp->nr_fd >= 0)
close(rqp->nr_fd);
mb_done(&rqp->nr_rq);
mb_done(&rqp->nr_rp);
free(rqp);
}
/*
* Extract resource record from the packet. Assume that there is only
* one mbuf.
*/
int
nbns_rq_getrr(struct nbns_rq *rqp, struct nbns_rr *rrp)
{
struct mbdata *mbp = &rqp->nr_rp;
u_char *cp;
int error, len;
bzero(rrp, sizeof(*rrp));
cp = mbp->mb_pos;
len = nb_encname_len(cp);
if (len < 1)
return NBERROR(NBERR_INVALIDRESPONSE);
rrp->rr_name = cp;
error = mb_get_mem(mbp, NULL, len);
if (error)
return error;
mb_get_uint16be(mbp, &rrp->rr_type);
mb_get_uint16be(mbp, &rrp->rr_class);
mb_get_uint32be(mbp, &rrp->rr_ttl);
mb_get_uint16be(mbp, &rrp->rr_rdlength);
rrp->rr_data = mbp->mb_pos;
error = mb_get_mem(mbp, NULL, rrp->rr_rdlength);
return error;
}
int
nbns_rq_prepare(struct nbns_rq *rqp)
{
struct nb_ctx *ctx = rqp->nr_nbd;
struct mbdata *mbp = &rqp->nr_rq;
u_int8_t nmflags;
u_char *cp;
int len, error;
error = mb_init(&rqp->nr_rp, NBDG_MAXSIZE);
if (error)
return error;
if (rqp->nr_dest.sin_addr.s_addr == INADDR_BROADCAST) {
rqp->nr_nmflags |= NBNS_NMFLAG_BCAST;
if (nb_iflist == NULL) {
error = nb_enum_if(&nb_iflist, 100);
if (error)
return error;
}
} else
rqp->nr_nmflags &= ~NBNS_NMFLAG_BCAST;
mb_put_uint16be(mbp, rqp->nr_trnid);
nmflags = ((rqp->nr_opcode & 0x1F) << 3) | ((rqp->nr_nmflags & 0x70) >> 4);
mb_put_uint8(mbp, nmflags);
mb_put_uint8(mbp, (rqp->nr_nmflags & 0x0f) << 4 /* rcode */);
mb_put_uint16be(mbp, rqp->nr_qdcount);
mb_put_uint16be(mbp, rqp->nr_ancount);
mb_put_uint16be(mbp, rqp->nr_nscount);
mb_put_uint16be(mbp, rqp->nr_arcount);
if (rqp->nr_qdcount) {
if (rqp->nr_qdcount > 1)
return EINVAL;
len = nb_name_len(rqp->nr_qdname);
error = mb_fit(mbp, len, (char**)&cp);
if (error)
return error;
nb_name_encode(rqp->nr_qdname, cp);
mb_put_uint16be(mbp, rqp->nr_qdtype);
mb_put_uint16be(mbp, rqp->nr_qdclass);
}
m_lineup(mbp->mb_top, &mbp->mb_top);
if (ctx->nb_timo == 0)
ctx->nb_timo = 1; /* by default 1 second */
return 0;
}
static int
nbns_rq_recv(struct nbns_rq *rqp)
{
struct mbdata *mbp = &rqp->nr_rp;
void *rpdata = mtod(mbp->mb_top, void *);
fd_set rd, wr, ex;
struct timeval tv;
struct sockaddr_in sender;
int s = rqp->nr_fd;
int n, len;
FD_ZERO(&rd);
FD_ZERO(&wr);
FD_ZERO(&ex);
FD_SET(s, &rd);
tv.tv_sec = rqp->nr_nbd->nb_timo;
tv.tv_usec = 0;
n = select(s + 1, &rd, &wr, &ex, &tv);
if (n == -1)
return -1;
if (n == 0)
return ETIMEDOUT;
if (FD_ISSET(s, &rd) == 0)
return ETIMEDOUT;
len = sizeof(sender);
n = recvfrom(s, rpdata, mbp->mb_top->m_maxlen, 0,
(struct sockaddr*)&sender, &len);
if (n < 0)
return errno;
mbp->mb_top->m_len = mbp->mb_count = n;
rqp->nr_sender = sender;
return 0;
}
static int
nbns_rq_opensocket(struct nbns_rq *rqp)
{
struct sockaddr_in locaddr;
int opt, s;
s = rqp->nr_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0)
return errno;
if (rqp->nr_flags & NBRQF_BROADCAST) {
opt = 1;
if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt)) < 0)
return errno;
if (rqp->nr_if == NULL)
return NBERROR(NBERR_NOBCASTIFS);
bzero(&locaddr, sizeof(locaddr));
locaddr.sin_family = AF_INET;
locaddr.sin_len = sizeof(locaddr);
locaddr.sin_addr = rqp->nr_if->id_addr;
rqp->nr_dest.sin_addr.s_addr = rqp->nr_if->id_addr.s_addr | ~rqp->nr_if->id_mask.s_addr;
if (bind(s, (struct sockaddr*)&locaddr, sizeof(locaddr)) < 0)
return errno;
}
return 0;
}
static int
nbns_rq_send(struct nbns_rq *rqp)
{
struct mbdata *mbp = &rqp->nr_rq;
int s = rqp->nr_fd;
if (sendto(s, mtod(mbp->mb_top, char *), mbp->mb_count, 0,
(struct sockaddr*)&rqp->nr_dest, sizeof(rqp->nr_dest)) < 0)
return errno;
return 0;
}
int
nbns_rq(struct nbns_rq *rqp)
{
struct mbdata *mbp = &rqp->nr_rq;
u_int16_t rpid;
u_int8_t nmflags;
int error, retrycount;
rqp->nr_if = nb_iflist;
again:
error = nbns_rq_opensocket(rqp);
if (error)
return error;
retrycount = 3; /* XXX - configurable */
for (;;) {
error = nbns_rq_send(rqp);
if (error)
return error;
error = nbns_rq_recv(rqp);
if (error) {
if (error != ETIMEDOUT || retrycount == 0) {
if ((rqp->nr_nmflags & NBNS_NMFLAG_BCAST) &&
rqp->nr_if != NULL &&
rqp->nr_if->id_next != NULL) {
rqp->nr_if = rqp->nr_if->id_next;
close(rqp->nr_fd);
goto again;
} else
return error;
}
retrycount--;
continue;
}
mbp = &rqp->nr_rp;
if (mbp->mb_count < 12)
return NBERROR(NBERR_INVALIDRESPONSE);
mb_get_uint16be(mbp, &rpid);
if (rpid != rqp->nr_trnid)
return NBERROR(NBERR_INVALIDRESPONSE);
break;
}
mb_get_uint8(mbp, &nmflags);
rqp->nr_rpnmflags = (nmflags & 7) << 4;
mb_get_uint8(mbp, &nmflags);
rqp->nr_rpnmflags |= (nmflags & 0xf0) >> 4;
rqp->nr_rprcode = nmflags & 0xf;
if (rqp->nr_rprcode)
return NBERROR(rqp->nr_rprcode);
mb_get_uint16be(mbp, &rpid); /* QDCOUNT */
mb_get_uint16be(mbp, &rqp->nr_rpancount);
mb_get_uint16be(mbp, &rqp->nr_rpnscount);
mb_get_uint16be(mbp, &rqp->nr_rparcount);
return 0;
}

214
contrib/smbfs/lib/smb/nls.c Normal file
View file

@ -0,0 +1,214 @@
/*
* Copyright (c) 2000-2001, Boris Popov
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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.
*
* $Id: nls.c,v 1.8 2001/04/16 12:46:46 bp Exp $
*/
#include <sys/types.h>
#include <sys/iconv.h>
#include <sys/sysctl.h>
#include <ctype.h>
#include <dlfcn.h>
#include <errno.h>
#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
#include <locale.h>
#include <err.h>
#include <netsmb/smb_lib.h>
/*
* prototype iconv* functions
*/
typedef void *iconv_t;
static iconv_t (*my_iconv_open)(const char *, const char *);
static size_t(*my_iconv)(iconv_t, const char **, size_t *, char **, size_t *);
static int(*my_iconv_close)(iconv_t);
u_char nls_lower[256];
u_char nls_upper[256];
static iconv_t nls_toext, nls_toloc;
static int iconv_loaded;
static void *iconv_lib;
int
nls_setlocale(const char *name)
{
int i;
if (setlocale(LC_CTYPE, name) == NULL) {
warnx("can't set locale '%s'\n", name);
return EINVAL;
}
for (i = 0; i < 256; i++) {
nls_lower[i] = tolower(i);
nls_upper[i] = toupper(i);
}
return 0;
}
int
nls_setrecode(const char *local, const char *external)
{
iconv_t icd;
if (iconv_loaded == 2)
return ENOENT;
else if (iconv_loaded == 0) {
iconv_loaded++;
iconv_lib = dlopen("libiconv.so", RTLD_LAZY | RTLD_GLOBAL);
if (iconv_lib == NULL) {
warn("Unable to load iconv library: %s\n", dlerror());
iconv_loaded++;
return ENOENT;
}
my_iconv_open = dlsym(iconv_lib, "iconv_open");
my_iconv = dlsym(iconv_lib, "iconv");
my_iconv_close = dlsym(iconv_lib, "iconv_close");
}
if (nls_toext)
my_iconv_close(nls_toext);
if (nls_toloc)
my_iconv_close(nls_toloc);
nls_toext = nls_toloc = (iconv_t)0;
icd = my_iconv_open(external, local);
if (icd == (iconv_t)-1)
return errno;
nls_toext = icd;
icd = my_iconv_open(local, external);
if (icd == (iconv_t)-1) {
my_iconv_close(nls_toext);
nls_toext = (iconv_t)0;
return errno;
}
nls_toloc = icd;
return 0;
}
char *
nls_str_toloc(char *dst, const char *src)
{
char *p = dst;
int inlen, outlen;
if (!iconv_loaded)
return strcpy(dst, src);
if (nls_toloc == (iconv_t)0)
return strcpy(dst, src);
inlen = outlen = strlen(src);
my_iconv(nls_toloc, NULL, NULL, &p, &outlen);
my_iconv(nls_toloc, &src, &inlen, &p, &outlen);
*p = 0;
return dst;
}
char *
nls_str_toext(char *dst, const char *src)
{
char *p = dst;
int inlen, outlen;
if (!iconv_loaded)
return strcpy(dst, src);
if (nls_toext == (iconv_t)0)
return strcpy(dst, src);
inlen = outlen = strlen(src);
my_iconv(nls_toext, NULL, NULL, &p, &outlen);
my_iconv(nls_toext, &src, &inlen, &p, &outlen);
*p = 0;
return dst;
}
void *
nls_mem_toloc(void *dst, const void *src, int size)
{
char *p = dst;
const char *s = src;
int inlen, outlen;
if (!iconv_loaded)
return memcpy(dst, src, size);
if (size == 0)
return NULL;
if (nls_toloc == (iconv_t)0)
return memcpy(dst, src, size);
inlen = outlen = size;
my_iconv(nls_toloc, NULL, NULL, &p, &outlen);
my_iconv(nls_toloc, &s, &inlen, &p, &outlen);
return dst;
}
void *
nls_mem_toext(void *dst, const void *src, int size)
{
char *p = dst;
const char *s = src;
int inlen, outlen;
if (size == 0)
return NULL;
if (!iconv_loaded || nls_toext == (iconv_t)0)
return memcpy(dst, src, size);
inlen = outlen = size;
my_iconv(nls_toext, NULL, NULL, &p, &outlen);
my_iconv(nls_toext, &s, &inlen, &p, &outlen);
return dst;
}
char *
nls_str_upper(char *dst, const char *src)
{
char *p = dst;
while (*src)
*dst++ = toupper(*src++);
*dst = 0;
return p;
}
char *
nls_str_lower(char *dst, const char *src)
{
char *p = dst;
while (*src)
*dst++ = tolower(*src++);
*dst = 0;
return p;
}

View file

@ -0,0 +1,97 @@
/*
* Copyright (c) 2000, Boris Popov
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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.
*
* $Id: print.c,v 1.4 2001/04/16 04:33:01 bp Exp $
*/
#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/mount.h>
#include <fcntl.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pwd.h>
#include <grp.h>
#include <unistd.h>
/*#include <netnb/netbios.h>*/
#include <netsmb/smb_lib.h>
#include <netsmb/smb_conn.h>
#include <cflib.h>
int
smb_smb_open_print_file(struct smb_ctx *ctx, int setuplen, int mode,
const char *ident, smbfh *fhp)
{
struct smb_rq *rqp;
struct mbdata *mbp;
int error;
error = smb_rq_init(ctx, SMB_COM_OPEN_PRINT_FILE, 2, &rqp);
if (error)
return error;
mbp = smb_rq_getrequest(rqp);
mb_put_uint16le(mbp, setuplen);
mb_put_uint16le(mbp, mode);
smb_rq_wend(rqp);
mb_put_uint8(mbp, SMB_DT_ASCII);
smb_rq_dstring(mbp, ident);
error = smb_rq_simple(rqp);
if (!error) {
mbp = smb_rq_getreply(rqp);
mb_get_uint16(mbp, fhp);
}
smb_rq_done(rqp);
return error;
}
int
smb_smb_close_print_file(struct smb_ctx *ctx, smbfh fh)
{
struct smb_rq *rqp;
struct mbdata *mbp;
int error;
error = smb_rq_init(ctx, SMB_COM_CLOSE_PRINT_FILE, 0, &rqp);
if (error)
return error;
mbp = smb_rq_getrequest(rqp);
mb_put_mem(mbp, (char*)&fh, 2);
smb_rq_wend(rqp);
error = smb_rq_simple(rqp);
smb_rq_done(rqp);
return error;
}

404
contrib/smbfs/lib/smb/rap.c Normal file
View file

@ -0,0 +1,404 @@
/*
* Copyright (c) 2000, Boris Popov
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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.
*
* $Id: rap.c,v 1.8 2001/02/24 15:56:05 bp Exp $
*
* This is very simple implementation of RAP protocol.
*/
#include <sys/param.h>
#include <sys/errno.h>
#include <sys/stat.h>
#include <ctype.h>
#include <err.h>
#include <stdio.h>
#include <unistd.h>
#include <strings.h>
#include <stdlib.h>
#include <sysexits.h>
#include <sys/mchain.h>
#include <netsmb/smb_lib.h>
#include <netsmb/smb_conn.h>
#include <netsmb/smb_rap.h>
/*#include <sys/ioctl.h>*/
static int
smb_rap_parserqparam(const char *s, char **next, int *rlen)
{
char *np;
int len, m;
m = 1;
switch (*s++) {
case 'L':
case 'T':
case 'W':
len = 2;
break;
case 'D':
case 'O':
len = 4;
break;
case 'b':
case 'F':
len = 1;
break;
case 'r':
case 's':
len = 0;
break;
default:
return EINVAL;
}
if (isdigit(*s)) {
len *= strtoul(s, &np, 10);
s = np;
}
*rlen = len;
*(const char**)next = s;
return 0;
}
static int
smb_rap_parserpparam(const char *s, char **next, int *rlen)
{
char *np;
int len, m;
m = 1;
switch (*s++) {
case 'e':
case 'h':
len = 2;
break;
case 'i':
len = 4;
break;
case 'g':
len = 1;
break;
default:
return EINVAL;
}
if (isdigit(*s)) {
len *= strtoul(s, &np, 10);
s = np;
}
*rlen = len;
*(const char**)next = s;
return 0;
}
static int
smb_rap_parserpdata(const char *s, char **next, int *rlen)
{
char *np;
int len, m;
m = 1;
switch (*s++) {
case 'B':
len = 1;
break;
case 'W':
len = 2;
break;
case 'D':
case 'O':
case 'z':
len = 4;
break;
default:
return EINVAL;
}
if (isdigit(*s)) {
len *= strtoul(s, &np, 10);
s = np;
}
*rlen = len;
*(const char**)next = s;
return 0;
}
static int
smb_rap_rqparam_z(struct smb_rap *rap, const char *value)
{
int len = strlen(value) + 1;
bcopy(value, rap->r_npbuf, len);
rap->r_npbuf += len;
rap->r_plen += len;
return 0;
}
static int
smb_rap_rqparam(struct smb_rap *rap, char ptype, char plen, long value)
{
char *p = rap->r_npbuf;
int len;
switch (ptype) {
case 'L':
case 'W':
setwle(p, 0, value);
len = 2;
break;
case 'D':
setdle(p, 0, value);
len = 4;
break;
case 'b':
memset(p, value, plen);
len = plen;
default:
return EINVAL;
}
rap->r_npbuf += len;
rap->r_plen += len;
return 0;
}
int
smb_rap_create(int fn, const char *param, const char *data,
struct smb_rap **rapp)
{
struct smb_rap *rap;
char *p;
int plen, len;
rap = malloc(sizeof(*rap));
if (rap == NULL)
return NULL;
bzero(rap, sizeof(*rap));
p = rap->r_sparam = rap->r_nparam = strdup(param);
rap->r_sdata = rap->r_ndata = strdup(data);
/*
* Calculate length of request parameter block
*/
len = 2 + strlen(param) + 1 + strlen(data) + 1;
while (*p) {
if (smb_rap_parserqparam(p, &p, &plen) != 0)
break;
len += plen;
}
rap->r_pbuf = rap->r_npbuf = malloc(len);
smb_rap_rqparam(rap, 'W', 1, fn);
smb_rap_rqparam_z(rap, rap->r_sparam);
smb_rap_rqparam_z(rap, rap->r_sdata);
*rapp = rap;
return 0;
}
void
smb_rap_done(struct smb_rap *rap)
{
if (rap->r_sparam)
free(rap->r_sparam);
if (rap->r_sdata)
free(rap->r_sdata);
free(rap);
}
int
smb_rap_setNparam(struct smb_rap *rap, long value)
{
char *p = rap->r_nparam;
char ptype = *p;
int error, plen;
error = smb_rap_parserqparam(p, &p, &plen);
if (error)
return error;
switch (ptype) {
case 'L':
rap->r_rcvbuflen = value;
/* FALLTHROUGH */
case 'W':
case 'D':
case 'b':
error = smb_rap_rqparam(rap, ptype, plen, value);
break;
default:
return EINVAL;
}
rap->r_nparam = p;
return 0;
}
int
smb_rap_setPparam(struct smb_rap *rap, void *value)
{
char *p = rap->r_nparam;
char ptype = *p;
int error, plen;
error = smb_rap_parserqparam(p, &p, &plen);
if (error)
return error;
switch (ptype) {
case 'r':
rap->r_rcvbuf = value;
break;
default:
return EINVAL;
}
rap->r_nparam = p;
return 0;
}
static int
smb_rap_getNparam(struct smb_rap *rap, long *value)
{
char *p = rap->r_nparam;
char ptype = *p;
int error, plen;
error = smb_rap_parserpparam(p, &p, &plen);
if (error)
return error;
switch (ptype) {
case 'h':
*value = letohs(*(u_int16_t*)rap->r_npbuf);
break;
default:
return EINVAL;
}
rap->r_npbuf += plen;
rap->r_nparam = p;
return 0;
}
int
smb_rap_request(struct smb_rap *rap, struct smb_ctx *ctx)
{
u_int16_t *rp, conv;
u_int32_t *p32;
char *dp, *p = rap->r_nparam;
char ptype;
int error, rdatacnt, rparamcnt, entries, done, dlen;
rdatacnt = rap->r_rcvbuflen;
rparamcnt = rap->r_plen;
error = smb_t2_request(ctx, 0, 0, "\\PIPE\\LANMAN",
rap->r_plen, rap->r_pbuf, /* int tparamcnt, void *tparam */
0, NULL, /* int tdatacnt, void *tdata */
&rparamcnt, rap->r_pbuf, /* rparamcnt, void *rparam */
&rdatacnt, rap->r_rcvbuf /* int *rdatacnt, void *rdata */
);
if (error)
return error;
rp = (u_int16_t*)rap->r_pbuf;
rap->r_result = letohs(*rp++);
conv = letohs(*rp++);
rap->r_npbuf = (char*)rp;
rap->r_entries = entries = 0;
done = 0;
while (!done && *p) {
ptype = *p;
switch (ptype) {
case 'e':
rap->r_entries = entries = letohs(*(u_int16_t*)rap->r_npbuf);
rap->r_npbuf += 2;
p++;
break;
default:
done = 1;
}
/* error = smb_rap_parserpparam(p, &p, &plen);
if (error) {
smb_error("reply parameter mismath %s", 0, p);
return EBADRPC;
}*/
}
rap->r_nparam = p;
/*
* In general, unpacking entries we may need to relocate
* entries for proper alingning. For now use them as is.
*/
dp = rap->r_rcvbuf;
while (entries--) {
p = rap->r_sdata;
while (*p) {
ptype = *p;
error = smb_rap_parserpdata(p, &p, &dlen);
if (error) {
smb_error("reply data mismath %s", 0, p);
return EBADRPC;
}
switch (ptype) {
case 'z':
p32 = (u_int32_t*)dp;
*p32 = (*p32 & 0xffff) - conv;
break;
}
dp += dlen;
}
}
return error;
}
int
smb_rap_error(struct smb_rap *rap, int error)
{
if (error)
return error;
if (rap->r_result == 0)
return 0;
return rap->r_result | SMB_RAP_ERROR;
}
int
smb_rap_NetShareEnum(struct smb_ctx *ctx, int sLevel, void *pbBuffer,
int cbBuffer, int *pcEntriesRead, int *pcTotalAvail)
{
struct smb_rap *rap;
long lval;
int error;
error = smb_rap_create(0, "WrLeh", "B13BWz", &rap);
if (error)
return error;
smb_rap_setNparam(rap, sLevel); /* W - sLevel */
smb_rap_setPparam(rap, pbBuffer); /* r - pbBuffer */
smb_rap_setNparam(rap, cbBuffer); /* L - cbBuffer */
error = smb_rap_request(rap, ctx);
if (error == 0) {
*pcEntriesRead = rap->r_entries;
error = smb_rap_getNparam(rap, &lval);
*pcTotalAvail = lval;
}
error = smb_rap_error(rap, error);
smb_rap_done(rap);
return error;
}

View file

@ -0,0 +1,499 @@
/*
* Copyright (c) 2000, Boris Popov
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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.
*
* $Id: rcfile.c,v 1.5 2001/04/16 12:46:46 bp Exp $
*/
#include <sys/types.h>
#include <sys/queue.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pwd.h>
#include <unistd.h>
#include <err.h>
#include <cflib.h>
#include "rcfile_priv.h"
SLIST_HEAD(rcfile_head, rcfile);
static struct rcfile_head pf_head = {NULL};
static struct rcfile* rc_cachelookup(const char *filename);
static struct rcsection *rc_findsect(struct rcfile *rcp, const char *sectname);
static struct rcsection *rc_addsect(struct rcfile *rcp, const char *sectname);
static int rc_freesect(struct rcfile *rcp, struct rcsection *rsp);
static struct rckey *rc_sect_findkey(struct rcsection *rsp, const char *keyname);
static struct rckey *rc_sect_addkey(struct rcsection *rsp, const char *name, const char *value);
static void rc_key_free(struct rckey *p);
static void rc_parse(struct rcfile *rcp);
/*
* open rcfile and load its content, if already open - return previous handle
*/
int
rc_open(const char *filename, const char *mode, struct rcfile **rcfile)
{
struct rcfile *rcp;
FILE *f;
rcp = rc_cachelookup(filename);
if (rcp) {
*rcfile = rcp;
return 0;
}
f = fopen(filename, mode);
if (f == NULL)
return errno;
rcp = malloc(sizeof(struct rcfile));
if (rcp == NULL) {
fclose(f);
return ENOMEM;
}
bzero(rcp, sizeof(struct rcfile));
rcp->rf_name = strdup(filename);
rcp->rf_f = f;
SLIST_INSERT_HEAD(&pf_head, rcp, rf_next);
rc_parse(rcp);
*rcfile = rcp;
return 0;
}
int
rc_merge(const char *filename, struct rcfile **rcfile)
{
struct rcfile *rcp = *rcfile;
FILE *f, *t;
if (rcp == NULL) {
return rc_open(filename, "r", rcfile);
}
f = fopen (filename, "r");
if (f == NULL)
return errno;
t = rcp->rf_f;
rcp->rf_f = f;
rc_parse(rcp);
rcp->rf_f = t;
fclose(f);
return 0;
}
int
rc_close(struct rcfile *rcp)
{
struct rcsection *p, *n;
fclose(rcp->rf_f);
for(p = SLIST_FIRST(&rcp->rf_sect); p;) {
n = p;
p = SLIST_NEXT(p,rs_next);
rc_freesect(rcp, n);
}
free(rcp->rf_name);
SLIST_REMOVE(&pf_head, rcp, rcfile, rf_next);
free(rcp);
return 0;
}
static struct rcfile*
rc_cachelookup(const char *filename)
{
struct rcfile *p;
SLIST_FOREACH(p, &pf_head, rf_next)
if (strcmp (filename, p->rf_name) == 0)
return p;
return 0;
}
static struct rcsection *
rc_findsect(struct rcfile *rcp, const char *sectname)
{
struct rcsection *p;
SLIST_FOREACH(p, &rcp->rf_sect, rs_next)
if (strcmp(p->rs_name, sectname)==0)
return p;
return NULL;
}
static struct rcsection *
rc_addsect(struct rcfile *rcp, const char *sectname)
{
struct rcsection *p;
p = rc_findsect(rcp, sectname);
if (p) return p;
p = malloc(sizeof(*p));
if (!p) return NULL;
p->rs_name = strdup(sectname);
SLIST_INIT(&p->rs_keys);
SLIST_INSERT_HEAD(&rcp->rf_sect, p, rs_next);
return p;
}
static int
rc_freesect(struct rcfile *rcp, struct rcsection *rsp)
{
struct rckey *p,*n;
SLIST_REMOVE(&rcp->rf_sect, rsp, rcsection, rs_next);
for(p = SLIST_FIRST(&rsp->rs_keys);p;) {
n = p;
p = SLIST_NEXT(p,rk_next);
rc_key_free(n);
}
free(rsp->rs_name);
free(rsp);
return 0;
}
static struct rckey *
rc_sect_findkey(struct rcsection *rsp, const char *keyname)
{
struct rckey *p;
SLIST_FOREACH(p, &rsp->rs_keys, rk_next)
if (strcmp(p->rk_name, keyname)==0)
return p;
return NULL;
}
static struct rckey *
rc_sect_addkey(struct rcsection *rsp, const char *name, const char *value)
{
struct rckey *p;
p = rc_sect_findkey(rsp, name);
if (p) {
free(p->rk_value);
} else {
p = malloc(sizeof(*p));
if (!p) return NULL;
SLIST_INSERT_HEAD(&rsp->rs_keys, p, rk_next);
p->rk_name = strdup(name);
}
p->rk_value = value ? strdup(value) : strdup("");
return p;
}
#if 0
void
rc_sect_delkey(struct rcsection *rsp, struct rckey *p)
{
SLIST_REMOVE(&rsp->rs_keys, p, rckey, rk_next);
rc_key_free(p);
return;
}
#endif
static void
rc_key_free(struct rckey *p)
{
free(p->rk_value);
free(p->rk_name);
free(p);
}
enum { stNewLine, stHeader, stSkipToEOL, stGetKey, stGetValue};
static void
rc_parse(struct rcfile *rcp)
{
FILE *f = rcp->rf_f;
int state = stNewLine, c;
struct rcsection *rsp = NULL;
struct rckey *rkp = NULL;
char buf[2048];
char *next = buf, *last = &buf[sizeof(buf)-1];
while ((c = getc (f)) != EOF) {
if (c == '\r')
continue;
if (state == stNewLine) {
next = buf;
if (isspace(c))
continue; /* skip leading junk */
if (c == '[') {
state = stHeader;
rsp = NULL;
continue;
}
if (c == '#' || c == ';') {
state = stSkipToEOL;
} else { /* something meaningfull */
state = stGetKey;
}
}
if (state == stSkipToEOL || next == last) {/* ignore long lines */
if (c == '\n'){
state = stNewLine;
next = buf;
}
continue;
}
if (state == stHeader) {
if (c == ']') {
*next = 0;
next = buf;
rsp = rc_addsect(rcp, buf);
state = stSkipToEOL;
} else
*next++ = c;
continue;
}
if (state == stGetKey) {
if (c == ' ' || c == '\t')/* side effect: 'key name='*/
continue; /* become 'keyname=' */
if (c == '\n') { /* silently ignore ... */
state = stNewLine;
continue;
}
if (c != '=') {
*next++ = c;
continue;
}
*next = 0;
if (rsp == NULL) {
fprintf(stderr, "Key '%s' defined before section\n", buf);
state = stSkipToEOL;
continue;
}
rkp = rc_sect_addkey(rsp, buf, NULL);
next = buf;
state = stGetValue;
continue;
}
/* only stGetValue left */
if (state != stGetValue) {
fprintf(stderr, "Well, I can't parse file '%s'\n",rcp->rf_name);
state = stSkipToEOL;
}
if (c != '\n') {
*next++ = c;
continue;
}
*next = 0;
rkp->rk_value = strdup(buf);
state = stNewLine;
rkp = NULL;
} /* while */
if (c == EOF && state == stGetValue) {
*next = 0;
rkp->rk_value = strdup(buf);
}
return;
}
int
rc_getstringptr(struct rcfile *rcp, const char *section, const char *key,
char **dest)
{
struct rcsection *rsp;
struct rckey *rkp;
*dest = NULL;
rsp = rc_findsect(rcp, section);
if (!rsp) return ENOENT;
rkp = rc_sect_findkey(rsp,key);
if (!rkp) return ENOENT;
*dest = rkp->rk_value;
return 0;
}
int
rc_getstring(struct rcfile *rcp, const char *section, const char *key,
size_t maxlen, char *dest)
{
char *value;
int error;
error = rc_getstringptr(rcp, section, key, &value);
if (error)
return error;
if (strlen(value) >= maxlen) {
warnx("line too long for key '%s' in section '%s', max = %d\n", key, section, maxlen);
return EINVAL;
}
strcpy(dest, value);
return 0;
}
int
rc_getint(struct rcfile *rcp, const char *section, const char *key, int *value)
{
struct rcsection *rsp;
struct rckey *rkp;
rsp = rc_findsect(rcp, section);
if (!rsp)
return ENOENT;
rkp = rc_sect_findkey(rsp, key);
if (!rkp)
return ENOENT;
errno = 0;
*value = strtol(rkp->rk_value, NULL, 0);
if (errno) {
warnx("invalid int value '%s' for key '%s' in section '%s'\n", rkp->rk_value, key, section);
return errno;
}
return 0;
}
/*
* 1,yes,true
* 0,no,false
*/
int
rc_getbool(struct rcfile *rcp, const char *section, const char *key, int *value)
{
struct rcsection *rsp;
struct rckey *rkp;
char *p;
rsp = rc_findsect(rcp, section);
if (!rsp) return ENOENT;
rkp = rc_sect_findkey(rsp,key);
if (!rkp) return ENOENT;
p = rkp->rk_value;
while (*p && isspace(*p)) p++;
if (*p == '0' || strcasecmp(p,"no") == 0 || strcasecmp(p,"false") == 0) {
*value = 0;
return 0;
}
if (*p == '1' || strcasecmp(p,"yes") == 0 || strcasecmp(p,"true") == 0) {
*value = 1;
return 0;
}
fprintf(stderr, "invalid boolean value '%s' for key '%s' in section '%s' \n",p, key, section);
return EINVAL;
}
/*
* Unified command line/rc file parser
*/
int
opt_args_parse(struct rcfile *rcp, struct opt_args *ap, const char *sect,
opt_callback_t *callback)
{
int len, error;
for (; ap->opt; ap++) {
switch (ap->type) {
case OPTARG_STR:
if (rc_getstringptr(rcp, sect, ap->name, &ap->str) != 0)
break;
len = strlen(ap->str);
if (len > ap->ival) {
warnx("rc: argument for option '%c' (%s) too long\n", ap->opt, ap->name);
return EINVAL;
}
callback(ap);
break;
case OPTARG_BOOL:
error = rc_getbool(rcp, sect, ap->name, &ap->ival);
if (error == ENOENT)
break;
if (error)
return EINVAL;
callback(ap);
break;
case OPTARG_INT:
if (rc_getint(rcp, sect, ap->name, &ap->ival) != 0)
break;
if (((ap->flag & OPTFL_HAVEMIN) && ap->ival < ap->min) ||
((ap->flag & OPTFL_HAVEMAX) && ap->ival > ap->max)) {
warnx("rc: argument for option '%c' (%s) should be in [%d-%d] range\n",
ap->opt, ap->name, ap->min, ap->max);
return EINVAL;
}
callback(ap);
break;
default:
break;
}
}
return 0;
}
int
opt_args_parseopt(struct opt_args *ap, int opt, char *arg,
opt_callback_t *callback)
{
int len;
for (; ap->opt; ap++) {
if (ap->opt != opt)
continue;
switch (ap->type) {
case OPTARG_STR:
ap->str = arg;
if (arg) {
len = strlen(ap->str);
if (len > ap->ival) {
warnx("opt: Argument for option '%c' (%s) too long\n", ap->opt, ap->name);
return EINVAL;
}
callback(ap);
}
break;
case OPTARG_BOOL:
ap->ival = 0;
callback(ap);
break;
case OPTARG_INT:
errno = 0;
ap->ival = strtol(arg, NULL, 0);
if (errno) {
warnx("opt: Invalid integer value for option '%c' (%s).\n",ap->opt,ap->name);
return EINVAL;
}
if (((ap->flag & OPTFL_HAVEMIN) &&
(ap->ival < ap->min)) ||
((ap->flag & OPTFL_HAVEMAX) &&
(ap->ival > ap->max))) {
warnx("opt: Argument for option '%c' (%s) should be in [%d-%d] range\n",ap->opt,ap->name,ap->min,ap->max);
return EINVAL;
}
callback(ap);
break;
default:
break;
}
break;
}
return 0;
}

View file

@ -0,0 +1,20 @@
struct rckey {
SLIST_ENTRY(rckey) rk_next;
char *rk_name;
char *rk_value;
};
struct rcsection {
SLIST_ENTRY(rcsection) rs_next;
SLIST_HEAD(rckey_head,rckey) rs_keys;
char *rs_name;
};
struct rcfile {
SLIST_ENTRY(rcfile) rf_next;
SLIST_HEAD(rcsec_head, rcsection) rf_sect;
char *rf_name;
FILE *rf_f;
};

179
contrib/smbfs/lib/smb/rq.c Normal file
View file

@ -0,0 +1,179 @@
/*
* Copyright (c) 2000, Boris Popov
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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.
*
* $Id: rq.c,v 1.7 2001/04/16 04:33:01 bp Exp $
*/
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/errno.h>
#include <sys/stat.h>
#include <ctype.h>
#include <err.h>
#include <stdio.h>
#include <unistd.h>
#include <strings.h>
#include <stdlib.h>
#include <sysexits.h>
#include <sys/mchain.h>
#include <netsmb/smb_lib.h>
#include <netsmb/smb_conn.h>
#include <netsmb/smb_rap.h>
int
smb_rq_init(struct smb_ctx *ctx, u_char cmd, size_t rpbufsz, struct smb_rq **rqpp)
{
struct smb_rq *rqp;
rqp = malloc(sizeof(*rqp));
if (rqp == NULL)
return ENOMEM;
bzero(rqp, sizeof(*rqp));
rqp->rq_cmd = cmd;
rqp->rq_ctx = ctx;
mb_init(&rqp->rq_rq, M_MINSIZE);
mb_init(&rqp->rq_rp, rpbufsz);
*rqpp = rqp;
return 0;
}
void
smb_rq_done(struct smb_rq *rqp)
{
mb_done(&rqp->rq_rp);
mb_done(&rqp->rq_rq);
free(rqp);
}
void
smb_rq_wend(struct smb_rq *rqp)
{
if (rqp->rq_rq.mb_count & 1)
smb_error("smbrq_wend: odd word count\n", 0);
rqp->rq_wcount = rqp->rq_rq.mb_count / 2;
rqp->rq_rq.mb_count = 0;
}
int
smb_rq_dmem(struct mbdata *mbp, const char *src, size_t size)
{
struct mbuf *m;
char * dst;
int cplen, error;
if (size == 0)
return 0;
m = mbp->mb_cur;
if ((error = m_getm(m, size, &m)) != 0)
return error;
while (size > 0) {
cplen = M_TRAILINGSPACE(m);
if (cplen == 0) {
m = m->m_next;
continue;
}
if (cplen > (int)size)
cplen = size;
dst = mtod(m, char *) + m->m_len;
nls_mem_toext(dst, src, cplen);
size -= cplen;
src += cplen;
m->m_len += cplen;
mbp->mb_count += cplen;
}
mbp->mb_pos = mtod(m, char *) + m->m_len;
mbp->mb_cur = m;
return 0;
}
int
smb_rq_dstring(struct mbdata *mbp, const char *s)
{
return smb_rq_dmem(mbp, s, strlen(s) + 1);
}
int
smb_rq_simple(struct smb_rq *rqp)
{
struct smbioc_rq krq;
struct mbdata *mbp;
char *data;
mbp = smb_rq_getrequest(rqp);
m_lineup(mbp->mb_top, &mbp->mb_top);
data = mtod(mbp->mb_top, char*);
bzero(&krq, sizeof(krq));
krq.ioc_cmd = rqp->rq_cmd;
krq.ioc_twc = rqp->rq_wcount;
krq.ioc_twords = data;
krq.ioc_tbc = mbp->mb_count;
krq.ioc_tbytes = data + rqp->rq_wcount * 2;
mbp = smb_rq_getreply(rqp);
krq.ioc_rpbufsz = mbp->mb_top->m_maxlen;
krq.ioc_rpbuf = mtod(mbp->mb_top, char *);
if (ioctl(rqp->rq_ctx->ct_fd, SMBIOC_REQUEST, &krq) == -1)
return errno;
mbp->mb_top->m_len = krq.ioc_rwc * 2 + krq.ioc_rbc;
rqp->rq_wcount = krq.ioc_rwc;
rqp->rq_bcount = krq.ioc_rbc;
return 0;
}
int
smb_t2_request(struct smb_ctx *ctx, int setup, int setupcount,
const char *name,
int tparamcnt, void *tparam,
int tdatacnt, void *tdata,
int *rparamcnt, void *rparam,
int *rdatacnt, void *rdata)
{
struct smbioc_t2rq krq;
bzero(&krq, sizeof(krq));
krq.ioc_setup[0] = setup;
krq.ioc_setupcnt = setupcount;
(const char*)krq.ioc_name = name;
krq.ioc_tparamcnt = tparamcnt;
krq.ioc_tparam = tparam;
krq.ioc_tdatacnt = tdatacnt;
krq.ioc_tdata = tdata;
krq.ioc_rparamcnt = *rparamcnt;
krq.ioc_rparam = rparam;
krq.ioc_rdatacnt = *rdatacnt;
krq.ioc_rdata = rdata;
if (ioctl(ctx->ct_fd, SMBIOC_T2RQ, &krq) == -1)
return errno;
*rparamcnt = krq.ioc_rparamcnt;
*rdatacnt = krq.ioc_rdatacnt;
return 0;
}

View file

@ -0,0 +1,243 @@
/*
* Copyright (c) 2000, Boris Popov
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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.
*
* $Id: subr.c,v 1.11 2001/04/16 04:33:01 bp Exp $
*/
#include <sys/param.h>
#include <sys/types.h>
#include <sys/errno.h>
#include <sys/sysctl.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <err.h>
#include <netsmb/netbios.h>
#include <netsmb/smb_lib.h>
#include <netsmb/nb_lib.h>
#include <cflib.h>
extern char *__progname;
static int smblib_initialized;
struct rcfile *smb_rc;
int
smb_lib_init(void)
{
int error;
int kv;
size_t kvlen = sizeof(kv);
if (smblib_initialized)
return 0;
#if __FreeBSD_version > 400000
error = sysctlbyname("net.smb.version", &kv, &kvlen, NULL, 0);
if (error) {
warnx("%s: can't find kernel module\n", __FUNCTION__);
return error;
}
if (NSMB_VERSION != kv) {
warnx("%s: kernel module version(%d) don't match library(%d).\n", __FUNCTION__, kv, NSMB_VERSION);
return EINVAL;
}
#endif
if ((error = nls_setlocale("")) != 0) {
warnx("%s: can't initialise locale\n", __FUNCTION__);
return error;
}
smblib_initialized++;
return 0;
}
/*
* Print a (descriptive) error message
* error values:
* 0 - no specific error code available;
* 1..32767 - system error
*/
void
smb_error(const char *fmt, int error,...) {
va_list ap;
const char *cp;
int errtype = error & SMB_ERRTYPE_MASK;
fprintf(stderr, "%s: ", __progname);
va_start(ap, error);
vfprintf(stderr, fmt, ap);
va_end(ap);
if (error == -1)
error = errno;
else
error &= ~SMB_ERRTYPE_MASK;
switch (errtype) {
case SMB_SYS_ERROR:
if (error)
fprintf(stderr, ": syserr = %s\n", strerror(error));
else
fprintf(stderr, "\n");
break;
case SMB_RAP_ERROR:
fprintf(stderr, ": raperr = %d (0x%04x)\n", error, error);
break;
case SMB_NB_ERROR:
cp = nb_strerror(error);
if (cp == NULL)
fprintf(stderr, ": nberr = unknown (0x%04x)\n", error);
else
fprintf(stderr, ": nberr = %s\n", cp);
break;
default:
fprintf(stderr, "\n");
}
}
char *
smb_printb(char *dest, int flags, const struct smb_bitname *bnp) {
int first = 1;
strcpy(dest, "<");
for(; bnp->bn_bit; bnp++) {
if (flags & bnp->bn_bit) {
strcat(dest, bnp->bn_name);
first = 0;
}
if (!first && (flags & bnp[1].bn_bit))
strcat(dest, "|");
}
strcat(dest, ">");
return dest;
}
/*
* first read ~/.smbrc, next try to merge SMB_CFG_FILE
*/
int
smb_open_rcfile(void)
{
char *home, *fn;
int error;
home = getenv("HOME");
if (home) {
fn = malloc(strlen(home) + 20);
sprintf(fn, "%s/.nsmbrc", home);
error = rc_open(fn, "r", &smb_rc);
free(fn);
}
error = rc_merge(SMB_CFG_FILE, &smb_rc);
if (smb_rc == NULL) {
printf("Warning: no cfg file(s) found.\n");
return ENOENT;
}
return 0;
}
void *
smb_dumptree(void)
{
size_t len;
void *p;
int error;
error = sysctlbyname("net.smb.treedump", NULL, &len, NULL, 0);
if (error)
return NULL;
p = malloc(len);
if (p == NULL)
return NULL;
error = sysctlbyname("net.smb.treedump", p, &len, NULL, 0);
if (error) {
free(p);
return NULL;
}
return p;
}
void
smb_simplecrypt(char *dst, const char *src)
{
int ch, pos;
*dst++ = '$';
*dst++ = '$';
*dst++ = '1';
pos = 27;
while (*src) {
ch = *src++;
if (isascii(ch))
ch = (isupper(ch) ? ('A' + (ch - 'A' + 13) % 26) :
islower(ch) ? ('a' + (ch - 'a' + 13) % 26) : ch);
ch ^= pos;
pos += 13;
sprintf(dst, "%02x", ch);
dst += 2;
}
*dst = 0;
}
int
smb_simpledecrypt(char *dst, const char *src)
{
char *ep, hexval[3];
int len, ch, pos;
if (strncmp(src, "$$1", 3) != 0)
return EINVAL;
src += 3;
len = strlen(src);
if (len & 1)
return EINVAL;
len /= 2;
hexval[2] = 0;
pos = 27;
while (len--) {
hexval[0] = *src++;
hexval[1] = *src++;
ch = strtoul(hexval, &ep, 16);
if (*ep != 0)
return EINVAL;
ch ^= pos;
pos += 13;
if (isascii(ch))
ch = (isupper(ch) ? ('A' + (ch - 'A' + 13) % 26) :
islower(ch) ? ('a' + (ch - 'a' + 13) % 26) : ch);
*dst++ = ch;
}
*dst = 0;
return 0;
}

View file

@ -0,0 +1,18 @@
# $Id: Makefile,v 1.7 2001/04/16 04:34:26 bp Exp $
PROG= mount_smbfs
SRCS= mount_smbfs.c getmntopts.c
MAN8= mount_smbfs.8
BINDIR= /sbin
#NOSHARED=yes
MOUNT= ${.CURDIR}/../mount
CFLAGS+= -DSMBFS -I${MOUNT}
.PATH: ${MOUNT}
LDADD+= -lsmb
DPADD+= ${LIBSMB}
.include <bsd.prog.mk>

View file

@ -0,0 +1,108 @@
/*-
* Copyright (c) 1994
* The Regents of the University of California. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*/
#ifndef lint
#if 0
static char sccsid[] = "@(#)getmntopts.c 8.3 (Berkeley) 3/29/95";
#else
static const char rcsid[] =
"$Id: getmntopts.c,v 1.1 2000/03/29 01:26:41 bp Exp $";
#endif
#endif /* not lint */
#include <sys/param.h>
#include <err.h>
#include <stdlib.h>
#include <string.h>
#include "mntopts.h"
int getmnt_silent = 0;
void
getmntopts(options, m0, flagp, altflagp)
const char *options;
const struct mntopt *m0;
int *flagp;
int *altflagp;
{
const struct mntopt *m;
int negative, len;
char *opt, *optbuf, *p;
int *thisflagp;
/* Copy option string, since it is about to be torn asunder... */
if ((optbuf = strdup(options)) == NULL)
err(1, NULL);
for (opt = optbuf; (opt = strtok(opt, ",")) != NULL; opt = NULL) {
/* Check for "no" prefix. */
if (opt[0] == 'n' && opt[1] == 'o') {
negative = 1;
opt += 2;
} else
negative = 0;
/*
* for options with assignments in them (ie. quotas)
* ignore the assignment as it's handled elsewhere
*/
p = strchr(opt, '=');
if (p)
*++p = '\0';
/* Scan option table. */
for (m = m0; m->m_option != NULL; ++m) {
len = strlen(m->m_option);
if (strncasecmp(opt, m->m_option, len) == 0)
if ( m->m_option[len] == '\0'
|| m->m_option[len] == '='
)
break;
}
/* Save flag, or fail if option is not recognized. */
if (m->m_option) {
thisflagp = m->m_altloc ? altflagp : flagp;
if (negative == m->m_inverse)
*thisflagp |= m->m_flag;
else
*thisflagp &= ~m->m_flag;
} else if (!getmnt_silent) {
errx(1, "-o %s: option not supported", opt);
}
}
free(optbuf);
}

View file

@ -0,0 +1,91 @@
/*-
* Copyright (c) 1994
* The Regents of the University of California. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)mntopts.h 8.7 (Berkeley) 3/29/95
* $Id: mntopts.h,v 1.1 2000/03/29 01:26:41 bp Exp $
*/
struct mntopt {
const char *m_option; /* option name */
int m_inverse; /* if a negative option, e.g. "dev" */
int m_flag; /* bit to set, e.g. MNT_RDONLY */
int m_altloc; /* 1 => set bit in altflags */
};
/* User-visible MNT_ flags. */
#define MOPT_ASYNC { "async", 0, MNT_ASYNC, 0 }
#define MOPT_NOATIME { "atime", 1, MNT_NOATIME, 0 }
#define MOPT_NODEV { "dev", 1, MNT_NODEV, 0 }
#define MOPT_NOEXEC { "exec", 1, MNT_NOEXEC, 0 }
#define MOPT_NOSUID { "suid", 1, MNT_NOSUID, 0 }
#define MOPT_NOSYMFOLLOW { "symfollow", 1, MNT_NOSYMFOLLOW, 0 }
#define MOPT_RDONLY { "rdonly", 0, MNT_RDONLY, 0 }
#define MOPT_SYNC { "sync", 0, MNT_SYNCHRONOUS, 0 }
#define MOPT_UNION { "union", 0, MNT_UNION, 0 }
#define MOPT_USERQUOTA { "userquota", 0, 0, 0 }
#define MOPT_GROUPQUOTA { "groupquota", 0, 0, 0 }
#define MOPT_NOCLUSTERR { "clusterr", 1, MNT_NOCLUSTERR, 0 }
#define MOPT_NOCLUSTERW { "clusterw", 1, MNT_NOCLUSTERW, 0 }
#define MOPT_SUIDDIR { "suiddir", 0, MNT_SUIDDIR, 0 }
/* Control flags. */
#define MOPT_FORCE { "force", 0, MNT_FORCE, 0 }
#define MOPT_UPDATE { "update", 0, MNT_UPDATE, 0 }
#define MOPT_RO { "ro", 0, MNT_RDONLY, 0 }
#define MOPT_RW { "rw", 1, MNT_RDONLY, 0 }
/* This is parsed by mount(8), but is ignored by specific mount_*(8)s. */
#define MOPT_AUTO { "auto", 0, 0, 0 }
#define MOPT_FSTAB_COMPAT \
MOPT_RO, \
MOPT_RW, \
MOPT_AUTO
/* Standard options which all mounts can understand. */
#define MOPT_STDOPTS \
MOPT_USERQUOTA, \
MOPT_GROUPQUOTA, \
MOPT_FSTAB_COMPAT, \
MOPT_NOATIME, \
MOPT_NODEV, \
MOPT_NOEXEC, \
MOPT_SUIDDIR, /* must be before MOPT_NOSUID */ \
MOPT_NOSUID, \
MOPT_NOSYMFOLLOW, \
MOPT_RDONLY, \
MOPT_UNION, \
MOPT_NOCLUSTERR, \
MOPT_NOCLUSTERW
void getmntopts __P((const char *, const struct mntopt *, int *, int *));
extern int getmnt_silent;

View file

@ -0,0 +1,158 @@
.\" $Id: mount_smbfs.8,v 1.8 2000/06/09 13:52:56 bp Exp $
.Dd Mar 10, 2000
.Dt MOUNT_SMBFS 8
.Os FreeBSD
.Sh NAME
.Nm mount_smbfs
.Nd mounts a shared resource from an SMB file server
.Sh SYNOPSIS
.Nm mount_smbfs
.Op Fl E Ar cs1:cs2
.Op Fl I Ar host
.Op Fl L Ar locale
.Op Fl M Ar crights:srights
.Op Fl N
.Op Fl O Ar cowner:cgroup/sowner:sgroup
.Op Fl R Ar retrycount
.Op Fl T Ar timeout
.Op Fl W Ar workgroup
.Op Fl c Ar case
.Op Fl d Ar mode
.Op Fl f Ar mode
.Op Fl g Ar gid
.Op Fl n Ar opt
.Op Fl u Ar uid
.Ar //user@server/share
.Ar node
.Sh DESCRIPTION
The
.Nm
command mounts a share from a remote server using SMB/CIFS protocol.
.Pp
The options are:
.Bl -tag -width indent
.It Fl E Ar cs1:cs2
Specifies local
.Ar (cs1)
and server's
.Ar (cs2)
character sets.
.It Fl I Ar host
Do not use NetBIOS name resolver and connect directly to
.Ar host ,
which can be either a valid DNS name or an IP address.
.It Fl L Ar locale
Use
.Ar locale
for lower/upper case conversion routines.
Set the locale for case conversion.
By default
.Nm
tries to use an environment variable
.Ev LC_*
to determine it.
.It Fl M Ar crights:srights
Assign access rights to the newly created connection.
See
.Xr nsmb 8
for theory.
.It Fl N
Do not ask for a password.
At run time,
.Nm
reads the
.Pa ~/.nsmbrc
file for additional configuration parameters and a password.
If no password is found the
.Nm
prompts for it.
.It Fl O Ar cowner:cgroup/sowner:sgroup
Assign owner/group attributes to the newly created connection.
See
.Xr nsmb 8
for theory.
.It Fl R Ar retrycount
How many retries should be done before the SMB requester decides to drop
the connection.
.It Fl T Ar timeout
Timeout in seconds for each request.
.It Fl W Ar workgroup
This option specifies the workgroup to be used in the authentication request.
.It Fl c Ar case
Set a
.Ar case
option which affects name representation.
.Ar case
can be one of the following:
.Bl -tag -width "ValueXX"
.It Em Value
.Em Meaning
.It l
All existing file names converted to lower case.
Newly created file gets a lower case.
.It u
All existing file names converted to upper case.
Newly created file gets an upper case unde.
.El
.It Fl f Ar mode , Fl d Ar mode
Specify permissions that should be assigned to files and directories.
The values must be specified as octal numbers.
Default value for the file mode
is taken from mount point, default value for the dir mode adds execute
permission where the file mode gives read permission.
Note that these permissions can differ from the rights granted by SMB
server.
.It Fl u Ar uid , Fl g Ar gid
User id and group id assigned to files.
The default is owner and group id from
directory where the volume is mounted.
.It Ar //user@server/share
The
.Nm
command will use
.Ar server
as the NetBIOS name of remote computer,
.Ar user
as the remote user name and
.Ar share
as the resource name on a remote server.
.It Ar node
Path to mount point.
.El
.Sh FILES
.Bl -tag -width /var/log/wtmp -compact
.It Pa ~/.nsmbrc
Keeps static parameters for connections and other information.
See
.Pa ./examples/dot.nsmbrc
for details.
.El
.Sh EXAMPLES
The following examples illustrate how to connect to a SMB server
.Em SAMBA
as user
.Em GUEST
and mount shares
.Em PUBLIC
and
.Em TMP :
.Bd -literal -offset indent
mount_smbfs -I samba.mydomain.com //guest@samba/public /smb/public
mount_smbfs -I 192.168.20.3 -E koi8-r:cp866 //guest@samba/tmp /smb/tmp
.Ed
.Pp
It is possible to use
.Xr fstab 5
for smbfs mounts:
.Bd -literal -offset indent
//guest@samba/public /smb/public smbfs rw,noauto 0 0
.Ed
.Sh BUGS
Please report bugs to the author.
.Sh AUTHORS
.An Boris Popov Aq bp@butya.kz ,
.Aq bp@freebsd.org

View file

@ -0,0 +1,265 @@
/*
* Copyright (c) 2000-2001, Boris Popov
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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.
*
* $Id: mount_smbfs.c,v 1.13 2001/04/16 12:46:46 bp Exp $
*/
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/errno.h>
#include <sys/mount.h>
#include <stdio.h>
#include <string.h>
#include <pwd.h>
#include <grp.h>
#include <unistd.h>
#include <ctype.h>
#include <stdlib.h>
#include <err.h>
#include <sysexits.h>
#include <cflib.h>
#include <netsmb/smb.h>
#include <netsmb/smb_conn.h>
#include <netsmb/smb_lib.h>
#include <fs/smbfs/smbfs.h>
#include "mntopts.h"
static char mount_point[MAXPATHLEN + 1];
static void usage(void);
static struct mntopt mopts[] = {
MOPT_STDOPTS,
{ NULL }
};
int
main(int argc, char *argv[])
{
struct smb_ctx sctx, *ctx = &sctx;
struct smbfs_args mdata;
struct stat st;
struct vfsconf vfc;
char *next;
int opt, error, mntflags, caseopt;
if (argc == 2) {
if (strcmp(argv[1], "-h") == 0) {
usage();
} else if (strcmp(argv[1], "-v") == 0) {
errx(EX_OK, "version %d.%d.%d", SMBFS_VERSION / 100000,
(SMBFS_VERSION % 10000) / 1000,
(SMBFS_VERSION % 1000) / 100);
}
}
if (argc < 3)
usage();
error = getvfsbyname(SMBFS_VFSNAME, &vfc);
if (error && vfsisloadable(SMBFS_VFSNAME)) {
if(vfsload(SMBFS_VFSNAME))
err(EX_OSERR, "vfsload("SMBFS_VFSNAME")");
endvfsent();
error = getvfsbyname(SMBFS_VFSNAME, &vfc);
}
if (error)
errx(EX_OSERR, "SMB filesystem is not available");
if (smb_lib_init() != 0)
exit(1);
mntflags = error = 0;
bzero(&mdata, sizeof(mdata));
mdata.uid = mdata.gid = -1;
caseopt = SMB_CS_NONE;
if (smb_ctx_init(ctx, argc, argv, SMBL_SHARE, SMBL_SHARE, SMB_ST_DISK) != 0)
exit(1);
if (smb_ctx_readrc(ctx) != 0)
exit(1);
if (smb_rc)
rc_close(smb_rc);
while ((opt = getopt(argc, argv, STDPARAM_OPT"c:d:f:g:l:n:o:u:w:")) != -1) {
switch (opt) {
case STDPARAM_ARGS:
error = smb_ctx_opt(ctx, opt, optarg);
if (error)
exit(1);
break;
case 'u': {
struct passwd *pwd;
pwd = isdigit(optarg[0]) ?
getpwuid(atoi(optarg)) : getpwnam(optarg);
if (pwd == NULL)
errx(EX_NOUSER, "unknown user '%s'", optarg);
mdata.uid = pwd->pw_uid;
break;
}
case 'g': {
struct group *grp;
grp = isdigit(optarg[0]) ?
getgrgid(atoi(optarg)) : getgrnam(optarg);
if (grp == NULL)
errx(EX_NOUSER, "unknown group '%s'", optarg);
mdata.gid = grp->gr_gid;
break;
}
case 'd':
errno = 0;
mdata.dir_mode = strtol(optarg, &next, 8);
if (errno || *next != 0)
errx(EX_DATAERR, "invalid value for directory mode");
break;
case 'f':
errno = 0;
mdata.file_mode = strtol(optarg, &next, 8);
if (errno || *next != 0)
errx(EX_DATAERR, "invalid value for file mode");
break;
case '?':
usage();
/*NOTREACHED*/
case 'n': {
char *inp, *nsp;
nsp = inp = optarg;
while ((nsp = strsep(&inp, ",;:")) != NULL) {
if (strcasecmp(nsp, "LONG") == 0)
mdata.flags |= SMBFS_MOUNT_NO_LONG;
else
errx(EX_DATAERR, "unknown suboption '%s'", nsp);
}
break;
};
case 'o':
getmntopts(optarg, mopts, &mntflags, 0);
break;
case 'c':
switch (optarg[0]) {
case 'l':
caseopt |= SMB_CS_LOWER;
break;
case 'u':
caseopt |= SMB_CS_UPPER;
break;
default:
errx(EX_DATAERR, "invalid suboption '%c' for -c",
optarg[0]);
}
break;
default:
usage();
}
}
if (optind == argc - 2)
optind++;
if (optind != argc - 1)
usage();
realpath(argv[optind], mount_point);
if (stat(mount_point, &st) == -1)
err(EX_OSERR, "could not find mount point %s", mount_point);
if (!S_ISDIR(st.st_mode)) {
errno = ENOTDIR;
err(EX_OSERR, "can't mount on %s", mount_point);
}
/*
if (smb_getextattr(mount_point, &einfo) == 0)
errx(EX_OSERR, "can't mount on %s twice", mount_point);
*/
if (mdata.uid == -1)
mdata.uid = st.st_uid;
if (mdata.gid == -1)
mdata.gid = st.st_gid;
if (mdata.file_mode == 0 )
mdata.file_mode = st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
if (mdata.dir_mode == 0) {
mdata.dir_mode = mdata.file_mode;
if (mdata.dir_mode & S_IRUSR)
mdata.dir_mode |= S_IXUSR;
if (mdata.dir_mode & S_IRGRP)
mdata.dir_mode |= S_IXGRP;
if (mdata.dir_mode & S_IROTH)
mdata.dir_mode |= S_IXOTH;
}
/*
* For now, let connection be private for this mount
*/
ctx->ct_ssn.ioc_opt |= SMBVOPT_PRIVATE;
ctx->ct_ssn.ioc_owner = ctx->ct_sh.ioc_owner = 0; /* root */
ctx->ct_ssn.ioc_group = ctx->ct_sh.ioc_group = mdata.gid;
opt = 0;
if (mdata.dir_mode & S_IXGRP)
opt |= SMBM_EXECGRP;
if (mdata.dir_mode & S_IXOTH)
opt |= SMBM_EXECOTH;
ctx->ct_ssn.ioc_rights |= opt;
ctx->ct_sh.ioc_rights |= opt;
error = smb_ctx_resolve(ctx);
if (error)
exit(1);
error = smb_ctx_lookup(ctx, SMBL_SHARE, SMBLK_CREATE);
if (error) {
exit(1);
}
strcpy(mdata.mount_point,mount_point);
mdata.version = SMBFS_VERSION;
mdata.dev = ctx->ct_fd;
mdata.caseopt = caseopt;
error = mount(SMBFS_VFSNAME, mdata.mount_point, mntflags, (void*)&mdata);
smb_ctx_done(ctx);
if (error) {
smb_error("mount error: %s", error, mdata.mount_point);
exit(1);
}
return 0;
}
static void
usage(void)
{
fprintf(stderr, "%s\n%s\n%s\n%s\n",
"usage: mount_smbfs [-Chv] [-U user] [-connection options]",
" [-M mode] [-c case] [-d mode] [-f mode]",
" [-g gid] [-l locale] [-n os2] [-u uid] [-w scheme]",
" /user@server/share node");
exit (1);
}

View file

@ -0,0 +1,9 @@
# $Id: Makefile,v 1.7 2001/04/16 04:34:26 bp Exp $
PROG= smbutil
SRCS= smbutil.c dumptree.c login.c lookup.c view.c print.c
DPADD= ${LIBSMB}
LDADD= -lsmb
.include <bsd.prog.mk>

View file

@ -0,0 +1,17 @@
#define iprintf(ident,args...) do { printf("%-" # ident "s", ""); \
printf(## args);}while(0)
extern int verbose;
int cmd_dumptree(int argc, char *argv[]);
int cmd_login(int argc, char *argv[]);
int cmd_logout(int argc, char *argv[]);
int cmd_lookup(int argc, char *argv[]);
int cmd_print(int argc, char *argv[]);
int cmd_view(int argc, char *argv[]);
void login_usage(void);
void logout_usage(void);
void lookup_usage(void);
void print_usage(void);
void view_usage(void);

View file

@ -0,0 +1,134 @@
#include <sys/param.h>
#include <sys/time.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <netsmb/smb_lib.h>
#include <netsmb/smb_conn.h>
#include "common.h"
#define DEFBIT(bit) {bit, #bit}
static struct smb_bitname conn_caps[] = {
DEFBIT(SMB_CAP_RAW_MODE),
DEFBIT(SMB_CAP_MPX_MODE),
DEFBIT(SMB_CAP_UNICODE),
DEFBIT(SMB_CAP_LARGE_FILES),
DEFBIT(SMB_CAP_NT_SMBS),
DEFBIT(SMB_CAP_NT_FIND),
DEFBIT(SMB_CAP_EXT_SECURITY),
{0, NULL}
};
static struct smb_bitname vc_flags[] = {
DEFBIT(SMBV_PERMANENT),
{SMBV_PRIVATE, "private"},
{SMBV_SINGLESHARE, "singleshare"},
{SMBV_ENCRYPT, "encpwd"},
{SMBV_WIN95, "win95"},
{SMBV_LONGNAMES,"longnames"},
{0, NULL}
};
static struct smb_bitname ss_flags[] = {
DEFBIT(SMBS_PERMANENT),
{0, NULL}
};
static char *conn_proto[] = {
"unknown",
"PC NETWORK PROGRAM 1.0, PCLAN1.0",
"MICROSOFT NETWORKS 1.03",
"MICROSOFT NETWORKS 3.0, LANMAN1.0",
"LM1.2X002, DOS LM1.2X002",
"DOS LANMAN2.1, LANMAN2.1",
"NT LM 0.12, Windows for Workgroups 3.1a, NT LANMAN 1.0"
};
static char *iod_state[] = {
"Not connected",
"Reconnecting",
"Transport activated",
"Session active",
"Session dead"
};
static void
print_vcinfo(struct smb_vc_info *vip)
{
char buf[200];
printf("VC: \\\\%s\\%s\n", vip->srvname, vip->vcname);
printf("(%s:%s) %o", user_from_uid(vip->uid, 0),
group_from_gid(vip->gid, 0), vip->mode);
printf("\n");
if (!verbose)
return;
iprintf(4, "state: %s\n", iod_state[vip->iodstate]);
iprintf(4, "flags: 0x%04x %s\n", vip->flags,
smb_printb(buf, vip->flags, vc_flags));
iprintf(4, "usecount: %d\n", vip->usecount);
iprintf(4, "dialect: %d (%s)\n", vip->sopt.sv_proto, conn_proto[vip->sopt.sv_proto]);
iprintf(4, "smode: %d\n", vip->sopt.sv_sm);
iprintf(4, "caps: 0x%04x %s\n", vip->sopt.sv_caps,
smb_printb(buf, vip->sopt.sv_caps, conn_caps));
iprintf(4, "maxmux: %d\n", vip->sopt.sv_maxmux);
iprintf(4, "maxvcs: %d\n", vip->sopt.sv_maxvcs);
}
static void
print_shareinfo(struct smb_share_info *sip)
{
char buf[200];
iprintf(4, "Share: %s", sip->sname);
printf("(%s:%s) %o", user_from_uid(sip->uid, 0),
group_from_gid(sip->gid, 0), sip->mode);
printf("\n");
if (!verbose)
return;
iprintf(8, "flags: 0x%04x %s\n", sip->flags,
smb_printb(buf, sip->flags, ss_flags));
iprintf(8, "usecount: %d\n", sip->usecount);
}
int
cmd_dumptree(int argc, char *argv[])
{
void *p, *op;
int *itype;
printf("SMB connections:\n");
p = smb_dumptree();
if (p == NULL) {
printf("None\n");
return 0;
}
op = p;
for (;;) {
itype = p;
if (*itype == SMB_INFO_NONE)
break;
switch (*itype) {
case SMB_INFO_VC:
print_vcinfo(p);
p = (struct smb_vc_info*)p + 1;
break;
case SMB_INFO_SHARE:
print_shareinfo(p);
p = (struct smb_share_info*)p + 1;
break;
default:
printf("Out of sync\n");
free(op);
return 1;
}
}
free(op);
printf("\n");
return 0;
}

View file

@ -0,0 +1,202 @@
/*
* Copyright (c) 2000, Boris Popov
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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.
*
* $Id: login.c,v 1.5 2001/01/28 07:35:00 bp Exp $
*/
#include <sys/param.h>
#include <sys/errno.h>
#include <sys/stat.h>
#include <err.h>
#include <stdio.h>
#include <unistd.h>
#include <strings.h>
#include <stdlib.h>
#include <sysexits.h>
#include <cflib.h>
#include <netsmb/smb_lib.h>
#include <netsmb/smb_conn.h>
#include "common.h"
int
cmd_login(int argc, char *argv[])
{
struct smb_ctx sctx, *ctx = &sctx;
int error, opt, setprimary = 0, level;
if (argc < 2)
login_usage();
if (smb_ctx_init(ctx, argc, argv, SMBL_VC, SMBL_SHARE, SMB_ST_ANY) != 0)
exit(1);
if (smb_ctx_readrc(ctx) != 0)
exit(1);
if (smb_rc)
rc_close(smb_rc);
while ((opt = getopt(argc, argv, STDPARAM_OPT"D")) != EOF) {
switch(opt){
case STDPARAM_ARGS:
error = smb_ctx_opt(ctx, opt, optarg);
if (error)
exit(1);
break;
case 'D':
setprimary = 1;
break;
default:
login_usage();
/*NOTREACHED*/
}
}
if (smb_ctx_resolve(ctx) != 0)
exit(1);
level = ctx->ct_parsedlevel;
error = smb_ctx_lookup(ctx, level, 0);
if (error == 0) {
smb_error("connection already exists", error);
exit(0);
}
error = smb_ctx_lookup(ctx, level, SMBLK_CREATE);
if (error) {
smb_error("could not login to server %s", error, ctx->ct_ssn.ioc_srvname);
exit(1);
}
switch (level) {
case SMBL_VC:
opt = SMBV_PERMANENT;
break;
case SMBL_SHARE:
opt = SMBS_PERMANENT;
break;
default:
smb_error("unknown connection level %d", 0, level);
exit(1);
}
error = smb_ctx_setflags(ctx, level, opt, opt);
if (error && error != EACCES) {
smb_error("Can't make connection permanent", error);
exit(1);
}
printf("Connected to %s%s%s\n", ctx->ct_ssn.ioc_user,
level == SMBL_SHARE ? "@" : "",
level == SMBL_SHARE ? ctx->ct_sh.ioc_share : "");
return 0;
}
int
cmd_logout(int argc, char *argv[])
{
struct smb_ctx sctx, *ctx = &sctx;
int error, opt, level;
if (argc < 2)
logout_usage();
if (smb_ctx_init(ctx, argc, argv, SMBL_VC, SMBL_SHARE, SMB_ST_ANY) != 0)
exit(1);
if (smb_ctx_readrc(ctx) != 0)
exit(1);
if (smb_rc)
rc_close(smb_rc);
while ((opt = getopt(argc, argv, STDPARAM_OPT)) != EOF){
switch (opt) {
case STDPARAM_ARGS:
error = smb_ctx_opt(ctx, opt, optarg);
if (error)
exit(1);
break;
default:
logout_usage();
/*NOTREACHED*/
}
}
ctx->ct_ssn.ioc_opt &= ~SMBVOPT_CREATE;
ctx->ct_sh.ioc_opt &= ~SMBSOPT_CREATE;
if (smb_ctx_resolve(ctx) != 0)
exit(1);
level = ctx->ct_parsedlevel;
error = smb_ctx_lookup(ctx, level, 0);
if (error == ENOENT) {
/* ctx->ct_ssn.ioc_opt |= SMBCOPT_SINGLE;
error = smb_ctx_login(ctx);
if (error == ENOENT) {
ctx->ct_ssn.ioc_opt |= SMBCOPT_PRIVATE;
error = smb_ctx_login(ctx);
if (error == ENOENT) {
ctx->ct_ssn.ioc_opt &= ~SMBCOPT_SINGLE;
error = smb_ctx_login(ctx);
}
}*/
if (error) {
smb_error("There is no connection to %s", error, ctx->ct_ssn.ioc_srvname);
exit(1);
}
}
if (error)
exit(1);
switch (level) {
case SMBL_VC:
opt = SMBV_PERMANENT;
break;
case SMBL_SHARE:
opt = SMBS_PERMANENT;
break;
default:
smb_error("unknown connection level %d", 0, level);
exit(1);
}
error = smb_ctx_setflags(ctx, level, opt, 0);
if (error && error != EACCES) {
smb_error("Can't release connection", error);
exit(1);
}
printf("Connection unmarked as permanent and will be closed when possible\n");
exit(0);
}
void
login_usage(void)
{
printf(
"usage: smbutil login [-E cs1:cs2] [-I host] [-L locale] [-M crights:srights]\n"
" [-N cowner:cgroup/sowner:sgroup] [-P]\n"
" [-R retrycount] [-T timeout]\n"
" [-W workgroup] //user@server\n");
exit(1);
}
void
logout_usage(void)
{
printf("usage: smbutil logout [user@server]\n");
exit(1);
}

View file

@ -0,0 +1,110 @@
/*
* Copyright (c) 2000, Boris Popov
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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.
*
* $Id: lookup.c,v 1.3 2000/10/15 14:26:49 bp Exp $
*/
#include <sys/param.h>
#include <sys/errno.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <err.h>
#include <stdio.h>
#include <unistd.h>
#include <strings.h>
#include <stdlib.h>
#include <sysexits.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cflib.h>
#include <netsmb/netbios.h>
#include <netsmb/smb_lib.h>
#include <netsmb/nb_lib.h>
#include <netsmb/smb_conn.h>
#include "common.h"
int
cmd_lookup(int argc, char *argv[])
{
struct nb_ctx *ctx;
struct sockaddr *sap;
char *hostname;
int error, opt;
if (argc < 2)
lookup_usage();
error = nb_ctx_create(&ctx);
if (error) {
smb_error("unable to create nbcontext", error);
exit(1);
}
if (smb_open_rcfile() == 0) {
if (nb_ctx_readrcsection(smb_rc, ctx, "default", 0) != 0)
exit(1);
rc_close(smb_rc);
}
while ((opt = getopt(argc, argv, "w:")) != EOF) {
switch(opt){
case 'w':
nb_ctx_setns(ctx, optarg);
break;
default:
lookup_usage();
/*NOTREACHED*/
}
}
if (optind >= argc)
lookup_usage();
if (nb_ctx_resolve(ctx) != 0)
exit(1);
hostname = argv[argc - 1];
/* printf("Looking for %s...\n", hostname);*/
error = nbns_resolvename(hostname, ctx, &sap);
if (error) {
smb_error("unable to resolve %s", error, hostname);
exit(1);
}
printf("Got response from %s\n", inet_ntoa(ctx->nb_lastns.sin_addr));
printf("IP address of %s: %s\n", hostname, inet_ntoa(((struct sockaddr_in*)sap)->sin_addr));
return 0;
}
void
lookup_usage(void)
{
printf("usage: smbutil lookup [-w host] name\n");
exit(1);
}

View file

@ -0,0 +1,152 @@
/*
* Copyright (c) 2000, Boris Popov
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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.
*
* $Id: print.c,v 1.4 2001/01/28 07:35:01 bp Exp $
*/
#include <sys/param.h>
#include <sys/errno.h>
#include <sys/stat.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <strings.h>
#include <stdlib.h>
#include <sysexits.h>
#include <cflib.h>
#include <netsmb/smb_lib.h>
#include <netsmb/smb_conn.h>
#include "common.h"
int
cmd_print(int argc, char *argv[])
{
struct smb_ctx sctx, *ctx = &sctx;
smbfh fh;
off_t offset;
char buf[8192];
char *filename;
char fnamebuf[256];
int error, opt, i, file, count;
if (argc < 2)
view_usage();
if (smb_ctx_init(ctx, argc, argv, SMBL_SHARE, SMBL_SHARE, SMB_ST_PRINTER) != 0)
exit(1);
if (smb_ctx_readrc(ctx) != 0)
exit(1);
if (smb_rc)
rc_close(smb_rc);
while ((opt = getopt(argc, argv, STDPARAM_OPT)) != EOF) {
switch(opt){
case STDPARAM_ARGS:
error = smb_ctx_opt(ctx, opt, optarg);
if (error)
exit(1);
break;
default:
view_usage();
/*NOTREACHED*/
}
}
if (optind + 1 >= argc)
print_usage();
filename = argv[optind + 1];
if (strcmp(filename, "-") == 0) {
file = 0; /* stdin */
filename = "stdin";
} else {
file = open(filename, O_RDONLY, 0);
if (file < 0) {
smb_error("could not open file %s\n", errno, filename);
exit(1);
}
}
if (smb_ctx_resolve(ctx) != 0)
exit(1);
error = smb_ctx_lookup(ctx, SMBL_SHARE, SMBLK_CREATE);
if (error) {
smb_error("could not login to server %s", error, ctx->ct_ssn.ioc_srvname);
exit(1);
}
snprintf(fnamebuf, sizeof(fnamebuf), "%s_%s_%s", ctx->ct_ssn.ioc_user,
ctx->ct_ssn.ioc_srvname, filename);
error = smb_smb_open_print_file(ctx, 0, 1, fnamebuf, &fh);
if (error) {
smb_error("could not open print job", error);
exit(1);
}
offset = 0;
error = 0;
for(;;) {
count = read(file, buf, sizeof(buf));
if (count == 0)
break;
if (count < 0) {
error = errno;
smb_error("error reading input file\n", error);
break;
}
i = smb_write(ctx, fh, offset, count, buf);
if (i < 0) {
error = errno;
smb_error("error writing spool file\n", error);
break;
}
if (i != count) {
smb_error("incomplete write to spool file\n", 0);
error = EIO;
break;
}
offset += count;
}
close(file);
error = smb_smb_close_print_file(ctx, fh);
if (error)
smb_error("an error while closing spool file\n", error);
return error ? 1 : 0;
}
void
print_usage(void)
{
printf(
"usage: smbutil print [connection optinons] //user@server/share\n"
);
exit(1);
}

View file

@ -0,0 +1,124 @@
.\" $Id: smbutil.1,v 1.3 2000/07/17 01:49:27 bp Exp $
.Dd Feb 14, 2000
.Dt SMBUTIL 1
.Os
.Sh NAME
.Nm smbutil
.Nd Interface to SMB requester
.Sh SYNOPSIS
.Nm smbutil
.Op Fl hv
.Ar command
.Op Fl options
.Op Ar args
.Sh DESCRIPTION
The
.Nm
command used to control SMB requester and issue various commands.
.Pp
There are two types of options - global and local to specified command.
.Pp
The global options are:
.Bl -tag -width indent
.It Fl h
Print short help message.
.It Fl v
Verbose output.
.El
.Pp
The commands and local options are:
.Bl -tag -width indent
.It Em crypt Op password
Slightly encrypt clear text password to use it in the
.Pa ~/.nsmbrc
file. The encrypted password starts with '$$1' symbols.
Warning: the encryption function is very weak and intented only to hide
clear text password.
If
.Ar password
is ommited from command line, program will prompt for one.
.It Em help Ar command
Print usage information about
.Ar command .
.It Em lc
List active connections and their parameters.
.It Xo
.Em login
.Op Fl connection\ options
.Ar //user@server Ns Op Ar /share
.Xc
Login/attach to the specified
.Ar server
and/or
.Ar share
as
.Ar user .
This command will create and authenticate connection to an SMB server, and
will leave it active after exit.
Thus, one can login only once and then
use other SMB commands without authentication procedure and additional
connections.
For the description of
.Op Fl connection\ options
see
.Xr mount_smbfs 8
command (all uppercase options are connection options).
.It Xo
.Em logout
.Ar //user@server Ns Op Ar /share
.Xc
Logout/detach from the specified
.Ar server
and/or
.Ar share
as
.Ar user .
This command will destroy connection created by
.Ar login
command. A connection may not be closed immediately if it used by other
programs.
.It Xo
.Em lookup
.Op Fl w Ar host
.Ar name
.Xc
Resolve given
.Ar name
to IP address.
NetBIOS name server can be directly specified via
.Op Fl w
option.
.It Xo
.Em print
.Op Fl connection\ options
.Ar //user@server/share
.Ar file
.Xc
Send given
.Ar file
to the specified queue on the remote server.
If
.Ar file
is '-', then standard input will be used.
.It Xo
.Em view
.Op Fl connection\ options
.Ar //user@server
.Xc
List resources avaliable on the specified
.Ar server
for the user
.Ar user .
.El
.Sh FILES
.Bl -tag -width /var/log/wtmp -compact
.It Pa ~/.nsmbrc
keeps description for each connection.
See
.Pa ./examples/dot.nsmbrc
for details.
.Sh AUTHORS
.An Boris Popov Aq bp@butya.kz ,
.Aq bp@freebsd.org
.Sh BUGS
Please report any bugs to the author.

View file

@ -0,0 +1,155 @@
#include <sys/param.h>
#include <sys/time.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <err.h>
#include <sysexits.h>
#include <netsmb/smb_lib.h>
#include <netsmb/smb_conn.h>
#include "common.h"
extern char *__progname;
static void help(void);
static void help_usage(void);
static int cmd_crypt(int argc, char *argv[]);
static int cmd_help(int argc, char *argv[]);
int verbose;
typedef int cmd_fn_t (int argc, char *argv[]);
typedef void cmd_usage_t (void);
#define CMDFL_NO_KMOD 0x0001
static struct commands {
const char * name;
cmd_fn_t* fn;
cmd_usage_t * usage;
int flags;
} commands[] = {
{"crypt", cmd_crypt, NULL, CMDFL_NO_KMOD},
{"help", cmd_help, help_usage, CMDFL_NO_KMOD},
{"lc", cmd_dumptree, NULL},
{"login", cmd_login, login_usage},
{"logout", cmd_logout, logout_usage},
{"lookup", cmd_lookup, lookup_usage, CMDFL_NO_KMOD},
{"print", cmd_print, print_usage},
{"view", cmd_view, view_usage},
{NULL, NULL}
};
static struct commands *
lookupcmd(const char *name)
{
struct commands *cmd;
for (cmd = commands; cmd->name; cmd++) {
if (strcmp(cmd->name, name) == 0)
return cmd;
}
return NULL;
}
int
cmd_crypt(int argc, char *argv[])
{
char *cp, *psw;
if (argc < 2)
psw = getpass("Password:");
else
psw = argv[1];
cp = malloc(strlen(psw + 4));
if (cp == NULL)
errx(EX_DATAERR, "out of memory");
smb_simplecrypt(cp, psw);
printf("%s\n", cp);
free(cp);
exit(0);
}
int
cmd_help(int argc, char *argv[])
{
struct commands *cmd;
char *cp;
if (argc < 2)
help_usage();
cp = argv[1];
cmd = lookupcmd(cp);
if (cmd == NULL)
errx(EX_DATAERR, "unknown command %s", cp);
if (cmd->usage == NULL)
errx(EX_DATAERR, "no specific help for command %s", cp);
cmd->usage();
exit(0);
}
int
main(int argc, char *argv[])
{
struct commands *cmd;
char *cp;
int opt;
if (argc < 2)
help();
while ((opt = getopt(argc, argv, "hv")) != EOF) {
switch (opt) {
case 'h':
help();
/*NOTREACHED */
case 'v':
verbose = 1;
break;
default:
warnx("invalid option %c", opt);
help();
/*NOTREACHED */
}
}
if (optind >= argc)
help();
cp = argv[optind];
cmd = lookupcmd(cp);
if (cmd == NULL)
errx(EX_DATAERR, "unknown command %s", cp);
if ((cmd->flags & CMDFL_NO_KMOD) == 0 && smb_lib_init() != 0)
exit(1);
argc -= optind;
argv += optind;
optind = optreset = 1;
return cmd->fn(argc, argv);
}
static void
help(void) {
printf("\n");
printf("usage: %s [-hv] command [args]\n", __progname);
printf("where commands are:\n"
" crypt [password] slightly encrypt password\n"
" help command display help on \"command\"\n"
" lc display active connections\n"
" login //user@host[/share] login to the specified host\n"
" logout //user@host[/share] logout from the specified host\n"
" print //user@host/share file print file to the specified remote printer\n"
" view //user@host list resources on the specified host\n"
"\n");
exit(1);
}
static void
help_usage(void) {
printf("usage: smbutil help command\n");
exit(1);
}

View file

@ -0,0 +1,127 @@
/*
* Copyright (c) 2000, Boris Popov
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* 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.
*
* $Id: view.c,v 1.7 2001/01/28 07:35:01 bp Exp $
*/
#include <sys/param.h>
#include <sys/errno.h>
#include <sys/stat.h>
#include <sys/iconv.h>
#include <err.h>
#include <stdio.h>
#include <unistd.h>
#include <strings.h>
#include <stdlib.h>
#include <sysexits.h>
#include <cflib.h>
#include <netsmb/smb_lib.h>
#include <netsmb/smb_conn.h>
#include <netsmb/smb_rap.h>
#include "common.h"
static char *shtype[] = {
"disk",
"printer",
"pipe",
"comm",
"unknown"
};
int
cmd_view(int argc, char *argv[])
{
struct smb_ctx sctx, *ctx = &sctx;
struct smb_share_info_1 *rpbuf, *ep;
char *cp;
int error, opt, bufsize, i, entries, total;
if (argc < 2)
view_usage();
if (smb_ctx_init(ctx, argc, argv, SMBL_VC, SMBL_VC, SMB_ST_ANY) != 0)
exit(1);
if (smb_ctx_readrc(ctx) != 0)
exit(1);
if (smb_rc)
rc_close(smb_rc);
while ((opt = getopt(argc, argv, STDPARAM_OPT)) != EOF) {
switch(opt){
case STDPARAM_ARGS:
error = smb_ctx_opt(ctx, opt, optarg);
if (error)
exit(1);
break;
default:
view_usage();
/*NOTREACHED*/
}
}
smb_ctx_setshare(ctx, "IPC$", SMB_ST_ANY);
if (smb_ctx_resolve(ctx) != 0)
exit(1);
error = smb_ctx_lookup(ctx, SMBL_SHARE, SMBLK_CREATE);
if (error) {
smb_error("could not login to server %s", error, ctx->ct_ssn.ioc_srvname);
exit(1);
}
printf("Share Type Comment\n");
printf("-------------------------------\n");
bufsize = 65535;
rpbuf = malloc(bufsize);
error = smb_rap_NetShareEnum(ctx, 1, rpbuf, bufsize, &entries, &total);
if (error &&
error != (SMB_ERROR_MORE_DATA | SMB_RAP_ERROR)) {
smb_error("unable to list resources", error);
exit(1);
}
for (ep = rpbuf, i = 0; i < entries; i++, ep++) {
cp = (char*)rpbuf + ep->shi1_remark;
printf("%-12s %-10s %s\n", ep->shi1_netname,
shtype[ep->shi1_type],
ep->shi1_remark ? nls_str_toloc(cp, cp) : "");
}
printf("\n%d shares listed from %d available\n", entries, total);
free(rpbuf);
return 0;
}
void
view_usage(void)
{
printf(
"usage: smbutil view [connection optinons] //[user@]server\n"
);
exit(1);
}