patch-1.3.53 linux/fs/ncpfs/file.c

Next file: linux/fs/ncpfs/inode.c
Previous file: linux/fs/ncpfs/dir.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v1.3.52/linux/fs/ncpfs/file.c linux/fs/ncpfs/file.c
@@ -0,0 +1,284 @@
+/*
+ *  file.c
+ *
+ *  Copyright (C) 1995 by Paal-Kr. Engstad and Volker Lendecke
+ *
+ */
+
+#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_kernel.h"
+#include <linux/malloc.h>
+
+static inline int min(int a, int b)
+{
+	return a<b ? a : b;
+}
+
+static int 
+ncp_fsync(struct inode *inode, struct file *file)
+{
+	return 0;
+}
+
+int
+ncp_make_open(struct inode *i, int right)
+{
+        struct nw_file_info *finfo;
+
+        if (i == NULL)
+	{
+                printk("ncp_make_open: got NULL inode\n");
+                return -EINVAL;
+        }
+
+        finfo = NCP_FINFO(i);
+
+        DPRINTK("ncp_make_open: dirent->opened = %d\n", finfo->opened);
+
+        if (finfo->opened == 0)
+	{
+                /* tries max. rights */
+		if (ncp_open_create_file_or_subdir(NCP_SERVER(i),
+						   NULL, NULL,
+						   OC_MODE_OPEN, 0,
+						   AR_READ | AR_WRITE,
+						   finfo) == 0)
+		{
+			finfo->access = O_RDWR;
+		}
+		else if (ncp_open_create_file_or_subdir(NCP_SERVER(i),
+							NULL, NULL,
+							OC_MODE_OPEN, 0,
+							AR_READ,
+							finfo) == 0)
+		{
+			finfo->access = O_RDONLY;
+		}
+		else
+		{
+			return -EACCES;
+		}
+        }
+
+        if (   ((right == O_RDONLY) && (   (finfo->access == O_RDONLY)
+                                        || (finfo->access == O_RDWR)))
+            || ((right == O_WRONLY) && (   (finfo->access == O_WRONLY)
+                                        || (finfo->access == O_RDWR)))
+            || ((right == O_RDWR)   && (finfo->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_ISTRUCT(inode)->entryName);
+        
+	if (inode == NULL)
+	{
+		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;
+	}
+
+	pos = file->f_pos;
+
+	if (pos + count > inode->i_size)
+	{
+		count = inode->i_size - pos;
+	}
+
+	if (count <= 0)
+	{
+		return 0;
+	}
+
+        if ((errno = ncp_make_open(inode, O_RDONLY)) != 0)
+	{
+                return errno;
+	}
+        
+	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_handle,
+			     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_ISTRUCT(inode)->entryName);
+
+        return already_read;
+}
+
+static int 
+ncp_file_write(struct inode *inode, struct file *file, const char *buf,
+	       int count)
+{
+	int bufsize, to_write, already_written;
+        off_t pos;
+        int errno;
+			  
+	if (inode == NULL)
+	{
+		DPRINTK("ncp_file_write: inode = NULL\n");
+		return -EINVAL;
+	}
+
+	if (!S_ISREG(inode->i_mode))
+	{
+		DPRINTK("ncp_file_write: write to non-file, mode %07o\n",
+                       inode->i_mode);
+		return -EINVAL;
+	}
+
+        DPRINTK("ncp_file_write: enter %s\n", NCP_ISTRUCT(inode)->entryName);
+
+	if (count <= 0)
+	{
+		return 0;
+	}
+
+        if ((errno = ncp_make_open(inode, O_RDWR)) != 0)
+	{
+                return errno;
+	}
+        
+	pos = file->f_pos;
+
+	if (file->f_flags & O_APPEND)
+	{
+		pos = inode->i_size;
+	}
+
+	bufsize = NCP_SERVER(inode)->buffer_size;
+
+        already_written = 0;
+
+        while (already_written < count)
+	{
+		int written_this_time;
+
+		if ((pos % bufsize) != 0)
+		{
+			to_write = bufsize - (pos % bufsize);
+		}
+		else
+		{
+			to_write = bufsize;
+		}
+
+		to_write = min(to_write, count - already_written);
+		if (ncp_write(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
+			      pos, to_write, buf, &written_this_time) != 0)
+		{
+			return -EIO;
+                }
+
+		pos += written_this_time;
+		buf += written_this_time;
+		already_written += written_this_time;
+
+		if (written_this_time < to_write)
+		{
+			break;
+		}
+	}
+
+	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	inode->i_dirt = 1;
+
+	file->f_pos = pos;
+
+        if (pos > inode->i_size)
+	{
+                inode->i_size = pos;
+        }
+
+        DPRINTK("ncp_file_write: exit %s\n", NCP_ISTRUCT(inode)->entryName);
+
+	return already_written;
+}
+
+static struct file_operations ncp_file_operations = {
+	NULL,			/* lseek - default */
+	ncp_file_read,		/* read */
+	ncp_file_write,		/* write */
+	NULL,			/* readdir - bad */
+	NULL,			/* select - default */
+	ncp_ioctl,		/* ioctl */
+	ncp_mmap,		/* 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 */
+};

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov with Sam's (original) version
of this