diff -r -c --new-file client-2.0.33.s.v0.4/fs/smbfs/dir.c client-2.0.33.s.v0.5/fs/smbfs/dir.c *** client-2.0.33.s.v0.4/fs/smbfs/dir.c Thu Apr 20 20:33:55 2000 --- client-2.0.33.s.v0.5/fs/smbfs/dir.c Tue May 2 19:13:18 2000 *************** *** 49,55 **** --- 49,57 ---- struct inode *new_dir, const char *new_name, int new_len, int must_be_dir); + #ifdef CONFIG_SMB_SYMLINKS int smb_symlink(struct inode *, const char *, int, const char *); + #endif static struct file_operations smb_dir_operations = { diff -r -c --new-file client-2.0.33.s.v0.4/fs/smbfs/inode.c client-2.0.33.s.v0.5/fs/smbfs/inode.c *** client-2.0.33.s.v0.4/fs/smbfs/inode.c Thu Apr 20 21:12:02 2000 --- client-2.0.33.s.v0.5/fs/smbfs/inode.c Tue May 2 19:37:54 2000 *************** *** 29,37 **** static void smb_put_super(struct super_block *); static void smb_statfs(struct super_block *, struct statfs *, int bufsiz); ! static int smb_follow_link(struct inode *, struct inode *, int, int, struct inode **); ! static int smb_readlink (struct inode *, char *, int); int smb_symlink(struct inode *, const char *, int, const char *); static struct super_operations smb_sops = --- 29,40 ---- static void smb_put_super(struct super_block *); static void smb_statfs(struct super_block *, struct statfs *, int bufsiz); ! #ifdef CONFIG_SMB_SYMLINKS ! int smb_follow_link(struct inode *, struct inode *, int, int, struct inode **); ! int smb_readlink (struct inode *, char *, int); int smb_symlink(struct inode *, const char *, int, const char *); + struct inode_operations smb_symlink_inode_operations; + #endif static struct super_operations smb_sops = *************** *** 46,53 **** NULL }; - struct inode_operations smb_symlink_inode_operations; - /* smb_read_inode: Called from iget, it only traverses the allocated smb_inode_info's and initializes the inode from the data found there. It does not allocate or deallocate anything. */ --- 49,54 ---- *************** *** 423,433 **** else finfo.attr &= ~aRONLY; if((attr->ia_mode & S_IFLNK) == S_IFLNK) finfo.attr |= aSYSTEM; else finfo.attr &= ~aSYSTEM; ! if ((error = smb_proc_setattr(SMB_SERVER(inode), inode, &finfo)) >= 0) --- 424,435 ---- else finfo.attr &= ~aRONLY; + #ifdef CONFIG_SMB_SYMLINKS if((attr->ia_mode & S_IFLNK) == S_IFLNK) finfo.attr |= aSYSTEM; else finfo.attr &= ~aSYSTEM; ! #endif if ((error = smb_proc_setattr(SMB_SERVER(inode), inode, &finfo)) >= 0) diff -r -c --new-file client-2.0.33.s.v0.4/fs/smbfs/proc.c client-2.0.33.s.v0.5/fs/smbfs/proc.c *** client-2.0.33.s.v0.4/fs/smbfs/proc.c Fri Apr 21 22:12:45 2000 --- client-2.0.33.s.v0.5/fs/smbfs/proc.c Wed May 3 00:03:26 2000 *************** *** 18,23 **** --- 18,27 ---- #include #include + #ifdef CONFIG_SMB_SYMLINKS + #include "symlink.h" + #endif + #define SMB_VWV(packet) ((packet) + SMB_HEADER_LEN) #define SMB_CMD(packet) (BVAL(packet,8)) #define SMB_WCT(packet) (BVAL(packet, SMB_HEADER_LEN - 1)) *************** *** 902,907 **** --- 906,943 ---- entry->f_blksize = 512; } + #ifdef CONFIG_SMB_SYMLINKS + static void + smb_finish_dirent_sym(struct smb_server *server, struct smb_dirent *entry) + { + if ((entry->attr & aDIR) != 0) + { + entry->f_mode = server->m.dir_mode; + entry->f_size = 512; + } else + { + entry->f_mode = server->m.file_mode; + } + + if (entry->attr & aRONLY) + entry->f_mode &= ~0222; + + if (entry->attr & aSYSTEM) { + entry->f_mode = (entry->f_mode & ~S_IFMT) | S_IFLNK | 0777; + } + + if ((entry->f_blksize != 0) && (entry->f_size != 0)) + { + entry->f_blocks = + (entry->f_size - 1) / entry->f_blksize + 1; + } else + { + entry->f_blocks = 0; + } + return; + } + #endif + static void smb_finish_dirent(struct smb_server *server, struct smb_dirent *entry) { *************** *** 918,926 **** entry->f_mode &= ~0222; #ifdef CONFIG_SMB_SYMLINKS ! /* symlinks mustn't be anything but symlinks */ ! if (entry->attr & aSYSTEM) ! entry->f_mode = (entry->f_mode & ~S_IFMT) | S_IFLNK; #endif if ((entry->f_blksize != 0) && (entry->f_size != 0)) --- 954,966 ---- entry->f_mode &= ~0222; #ifdef CONFIG_SMB_SYMLINKS ! if (entry->attr & aSYSTEM) { ! if (entry->f_size == SMB_MAX_SYMLINK_SIZE) /* || ! (entry->f_size == 0)) * kludge, new symlinks have no size*/ ! entry->f_mode = (entry->f_mode & ~S_IFMT) | S_IFLNK | 0777; ! else ! DPRINTK("smbfs: bad size symlink %i; fix: chmod g-x on server or fill with NULs\n",(int)entry->f_size); ! } #endif if ((entry->f_blksize != 0) && (entry->f_size != 0)) *************** *** 1432,1437 **** --- 1472,1497 ---- return result; } + + #ifdef CONFIG_SMB_SYMLINKS + int + smb_proc_getattr_sym(struct inode *dir, const char *name, int len, + struct smb_dirent *entry) + { + struct smb_server *server = SMB_SERVER(dir); + int result; + + smb_init_dirent(server, entry); + result = smb_proc_getattr_core(dir, name, len, entry); + smb_finish_dirent_sym(server, entry); + + entry->len = len; + memcpy(entry->name, name, len); + /* entry->name is null terminated from smb_init_dirent */ + + return result; + } + #endif int smb_proc_setattr(struct smb_server *server, diff -r -c --new-file client-2.0.33.s.v0.4/fs/smbfs/symlink.c client-2.0.33.s.v0.5/fs/smbfs/symlink.c *** client-2.0.33.s.v0.4/fs/smbfs/symlink.c Thu Apr 27 23:52:16 2000 --- client-2.0.33.s.v0.5/fs/smbfs/symlink.c Tue May 2 23:24:32 2000 *************** *** 1,6 **** /* * symlink.c ! * v 0.3, Wed Apr 26 14:53:02 CEST 2000 * * built using parts of smbfs/file.c * Copyright (C) 1995, 1996, 1997 by Paal-Kr. Engstad and Volker Lendecke --- 1,6 ---- /* * symlink.c ! * v 0.5, Tue May 2 23:23:15 CEST 2000 * * built using parts of smbfs/file.c * Copyright (C) 1995, 1996, 1997 by Paal-Kr. Engstad and Volker Lendecke *************** *** 48,53 **** --- 48,56 ---- ino_t smb_fresh_inodes(struct smb_server *server, int no); struct inode * smb_iget(struct inode *dir, struct smb_inode_info *new_inode_info); + int smb_proc_write_mem(struct smb_server *server, struct smb_dirent *finfo, + off_t offset, int count, const char *data); + *************** *** 202,213 **** return err; } ! if ((err = smb_proc_getattr(dir, name, len, &entry)) < 0) { smb_kfree_s(new_inode_info, sizeof(struct smb_inode_info)); iput(dir); return err; } entry.f_ino = smb_fresh_inodes(SMB_SERVER(dir), 1); new_inode_info->finfo = entry; --- 205,218 ---- return err; } ! ! if ((err = smb_proc_getattr_sym(dir, name, len, &entry)) < 0) { smb_kfree_s(new_inode_info, sizeof(struct smb_inode_info)); iput(dir); return err; } + entry.f_ino = smb_fresh_inodes(SMB_SERVER(dir), 1); new_inode_info->finfo = entry; *************** *** 227,232 **** --- 232,238 ---- #endif return -ENOMEM; } + memset(link,0,SMB_MAX_SYMLINK_SIZE); ((__u32 *)link)[0]=SMB_SYMLINK_MAGIC0; ((__u32 *)link)[1]=SMB_SYMLINK_MAGIC1; *************** *** 249,255 **** printk(" inode population,"); #endif dirent = &(SMB_INOP(inode)->finfo); ! DDPRINTK("smb_make_open: dirent->opened = %d\n", dirent->opened); if ((dirent->opened) == 0) { /* tries max. rights */ --- 255,261 ---- printk(" inode population,"); #endif dirent = &(SMB_INOP(inode)->finfo); ! DPRINTK("smb_make_open: dirent->opened = %d\n", dirent->opened); if ((dirent->opened) == 0) { /* tries max. rights */ *************** *** 268,282 **** DPRINTK("preparing to write %i (%s),",length+8,link); bufsize = SMB_SERVER(inode)->max_xmit - SMB_HEADER_LEN - 5 * 2 - 5; ! if ((err = smb_proc_write_mem(SMB_SERVER(inode), SMB_FINFO(inode), 0, length+8, link)) < 0) { #ifdef SMBFS_DEBUG_VERBOSE printk(" bombed on write (%s) error %i\n",link+8, err); #endif smb_kfree_s(link,SMB_MAX_SYMLINK_SIZE); return -EIO; } - inode->i_size = length+8; inode->i_dirt = 1; inode->i_mode = S_IFLNK | S_IRWXUGO; --- 274,288 ---- DPRINTK("preparing to write %i (%s),",length+8,link); bufsize = SMB_SERVER(inode)->max_xmit - SMB_HEADER_LEN - 5 * 2 - 5; + inode->i_size = SMB_MAX_SYMLINK_SIZE; ! if ((err = smb_proc_write_mem(SMB_SERVER(inode), SMB_FINFO(inode), 0, SMB_MAX_SYMLINK_SIZE, link)) < 0) { #ifdef SMBFS_DEBUG_VERBOSE printk(" bombed on write (%s) error %i\n",link+8, err); #endif smb_kfree_s(link,SMB_MAX_SYMLINK_SIZE); return -EIO; } inode->i_dirt = 1; inode->i_mode = S_IFLNK | S_IRWXUGO; diff -r -c --new-file client-2.0.33.s.v0.4/fs/smbfs/symlink.h client-2.0.33.s.v0.5/fs/smbfs/symlink.h *** client-2.0.33.s.v0.4/fs/smbfs/symlink.h Wed Apr 19 21:18:12 2000 --- client-2.0.33.s.v0.5/fs/smbfs/symlink.h Tue May 2 19:32:46 2000 *************** *** 13,19 **** /* adopted from fs/ncpfs/ncplib_kernel.h */ #define SMB_MIN_SYMLINK_SIZE 8 ! #define SMB_MAX_SYMLINK_SIZE 512 #define TWENTY_YEARS 631152043 /* wtf? yields 631152000 on my clock */ #define TEN_YEARS (TWENTY_YEARS/2) --- 13,19 ---- /* adopted from fs/ncpfs/ncplib_kernel.h */ #define SMB_MIN_SYMLINK_SIZE 8 ! #define SMB_MAX_SYMLINK_SIZE 269 /* suitable prime after 255+8 */ #define TWENTY_YEARS 631152043 /* wtf? yields 631152000 on my clock */ #define TEN_YEARS (TWENTY_YEARS/2)