ncplib_kernel.c revision 32c419d95f3d1da891ab9bd032a214ee05b94ed4
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ncplib_kernel.c 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1995, 1996 by Volker Lendecke 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Modified for big endian by J.F. Chadima and David S. Miller 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Modified 1999 Wolfram Pienkoss for NLS 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Modified 2000 Ben Harris, University of Cambridge for NFS NS meta-info 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1432c419d95f3d1da891ab9bd032a214ee05b94ed4Al Viro#include "ncp_fs.h" 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void assert_server_locked(struct ncp_server *server) 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (server->lock == 0) { 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DPRINTK("ncpfs: server not locked!\n"); 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void ncp_add_byte(struct ncp_server *server, __u8 x) 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds assert_server_locked(server); 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(__u8 *) (&(server->packet[server->current_size])) = x; 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds server->current_size += 1; 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void ncp_add_word(struct ncp_server *server, __le16 x) 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds assert_server_locked(server); 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds put_unaligned(x, (__le16 *) (&(server->packet[server->current_size]))); 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds server->current_size += 2; 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void ncp_add_be16(struct ncp_server *server, __u16 x) 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds assert_server_locked(server); 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds put_unaligned(cpu_to_be16(x), (__be16 *) (&(server->packet[server->current_size]))); 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds server->current_size += 2; 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void ncp_add_dword(struct ncp_server *server, __le32 x) 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds assert_server_locked(server); 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds put_unaligned(x, (__le32 *) (&(server->packet[server->current_size]))); 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds server->current_size += 4; 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void ncp_add_be32(struct ncp_server *server, __u32 x) 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds assert_server_locked(server); 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds put_unaligned(cpu_to_be32(x), (__be32 *)(&(server->packet[server->current_size]))); 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds server->current_size += 4; 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void ncp_add_dword_lh(struct ncp_server *server, __u32 x) { 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword(server, cpu_to_le32(x)); 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void ncp_add_mem(struct ncp_server *server, const void *source, int size) 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds assert_server_locked(server); 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(&(server->packet[server->current_size]), source, size); 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds server->current_size += size; 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void ncp_add_pstring(struct ncp_server *server, const char *s) 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int len = strlen(s); 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds assert_server_locked(server); 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (len > 255) { 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DPRINTK("ncpfs: string too long: %s\n", s); 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = 255; 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, len); 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_mem(server, s, len); 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void ncp_init_request(struct ncp_server *server) 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_lock_server(server); 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds server->current_size = sizeof(struct ncp_request_header); 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds server->has_subfunction = 0; 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void ncp_init_request_s(struct ncp_server *server, int subfunction) 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_lock_server(server); 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds server->current_size = sizeof(struct ncp_request_header) + 2; 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, subfunction); 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds server->has_subfunction = 1; 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline char * 10597a4feb4a78ae5cd130be7d546471a0779f1aa14Harvey Harrisonncp_reply_data(struct ncp_server *server, int offset) 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return &(server->packet[sizeof(struct ncp_reply_header) + offset]); 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1102e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovecstatic inline u8 BVAL(const void *data) 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1122e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec return *(const u8 *)data; 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11597a4feb4a78ae5cd130be7d546471a0779f1aa14Harvey Harrisonstatic u8 ncp_reply_byte(struct ncp_server *server, int offset) 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1172e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec return *(const u8 *)ncp_reply_data(server, offset); 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1202e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovecstatic inline u16 WVAL_LH(const void *data) 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12297a4feb4a78ae5cd130be7d546471a0779f1aa14Harvey Harrison return get_unaligned_le16(data); 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12597a4feb4a78ae5cd130be7d546471a0779f1aa14Harvey Harrisonstatic u16 12697a4feb4a78ae5cd130be7d546471a0779f1aa14Harvey Harrisonncp_reply_le16(struct ncp_server *server, int offset) 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12897a4feb4a78ae5cd130be7d546471a0779f1aa14Harvey Harrison return get_unaligned_le16(ncp_reply_data(server, offset)); 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13197a4feb4a78ae5cd130be7d546471a0779f1aa14Harvey Harrisonstatic u16 13297a4feb4a78ae5cd130be7d546471a0779f1aa14Harvey Harrisonncp_reply_be16(struct ncp_server *server, int offset) 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13497a4feb4a78ae5cd130be7d546471a0779f1aa14Harvey Harrison return get_unaligned_be16(ncp_reply_data(server, offset)); 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1372e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovecstatic inline u32 DVAL_LH(const void *data) 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13997a4feb4a78ae5cd130be7d546471a0779f1aa14Harvey Harrison return get_unaligned_le32(data); 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic __le32 14397a4feb4a78ae5cd130be7d546471a0779f1aa14Harvey Harrisonncp_reply_dword(struct ncp_server *server, int offset) 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14597a4feb4a78ae5cd130be7d546471a0779f1aa14Harvey Harrison return get_unaligned((__le32 *)ncp_reply_data(server, offset)); 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline __u32 ncp_reply_dword_lh(struct ncp_server* server, int offset) { 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return le32_to_cpu(ncp_reply_dword(server, offset)); 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_negotiate_buffersize(struct ncp_server *server, int size, int *target) 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_be16(server, size); 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_request(server, 33)) != 0) { 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *target = min_t(unsigned int, ncp_reply_be16(server, 0), size); 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* options: 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * bit 0 ipx checksum 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * bit 1 packet signing 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_negotiate_size_and_options(struct ncp_server *server, 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int size, int options, int *ret_size, int *ret_options) { 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* there is minimum */ 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (size < NCP_BLOCK_SIZE) size = NCP_BLOCK_SIZE; 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_be16(server, size); 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, options); 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_request(server, 0x61)) != 0) 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* NCP over UDP returns 0 (!!!) */ 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_reply_be16(server, 0); 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (result >= NCP_BLOCK_SIZE) 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = min(result, size); 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ret_size = size; 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ret_options = ncp_reply_byte(server, 4); 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ncp_get_volume_info_with_number(struct ncp_server* server, 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int n, struct ncp_volume_info* target) { 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int len; 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request_s(server, 44); 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, n); 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_request(server, 22)) != 0) { 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->total_blocks = ncp_reply_dword_lh(server, 0); 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->free_blocks = ncp_reply_dword_lh(server, 4); 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->purgeable_blocks = ncp_reply_dword_lh(server, 8); 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->not_yet_purgeable_blocks = ncp_reply_dword_lh(server, 12); 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->total_dir_entries = ncp_reply_dword_lh(server, 16); 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->available_dir_entries = ncp_reply_dword_lh(server, 20); 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->sectors_per_block = ncp_reply_byte(server, 28); 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(&(target->volume_name), 0, sizeof(target->volume_name)); 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = -EIO; 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = ncp_reply_byte(server, 29); 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (len > NCP_VOLNAME_LEN) { 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DPRINTK("ncpfs: volume name too long: %d\n", len); 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(&(target->volume_name), ncp_reply_data(server, 30), len); 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = 0; 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ncp_get_directory_info(struct ncp_server* server, __u8 n, 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct ncp_volume_info* target) { 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int len; 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request_s(server, 45); 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, n); 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_request(server, 22)) != 0) { 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->total_blocks = ncp_reply_dword_lh(server, 0); 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->free_blocks = ncp_reply_dword_lh(server, 4); 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->purgeable_blocks = 0; 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->not_yet_purgeable_blocks = 0; 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->total_dir_entries = ncp_reply_dword_lh(server, 8); 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->available_dir_entries = ncp_reply_dword_lh(server, 12); 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->sectors_per_block = ncp_reply_byte(server, 20); 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(&(target->volume_name), 0, sizeof(target->volume_name)); 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = -EIO; 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = ncp_reply_byte(server, 21); 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (len > NCP_VOLNAME_LEN) { 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DPRINTK("ncpfs: volume name too long: %d\n", len); 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(&(target->volume_name), ncp_reply_data(server, 22), len); 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = 0; 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_close_file(struct ncp_server *server, const char *file_id) 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_mem(server, file_id, 6); 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_request(server, 66); 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_make_closed(struct inode *inode) 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = 0; 2928e3f90459b7052c31a9669417b837fb14aa6d313Ingo Molnar mutex_lock(&NCP_FINFO(inode)->open_mutex); 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (atomic_read(&NCP_FINFO(inode)->opened) == 1) { 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds atomic_set(&NCP_FINFO(inode)->opened, 0); 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = ncp_close_file(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle); 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!err) 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds PPRINTK("ncp_make_closed: volnum=%d, dirent=%u, error=%d\n", 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCP_FINFO(inode)->volNumber, 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NCP_FINFO(inode)->dirEntNum, err); 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3028e3f90459b7052c31a9669417b837fb14aa6d313Ingo Molnar mutex_unlock(&NCP_FINFO(inode)->open_mutex); 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void ncp_add_handle_path(struct ncp_server *server, __u8 vol_num, 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le32 dir_base, int have_dir_base, 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const char *path) 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, vol_num); 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword(server, dir_base); 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (have_dir_base != 0) { 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 1); /* dir_base */ 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0xff); /* no handle */ 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (path != NULL) { 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 1); /* 1 component */ 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_pstring(server, path); 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ncp_dirhandle_alloc(struct ncp_server* server, __u8 volnum, __le32 dirent, 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8* dirhandle) { 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 12); /* subfunction */ 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, NW_NS_DOS); 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_word(server, 0); 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_handle_path(server, volnum, dirent, 1, NULL); 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_request(server, 87)) == 0) { 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *dirhandle = ncp_reply_byte(server, 0); 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ncp_dirhandle_free(struct ncp_server* server, __u8 dirhandle) { 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request_s(server, 20); 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, dirhandle); 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_request(server, 22); 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3522e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovecvoid ncp_extract_file_info(const void *structure, struct nw_info_struct *target) 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3542e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec const __u8 *name_len; 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const int info_struct_size = offsetof(struct nw_info_struct, nameLen); 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(target, structure, info_struct_size); 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds name_len = structure + info_struct_size; 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->nameLen = *name_len; 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(target->entryName, name_len + 1, *name_len); 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->entryName[*name_len] = '\0'; 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->volNumber = le32_to_cpu(target->volNumber); 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_NCPFS_NFS_NS 3672e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovecstatic inline void ncp_extract_nfs_info(const unsigned char *structure, 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct nw_nfs_info *target) 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->mode = DVAL_LH(structure); 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->rdev = DVAL_LH(structure + 8); 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ncp_obtain_nfs_info(struct ncp_server *server, 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct nw_info_struct *target) 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result = 0; 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_NCPFS_NFS_NS 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u32 volnum = target->volNumber; 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ncp_is_nfs_extras(server, volnum)) { 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 19); /* subfunction */ 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, server->name_space[volnum]); 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, NW_NS_NFS); 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, volnum); 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword(server, target->dirEntNum); 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* We must retrieve both nlinks and rdev, otherwise some server versions 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds report zeroes instead of valid data */ 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword_lh(server, NSIBM_NFS_MODE | NSIBM_NFS_NLINKS | NSIBM_NFS_RDEV); 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_request(server, 87)) == 0) { 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_extract_nfs_info(ncp_reply_data(server, 0), &target->nfs); 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DPRINTK(KERN_DEBUG 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "ncp_obtain_nfs_info: (%s) mode=0%o, rdev=0x%x\n", 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->entryName, target->nfs.mode, 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->nfs.rdev); 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->nfs.mode = 0; 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->nfs.rdev = 0; 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->nfs.mode = 0; 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->nfs.rdev = 0; 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns information for a (one-component) name relative to 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the specified directory. 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4202e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovecint ncp_obtain_info(struct ncp_server *server, struct inode *dir, const char *path, 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct nw_info_struct *target) 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 volnum = NCP_FINFO(dir)->volNumber; 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le32 dirent = NCP_FINFO(dir)->dirEntNum; 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (target == NULL) { 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "ncp_obtain_info: invalid call\n"); 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 6); /* subfunction */ 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, server->name_space[volnum]); 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, server->name_space[volnum]); /* N.B. twice ?? */ 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_word(server, cpu_to_le16(0x8006)); /* get all */ 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword(server, RIM_ALL); 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_handle_path(server, volnum, dirent, 1, path); 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_request(server, 87)) != 0) 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_extract_file_info(ncp_reply_data(server, 0), target); 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_obtain_nfs_info(server, target); 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_NCPFS_NFS_NS 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_obtain_DOS_dir_base(struct ncp_server *server, 4552e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec __u8 ns, __u8 volnum, __le32 dirent, 4562e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec const char *path, /* At most 1 component */ 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le32 *DOS_dir_base) 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 6); /* subfunction */ 4632e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec ncp_add_byte(server, ns); 4642e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec ncp_add_byte(server, ns); 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_word(server, cpu_to_le16(0x8006)); /* get all */ 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword(server, RIM_DIRECTORY); 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_handle_path(server, volnum, dirent, 1, path); 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_request(server, 87)) == 0) 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (DOS_dir_base) *DOS_dir_base=ncp_reply_dword(server, 0x34); 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* CONFIG_NCPFS_NFS_NS */ 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline int 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_get_known_namespace(struct ncp_server *server, __u8 volume) 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if defined(CONFIG_NCPFS_OS2_NS) || defined(CONFIG_NCPFS_NFS_NS) 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 *namespace; 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 no_namespaces; 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 24); /* Subfunction: Get Name Spaces Loaded */ 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_word(server, 0); 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, volume); 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_request(server, 87)) != 0) { 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NW_NS_DOS; /* not result ?? */ 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = NW_NS_DOS; 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds no_namespaces = ncp_reply_le16(server, 0); 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds namespace = ncp_reply_data(server, 2); 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (no_namespaces > 0) { 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DPRINTK("get_namespaces: found %d on %d\n", *namespace, volume); 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_NCPFS_NFS_NS 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((*namespace == NW_NS_NFS) && !(server->m.flags&NCP_MOUNT_NO_NFS)) 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = NW_NS_NFS; 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* CONFIG_NCPFS_NFS_NS */ 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_NCPFS_OS2_NS 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((*namespace == NW_NS_OS2) && !(server->m.flags&NCP_MOUNT_NO_OS2)) 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = NW_NS_OS2; 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* CONFIG_NCPFS_OS2_NS */ 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds namespace += 1; 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds no_namespaces -= 1; 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else /* neither OS2 nor NFS - only DOS */ 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NW_NS_DOS; 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* defined(CONFIG_NCPFS_OS2_NS) || defined(CONFIG_NCPFS_NFS_NS) */ 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5262e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovecint 5272e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovecncp_update_known_namespace(struct ncp_server *server, __u8 volume, int *ret_ns) 5282e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec{ 5292e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec int ns = ncp_get_known_namespace(server, volume); 5302e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec 5312e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec if (ret_ns) 5322e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec *ret_ns = ns; 5332e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec 5342e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec DPRINTK("lookup_vol: namespace[%d] = %d\n", 5352e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec volume, server->name_space[volume]); 5362e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec 5372e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec if (server->name_space[volume] == ns) 5382e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec return 0; 5392e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec server->name_space[volume] = ns; 5402e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec return 1; 5412e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec} 5422e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_ObtainSpecificDirBase(struct ncp_server *server, 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 nsSrc, __u8 nsDst, __u8 vol_num, __le32 dir_base, 5462e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec const char *path, /* At most 1 component */ 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le32 *dirEntNum, __le32 *DosDirNum) 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 6); /* subfunction */ 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, nsSrc); 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, nsDst); 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_word(server, cpu_to_le16(0x8006)); /* get all */ 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword(server, RIM_ALL); 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_handle_path(server, vol_num, dir_base, 1, path); 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_request(server, 87)) != 0) 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dirEntNum) 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *dirEntNum = ncp_reply_dword(server, 0x30); 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (DosDirNum) 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *DosDirNum = ncp_reply_dword(server, 0x34); 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_mount_subdir(struct ncp_server *server, 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 volNumber, __u8 srcNS, __le32 dirEntNum, 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u32* volume, __le32* newDirEnt, __le32* newDosEnt) 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int dstNS; 5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 5802e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec 5812e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec ncp_update_known_namespace(server, volNumber, &dstNS); 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_ObtainSpecificDirBase(server, srcNS, dstNS, volNumber, 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dirEntNum, NULL, newDirEnt, newDosEnt)) != 0) 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *volume = volNumber; 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds server->m.mounted_vol[1] = 0; 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds server->m.mounted_vol[0] = 'X'; 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 5942e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovecncp_get_volume_root(struct ncp_server *server, 5952e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec const char *volname, __u32* volume, __le32* dirent, __le32* dosdirent) 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DPRINTK("ncp_get_volume_root: looking up vol %s\n", volname); 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 22); /* Subfunction: Generate dir handle */ 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); /* DOS namespace */ 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); /* reserved */ 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); /* reserved */ 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); /* reserved */ 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); /* faked volume number */ 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword(server, 0); /* faked dir_base */ 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0xff); /* Don't have a dir_base */ 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 1); /* 1 path component */ 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_pstring(server, volname); 6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_request(server, 87)) != 0) { 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *dirent = *dosdirent = ncp_reply_dword(server, 4); 6192e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec *volume = ncp_reply_byte(server, 8); 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 6252e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovecncp_lookup_volume(struct ncp_server *server, 6262e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec const char *volname, struct nw_info_struct *target) 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(target, 0, sizeof(*target)); 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_get_volume_root(server, volname, 6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &target->volNumber, &target->dirEntNum, &target->DosDirNum); 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (result) { 6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6362e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec ncp_update_known_namespace(server, target->volNumber, NULL); 6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->nameLen = strlen(volname); 6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(target->entryName, volname, target->nameLen+1); 6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->attributes = aDIR; 6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* set dates to Jan 1, 1986 00:00 */ 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->creationTime = target->modifyTime = cpu_to_le16(0x0000); 6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->creationDate = target->modifyDate = target->lastAccessDate = cpu_to_le16(0x0C21); 6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->nfs.mode = 0; 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ncp_modify_file_or_subdir_dos_info_path(struct ncp_server *server, 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct inode *dir, 6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const char *path, 6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le32 info_mask, 6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const struct nw_modify_dos_info *info) 6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 volnum = NCP_FINFO(dir)->volNumber; 6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le32 dirent = NCP_FINFO(dir)->dirEntNum; 6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 7); /* subfunction */ 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, server->name_space[volnum]); 6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); /* reserved */ 6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_word(server, cpu_to_le16(0x8006)); /* search attribs: all */ 6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword(server, info_mask); 6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_mem(server, info, sizeof(*info)); 6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_handle_path(server, volnum, dirent, 1, path); 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_request(server, 87); 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ncp_modify_file_or_subdir_dos_info(struct ncp_server *server, 6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct inode *dir, 6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le32 info_mask, 6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const struct nw_modify_dos_info *info) 6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ncp_modify_file_or_subdir_dos_info_path(server, dir, NULL, 6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds info_mask, info); 6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_NCPFS_NFS_NS 6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ncp_modify_nfs_info(struct ncp_server *server, __u8 volnum, __le32 dirent, 6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u32 mode, __u32 rdev) 6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result = 0; 6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6882e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec ncp_init_request(server); 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (server->name_space[volnum] == NW_NS_NFS) { 6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 25); /* subfunction */ 6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, server->name_space[volnum]); 6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, NW_NS_NFS); 6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, volnum); 6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword(server, dirent); 6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* we must always operate on both nlinks and rdev, otherwise 6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rdev is not set */ 6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword_lh(server, NSIBM_NFS_MODE | NSIBM_NFS_NLINKS | NSIBM_NFS_RDEV); 6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword_lh(server, mode); 6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword_lh(server, 1); /* nlinks */ 7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword_lh(server, rdev); 7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_request(server, 87); 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7032e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec ncp_unlock_server(server); 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_DeleteNSEntry(struct ncp_server *server, 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 have_dir_base, __u8 volnum, __le32 dirent, 7122e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec const char* name, __u8 ns, __le16 attr) 7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 8); /* subfunction */ 7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, ns); 7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); /* reserved */ 7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_word(server, attr); /* search attribs: all */ 7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_handle_path(server, volnum, dirent, have_dir_base, name); 7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_request(server, 87); 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_del_file_or_subdir2(struct ncp_server *server, 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dentry *dentry) 7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct inode *inode = dentry->d_inode; 7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 volnum; 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le32 dirent; 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!inode) { 7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0xFF; /* Any error */ 7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds volnum = NCP_FINFO(inode)->volNumber; 7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dirent = NCP_FINFO(inode)->DosDirNum; 7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ncp_DeleteNSEntry(server, 1, volnum, dirent, NULL, NW_NS_DOS, cpu_to_le16(0x8006)); 7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_del_file_or_subdir(struct ncp_server *server, 7462e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec struct inode *dir, const char *name) 7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 volnum = NCP_FINFO(dir)->volNumber; 7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le32 dirent = NCP_FINFO(dir)->dirEntNum; 7502e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec int name_space; 7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7522e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec name_space = server->name_space[volnum]; 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_NCPFS_NFS_NS 7542e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec if (name_space == NW_NS_NFS) 7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7582e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec result=ncp_obtain_DOS_dir_base(server, name_space, volnum, dirent, name, &dirent); 7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (result) return result; 7602e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec name = NULL; 7612e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec name_space = NW_NS_DOS; 7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* CONFIG_NCPFS_NFS_NS */ 7642e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec return ncp_DeleteNSEntry(server, 1, volnum, dirent, name, name_space, cpu_to_le16(0x8006)); 7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void ConvertToNWfromDWORD(__u16 v0, __u16 v1, __u8 ret[6]) 7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le16 *dest = (__le16 *) ret; 7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dest[1] = cpu_to_le16(v0); 7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dest[2] = cpu_to_le16(v1); 7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dest[0] = cpu_to_le16(v0 + 1); 7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* If both dir and name are NULL, then in target there's already a 7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds looked-up entry that wants to be opened. */ 7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ncp_open_create_file_or_subdir(struct ncp_server *server, 7792e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec struct inode *dir, const char *name, 7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int open_create_mode, 7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le32 create_attributes, 7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le16 desired_acc_rights, 7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct ncp_entry_info *target) 7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le16 search_attribs = cpu_to_le16(0x0006); 7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 volnum; 7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le32 dirent; 7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds volnum = NCP_FINFO(dir)->volNumber; 7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dirent = NCP_FINFO(dir)->dirEntNum; 7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((create_attributes & aDIR) != 0) { 7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds search_attribs |= cpu_to_le16(0x8000); 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 1); /* subfunction */ 7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, server->name_space[volnum]); 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, open_create_mode); 8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_word(server, search_attribs); 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword(server, RIM_ALL); 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword(server, create_attributes); 8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* The desired acc rights seem to be the inherited rights mask 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for directories */ 8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_word(server, desired_acc_rights); 8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_handle_path(server, volnum, dirent, 1, name); 8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_request(server, 87)) != 0) 8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(create_attributes & aDIR)) 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->opened = 1; 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* in target there's a new finfo to fill */ 8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_extract_file_info(ncp_reply_data(server, 6), &(target->i)); 8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->volume = target->i.volNumber; 8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ConvertToNWfromDWORD(ncp_reply_le16(server, 0), 8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_reply_le16(server, 2), 8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->file_handle); 8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (void)ncp_obtain_nfs_info(server, &(target->i)); 8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_initialize_search(struct ncp_server *server, struct inode *dir, 8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct nw_search_sequence *target) 8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 volnum = NCP_FINFO(dir)->volNumber; 8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le32 dirent = NCP_FINFO(dir)->dirEntNum; 8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 2); /* subfunction */ 8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, server->name_space[volnum]); 8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); /* reserved */ 8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_handle_path(server, volnum, dirent, 1, NULL); 8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_request(server, 87); 8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (result) 8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(target, ncp_reply_data(server, 0), sizeof(*target)); 8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ncp_search_for_fileset(struct ncp_server *server, 8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct nw_search_sequence *seq, 8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int* more, 8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int* cnt, 8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char* buffer, 8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size_t bufsize, 8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char** rbuf, 8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size_t* rsize) 8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 20); 8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, server->name_space[seq->volNumber]); 8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); /* datastream */ 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_word(server, cpu_to_le16(0x8006)); 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword(server, RIM_ALL); 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_word(server, cpu_to_le16(32767)); /* max returned items */ 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_mem(server, seq, 9); 8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_NCPFS_NFS_NS 8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (server->name_space[seq->volNumber] == NW_NS_NFS) { 8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); /* 0 byte pattern */ 8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 2); /* 2 byte pattern */ 8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0xff); /* following is a wildcard */ 8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, '*'); 8821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_request2(server, 87, buffer, bufsize); 8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (result) { 8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (server->ncp_reply_size < 12) { 8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0xFF; 8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *rsize = server->ncp_reply_size - 12; 8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buffer = buffer + sizeof(struct ncp_reply_header); 8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *rbuf = buffer + 12; 8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *cnt = WVAL_LH(buffer + 10); 8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *more = BVAL(buffer + 9); 8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(seq, buffer, 9); 8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_RenameNSEntry(struct ncp_server *server, 9042e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec struct inode *old_dir, const char *old_name, __le16 old_type, 9052e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec struct inode *new_dir, const char *new_name) 9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result = -EINVAL; 9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((old_dir == NULL) || (old_name == NULL) || 9101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (new_dir == NULL) || (new_name == NULL)) 9111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 9121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 9141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 4); /* subfunction */ 9151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, server->name_space[NCP_FINFO(old_dir)->volNumber]); 9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 1); /* rename flag */ 9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_word(server, old_type); /* search attributes */ 9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* source Handle Path */ 9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, NCP_FINFO(old_dir)->volNumber); 9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword(server, NCP_FINFO(old_dir)->dirEntNum); 9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 1); 9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 1); /* 1 source component */ 9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* dest Handle Path */ 9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, NCP_FINFO(new_dir)->volNumber); 9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword(server, NCP_FINFO(new_dir)->dirEntNum); 9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 1); 9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 1); /* 1 destination component */ 9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* source path string */ 9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_pstring(server, old_name); 9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* dest path string */ 9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_pstring(server, new_name); 9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_request(server, 87); 9371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 9381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 9391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ncp_ren_or_mov_file_or_subdir(struct ncp_server *server, 9432e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec struct inode *old_dir, const char *old_name, 9442e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec struct inode *new_dir, const char *new_name) 9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le16 old_type = cpu_to_le16(0x06); 9481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* If somebody can do it atomic, call me... vandrove@vc.cvut.cz */ 9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_RenameNSEntry(server, old_dir, old_name, old_type, 9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new_dir, new_name); 9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (result == 0xFF) /* File Not Found, try directory */ 9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds old_type = cpu_to_le16(0x16); 9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_RenameNSEntry(server, old_dir, old_name, old_type, 9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new_dir, new_name); 9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (result != 0x92) return result; /* All except NO_FILES_RENAMED */ 9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_del_file_or_subdir(server, new_dir, new_name); 9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (result != 0) return -EACCES; 9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_RenameNSEntry(server, old_dir, old_name, old_type, 9621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new_dir, new_name); 9631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* We have to transfer to/from user space */ 9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_read_kernel(struct ncp_server *server, const char *file_id, 9701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u32 offset, __u16 to_read, char *target, int *bytes_read) 9711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9722e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec const char *source; 9731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 9741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); 9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_mem(server, file_id, 6); 9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_be32(server, offset); 9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_be16(server, to_read); 9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_request(server, 72)) != 0) { 9821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 9831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *bytes_read = ncp_reply_be16(server, 0); 9851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds source = ncp_reply_data(server, 2 + (offset & 1)); 9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(target, source, *bytes_read); 9881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 9891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 9901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 9911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* There is a problem... egrep and some other silly tools do: 9941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds x = mmap(NULL, MAP_PRIVATE, PROT_READ|PROT_WRITE, <ncpfs fd>, 32768); 9951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds read(<ncpfs fd>, x, 32768); 9961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Now copying read result by copy_to_user causes pagefault. This pagefault 9971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds could not be handled because of server was locked due to read. So we have 9981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds to use temporary buffer. So ncp_unlock_server must be done before 9991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds copy_to_user (and for write, copy_from_user must be done before 10001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request... same applies for send raw packet ioctl). Because of 10011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds file is normally read in bigger chunks, caller provides kmalloced 10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (vmalloced) chunk of memory with size >= to_read... 10031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 10041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 10051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_read_bounce(struct ncp_server *server, const char *file_id, 10061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u32 offset, __u16 to_read, char __user *target, int *bytes_read, 10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void* bounce, __u32 bufsize) 10081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 10121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); 10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_mem(server, file_id, 6); 10141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_be32(server, offset); 10151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_be16(server, to_read); 10161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_request2(server, 72, bounce, bufsize); 10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 10181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!result) { 101997a4feb4a78ae5cd130be7d546471a0779f1aa14Harvey Harrison int len = get_unaligned_be16((char *)bounce + 102097a4feb4a78ae5cd130be7d546471a0779f1aa14Harvey Harrison sizeof(struct ncp_reply_header)); 10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = -EIO; 10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (len <= to_read) { 10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char* source; 10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds source = (char*)bounce + 10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sizeof(struct ncp_reply_header) + 2 + 10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (offset & 1); 10281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *bytes_read = len; 10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = 0; 10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (copy_to_user(target, source, len)) 10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = -EFAULT; 10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 10351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 10381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_write_kernel(struct ncp_server *server, const char *file_id, 10391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u32 offset, __u16 to_write, 10401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const char *source, int *bytes_written) 10411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 10431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); 10461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_mem(server, file_id, 6); 10471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_be32(server, offset); 10481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_be16(server, to_write); 10491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_mem(server, source, to_write); 10501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_request(server, 73)) == 0) 10521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *bytes_written = to_write; 10531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 10541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 10551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_NCPFS_IOCTL_LOCKING 10581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 10591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_LogPhysicalRecord(struct ncp_server *server, const char *file_id, 10601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 locktype, __u32 offset, __u32 length, __u16 timeout) 10611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 10631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 10651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, locktype); 10661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_mem(server, file_id, 6); 10671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_be32(server, offset); 10681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_be32(server, length); 10691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_be16(server, timeout); 10701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_request(server, 0x1A)) != 0) 10721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 10731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 10741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 10751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 10771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 10781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 10811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_ClearPhysicalRecord(struct ncp_server *server, const char *file_id, 10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u32 offset, __u32 length) 10831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 10851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 10871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); /* who knows... lanalyzer says that */ 10881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_mem(server, file_id, 6); 10891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_be32(server, offset); 10901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_be32(server, length); 10911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_request(server, 0x1E)) != 0) 10931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 10941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 10951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 10961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 10981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 10991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* CONFIG_NCPFS_IOCTL_LOCKING */ 11011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_NCPFS_NLS 11031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* This are the NLS conversion routines with inspirations and code parts 11041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * from the vfat file system and hints from Petr Vandrovec. 11051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 11061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 11081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp__io2vol(struct ncp_server *server, unsigned char *vname, unsigned int *vlen, 11091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const unsigned char *iname, unsigned int ilen, int cc) 11101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct nls_table *in = server->nls_io; 11121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct nls_table *out = server->nls_vol; 11131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char *vname_start; 11141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char *vname_end; 11151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const unsigned char *iname_end; 11161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iname_end = iname + ilen; 11181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vname_start = vname; 11191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vname_end = vname + *vlen - 1; 11201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (iname < iname_end) { 11221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int chl; 11231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wchar_t ec; 11241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (NCP_IS_FLAG(server, NCP_FLAG_UTF8)) { 11261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int k; 112774675a58507e769beee7d949dbed788af3c4139dAlan Stern unicode_t u; 11281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 112974675a58507e769beee7d949dbed788af3c4139dAlan Stern k = utf8_to_utf32(iname, iname_end - iname, &u); 113074675a58507e769beee7d949dbed788af3c4139dAlan Stern if (k < 0 || u > MAX_WCHAR_T) 11311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 11321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iname += k; 113374675a58507e769beee7d949dbed788af3c4139dAlan Stern ec = u; 11341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 11351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (*iname == NCP_ESC) { 11361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int k; 11371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (iname_end - iname < 5) 11391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto nospec; 11401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ec = 0; 11421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (k = 1; k < 5; k++) { 11431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char nc; 11441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nc = iname[k] - '0'; 11461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nc >= 10) { 11471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nc -= 'A' - '0' - 10; 11481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((nc < 10) || (nc > 15)) { 11491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto nospec; 11501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ec = (ec << 4) | nc; 11531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iname += 5; 11551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 11561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsnospec:; 11571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ( (chl = in->char2uni(iname, iname_end - iname, &ec)) < 0) 11581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return chl; 11591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iname += chl; 11601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* unitoupper should be here! */ 11641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds chl = out->uni2char(ec, vname, vname_end - vname); 11661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (chl < 0) 11671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return chl; 11681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* this is wrong... */ 11701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cc) { 11711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int chi; 11721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (chi = 0; chi < chl; chi++){ 11741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vname[chi] = ncp_toupper(out, vname[chi]); 11751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vname += chl; 11781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *vname = 0; 11811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *vlen = vname - vname_start; 11821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 11831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 11861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp__vol2io(struct ncp_server *server, unsigned char *iname, unsigned int *ilen, 11871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const unsigned char *vname, unsigned int vlen, int cc) 11881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct nls_table *in = server->nls_vol; 11901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct nls_table *out = server->nls_io; 11911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const unsigned char *vname_end; 11921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char *iname_start; 11931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char *iname_end; 11941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char *vname_cc; 11951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 11961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vname_cc = NULL; 11981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cc) { 12001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 12011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* this is wrong! */ 12031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vname_cc = kmalloc(vlen, GFP_KERNEL); 12041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!vname_cc) 12051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 12061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < vlen; i++) 12071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vname_cc[i] = ncp_tolower(in, vname[i]); 12081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vname = vname_cc; 12091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iname_start = iname; 12121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iname_end = iname + *ilen - 1; 12131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vname_end = vname + vlen; 12141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (vname < vname_end) { 12161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wchar_t ec; 12171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int chl; 12181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ( (chl = in->char2uni(vname, vname_end - vname, &ec)) < 0) { 12201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = chl; 12211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto quit; 12221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vname += chl; 12241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* unitolower should be here! */ 12261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (NCP_IS_FLAG(server, NCP_FLAG_UTF8)) { 12281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int k; 12291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 123074675a58507e769beee7d949dbed788af3c4139dAlan Stern k = utf32_to_utf8(ec, iname, iname_end - iname); 12311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (k < 0) { 12321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = -ENAMETOOLONG; 12331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto quit; 12341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iname += k; 12361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 12371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ( (chl = out->uni2char(ec, iname, iname_end - iname)) >= 0) { 12381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iname += chl; 12391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 12401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int k; 12411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (iname_end - iname < 5) { 12431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = -ENAMETOOLONG; 12441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto quit; 12451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *iname = NCP_ESC; 12471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (k = 4; k > 0; k--) { 12481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char v; 12491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds v = (ec & 0xF) + '0'; 12511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (v > '9') { 12521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds v += 'A' - '9' - 1; 12531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iname[k] = v; 12551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ec >>= 4; 12561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iname += 5; 12581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *iname = 0; 12631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ilen = iname - iname_start; 12641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = 0; 12651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsquit:; 12661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cc) 12671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(vname_cc); 12681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 12691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 12721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 12741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp__io2vol(unsigned char *vname, unsigned int *vlen, 12751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const unsigned char *iname, unsigned int ilen, int cc) 12761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 12781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (*vlen <= ilen) 12801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENAMETOOLONG; 12811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cc) 12831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < ilen; i++) { 12841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *vname = toupper(*iname); 12851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vname++; 12861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iname++; 12871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 12891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memmove(vname, iname, ilen); 12901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vname += ilen; 12911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *vlen = ilen; 12941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *vname = 0; 12951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 12961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 12991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp__vol2io(unsigned char *iname, unsigned int *ilen, 13001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const unsigned char *vname, unsigned int vlen, int cc) 13011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 13031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (*ilen <= vlen) 13051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENAMETOOLONG; 13061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cc) 13081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < vlen; i++) { 13091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *iname = tolower(*vname); 13101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iname++; 13111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vname++; 13121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 13141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memmove(iname, vname, vlen); 13151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iname += vlen; 13161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ilen = vlen; 13191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *iname = 0; 13201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 13211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 1324