177 lines
4.0 KiB
C
177 lines
4.0 KiB
C
/*
|
|
* file.c
|
|
*
|
|
* Copyright (C) 1995 by Paal-Kr. Engstad and Volker Lendecke
|
|
*
|
|
*/
|
|
|
|
#include <linux/config.h>
|
|
#ifdef MODULE
|
|
#include <linux/module.h>
|
|
#include <linux/version.h>
|
|
#endif
|
|
|
|
#include <asm/segment.h>
|
|
#include <asm/system.h>
|
|
|
|
#include <linux/sched.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/errno.h>
|
|
#include <linux/fcntl.h>
|
|
#include <linux/stat.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/ncp_fs.h>
|
|
#include "ncplib.h"
|
|
#include <linux/malloc.h>
|
|
|
|
static int
|
|
ncp_fsync(struct inode *inode, struct file *file)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
ncp_make_open(struct inode *i, int right)
|
|
{
|
|
struct ncp_dirent *dirent;
|
|
|
|
if (i == NULL) {
|
|
printk("ncp_make_open: got NULL inode\n");
|
|
return -EINVAL;
|
|
}
|
|
|
|
dirent = &(NCP_INOP(i)->finfo);
|
|
|
|
DPRINTK("ncp_make_open: dirent->opened = %d\n", dirent->opened);
|
|
|
|
if ((dirent->opened) == 0) {
|
|
struct ncp_file_info finfo;
|
|
|
|
/* tries max. rights */
|
|
if (ncp_open_file(NCP_SERVER(i), 0, dirent->path, 0,
|
|
AR_READ | AR_WRITE, &finfo) == 0) {
|
|
dirent->access = O_RDWR;
|
|
}
|
|
else if (ncp_open_file(NCP_SERVER(i), 0, dirent->path, 0,
|
|
AR_READ, &finfo) == 0) {
|
|
dirent->access = O_RDONLY;
|
|
} else {
|
|
return -EACCES;
|
|
}
|
|
|
|
dirent->opened = 1;
|
|
memcpy(&(dirent->file_id), finfo.file_id, NCP_FILE_ID_LEN);
|
|
}
|
|
|
|
if ( ((right == O_RDONLY) && ( (dirent->access == O_RDONLY)
|
|
|| (dirent->access == O_RDWR)))
|
|
|| ((right == O_WRONLY) && ( (dirent->access == O_WRONLY)
|
|
|| (dirent->access == O_RDWR)))
|
|
|| ((right == O_RDWR) && (dirent->access == O_RDWR)))
|
|
return 0;
|
|
|
|
return -EACCES;
|
|
}
|
|
|
|
static int
|
|
ncp_file_read(struct inode *inode, struct file *file, char *buf, int count)
|
|
{
|
|
int bufsize, to_read, already_read;
|
|
off_t pos;
|
|
int errno;
|
|
|
|
DPRINTK("ncp_file_read: enter %s\n", NCP_FINFO(inode)->path);
|
|
|
|
if (!inode) {
|
|
DPRINTK("ncp_file_read: inode = NULL\n");
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (!S_ISREG(inode->i_mode)) {
|
|
DPRINTK("ncp_file_read: read from non-file, mode %07o\n",
|
|
inode->i_mode);
|
|
return -EINVAL;
|
|
}
|
|
|
|
if ((errno = ncp_make_open(inode, O_RDONLY)) != 0)
|
|
return errno;
|
|
|
|
pos = file->f_pos;
|
|
|
|
if (pos + count > inode->i_size)
|
|
count = inode->i_size - pos;
|
|
|
|
if (count <= 0)
|
|
return 0;
|
|
|
|
bufsize = NCP_SERVER(inode)->buffer_size;
|
|
|
|
already_read = 0;
|
|
|
|
/* First read in as much as possible for each bufsize. */
|
|
while (already_read < count) {
|
|
|
|
int read_this_time;
|
|
|
|
if ((pos % bufsize) != 0) {
|
|
to_read = bufsize - (pos % bufsize);
|
|
} else {
|
|
to_read = bufsize;
|
|
}
|
|
|
|
to_read = min(to_read, count - already_read);
|
|
|
|
if (ncp_read(NCP_SERVER(inode), NCP_FINFO(inode)->file_id,
|
|
pos, to_read, buf, &read_this_time) != 0) {
|
|
return -EIO; /* This is not exact, i know.. */
|
|
}
|
|
|
|
pos += read_this_time;
|
|
buf += read_this_time;
|
|
already_read += read_this_time;
|
|
|
|
if (read_this_time < to_read) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
file->f_pos = pos;
|
|
|
|
if (!IS_RDONLY(inode)) inode->i_atime = CURRENT_TIME;
|
|
inode->i_dirt = 1;
|
|
|
|
DPRINTK("ncp_file_read: exit %s\n", NCP_FINFO(inode)->path);
|
|
|
|
return already_read;
|
|
}
|
|
|
|
static struct file_operations ncp_file_operations = {
|
|
NULL, /* lseek - default */
|
|
ncp_file_read, /* read */
|
|
NULL, /* write */
|
|
NULL, /* readdir - bad */
|
|
NULL, /* select - default */
|
|
ncp_ioctl, /* ioctl */
|
|
NULL, /* mmap */
|
|
NULL, /* open */
|
|
NULL, /* release */
|
|
ncp_fsync, /* fsync */
|
|
};
|
|
|
|
struct inode_operations ncp_file_inode_operations = {
|
|
&ncp_file_operations, /* default file operations */
|
|
NULL, /* create */
|
|
NULL, /* lookup */
|
|
NULL, /* link */
|
|
NULL, /* unlink */
|
|
NULL, /* symlink */
|
|
NULL, /* mkdir */
|
|
NULL, /* rmdir */
|
|
NULL, /* mknod */
|
|
NULL, /* rename */
|
|
NULL, /* readlink */
|
|
NULL, /* follow_link */
|
|
NULL, /* bmap */
|
|
NULL /* truncate */
|
|
};
|