Import ncpfs 0.10

This commit is contained in:
ncpfs archive import
2026-04-28 20:39:57 +02:00
parent 5d4b23a5c1
commit 517e207709
45 changed files with 3393 additions and 6000 deletions

View File

@@ -9,9 +9,6 @@
#ifdef MODULE
#include <linux/module.h>
#include <linux/version.h>
#else
#define MOD_INC_USE_COUNT
#define MOD_DEC_USE_COUNT
#endif
#include <linux/sched.h>
@@ -76,9 +73,12 @@ ncp_rename(struct inode *old_dir, const char *old_name, int old_len,
static inline void
str_upper(char *name)
{
while (*name) {
while (*name)
{
if (*name >= 'a' && *name <= 'z')
{
*name -= ('a' - 'A');
}
name++;
}
}
@@ -86,9 +86,12 @@ str_upper(char *name)
static inline void
str_lower(char *name)
{
while (*name) {
while (*name)
{
if (*name >= 'A' && *name <= 'Z')
{
*name += ('a' - 'A');
}
name ++;
}
}
@@ -100,7 +103,7 @@ static struct file_operations ncp_dir_operations = {
ncp_readdir, /* readdir */
NULL, /* select - default */
ncp_ioctl, /* ioctl - default */
NULL, /* mmap */
NULL, /* mmap */
NULL, /* no special open code */
NULL, /* no special release code */
NULL /* fsync */
@@ -166,13 +169,13 @@ ncp_readdir(struct inode *inode, struct file *filp,
put_fs_word(f_pos, &dirent->d_off);
return 1;
}
DDPRINTK("ncp_readdir: filp->f_pos = %d\n", (int)filp->f_pos);
DDPRINTK("ncp_readdir: inode->i_ino = %ld, c_ino = %ld\n",
inode->i_ino, c_ino);
if (!inode || !S_ISDIR(inode->i_mode)) {
if (!inode || !S_ISDIR(inode->i_mode))
{
printk("ncp_readdir: inode is NULL or not a directory\n");
return -EBADF;
}
@@ -181,34 +184,40 @@ ncp_readdir(struct inode *inode, struct file *filp,
{
i = sizeof (struct ncp_dirent) * NCP_READDIR_CACHE_SIZE;
c_entry = (struct ncp_dirent *) ncp_kmalloc(i, GFP_KERNEL);
if (c_entry == NULL) {
if (c_entry == NULL)
{
printk("ncp_readdir: no MEMORY for cache\n");
return -ENOMEM;
}
}
if (filp->f_pos == 0) {
if (filp->f_pos == 0)
{
ncp_invalid_dir_cache(inode->i_ino);
if (filldir(dirent,".",1, filp->f_pos, (int)dir) < 0) {
if (filldir(dirent,".",1, filp->f_pos, (int)dir) < 0)
{
return 0;
}
filp->f_pos += 1;
return ROUND_UP(NAME_OFFSET(dirent)+i+1);
}
if (filp->f_pos == 1) {
if (filldir(dirent,"..",2, filp->f_pos, (int)(dir->dir)) < 0) {
if (filp->f_pos == 1)
{
if (filldir(dirent,"..",2, filp->f_pos, (int)(dir->dir)) < 0)
{
return 0;
}
filp->f_pos += 1;
return ROUND_UP(NAME_OFFSET(dirent)+i+1);
}
if (inode->i_ino == c_ino) {
for (i = 0; i < c_size; i++) {
if (filp->f_pos == c_entry[i].f_pos) {
if (inode->i_ino == c_ino)
{
for (i = 0; i < c_size; i++)
{
if (filp->f_pos == c_entry[i].f_pos)
{
entry = &c_entry[i];
c_last_returned_index = i;
index = i;
@@ -216,33 +225,38 @@ ncp_readdir(struct inode *inode, struct file *filp,
}
}
if ((entry == NULL) && c_seen_eof)
{
return 0;
}
}
if (entry == NULL) {
if (entry == NULL)
{
DDPRINTK("ncp_readdir: Not found in cache.\n");
if (inode->i_ino == (int)&(server->root)) {
if (inode->i_ino == (int)&(server->root))
{
result = ncp_read_volume_list(server, filp->f_pos,
NCP_READDIR_CACHE_SIZE);
DPRINTK("ncp_read_volume_list returned %d\n", result);
} else {
}
else
{
result = ncp_do_readdir(server, inode, filp->f_pos,
NCP_READDIR_CACHE_SIZE,
c_entry);
DPRINTK("ncp_readdir returned %d\n", result);
}
if (result < 0) {
if (result < 0)
{
c_ino = 0;
return result;
}
if (result > 0) {
if (result > 0)
{
c_seen_eof = (result < NCP_READDIR_CACHE_SIZE);
c_ino = inode->i_ino;
c_size = result;
@@ -250,19 +264,21 @@ ncp_readdir(struct inode *inode, struct file *filp,
c_last_returned_index = 0;
index = 0;
for (i = 0; i < c_size; i++) {
for (i = 0; i < c_size; i++)
{
str_lower(c_entry[i].i.entryName);
}
}
}
if (entry == NULL) {
if (entry == NULL)
{
/* Nothing found, even from a ncp call */
return 0;
}
if (index < c_size) {
if (index < c_size)
{
/* We found it. For getwd(), we have to return the
correct inode in d_ino if the inode is currently in
use. Otherwise the inode number does not
@@ -270,12 +286,12 @@ ncp_readdir(struct inode *inode, struct file *filp,
struct ncp_inode_info *ino_info;
ino_info = ncp_find_inode(inode, entry->i.entryName);
/* Some programs seem to be confused about a zero
inode number, so we set it to one. Thanks to
Gordon Chaffee for this one. */
if (ino_info == NULL) {
if (ino_info == NULL)
{
ino_info = (struct ncp_inode_info *) 1;
}
@@ -283,7 +299,8 @@ ncp_readdir(struct inode *inode, struct file *filp,
DDPRINTK("ncp_readdir: entry->f_pos = %ld\n", entry->f_pos);
if (filldir(dirent, entry->i.entryName, entry->i.nameLen,
entry->f_pos, (ino_t)ino_info) < 0) {
entry->f_pos, (ino_t)ino_info) < 0)
{
return 0;
}
@@ -304,33 +321,42 @@ ncp_read_volume_list(struct ncp_server *server, int fpos, int cache_size)
int i;
#if 1
if (fpos < 2) {
if (fpos < 2)
{
printk("OOPS, we expect fpos >= 2");
fpos = 2;
}
#endif
for (i=0; i<NCP_NUMBER_OF_VOLUMES; i++) {
for (i=0; i<NCP_NUMBER_OF_VOLUMES; i++)
{
struct ncp_volume_info info;
if (ncp_get_volume_info_with_number(server, i, &info) != 0) {
if (ncp_get_volume_info_with_number(server, i, &info) != 0)
{
return total_count;
}
if (strlen(info.volume_name) > 0) {
if (total_count < fpos) {
if (strlen(info.volume_name) > 0)
{
if (total_count < fpos)
{
DPRINTK("ncp_read_volumes: skipped vol: %s\n",
info.volume_name);
} else if (total_count >= fpos + cache_size) {
}
else if (total_count >= fpos + cache_size)
{
return (total_count - fpos);
} else {
}
else
{
DPRINTK("ncp_read_volumes: found vol: %s\n",
info.volume_name);
if (ncp_do_lookup(server, NULL,
info.volume_name,
&(entry->i)) != 0) {
&(entry->i)) != 0)
{
printk("ncpfs: could not lookup vol "
"%s\n", info.volume_name);
continue;
@@ -342,7 +368,6 @@ ncp_read_volume_list(struct ncp_server *server, int fpos, int cache_size)
total_count += 1;
}
}
return (total_count - fpos);
}
@@ -355,43 +380,50 @@ ncp_do_readdir(struct ncp_server *server, struct inode *dir, int fpos,
static int total_count;
#if 1
if (fpos < 2) {
if (fpos < 2)
{
printk("OOPS, we expect fpos >= 2");
fpos = 2;
}
#endif
DPRINTK("ncp_do_readdir: fpos = %d\n", fpos);
if (fpos == 2) {
if (fpos == 2)
{
last_dir = NULL;
total_count = 2;
}
if ((fpos != total_count) || (dir != last_dir)) {
if ((fpos != total_count) || (dir != last_dir))
{
total_count = 2;
last_dir = dir;
DPRINTK("ncp_do_readdir: re-used seq for %s\n",
NCP_ISTRUCT(dir)->entryName);
if (ncp_initialize_search(server, NCP_ISTRUCT(dir), &seq)!=0) {
if (ncp_initialize_search(server, NCP_ISTRUCT(dir), &seq)!=0)
{
DPRINTK("ncp_init_search failed\n");
return total_count - fpos;
}
}
while (total_count < fpos + cache_size) {
while (total_count < fpos + cache_size)
{
if (ncp_search_for_file_or_subdir(server, &seq,
&(entry->i)) != 0) {
&(entry->i)) != 0)
{
return total_count - fpos;
}
if (total_count < fpos) {
if (total_count < fpos)
{
DPRINTK("ncp_do_readdir: skipped file: %s\n",
entry->i.entryName);
} else {
}
else
{
DDPRINTK("ncp_do_r: file: %s, f_pos=%d,total_count=%d",
entry->i.entryName, fpos, total_count);
entry->s = seq;
@@ -400,7 +432,6 @@ ncp_do_readdir(struct ncp_server *server, struct inode *dir, int fpos,
}
total_count += 1;
}
return (total_count - fpos);
}
@@ -414,7 +445,8 @@ ncp_init_dir_cache(void)
void
ncp_invalid_dir_cache(unsigned long ino)
{
if (ino == c_ino) {
if (ino == c_ino)
{
c_ino = 0;
c_seen_eof = 0;
}
@@ -426,7 +458,9 @@ ncp_free_dir_cache(void)
DPRINTK("ncp_free_dir_cache: enter\n");
if (c_entry == NULL)
{
return;
}
ncp_kfree_s(c_entry,
sizeof(struct ncp_dirent) * NCP_READDIR_CACHE_SIZE);
@@ -443,12 +477,14 @@ ncp_iget(struct inode *dir, struct nw_file_info *finfo)
struct ncp_inode_info *new_inode_info;
struct ncp_inode_info *root;
if (!dir) {
if (dir == NULL)
{
printk("ncp_iget: dir is NULL\n");
return NULL;
}
if (!finfo) {
if (finfo == NULL)
{
printk("ncp_iget: finfo is NULL\n");
return NULL;
}
@@ -456,13 +492,14 @@ ncp_iget(struct inode *dir, struct nw_file_info *finfo)
new_inode_info = ncp_kmalloc(sizeof(struct ncp_inode_info),
GFP_KERNEL);
if (new_inode_info == NULL) {
if (new_inode_info == NULL)
{
printk("ncp_iget: could not alloc mem for %s\n",
finfo->i.entryName);
return NULL;
}
new_inode_info->state = INODE_LOOKED_UP;
new_inode_info->state = NCP_INODE_LOOKED_UP;
new_inode_info->nused = 0;
new_inode_info->dir = NCP_INOP(dir);
new_inode_info->finfo = *finfo;
@@ -480,7 +517,8 @@ ncp_iget(struct inode *dir, struct nw_file_info *finfo)
root->next->prev = new_inode_info;
root->next = new_inode_info;
if (!(inode = iget(dir->i_sb, (int)new_inode_info))) {
if (!(inode = iget(dir->i_sb, (int)new_inode_info)))
{
printk("ncp_iget: iget failed!");
return NULL;
}
@@ -491,13 +529,15 @@ ncp_iget(struct inode *dir, struct nw_file_info *finfo)
void
ncp_free_inode_info(struct ncp_inode_info *i)
{
if (i == NULL) {
if (i == NULL)
{
printk("ncp_free_inode: i == NULL\n");
return;
}
i->state = INODE_CACHED;
while ((i->nused == 0) && (i->state == INODE_CACHED)) {
i->state = NCP_INODE_CACHED;
while ((i->nused == 0) && (i->state == NCP_INODE_CACHED))
{
struct ncp_inode_info *dir = i->dir;
i->next->prev = i->prev;
@@ -522,7 +562,6 @@ ncp_init_root(struct ncp_server *server)
struct nw_info_struct *i = &(root->finfo.i);
unsigned short dummy;
DPRINTK("ncp_init_root: server %s\n", server->m.server_name);
DPRINTK("ncp_init_root: i = %x\n", (int)i);
root->finfo.opened = 0;
@@ -534,7 +573,7 @@ ncp_init_root(struct ncp_server *server)
i->nameLen = 0;
i->entryName[0] = '\0';
root->state = INODE_LOOKED_UP;
root->state = NCP_INODE_LOOKED_UP;
root->nused = 1;
root->dir = root;
root->next = root->prev = root;
@@ -550,11 +589,13 @@ ncp_free_all_inodes(struct ncp_server *server)
#if 1
struct ncp_inode_info *root = &(server->root);
if (root->next != root) {
if (root->next != root)
{
printk("ncp_free_all_inodes: INODES LEFT!!!\n");
}
while (root->next != root) {
while (root->next != root)
{
printk("ncp_free_all_inodes: freeing inode\n");
ncp_free_inode_info(root->next);
/* In case we have an endless loop.. */
@@ -575,17 +616,22 @@ ncp_find_inode(struct inode *dir, const char *name)
struct nw_info_struct *dir_info = NCP_ISTRUCT(dir);
struct ncp_inode_info *result = &(server->root);
if (name == NULL) {
if (name == NULL)
{
return NULL;
}
do {
do
{
if ( (result->dir->finfo.i.DosDirNum == dir_info->DosDirNum)
&& (strcmp(result->finfo.i.entryName, name) == 0))
{
return result;
}
result = result->next;
} while (result != &(server->root));
}
while (result != &(server->root));
return NULL;
}
@@ -601,7 +647,8 @@ ncp_lookup(struct inode *dir, const char *__name, int len,
*result = NULL;
if (!dir || !S_ISDIR(dir->i_mode)) {
if (!dir || !S_ISDIR(dir->i_mode))
{
printk("ncp_lookup: inode is NULL or not a directory.\n");
iput(dir);
return -ENOENT;
@@ -612,33 +659,42 @@ ncp_lookup(struct inode *dir, const char *__name, int len,
server = NCP_SERVER(dir);
/* Fast cheat for . */
if (len == 0 || (len == 1 && __name[0] == '.')) {
if (len == 0 || (len == 1 && __name[0] == '.'))
{
*result = dir;
return 0;
}
/* ..and for .. */
if (len == 2 && __name[0] == '.' && __name[1] == '.') {
if (len == 2 && __name[0] == '.' && __name[1] == '.')
{
struct ncp_inode_info *parent = NCP_INOP(dir)->dir;
if (parent->state == INODE_CACHED) {
parent->state = INODE_LOOKED_UP;
if (parent->state == NCP_INODE_CACHED)
{
parent->state = NCP_INODE_LOOKED_UP;
}
*result = iget(dir->i_sb, (int)parent);
iput(dir);
if (*result == 0)
{
return -EACCES;
}
else
{
return 0;
}
}
result_info = ncp_find_inode(dir, __name);
if (result_info != 0) {
if (result_info->state == INODE_CACHED)
result_info->state = INODE_LOOKED_UP;
if (result_info != 0)
{
if (result_info->state == NCP_INODE_CACHED)
{
result_info->state = NCP_INODE_LOOKED_UP;
}
/* Here we convert the inode_info address into an
inode number */
@@ -646,7 +702,8 @@ ncp_lookup(struct inode *dir, const char *__name, int len,
*result = iget(dir->i_sb, (int)result_info);
iput(dir);
if (*result == NULL) {
if (*result == NULL)
{
return -EACCES;
}
@@ -658,26 +715,31 @@ ncp_lookup(struct inode *dir, const char *__name, int len,
found_in_cache = 0;
if (dir->i_ino == c_ino) {
if (dir->i_ino == c_ino)
{
int first = c_last_returned_index;
int i;
i = first;
do {
do
{
DDPRINTK("ncp_lookup: trying index: %d, name: %s\n",
i, c_entry[i].i.entryName);
if (strcmp(c_entry[i].i.entryName, __name) == 0) {
if (strcmp(c_entry[i].i.entryName, __name) == 0)
{
DPRINTK("ncp_lookup: found in cache!\n");
finfo.i = c_entry[i].i;
found_in_cache = 1;
break;
}
i = (i + 1) % c_size;
} while (i != first);
}
while (i != first);
}
if (found_in_cache == 0) {
if (found_in_cache == 0)
{
char this_name[len+1];
memcpy(this_name, __name, len);
@@ -691,7 +753,8 @@ ncp_lookup(struct inode *dir, const char *__name, int len,
dir->i_ino == (int)&(NCP_SERVER(dir)->root)
? NULL : NCP_ISTRUCT(dir),
this_name,
&(finfo.i)) != 0) {
&(finfo.i)) != 0)
{
iput(dir);
return -ENOENT;
}
@@ -700,7 +763,8 @@ ncp_lookup(struct inode *dir, const char *__name, int len,
finfo.opened = 0;
str_lower(finfo.i.entryName);
if (!(*result = ncp_iget(dir, &finfo))) {
if (!(*result = ncp_iget(dir, &finfo)))
{
iput(dir);
return -EACCES;
}
@@ -718,7 +782,8 @@ ncp_create(struct inode *dir, const char *name, int len, int mode,
*result = NULL;
if (!dir || !S_ISDIR(dir->i_mode)) {
if (!dir || !S_ISDIR(dir->i_mode))
{
printk("ncp_create: inode is NULL or not a directory\n");
iput(dir);
return -ENOENT;
@@ -732,7 +797,8 @@ ncp_create(struct inode *dir, const char *name, int len, int mode,
NCP_ISTRUCT(dir), _name,
OC_MODE_CREATE|OC_MODE_OPEN,
0, AR_READ|AR_WRITE,
&finfo) != 0) {
&finfo) != 0)
{
iput(dir);
return -EACCES;
}
@@ -742,7 +808,8 @@ ncp_create(struct inode *dir, const char *name, int len, int mode,
str_lower(finfo.i.entryName);
finfo.access = O_RDWR;
if (!(*result = ncp_iget(dir, &finfo)) < 0) {
if (!(*result = ncp_iget(dir, &finfo)) < 0)
{
ncp_close_file(NCP_SERVER(dir), finfo.file_handle);
iput(dir);
return -EINVAL;
@@ -759,11 +826,20 @@ ncp_mkdir(struct inode *dir, const char *name, int len, int mode)
struct nw_file_info new_dir;
__u8 _name[len+1];
if ( (name[0] == '.')
&& ( (len == 1)
|| ( (len == 2)
&& (name[1] == '.'))))
{
return -EEXIST;
}
strncpy(_name, name, len);
_name[len] = '\0';
str_upper(_name);
if (!dir || !S_ISDIR(dir->i_mode)) {
if (!dir || !S_ISDIR(dir->i_mode))
{
printk("ncp_mkdir: inode is NULL or not a directory\n");
iput(dir);
return -ENOENT;
@@ -772,9 +848,12 @@ ncp_mkdir(struct inode *dir, const char *name, int len, int mode)
if (ncp_open_create_file_or_subdir(NCP_SERVER(dir),
NCP_ISTRUCT(dir), _name,
OC_MODE_CREATE, aDIR, 0xffff,
&new_dir) != 0) {
&new_dir) != 0)
{
error = -EACCES;
} else {
}
else
{
error = 0;
ncp_invalid_dir_cache(dir->i_ino);
}
@@ -789,12 +868,14 @@ ncp_rmdir(struct inode *dir, const char *name, int len)
int error;
__u8 _name[len+1];
if (!dir || !S_ISDIR(dir->i_mode)) {
if (!dir || !S_ISDIR(dir->i_mode))
{
printk("ncp_rmdir: inode is NULL or not a directory\n");
iput(dir);
return -ENOENT;
}
if (ncp_find_inode(dir, name) != NULL) {
if (ncp_find_inode(dir, name) != NULL)
{
error = -EBUSY;
}
else
@@ -806,7 +887,8 @@ ncp_rmdir(struct inode *dir, const char *name, int len)
if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir),
NCP_ISTRUCT(dir),
_name)) == 0) {
_name)) == 0)
{
ncp_invalid_dir_cache(dir->i_ino);
}
else
@@ -824,24 +906,26 @@ ncp_unlink(struct inode *dir, const char *name, int len)
int error;
__u8 _name[len+1];
if (!dir || !S_ISDIR(dir->i_mode)) {
if (!dir || !S_ISDIR(dir->i_mode))
{
printk("ncp_unlink: inode is NULL or not a directory\n");
iput(dir);
return -ENOENT;
}
if (ncp_find_inode(dir, name) != NULL) {
if (ncp_find_inode(dir, name) != NULL)
{
error = -EBUSY;
}
else
{
strncpy(_name, name, len);
_name[len] = '\0';
str_upper(_name);
if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir),
NCP_ISTRUCT(dir),
_name)) == 0) {
_name)) == 0)
{
ncp_invalid_dir_cache(dir->i_ino);
}
else
@@ -861,20 +945,23 @@ ncp_rename(struct inode *old_dir, const char *old_name, int old_len,
char _old_name[old_len+1];
char _new_name[new_len+1];
if (!old_dir || !S_ISDIR(old_dir->i_mode)) {
if (!old_dir || !S_ISDIR(old_dir->i_mode))
{
printk("ncp_rename: old inode is NULL or not a directory\n");
res = -ENOENT;
goto finished;
}
if (!new_dir || !S_ISDIR(new_dir->i_mode)) {
if (!new_dir || !S_ISDIR(new_dir->i_mode))
{
printk("ncp_rename: new inode is NULL or not a directory\n");
res = -ENOENT;
goto finished;
}
if ( (ncp_find_inode(old_dir, old_name) != NULL)
|| (ncp_find_inode(new_dir, new_name) != NULL)) {
|| (ncp_find_inode(new_dir, new_name) != NULL))
{
res = -EBUSY;
goto finished;
}
@@ -884,14 +971,15 @@ ncp_rename(struct inode *old_dir, const char *old_name, int old_len,
str_upper(_old_name);
strncpy(_new_name, new_name, new_len);
_new_name[old_len] = '\0';
_new_name[new_len] = '\0';
str_upper(_new_name);
res = ncp_ren_or_mov_file_or_subdir(NCP_SERVER(old_dir),
NCP_ISTRUCT(old_dir), _old_name,
NCP_ISTRUCT(new_dir), _new_name);
if (res == 0) {
if (res == 0)
{
ncp_invalid_dir_cache(old_dir->i_ino);
ncp_invalid_dir_cache(new_dir->i_ino);
}