diff -urN 2.0.7/fs/ncpfs/dir.c linux/fs/ncpfs/dir.c --- 2.0.7/fs/ncpfs/dir.c Mon Jul 8 17:19:03 1996 +++ linux/fs/ncpfs/dir.c Tue Jul 16 17:35:07 1996 @@ -92,6 +92,20 @@ } } +static inline int +ncp_namespace(struct inode *i) +{ + struct ncp_server *server = NCP_SERVER(i); + struct nw_info_struct *info = NCP_ISTRUCT(i); + return server->name_space[info->volNumber]; +} + +static inline int +ncp_preserve_case(struct inode *i) +{ + return (ncp_namespace(i) == NW_NS_OS2); +} + static struct file_operations ncp_dir_operations = { NULL, /* lseek - default */ ncp_dir_read, /* read - bad */ @@ -128,7 +142,7 @@ /* Here we encapsulate the inode number handling that depends upon the * mount mode: When we mount a complete server, the memory address of * the ncp_inode_info is used as the inode number. When only a single - * volume is mounted, then the DosDirNum is used as the inode + * volume is mounted, then the dirEntNum is used as the inode * number. As this is unique for the complete volume, this should * enable the NFS exportability of a ncpfs-mounted volume. */ @@ -143,7 +157,7 @@ ncp_info_ino(struct ncp_server *server, struct ncp_inode_info *info) { return ncp_single_volume(server) - ? info->finfo.i.DosDirNum : (ino_t)info; + ? info->finfo.i.dirEntNum : (ino_t)info; } static inline int @@ -177,8 +191,6 @@ return NULL; } - - static int ncp_dir_read(struct inode *inode, struct file *filp, char *buf, int count) { @@ -326,9 +338,12 @@ c_last_returned_index = 0; index = 0; - for (i = 0; i < c_size; i++) + if (!ncp_preserve_case(inode)) { - str_lower(c_entry[i].i.entryName); + for (i = 0; i < c_size; i++) + { + str_lower(c_entry[i].i.entryName); + } } } } @@ -345,7 +360,7 @@ if (ncp_single_volume(server)) { - ino = (ino_t)(entry->i.DosDirNum); + ino = (ino_t)(entry->i.dirEntNum); } else { @@ -652,7 +667,7 @@ root->finfo.opened = 0; i->attributes = aDIR; i->dataStreamSize = 1024; - i->DosDirNum = 0; + i->dirEntNum = i->DosDirNum = 0; i->volNumber = NCP_NUMBER_OF_VOLUMES+1; /* illegal volnum */ ncp_date_unix2dos(0, &(i->creationTime), &(i->creationDate)); ncp_date_unix2dos(0, &(i->modifyTime), &(i->modifyDate)); @@ -729,7 +744,7 @@ do { - if ( (result->dir->finfo.i.DosDirNum == dir_info->DosDirNum) + if ( (result->dir->finfo.i.dirEntNum == dir_info->dirEntNum) && (result->dir->finfo.i.volNumber == dir_info->volNumber) && (strcmp(result->finfo.i.entryName, name) == 0) /* The root dir is never looked up using this @@ -757,6 +772,7 @@ struct ncp_server *server; struct ncp_inode_info *result_info; int found_in_cache; + int down_case = 0; char name[len+1]; *result = NULL; @@ -867,20 +883,26 @@ if (found_in_cache == 0) { int res; - str_upper(name); DDPRINTK("ncp_lookup: do_lookup on %s/%s\n", NCP_ISTRUCT(dir)->entryName, name); if (ncp_is_server_root(dir)) { + str_upper(name); + down_case = 1; res = ncp_lookup_volume(server, name, &(finfo.i)); } else { + if (!ncp_preserve_case(dir)) + { + str_upper(name); + down_case = 1; + } res = ncp_obtain_info(server, NCP_ISTRUCT(dir)->volNumber, - NCP_ISTRUCT(dir)->DosDirNum, + NCP_ISTRUCT(dir)->dirEntNum, name, &(finfo.i)); } if (res != 0) @@ -892,7 +914,11 @@ } finfo.opened = 0; - str_lower(finfo.i.entryName); + + if (down_case != 0) + { + str_lower(finfo.i.entryName); + } if (!(*result = ncp_iget(dir, &finfo))) { @@ -929,7 +955,11 @@ strncpy(_name, name, len); _name[len] = '\0'; - str_upper(_name); + + if (!ncp_preserve_case(dir)) + { + str_upper(_name); + } lock_super(dir->i_sb); if (ncp_open_create_file_or_subdir(NCP_SERVER(dir), @@ -946,7 +976,11 @@ ncp_invalid_dir_cache(dir); - str_lower(finfo.i.entryName); + if (!ncp_preserve_case(dir)) + { + str_lower(finfo.i.entryName); + } + finfo.access = O_RDWR; if (!(*result = ncp_iget(dir, &finfo)) < 0) @@ -980,7 +1014,11 @@ strncpy(_name, name, len); _name[len] = '\0'; - str_upper(_name); + + if (!ncp_preserve_case(dir)) + { + str_upper(_name); + } if (!dir || !S_ISDIR(dir->i_mode)) { @@ -1038,7 +1076,11 @@ strncpy(_name, name, len); _name[len] = '\0'; - str_upper(_name); + + if (!ncp_preserve_case(dir)) + { + str_upper(_name); + } if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir), NCP_ISTRUCT(dir), @@ -1081,7 +1123,11 @@ { strncpy(_name, name, len); _name[len] = '\0'; - str_upper(_name); + + if (!ncp_preserve_case(dir)) + { + str_upper(_name); + } if ((error = ncp_del_file_or_subdir(NCP_SERVER(dir), NCP_ISTRUCT(dir), @@ -1136,11 +1182,19 @@ strncpy(_old_name, old_name, old_len); _old_name[old_len] = '\0'; - str_upper(_old_name); + + if (!ncp_preserve_case(old_dir)) + { + str_upper(_old_name); + } strncpy(_new_name, new_name, new_len); _new_name[new_len] = '\0'; - str_upper(_new_name); + + if (!ncp_preserve_case(new_dir)) + { + str_upper(_new_name); + } res = ncp_ren_or_mov_file_or_subdir(NCP_SERVER(old_dir), NCP_ISTRUCT(old_dir), _old_name, diff -urN 2.0.7/fs/ncpfs/ncplib_kernel.c linux/fs/ncpfs/ncplib_kernel.c --- 2.0.7/fs/ncpfs/ncplib_kernel.c Thu Apr 18 08:40:28 1996 +++ linux/fs/ncpfs/ncplib_kernel.c Tue Jul 16 10:52:33 1996 @@ -190,25 +190,6 @@ } int -ncp_get_volume_number(struct ncp_server *server, const char *name, int *target) -{ - int result; - - ncp_init_request_s(server, 5); - ncp_add_pstring(server, name); - - if ((result = ncp_request(server, 22)) != 0) - { - ncp_unlock_server(server); - return result; - } - - *target = ncp_reply_byte(server, 0); - ncp_unlock_server(server); - return 0; -} - -int ncp_close_file(struct ncp_server *server, const char *file_id) { int result; @@ -278,8 +259,8 @@ ncp_init_request(server); ncp_add_byte(server, 6); /* subfunction */ - ncp_add_byte(server, 0); /* dos name space */ - ncp_add_byte(server, 0); /* dos name space as dest */ + ncp_add_byte(server, server->name_space[vol_num]); + ncp_add_byte(server, server->name_space[vol_num]); ncp_add_word(server, 0xff); /* get all */ ncp_add_dword(server, RIM_ALL); ncp_add_handle_path(server, vol_num, dir_base, 1, path); @@ -295,20 +276,57 @@ return 0; } +static inline int +ncp_has_os2_namespace(struct ncp_server *server, __u8 volume) +{ + int result; + __u8 *namespace; + __u16 no_namespaces; + + ncp_init_request(server); + ncp_add_byte(server, 24); /* Subfunction: Get Name Spaces Loaded */ + ncp_add_word(server, 0); + ncp_add_byte(server, volume); + + if ((result = ncp_request(server, 87)) != 0) + { + ncp_unlock_server(server); + return 0; + } + + no_namespaces = ncp_reply_word(server, 0); + namespace = ncp_reply_data(server, 2); + + while (no_namespaces > 0) + { + DPRINTK("get_namespaces: found %d on %d\n", *namespace,volume); + + if (*namespace == 4) + { + DPRINTK("get_namespaces: found OS2\n"); + ncp_unlock_server(server); + return 1; + } + namespace += 1; + no_namespaces -= 1; + } + ncp_unlock_server(server); + return 0; +} + int ncp_lookup_volume(struct ncp_server *server, char *volname, struct nw_info_struct *target) { int result; - __u8 vol_num; - __u32 dir_base; + int volnum; DPRINTK("ncp_lookup_volume: looking up vol %s\n", volname); ncp_init_request(server); ncp_add_byte(server, 22); /* Subfunction: Generate dir handle */ - ncp_add_byte(server, 0); /* DOS name space */ + ncp_add_byte(server, 0); /* DOS namespace */ ncp_add_byte(server, 0); /* reserved */ ncp_add_byte(server, 0); /* reserved */ ncp_add_byte(server, 0); /* reserved */ @@ -325,20 +343,19 @@ return result; } - dir_base = ncp_reply_dword(server, 4); - vol_num = ncp_reply_byte(server, 8); + memset(target, 0, sizeof(*target)); + target->DosDirNum = target->dirEntNum = ncp_reply_dword(server, 4); + target->volNumber = volnum = ncp_reply_byte(server, 8); ncp_unlock_server(server); - if ((result = ncp_obtain_info(server, vol_num, dir_base, NULL, - target)) != 0) - { - return result; - } + server->name_space[volnum] = ncp_has_os2_namespace(server,volnum)?4:0; - DPRINTK("ncp_lookup_volume: attribs = %X\n", target->attributes); + DPRINTK("lookup_vol: namespace[%d] = %d\n", + volnum, server->name_space[volnum]); target->nameLen = strlen(volname); strcpy(target->entryName, volname); + target->attributes = aDIR; return 0; } @@ -352,14 +369,14 @@ ncp_init_request(server); ncp_add_byte(server, 7); /* subfunction */ - ncp_add_byte(server, 0); /* dos name space */ + ncp_add_byte(server, server->name_space[file->volNumber]); ncp_add_byte(server, 0); /* reserved */ ncp_add_word(server, 0x8006); /* search attribs: all */ ncp_add_dword(server, info_mask); ncp_add_mem(server, info, sizeof(*info)); ncp_add_handle_path(server, file->volNumber, - file->DosDirNum, 1, NULL); + file->dirEntNum, 1, NULL); result = ncp_request(server, 87); ncp_unlock_server(server); @@ -374,11 +391,11 @@ ncp_init_request(server); ncp_add_byte(server, 8); /* subfunction */ - ncp_add_byte(server, 0); /* dos name space */ + ncp_add_byte(server, server->name_space[dir->volNumber]); ncp_add_byte(server, 0); /* reserved */ ncp_add_word(server, 0x8006); /* search attribs: all */ ncp_add_handle_path(server, dir->volNumber, - dir->DosDirNum, 1, name); + dir->dirEntNum, 1, name); result = ncp_request(server, 87); ncp_unlock_server(server); @@ -406,15 +423,16 @@ { int result; __u16 search_attribs = 0x0006; + __u8 volume = (dir != NULL) ? dir->volNumber : target->i.volNumber; if ((create_attributes & aDIR) != 0) { - search_attribs |= 0x8000; - } + search_attribs |= 0x8000; +} ncp_init_request(server); ncp_add_byte(server, 1); /* subfunction */ - ncp_add_byte(server, 0); /* dos name space */ + ncp_add_byte(server, server->name_space[volume]); ncp_add_byte(server, open_create_mode); ncp_add_word(server, search_attribs); ncp_add_dword(server, RIM_ALL); @@ -425,13 +443,11 @@ if (dir != NULL) { - ncp_add_handle_path(server, dir->volNumber, - dir->DosDirNum, 1, name); + ncp_add_handle_path(server, volume, dir->dirEntNum, 1, name); } else { - ncp_add_handle_path(server, - target->i.volNumber, target->i.DosDirNum, + ncp_add_handle_path(server, volume, target->i.dirEntNum, 1, NULL); } @@ -467,9 +483,9 @@ ncp_init_request(server); ncp_add_byte(server, 2); /* subfunction */ - ncp_add_byte(server, 0); /* dos name space */ + ncp_add_byte(server, server->name_space[dir->volNumber]); ncp_add_byte(server, 0); /* reserved */ - ncp_add_handle_path(server, dir->volNumber, dir->DosDirNum, 1, NULL); + ncp_add_handle_path(server, dir->volNumber, dir->dirEntNum, 1, NULL); if ((result = ncp_request(server, 87)) != 0) { @@ -493,7 +509,7 @@ ncp_init_request(server); ncp_add_byte(server, 3); /* subfunction */ - ncp_add_byte(server, 0); /* dos name space */ + ncp_add_byte(server, server->name_space[seq->volNumber]); ncp_add_byte(server, 0); /* data stream (???) */ ncp_add_word(server, 0xffff); /* Search attribs */ ncp_add_dword(server, RIM_ALL); /* return info mask */ @@ -528,19 +544,19 @@ ncp_init_request(server); ncp_add_byte(server, 4); /* subfunction */ - ncp_add_byte(server, 0); /* dos name space */ + ncp_add_byte(server, server->name_space[old_dir->volNumber]); ncp_add_byte(server, 1); /* rename flag */ ncp_add_word(server, 0x8006); /* search attributes */ /* source Handle Path */ ncp_add_byte(server, old_dir->volNumber); - ncp_add_dword(server, old_dir->DosDirNum); + ncp_add_dword(server, old_dir->dirEntNum); ncp_add_byte(server, 1); ncp_add_byte(server, 1); /* 1 source component */ /* dest Handle Path */ ncp_add_byte(server, new_dir->volNumber); - ncp_add_dword(server, new_dir->DosDirNum); + ncp_add_dword(server, new_dir->dirEntNum); ncp_add_byte(server, 1); ncp_add_byte(server, 1); /* 1 destination component */ diff -urN 2.0.7/include/linux/ncp.h linux/include/linux/ncp.h --- 2.0.7/include/linux/ncp.h Thu Apr 18 08:40:36 1996 +++ linux/include/linux/ncp.h Tue Jul 16 17:27:45 1996 @@ -116,6 +116,12 @@ __u16 update_time; }; +/* Defines for Name Spaces */ +#define NW_NS_DOS 0 +#define NW_NS_MAC 1 +#define NW_NS_NFS 2 +#define NW_NS_FTAM 3 +#define NW_NS_OS2 4 /* Defines for ReturnInformationMask */ #define RIM_NAME (0x0001L) diff -urN 2.0.7/include/linux/ncp_fs_sb.h linux/include/linux/ncp_fs_sb.h --- 2.0.7/include/linux/ncp_fs_sb.h Thu Apr 18 08:40:36 1996 +++ linux/include/linux/ncp_fs_sb.h Tue Jul 16 17:35:17 1996 @@ -21,6 +21,8 @@ interest for us later, so we store it completely. */ + __u8 name_space[NCP_NUMBER_OF_VOLUMES]; + struct file *ncp_filp; /* File pointer to ncp socket */ struct file *wdog_filp; /* File pointer to wdog socket */ struct file *msg_filp; /* File pointer to message socket */