Import 2.1.89
[davej-history.git] / fs / ncpfs / inode.c
index 3a98b65..f11f464 100644 (file)
 static void ncp_read_inode(struct inode *);
 static void ncp_put_inode(struct inode *);
 static void ncp_delete_inode(struct inode *);
-static int  ncp_notify_change(struct dentry *, struct iattr *);
 static void ncp_put_super(struct super_block *);
 static int  ncp_statfs(struct super_block *, struct statfs *, int);
 
@@ -52,6+51,8 @@ static struct super_operations ncp_sops =
        NULL                    /* remount */
 };
 
+extern struct dentry_operations ncp_dentry_operations;
+
 static struct nw_file_info *read_nwinfo = NULL;
 static struct semaphore read_sem = MUTEX;
 
@@ -75,6+76,31 @@ nwinfo->i.entryName, NCP_FINFO(inode)->volNumber, NCP_FINFO(inode)->dirEntNum);
 #endif
 }
 
+void ncp_update_inode2(struct inode* inode, struct nw_file_info *nwinfo)
+{
+       struct nw_info_struct *nwi = &nwinfo->i;
+       struct ncp_server *server = NCP_SERVER(inode);
+
+       if (!NCP_FINFO(inode)->opened) {
+               if (nwi->attributes & aDIR) {
+                       inode->i_mode = server->m.dir_mode;
+                       inode->i_size = 512;
+               } else {
+                       inode->i_mode = server->m.file_mode;
+                       inode->i_size = le32_to_cpu(nwi->dataStreamSize);
+               }
+               if (nwi->attributes & aRONLY) inode->i_mode &= ~0222;
+       }
+       inode->i_blocks = 0;
+       if ((inode->i_size)&&(inode->i_blksize)) {
+               inode->i_blocks = (inode->i_size-1)/(inode->i_blksize)+1;
+       }
+       /* TODO: times? I'm not sure... */
+       NCP_FINFO(inode)->DosDirNum = nwinfo->i.DosDirNum;
+       NCP_FINFO(inode)->dirEntNum = nwinfo->i.dirEntNum;
+       NCP_FINFO(inode)->volNumber = nwinfo->i.volNumber;
+}
+
 /*
  * Fill in the inode based on the nw_file_info structure.
  */
@@ -92,6+118,7 @@ static void ncp_set_attr(struct inode *inode, struct nw_file_info *nwinfo)
                inode->i_mode = server->m.file_mode;
                inode->i_size = le32_to_cpu(nwi->dataStreamSize);
        }
+       if (nwi->attributes & aRONLY) inode->i_mode &= ~0222;
 
        DDPRINTK(KERN_DEBUG "ncp_read_inode: inode->i_mode = %u\n", inode->i_mode);
 
@@ -210,6+237,7 @@ static void ncp_init_root(struct ncp_server *server,
        root->finfo.opened= 0;
        info->ino = 2; /* tradition */
        info->nw_info = root->finfo;
+       return;
 }
 
 struct super_block *
@@ -221,6+249,9 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent)
        struct inode *root_inode;
        kdev_t dev = sb->s_dev;
        int error;
+#ifdef CONFIG_NCPFS_PACKET_SIGNING
+       int options;
+#endif
        struct ncpfs_inode_info finfo;
 
        MOD_INC_USE_COUNT;
@@ -228,13+259,13 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent)
                goto out_no_data;
        if (data->version != NCP_MOUNT_VERSION)
                goto out_bad_mount;
-       if ((data->ncp_fd >= NR_OPEN) ||
-           ((ncp_filp = current->files->fd[data->ncp_fd]) == NULL) ||
-           !S_ISSOCK(ncp_filp->f_dentry->d_inode->i_mode))
+       ncp_filp = fget(data->ncp_fd);
+       if (!ncp_filp)
                goto out_bad_file;
+       if (!S_ISSOCK(ncp_filp->f_dentry->d_inode->i_mode))
+               goto out_bad_file2;
 
        lock_super(sb);
-       ncp_filp->f_count++;
 
        sb->s_blocksize = 1024; /* Eh...  Is this correct? */
        sb->s_blocksize_bits = 10;
@@ -255,6+286,17 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent)
        server->packet = NULL;
        server->buffer_size = 0;
        server->conn_status = 0;
