Import ncpfs 0.3
This commit is contained in:
BIN
.downloads/ncpfs-0.3.tgz
Normal file
BIN
.downloads/ncpfs-0.3.tgz
Normal file
Binary file not shown.
17
BUGS
Normal file
17
BUGS
Normal file
@@ -0,0 +1,17 @@
|
||||
Maybe you want to look at LIMITATIONS in README. Some might consider
|
||||
them to be bugs.
|
||||
|
||||
But there are really problems that might be fixed in the future.
|
||||
|
||||
Invalid directory timestamps:
|
||||
I did not yet find out how to get valid timestamps for directories
|
||||
from a NetWare server. So I simply return 0, which means 01.01.70. If
|
||||
anybody knows how to get these values, please mail
|
||||
lendecke@namu01.gwdg.de.
|
||||
|
||||
'df' returns 0:
|
||||
Free disk space is distributed among the volumes in NetWare. df is
|
||||
only able to report one number per mounted filesystem. As connections
|
||||
are quite expensive for NetWare (with lwared that might change ...), I
|
||||
rejected the alternative to mount only a single volume for a unix
|
||||
mount point. So I simply return 0.
|
||||
7
Changes
7
Changes
@@ -1,3 +1,10 @@
|
||||
ncpfs-0.2 -> ncpfs-0.3
|
||||
|
||||
- removed bug in get_pname_static
|
||||
- removed bug in 'ncpmount -n'
|
||||
- fake '.' and '..'
|
||||
- return 0 for df and directory timestamps. See file BUGS
|
||||
|
||||
ncpfs-0.1 -> ncpfs-0.2
|
||||
|
||||
- should be compileable with gcc other than 2.7.0
|
||||
|
||||
4
Makefile
4
Makefile
@@ -6,8 +6,8 @@ INCLUDES = -I/usr/src/linux/include
|
||||
|
||||
CFLAGS = -Wall -Wstrict-prototypes -O2 -DMODULE -fomit-frame-pointer \
|
||||
$(INCLUDES) \
|
||||
-DDEBUG_NCP_MALLOC
|
||||
# -DDEBUG_NCP=1 -DDEBUG_NCP_MALLOC
|
||||
# -DDEBUG_NCP_MALLOC
|
||||
|
||||
CC = gcc -D__KERNEL__ -I.
|
||||
AS = as
|
||||
@@ -52,7 +52,7 @@ clean:
|
||||
rm -f *.o *~
|
||||
|
||||
realclean: clean
|
||||
rm -fr ncpmount ncptest .depend $(DISTFILE) mnt
|
||||
rm -fr ncpmount ncptest .depend $(DISTFILE) mnt *.out
|
||||
|
||||
modules: ncpfs.o
|
||||
|
||||
|
||||
46
README
46
README
@@ -17,13 +17,46 @@ I use tools written by Greg Page, Caldera. I hope I did not do too
|
||||
much harm to their business. For your convenience I included the file
|
||||
ipx.tar made available by Caldera.
|
||||
|
||||
For the curious: the file ncplib.c is usable from user space as well!
|
||||
Look at the file ncptest.c for a possible use. I use ncptest to check
|
||||
my assumptions about the widely undocumented NetWare Core
|
||||
Protocol. Maybe this is the beginning of a free NetWare API for Linux!
|
||||
I would be happy to receive your comments on this.
|
||||
My main source of information is a book written in german by Manfred
|
||||
Hill and Ralf Zessin, "Netzwerkprogrammierung in C", IWT Verlag GmbH,
|
||||
1995, ISBN 3-88322-491-X. It contains quite a lot of typographical and
|
||||
other errors, but I find it very valuable as an introduction to NCP
|
||||
programming. If you know about the concepts and possibilities of NCP,
|
||||
Ralph Brown's interrupt list becomes much more readable. It's much
|
||||
easier to find undocumented information if you know what to look for!
|
||||
|
||||
LIMITATIONS (compare these with smbfs :-))
|
||||
|
||||
MAILING LIST
|
||||
|
||||
There is a mailing list for discussing lwared and ncpfs. Here's the
|
||||
message I received after subscribing:
|
||||
|
||||
---
|
||||
Thank you for your subscription to the list "linware".
|
||||
|
||||
Topics for the list:
|
||||
- discussing LinWare server, its features, installation problems and bugs
|
||||
- using IPX protocol under Linux
|
||||
- IPX routing and router daemons under Linux
|
||||
|
||||
Send your list postings to address: "linware@sh.cvut.cz"
|
||||
Send your list control commands to address: "listserv@sh.cvut.cz"
|
||||
---
|
||||
|
||||
You can subscribe to this list by sending a message with a line
|
||||
'add your_name@your_host linware' to listserv@sh.cvut.cz .
|
||||
|
||||
|
||||
NCPLIB
|
||||
|
||||
For the curious: the file ncplib.c is usable from user space as well.
|
||||
Look at the file ncptest.c for a possible use. I use ncptest to check
|
||||
my assumptions about the widely undocumented NetWare Core Protocol.
|
||||
Maybe this is the beginning of a free NetWare API for Linux! I would
|
||||
be happy to receive your comments on this.
|
||||
|
||||
|
||||
LIMITATIONS (compare these with smbfs :-)
|
||||
|
||||
The limitations ncpfs has are the natural limitations of the NCP
|
||||
protocol, which was designed with MS-DOS based PCs in mind. The first
|
||||
@@ -44,4 +77,3 @@ different. You can never know when the client will access the file-id
|
||||
you offered, so you would have to cache the inode numbers
|
||||
indefinitely long. I think this should not be done in kernel mode, as
|
||||
it would require an unlimited amount of RAM.
|
||||
|
||||
|
||||
127
dir.c
127
dir.c
@@ -303,13 +303,34 @@ ncp_readdir(struct inode *inode, struct file *filp,
|
||||
}
|
||||
|
||||
static int
|
||||
ncp_read_volume_list(struct ncp_server *server, int start_with, int cache_size)
|
||||
ncp_read_volume_list(struct ncp_server *server, int fpos, int cache_size)
|
||||
{
|
||||
struct ncp_dirent *entry = c_entry;
|
||||
|
||||
int total_count = 0;
|
||||
int i;
|
||||
|
||||
void fill_one(char *name)
|
||||
{
|
||||
if (total_count < fpos) {
|
||||
DPRINTK("ncp_do_readdir: skipped file: %s\n", name);
|
||||
} else if (total_count >= fpos + cache_size) {
|
||||
return;
|
||||
} else {
|
||||
DPRINTK("ncp_do_readdir: found file: %s\n", name);
|
||||
|
||||
entry->attr = aDIR;
|
||||
entry->mtime = 0;
|
||||
entry->ctime = 0;
|
||||
entry->atime = 0;
|
||||
entry->size = 1024;
|
||||
entry->f_pos = total_count;
|
||||
strcpy(entry->path, name);
|
||||
entry += 1;
|
||||
}
|
||||
total_count += 1;
|
||||
}
|
||||
|
||||
for (i=0; i<NCP_NUMBER_OF_VOLUMES; i++) {
|
||||
|
||||
struct ncp_volume_info info;
|
||||
@@ -319,29 +340,12 @@ ncp_read_volume_list(struct ncp_server *server, int start_with, int cache_size)
|
||||
}
|
||||
|
||||
if (strlen(info.volume_name) > 0) {
|
||||
|
||||
if (total_count < start_with) {
|
||||
DPRINTK("ncp_read_volumes: skipped vol: %s\n",
|
||||
info.volume_name);
|
||||
} else if (total_count >= start_with + cache_size) {
|
||||
return (total_count - start_with);
|
||||
} else {
|
||||
DPRINTK("ncp_read_volumes: found vol %s\n",
|
||||
info.volume_name);
|
||||
entry->attr = aDIR;
|
||||
entry->mtime = 0;
|
||||
entry->ctime = 0;
|
||||
entry->atime = 0;
|
||||
entry->size = 1024;
|
||||
entry->f_pos = total_count;
|
||||
strcpy(entry->path, info.volume_name);
|
||||
entry += 1;
|
||||
}
|
||||
|
||||
total_count += 1;
|
||||
fill_one(info.volume_name);
|
||||
}
|
||||
}
|
||||
return (total_count - start_with);
|
||||
fill_one(".");
|
||||
fill_one("..");
|
||||
return (total_count - fpos);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -353,6 +357,41 @@ ncp_do_readdir(struct ncp_server *server, struct inode *dir, int fpos,
|
||||
|
||||
int total_count = 0;
|
||||
|
||||
void fill_one(int attr, char *name,
|
||||
int upd_time, int upd_date,
|
||||
int cr_date, int ac_date, int length)
|
||||
{
|
||||
if (total_count < fpos) {
|
||||
DPRINTK("ncp_do_readdir: skipped file: %s\n", name);
|
||||
} else if (total_count >= fpos + cache_size) {
|
||||
return;
|
||||
} else {
|
||||
DPRINTK("ncp_do_readdir: found file: %s\n", name);
|
||||
|
||||
entry->attr = attr;
|
||||
if ((attr & aDIR) == 0) {
|
||||
entry->mtime = date_dos2unix(upd_time,
|
||||
upd_date);
|
||||
entry->ctime = date_dos2unix(0, cr_date);
|
||||
entry->atime = date_dos2unix(0, ac_date);
|
||||
entry->size = length;
|
||||
} else {
|
||||
/* Sorry, I do not know how to get the
|
||||
* values for directories :-(. Mail
|
||||
* lendecke@namu01.gwdg.de if you
|
||||
* know more. */
|
||||
entry->mtime = 0;
|
||||
entry->ctime = 0;
|
||||
entry->atime = 0;
|
||||
entry->size = 1024;
|
||||
}
|
||||
entry->f_pos = total_count;
|
||||
strcpy(entry->path, name);
|
||||
entry += 1;
|
||||
}
|
||||
total_count += 1;
|
||||
}
|
||||
|
||||
void doit(int attr) {
|
||||
|
||||
if (ncp_file_search_init(server, 0, NCP_FINFO(dir)->path,
|
||||
@@ -363,35 +402,20 @@ ncp_do_readdir(struct ncp_server *server, struct inode *dir, int fpos,
|
||||
|
||||
while (ncp_file_search_continue(server, &fsinfo, attr, "*",
|
||||
&finfo) == 0) {
|
||||
|
||||
fill_one(attr, finfo.file_name,
|
||||
finfo.update_time, finfo.update_date,
|
||||
finfo.creation_date, finfo.access_date,
|
||||
finfo.file_length);
|
||||
|
||||
if (total_count < fpos) {
|
||||
DPRINTK("ncp_do_readdir: skipped file: %s\n",
|
||||
finfo.file_name);
|
||||
} else if (total_count >= fpos + cache_size) {
|
||||
return;
|
||||
} else {
|
||||
DPRINTK("ncp_do_readdir: found file: %s\n",
|
||||
finfo.file_name);
|
||||
|
||||
entry->attr = attr;
|
||||
entry->mtime =
|
||||
date_dos2unix(finfo.update_time,
|
||||
finfo.update_date);
|
||||
entry->ctime =
|
||||
date_dos2unix(0, finfo.creation_date);
|
||||
entry->atime =
|
||||
date_dos2unix(0, finfo.access_date);
|
||||
entry->size = (attr & aDIR) != 0 ?
|
||||
1024 : finfo.file_length;
|
||||
entry->f_pos = total_count;
|
||||
strcpy(entry->path, finfo.file_name);
|
||||
entry += 1;
|
||||
}
|
||||
total_count += 1;
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
fill_one(aDIR, ".", 0, 0, 0, 0, 0);
|
||||
fill_one(aDIR, "..", 0, 0, 0, 0, 0);
|
||||
|
||||
doit(0);
|
||||
doit(aDIR);
|
||||
|
||||
@@ -480,7 +504,7 @@ get_pname_static(struct inode *dir, const char *name, int len,
|
||||
/* We're at the top */
|
||||
|
||||
path[0] = '\0';
|
||||
*res_len = 1;
|
||||
*res_len = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -497,7 +521,6 @@ get_pname_static(struct inode *dir, const char *name, int len,
|
||||
path[len] = '\0';
|
||||
}
|
||||
else if (parentlen == 0) {
|
||||
|
||||
memcpy(path, name, len);
|
||||
path[len] = ':';
|
||||
path[len+1] = '\0';
|
||||
@@ -787,10 +810,10 @@ ncp_lookup(struct inode *dir, const char *__name, int len,
|
||||
i, c_entry[i].path);
|
||||
if (strcmp(c_entry[i].path, __name) == 0) {
|
||||
DPRINTK("ncp_lookup: found in cache!\n");
|
||||
finfo = c_entry[i];
|
||||
finfo.path = NULL; /* It's not ours! */
|
||||
found_in_cache = 1;
|
||||
break;
|
||||
finfo = c_entry[i];
|
||||
finfo.path = NULL; /* It's not ours! */
|
||||
found_in_cache = 1;
|
||||
break;
|
||||
}
|
||||
i = (i + 1) % c_size;
|
||||
DDPRINTK("ncp_lookup: index %d, name %s failed\n",
|
||||
|
||||
24
inode.c
24
inode.c
@@ -34,6 +34,7 @@ extern int close_fp(struct file *filp);
|
||||
static void ncp_put_inode(struct inode *);
|
||||
static void ncp_read_inode(struct inode *);
|
||||
static void ncp_put_super(struct super_block *);
|
||||
static void ncp_statfs(struct super_block *sb, struct statfs *buf, int bufsiz);
|
||||
static int ncp_notify_change(struct inode *inode, struct iattr *attr);
|
||||
|
||||
static struct super_operations ncp_sops = {
|
||||
@@ -43,7 +44,7 @@ static struct super_operations ncp_sops = {
|
||||
ncp_put_inode, /* put inode */
|
||||
ncp_put_super, /* put superblock */
|
||||
NULL, /* write superblock */
|
||||
NULL, /* stat filesystem */
|
||||
ncp_statfs, /* stat filesystem */
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -329,6 +330,27 @@ ncp_put_super(struct super_block *sb)
|
||||
MOD_DEC_USE_COUNT;
|
||||
}
|
||||
|
||||
static void
|
||||
ncp_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
|
||||
{
|
||||
struct statfs tmp;
|
||||
|
||||
/* We cannot say how much disk space is left on a mounted
|
||||
NetWare Server, because free space is distributed over
|
||||
volumes, and the current user might have disk quotas. So
|
||||
free space is not that simple to determine. Our decision
|
||||
here is to err conservatively. */
|
||||
|
||||
tmp.f_type = NCP_SUPER_MAGIC;
|
||||
tmp.f_bsize = 512;
|
||||
tmp.f_blocks = 0;
|
||||
tmp.f_bfree = 0;
|
||||
tmp.f_bavail = 0;
|
||||
tmp.f_files = -1;
|
||||
tmp.f_ffree = -1;
|
||||
tmp.f_namelen = 12;
|
||||
memcpy_tofs(buf, &tmp, bufsiz);
|
||||
}
|
||||
|
||||
/* DO MORE */
|
||||
static int
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
Begin3
|
||||
Title: ncpfs
|
||||
Version: 0.2
|
||||
Entered-date: 19. October 1995
|
||||
Version: 0.3
|
||||
Entered-date: 01. November 1995
|
||||
Description: With ncpfs you can mount volumes of your novell
|
||||
server under Linux.
|
||||
Keywords: filesystem kernel ncp novell netware
|
||||
Author: lendecke@namu01.gwdg.de (Volker Lendecke)
|
||||
Maintained-by: lendecke@namu01.gwdg.de (Volker Lendecke)
|
||||
Primary-site: linux01.gwdg.de:/pub/ncpfs
|
||||
~44k ncpfs-0.2.tgz
|
||||
~ 1k ncpfs-0.2.lsm
|
||||
~45k ncpfs-0.3.tgz
|
||||
~ 1k ncpfs-0.3.lsm
|
||||
Copying-policy: GPL
|
||||
End
|
||||
@@ -334,7 +334,7 @@ parse_args(int argc, char *argv[], struct ncp_mount_data *data,
|
||||
*got_password = 1;
|
||||
break;
|
||||
case 'n':
|
||||
data->password[0] = '0';
|
||||
data->password[0] = '\0';
|
||||
*got_password = 1;
|
||||
break;
|
||||
default:
|
||||
@@ -629,7 +629,7 @@ main(int argc, char *argv[])
|
||||
ment.mnt_fsname = server_name;
|
||||
ment.mnt_dir = fullpath(mount_point);
|
||||
ment.mnt_type = "ncpfs";
|
||||
ment.mnt_opts = "";
|
||||
ment.mnt_opts = "rw";
|
||||
ment.mnt_freq = 0;
|
||||
ment.mnt_passno= 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user