+       server->root_dentry = NULL;
+#ifdef CONFIG_NCPFS_PACKET_SIGNING
+       server->sign_wanted = 0;
+       server->sign_active = 0;
+#endif
+       server->auth.auth_type = NCP_AUTH_NONE;
+       server->auth.object_name_len = 0;
+       server->auth.object_name = NULL;
+       server->auth.object_type = 0;
+       server->priv.len = 0;
+       server->priv.data = NULL;
 
        server->m = *data;
        /* Althought anything producing this is buggy, it happens
@@ -280,21+322,41 @@ ncp_read_super(struct super_block *sb, void *raw_data, int silent)
                goto out_no_connect;
        DPRINTK(KERN_DEBUG "ncp_read_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb));
 
-       error = ncp_negotiate_buffersize(server, NCP_DEFAULT_BUFSIZE,
-                                               &(server->buffer_size));
-       if (error)
+#ifdef CONFIG_NCPFS_PACKET_SIGNING
+       if (ncp_negotiate_size_and_options(server, NCP_DEFAULT_BUFSIZE,
+               NCP_DEFAULT_OPTIONS, &(server->buffer_size), &options) == 0)
+       {
+               if (options != NCP_DEFAULT_OPTIONS)
+               {
+                       if (ncp_negotiate_size_and_options(server, 
+                               NCP_DEFAULT_BUFSIZE,
+                               options & 2, 
+                               &(server->buffer_size), &options) != 0)
+                               
+                       {
+                               goto out_no_bufsize;
+                       }
+               }
+               if (options & 2)
+                       server->sign_wanted = 1;
+       }
+       else 
+#endif /* CONFIG_NCPFS_PACKET_SIGNING */
+       if (ncp_negotiate_buffersize(server, NCP_DEFAULT_BUFSIZE,
+                                    &(server->buffer_size)) != 0)
                goto out_no_bufsize;
        DPRINTK(KERN_DEBUG "ncpfs: bufsize = %d\n", server->buffer_size);
 
        ncp_init_root(server, &finfo);
+       server->name_space[finfo.nw_info.i.volNumber] = NW_NS_DOS;
         root_inode = ncp_iget(sb, &finfo);
         if (!root_inode)
                goto out_no_root;
        DPRINTK(KERN_DEBUG "ncp_read_super: root vol=%d\n", NCP_FINFO(root_inode)->volNumber);
-        sb->s_root = d_alloc_root(root_inode, NULL);
+        server->root_dentry = sb->s_root = d_alloc_root(root_inode, NULL);
         if (!sb->s_root)
                goto out_no_root;
-
+       server->root_dentry->d_op = &ncp_dentry_operations;
        unlock_super(sb);
        return sb;
 
@@ -326,6+388,8 @@ out_unlock:
        unlock_super(sb);
        goto out;
 
+out_bad_file2:
+       fput(ncp_filp);
 out_bad_file:
        printk(KERN_ERR "ncp_read_super: invalid ncp socket\n");
        goto out;
@@ -354,6+418,10 @@ static void ncp_put_super(struct super_block *sb)
        fput(server->ncp_filp);
        kill_proc(server->m.wdog_pid, SIGTERM, 1);
 
+       if (server->priv.data) 
+               ncp_kfree_s(server->priv.data, server->priv.len);
+       if (server->auth.object_name)
+               ncp_kfree_s(server->auth.object_name, server->auth.object_name_len);
        ncp_kfree_s(server->packet, server->packet_size);
 
        ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server));
@@ -385,7+453,7 @@ static int ncp_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
        return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
 }
 
-static int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
+int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
 {
        struct inode *inode = dentry->d_inode;
        int result = 0;
@@ -417,6+485,33 @@ static int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
        info_mask = 0;
        memset(&info, 0, sizeof(info));
 
+#if 1 
+        if ((attr->ia_valid & ATTR_MODE) != 0)
+        {
+                if (!S_ISREG(inode->i_mode))
+                {
+                        return -EPERM;
+                }
+                else
+                {
+                       umode_t newmode;
+
+                        info_mask |= DM_ATTRIBUTES;
+                        newmode=attr->ia_mode;
+                        newmode &= NCP_SERVER(inode)->m.file_mode;
+
+                        if (newmode & 0222) /* any write bit set */
+                        {
+                                info.attributes &= ~0x60001;
+                        }
+                        else
+                        {
+                                info.attributes |= 0x60001;
+                        }
+                }
+        }
+#endif
+
        if ((attr->ia_valid & ATTR_CTIME) != 0) {
                info_mask |= (DM_CREATE_TIME | DM_CREATE_DATE);
                ncp_date_unix2dos(attr->ia_ctime,
close