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 12b41f8b84d01d32ea618dbbe5679bd07ce3444b88Joe Perches#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 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) { 19d3b73ca1be3236fc33f896af7e2ba637a677d5c9Joe Perches ncp_dbg(1, "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) { 78d3b73ca1be3236fc33f896af7e2ba637a677d5c9Joe Perches ncp_dbg(1, "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) { 228d3b73ca1be3236fc33f896af7e2ba637a677d5c9Joe Perches ncp_dbg(1, "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) { 262d3b73ca1be3236fc33f896af7e2ba637a677d5c9Joe Perches ncp_dbg(1, "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) 298e45ca8baa33e0c0228e84126c3a20df3abfd1771Joe Perches ncp_vdbg("volnum=%d, dirent=%u, error=%d\n", 299e45ca8baa33e0c0228e84126c3a20df3abfd1771Joe Perches NCP_FINFO(inode)->volNumber, 300e45ca8baa33e0c0228e84126c3a20df3abfd1771Joe Perches 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); 397d3b73ca1be3236fc33f896af7e2ba637a677d5c9Joe Perches ncp_dbg(1, "(%s) mode=0%o, rdev=0x%x\n", 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->entryName, target->nfs.mode, 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->nfs.rdev); 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->nfs.mode = 0; 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->nfs.rdev = 0; 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->nfs.mode = 0; 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->nfs.rdev = 0; 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns information for a (one-component) name relative to 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the specified directory. 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4192e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovecint ncp_obtain_info(struct ncp_server *server, struct inode *dir, const char *path, 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct nw_info_struct *target) 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 volnum = NCP_FINFO(dir)->volNumber; 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le32 dirent = NCP_FINFO(dir)->dirEntNum; 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (target == NULL) { 427b41f8b84d01d32ea618dbbe5679bd07ce3444b88Joe Perches pr_err("%s: invalid call\n", __func__); 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 6); /* subfunction */ 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, server->name_space[volnum]); 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, server->name_space[volnum]); /* N.B. twice ?? */ 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_word(server, cpu_to_le16(0x8006)); /* get all */ 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword(server, RIM_ALL); 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_handle_path(server, volnum, dirent, 1, path); 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_request(server, 87)) != 0) 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_extract_file_info(ncp_reply_data(server, 0), target); 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_obtain_nfs_info(server, target); 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_NCPFS_NFS_NS 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_obtain_DOS_dir_base(struct ncp_server *server, 4542e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec __u8 ns, __u8 volnum, __le32 dirent, 4552e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec const char *path, /* At most 1 component */ 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le32 *DOS_dir_base) 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 6); /* subfunction */ 4622e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec ncp_add_byte(server, ns); 4632e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec ncp_add_byte(server, ns); 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_word(server, cpu_to_le16(0x8006)); /* get all */ 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword(server, RIM_DIRECTORY); 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_handle_path(server, volnum, dirent, 1, path); 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_request(server, 87)) == 0) 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (DOS_dir_base) *DOS_dir_base=ncp_reply_dword(server, 0x34); 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* CONFIG_NCPFS_NFS_NS */ 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline int 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_get_known_namespace(struct ncp_server *server, __u8 volume) 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if defined(CONFIG_NCPFS_OS2_NS) || defined(CONFIG_NCPFS_NFS_NS) 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 *namespace; 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u16 no_namespaces; 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 24); /* Subfunction: Get Name Spaces Loaded */ 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_word(server, 0); 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, volume); 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_request(server, 87)) != 0) { 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NW_NS_DOS; /* not result ?? */ 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = NW_NS_DOS; 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds no_namespaces = ncp_reply_le16(server, 0); 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds namespace = ncp_reply_data(server, 2); 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (no_namespaces > 0) { 500d3b73ca1be3236fc33f896af7e2ba637a677d5c9Joe Perches ncp_dbg(1, "found %d on %d\n", *namespace, volume); 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_NCPFS_NFS_NS 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((*namespace == NW_NS_NFS) && !(server->m.flags&NCP_MOUNT_NO_NFS)) 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = NW_NS_NFS; 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* CONFIG_NCPFS_NFS_NS */ 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_NCPFS_OS2_NS 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((*namespace == NW_NS_OS2) && !(server->m.flags&NCP_MOUNT_NO_OS2)) 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = NW_NS_OS2; 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* CONFIG_NCPFS_OS2_NS */ 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds namespace += 1; 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds no_namespaces -= 1; 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else /* neither OS2 nor NFS - only DOS */ 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NW_NS_DOS; 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* defined(CONFIG_NCPFS_OS2_NS) || defined(CONFIG_NCPFS_NFS_NS) */ 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5252e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovecint 5262e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovecncp_update_known_namespace(struct ncp_server *server, __u8 volume, int *ret_ns) 5272e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec{ 5282e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec int ns = ncp_get_known_namespace(server, volume); 5292e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec 5302e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec if (ret_ns) 5312e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec *ret_ns = ns; 5322e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec 533d3b73ca1be3236fc33f896af7e2ba637a677d5c9Joe Perches ncp_dbg(1, "namespace[%d] = %d\n", volume, server->name_space[volume]); 5342e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec 5352e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec if (server->name_space[volume] == ns) 5362e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec return 0; 5372e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec server->name_space[volume] = ns; 5382e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec return 1; 5392e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec} 5402e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_ObtainSpecificDirBase(struct ncp_server *server, 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 nsSrc, __u8 nsDst, __u8 vol_num, __le32 dir_base, 5442e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec const char *path, /* At most 1 component */ 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le32 *dirEntNum, __le32 *DosDirNum) 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 6); /* subfunction */ 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, nsSrc); 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, nsDst); 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_word(server, cpu_to_le16(0x8006)); /* get all */ 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword(server, RIM_ALL); 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_handle_path(server, vol_num, dir_base, 1, path); 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_request(server, 87)) != 0) 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dirEntNum) 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *dirEntNum = ncp_reply_dword(server, 0x30); 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (DosDirNum) 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *DosDirNum = ncp_reply_dword(server, 0x34); 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_mount_subdir(struct ncp_server *server, 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 volNumber, __u8 srcNS, __le32 dirEntNum, 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u32* volume, __le32* newDirEnt, __le32* newDosEnt) 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int dstNS; 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 5782e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec 5792e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec ncp_update_known_namespace(server, volNumber, &dstNS); 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_ObtainSpecificDirBase(server, srcNS, dstNS, volNumber, 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dirEntNum, NULL, newDirEnt, newDosEnt)) != 0) 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *volume = volNumber; 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds server->m.mounted_vol[1] = 0; 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds server->m.mounted_vol[0] = 'X'; 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 5922e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovecncp_get_volume_root(struct ncp_server *server, 5932e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec const char *volname, __u32* volume, __le32* dirent, __le32* dosdirent) 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 597d3b73ca1be3236fc33f896af7e2ba637a677d5c9Joe Perches ncp_dbg(1, "looking up vol %s\n", volname); 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 22); /* Subfunction: Generate dir handle */ 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); /* DOS namespace */ 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); /* reserved */ 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); /* reserved */ 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); /* reserved */ 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); /* faked volume number */ 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword(server, 0); /* faked dir_base */ 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0xff); /* Don't have a dir_base */ 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 1); /* 1 path component */ 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_pstring(server, volname); 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_request(server, 87)) != 0) { 6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *dirent = *dosdirent = ncp_reply_dword(server, 4); 6172e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec *volume = ncp_reply_byte(server, 8); 6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 6232e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovecncp_lookup_volume(struct ncp_server *server, 6242e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec const char *volname, struct nw_info_struct *target) 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(target, 0, sizeof(*target)); 6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_get_volume_root(server, volname, 6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &target->volNumber, &target->dirEntNum, &target->DosDirNum); 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (result) { 6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6342e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec ncp_update_known_namespace(server, target->volNumber, NULL); 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->nameLen = strlen(volname); 6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(target->entryName, volname, target->nameLen+1); 6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->attributes = aDIR; 6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* set dates to Jan 1, 1986 00:00 */ 6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->creationTime = target->modifyTime = cpu_to_le16(0x0000); 6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->creationDate = target->modifyDate = target->lastAccessDate = cpu_to_le16(0x0C21); 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->nfs.mode = 0; 6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ncp_modify_file_or_subdir_dos_info_path(struct ncp_server *server, 6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct inode *dir, 6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const char *path, 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le32 info_mask, 6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const struct nw_modify_dos_info *info) 6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 volnum = NCP_FINFO(dir)->volNumber; 6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le32 dirent = NCP_FINFO(dir)->dirEntNum; 6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 7); /* subfunction */ 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, server->name_space[volnum]); 6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); /* reserved */ 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_word(server, cpu_to_le16(0x8006)); /* search attribs: all */ 6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword(server, info_mask); 6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_mem(server, info, sizeof(*info)); 6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_handle_path(server, volnum, dirent, 1, path); 6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_request(server, 87); 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ncp_modify_file_or_subdir_dos_info(struct ncp_server *server, 6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct inode *dir, 6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le32 info_mask, 6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const struct nw_modify_dos_info *info) 6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ncp_modify_file_or_subdir_dos_info_path(server, dir, NULL, 6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds info_mask, info); 6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_NCPFS_NFS_NS 6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ncp_modify_nfs_info(struct ncp_server *server, __u8 volnum, __le32 dirent, 6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u32 mode, __u32 rdev) 6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result = 0; 6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6862e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec ncp_init_request(server); 6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (server->name_space[volnum] == NW_NS_NFS) { 6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 25); /* subfunction */ 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, server->name_space[volnum]); 6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, NW_NS_NFS); 6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, volnum); 6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword(server, dirent); 6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* we must always operate on both nlinks and rdev, otherwise 6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rdev is not set */ 6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword_lh(server, NSIBM_NFS_MODE | NSIBM_NFS_NLINKS | NSIBM_NFS_RDEV); 6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword_lh(server, mode); 6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword_lh(server, 1); /* nlinks */ 6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword_lh(server, rdev); 6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_request(server, 87); 7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7012e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec ncp_unlock_server(server); 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_DeleteNSEntry(struct ncp_server *server, 7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 have_dir_base, __u8 volnum, __le32 dirent, 7102e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec const char* name, __u8 ns, __le16 attr) 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 8); /* subfunction */ 7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, ns); 7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); /* reserved */ 7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_word(server, attr); /* search attribs: all */ 7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_handle_path(server, volnum, dirent, have_dir_base, name); 7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_request(server, 87); 7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_del_file_or_subdir2(struct ncp_server *server, 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dentry *dentry) 7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct inode *inode = dentry->d_inode; 7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 volnum; 7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le32 dirent; 7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!inode) { 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0xFF; /* Any error */ 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds volnum = NCP_FINFO(inode)->volNumber; 7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dirent = NCP_FINFO(inode)->DosDirNum; 7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ncp_DeleteNSEntry(server, 1, volnum, dirent, NULL, NW_NS_DOS, cpu_to_le16(0x8006)); 7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_del_file_or_subdir(struct ncp_server *server, 7442e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec struct inode *dir, const char *name) 7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 volnum = NCP_FINFO(dir)->volNumber; 7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le32 dirent = NCP_FINFO(dir)->dirEntNum; 7482e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec int name_space; 7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7502e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec name_space = server->name_space[volnum]; 7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_NCPFS_NFS_NS 7522e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec if (name_space == NW_NS_NFS) 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7562e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec result=ncp_obtain_DOS_dir_base(server, name_space, volnum, dirent, name, &dirent); 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (result) return result; 7582e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec name = NULL; 7592e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec name_space = NW_NS_DOS; 7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* CONFIG_NCPFS_NFS_NS */ 7622e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec return ncp_DeleteNSEntry(server, 1, volnum, dirent, name, name_space, cpu_to_le16(0x8006)); 7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void ConvertToNWfromDWORD(__u16 v0, __u16 v1, __u8 ret[6]) 7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le16 *dest = (__le16 *) ret; 7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dest[1] = cpu_to_le16(v0); 7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dest[2] = cpu_to_le16(v1); 7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dest[0] = cpu_to_le16(v0 + 1); 7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* If both dir and name are NULL, then in target there's already a 7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds looked-up entry that wants to be opened. */ 7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ncp_open_create_file_or_subdir(struct ncp_server *server, 7772e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec struct inode *dir, const char *name, 7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int open_create_mode, 7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le32 create_attributes, 7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le16 desired_acc_rights, 7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct ncp_entry_info *target) 7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le16 search_attribs = cpu_to_le16(0x0006); 7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 volnum; 7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le32 dirent; 7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds volnum = NCP_FINFO(dir)->volNumber; 7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dirent = NCP_FINFO(dir)->dirEntNum; 7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((create_attributes & aDIR) != 0) { 7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds search_attribs |= cpu_to_le16(0x8000); 7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 1); /* subfunction */ 7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, server->name_space[volnum]); 7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, open_create_mode); 7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_word(server, search_attribs); 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword(server, RIM_ALL); 8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword(server, create_attributes); 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* The desired acc rights seem to be the inherited rights mask 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for directories */ 8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_word(server, desired_acc_rights); 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_handle_path(server, volnum, dirent, 1, name); 8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_request(server, 87)) != 0) 8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!(create_attributes & aDIR)) 8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->opened = 1; 8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* in target there's a new finfo to fill */ 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_extract_file_info(ncp_reply_data(server, 6), &(target->i)); 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->volume = target->i.volNumber; 8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ConvertToNWfromDWORD(ncp_reply_le16(server, 0), 8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_reply_le16(server, 2), 8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds target->file_handle); 8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (void)ncp_obtain_nfs_info(server, &(target->i)); 8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_initialize_search(struct ncp_server *server, struct inode *dir, 8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct nw_search_sequence *target) 8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 volnum = NCP_FINFO(dir)->volNumber; 8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le32 dirent = NCP_FINFO(dir)->dirEntNum; 8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 2); /* subfunction */ 8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, server->name_space[volnum]); 8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); /* reserved */ 8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_handle_path(server, volnum, dirent, 1, NULL); 8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_request(server, 87); 8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (result) 8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(target, ncp_reply_data(server, 0), sizeof(*target)); 8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ncp_search_for_fileset(struct ncp_server *server, 8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct nw_search_sequence *seq, 8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int* more, 8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int* cnt, 8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char* buffer, 8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size_t bufsize, 8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char** rbuf, 8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size_t* rsize) 8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 20); 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, server->name_space[seq->volNumber]); 8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); /* datastream */ 8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_word(server, cpu_to_le16(0x8006)); 8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword(server, RIM_ALL); 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_word(server, cpu_to_le16(32767)); /* max returned items */ 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_mem(server, seq, 9); 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_NCPFS_NFS_NS 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (server->name_space[seq->volNumber] == NW_NS_NFS) { 8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); /* 0 byte pattern */ 8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 2); /* 2 byte pattern */ 8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0xff); /* following is a wildcard */ 8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, '*'); 8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_request2(server, 87, buffer, bufsize); 8821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (result) { 8831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (server->ncp_reply_size < 12) { 8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 8881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0xFF; 8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *rsize = server->ncp_reply_size - 12; 8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buffer = buffer + sizeof(struct ncp_reply_header); 8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *rbuf = buffer + 12; 8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *cnt = WVAL_LH(buffer + 10); 8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *more = BVAL(buffer + 9); 8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(seq, buffer, 9); 8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_RenameNSEntry(struct ncp_server *server, 9022e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec struct inode *old_dir, const char *old_name, __le16 old_type, 9032e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec struct inode *new_dir, const char *new_name) 9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result = -EINVAL; 9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((old_dir == NULL) || (old_name == NULL) || 9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (new_dir == NULL) || (new_name == NULL)) 9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 9101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 9121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 4); /* subfunction */ 9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, server->name_space[NCP_FINFO(old_dir)->volNumber]); 9141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 1); /* rename flag */ 9151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_word(server, old_type); /* search attributes */ 9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* source Handle Path */ 9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, NCP_FINFO(old_dir)->volNumber); 9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword(server, NCP_FINFO(old_dir)->dirEntNum); 9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 1); 9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 1); /* 1 source component */ 9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* dest Handle Path */ 9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, NCP_FINFO(new_dir)->volNumber); 9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_dword(server, NCP_FINFO(new_dir)->dirEntNum); 9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 1); 9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 1); /* 1 destination component */ 9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* source path string */ 9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_pstring(server, old_name); 9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* dest path string */ 9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_pstring(server, new_name); 9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_request(server, 87); 9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 9361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 9371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 9381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ncp_ren_or_mov_file_or_subdir(struct ncp_server *server, 9412e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec struct inode *old_dir, const char *old_name, 9422e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec struct inode *new_dir, const char *new_name) 9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __le16 old_type = cpu_to_le16(0x06); 9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* If somebody can do it atomic, call me... vandrove@vc.cvut.cz */ 9481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_RenameNSEntry(server, old_dir, old_name, old_type, 9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new_dir, new_name); 9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (result == 0xFF) /* File Not Found, try directory */ 9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds old_type = cpu_to_le16(0x16); 9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_RenameNSEntry(server, old_dir, old_name, old_type, 9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new_dir, new_name); 9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (result != 0x92) return result; /* All except NO_FILES_RENAMED */ 9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_del_file_or_subdir(server, new_dir, new_name); 9581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (result != 0) return -EACCES; 9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_RenameNSEntry(server, old_dir, old_name, old_type, 9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds new_dir, new_name); 9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 9621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* We have to transfer to/from user space */ 9661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_read_kernel(struct ncp_server *server, const char *file_id, 9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u32 offset, __u16 to_read, char *target, int *bytes_read) 9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9702e54eb96e2c801f33d95b5dade15212ac4d6c4a5Petr Vandrovec const char *source; 9711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 9721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 9741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); 9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_mem(server, file_id, 6); 9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_be32(server, offset); 9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_be16(server, to_read); 9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_request(server, 72)) != 0) { 9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 9811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *bytes_read = ncp_reply_be16(server, 0); 9831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds source = ncp_reply_data(server, 2 + (offset & 1)); 9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(target, source, *bytes_read); 9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 9871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 9881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 9891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* There is a problem... egrep and some other silly tools do: 9921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds x = mmap(NULL, MAP_PRIVATE, PROT_READ|PROT_WRITE, <ncpfs fd>, 32768); 9931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds read(<ncpfs fd>, x, 32768); 9941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Now copying read result by copy_to_user causes pagefault. This pagefault 9951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds could not be handled because of server was locked due to read. So we have 9961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds to use temporary buffer. So ncp_unlock_server must be done before 9971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds copy_to_user (and for write, copy_from_user must be done before 9981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request... same applies for send raw packet ioctl). Because of 9991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds file is normally read in bigger chunks, caller provides kmalloced 10001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (vmalloced) chunk of memory with size >= to_read... 10011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 10031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_read_bounce(struct ncp_server *server, const char *file_id, 10041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u32 offset, __u16 to_read, char __user *target, int *bytes_read, 10051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void* bounce, __u32 bufsize) 10061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 10081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); 10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_mem(server, file_id, 6); 10121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_be32(server, offset); 10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_be16(server, to_read); 10141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = ncp_request2(server, 72, bounce, bufsize); 10151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 10161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!result) { 101797a4feb4a78ae5cd130be7d546471a0779f1aa14Harvey Harrison int len = get_unaligned_be16((char *)bounce + 101897a4feb4a78ae5cd130be7d546471a0779f1aa14Harvey Harrison sizeof(struct ncp_reply_header)); 10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = -EIO; 10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (len <= to_read) { 10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char* source; 10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds source = (char*)bounce + 10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sizeof(struct ncp_reply_header) + 2 + 10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (offset & 1); 10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *bytes_read = len; 10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = 0; 10281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (copy_to_user(target, source, len)) 10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds result = -EFAULT; 10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 10331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 10361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_write_kernel(struct ncp_server *server, const char *file_id, 10371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u32 offset, __u16 to_write, 10381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const char *source, int *bytes_written) 10391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 10411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 10431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); 10441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_mem(server, file_id, 6); 10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_be32(server, offset); 10461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_be16(server, to_write); 10471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_mem(server, source, to_write); 10481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_request(server, 73)) == 0) 10501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *bytes_written = to_write; 10511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 10521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 10531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_NCPFS_IOCTL_LOCKING 10561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 10571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_LogPhysicalRecord(struct ncp_server *server, const char *file_id, 10581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u8 locktype, __u32 offset, __u32 length, __u16 timeout) 10591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 10611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 10631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, locktype); 10641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_mem(server, file_id, 6); 10651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_be32(server, offset); 10661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_be32(server, length); 10671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_be16(server, timeout); 10681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_request(server, 0x1A)) != 0) 10701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 10711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 10721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 10731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 10751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 10761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 10791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp_ClearPhysicalRecord(struct ncp_server *server, const char *file_id, 10801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __u32 offset, __u32 length) 10811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int result; 10831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_init_request(server); 10851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_byte(server, 0); /* who knows... lanalyzer says that */ 10861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_mem(server, file_id, 6); 10871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_be32(server, offset); 10881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_add_be32(server, length); 10891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((result = ncp_request(server, 0x1E)) != 0) 10911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 10921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 10931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return result; 10941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ncp_unlock_server(server); 10961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 10971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* CONFIG_NCPFS_IOCTL_LOCKING */ 10991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_NCPFS_NLS 11011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* This are the NLS conversion routines with inspirations and code parts 11021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * from the vfat file system and hints from Petr Vandrovec. 11031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 11041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 11061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp__io2vol(struct ncp_server *server, unsigned char *vname, unsigned int *vlen, 11071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const unsigned char *iname, unsigned int ilen, int cc) 11081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct nls_table *in = server->nls_io; 11101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct nls_table *out = server->nls_vol; 11111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char *vname_start; 11121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char *vname_end; 11131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const unsigned char *iname_end; 11141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iname_end = iname + ilen; 11161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vname_start = vname; 11171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vname_end = vname + *vlen - 1; 11181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (iname < iname_end) { 11201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int chl; 11211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wchar_t ec; 11221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (NCP_IS_FLAG(server, NCP_FLAG_UTF8)) { 11241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int k; 112574675a58507e769beee7d949dbed788af3c4139dAlan Stern unicode_t u; 11261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 112774675a58507e769beee7d949dbed788af3c4139dAlan Stern k = utf8_to_utf32(iname, iname_end - iname, &u); 112874675a58507e769beee7d949dbed788af3c4139dAlan Stern if (k < 0 || u > MAX_WCHAR_T) 11291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 11301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iname += k; 113174675a58507e769beee7d949dbed788af3c4139dAlan Stern ec = u; 11321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 11331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (*iname == NCP_ESC) { 11341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int k; 11351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (iname_end - iname < 5) 11371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto nospec; 11381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ec = 0; 11401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (k = 1; k < 5; k++) { 11411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char nc; 11421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nc = iname[k] - '0'; 11441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (nc >= 10) { 11451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nc -= 'A' - '0' - 10; 11461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((nc < 10) || (nc > 15)) { 11471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto nospec; 11481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ec = (ec << 4) | nc; 11511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iname += 5; 11531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 11541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsnospec:; 11551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ( (chl = in->char2uni(iname, iname_end - iname, &ec)) < 0) 11561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return chl; 11571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iname += chl; 11581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* unitoupper should be here! */ 11621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds chl = out->uni2char(ec, vname, vname_end - vname); 11641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (chl < 0) 11651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return chl; 11661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* this is wrong... */ 11681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cc) { 11691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int chi; 11701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (chi = 0; chi < chl; chi++){ 11721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vname[chi] = ncp_toupper(out, vname[chi]); 11731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vname += chl; 11761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *vname = 0; 11791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *vlen = vname - vname_start; 11801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 11811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 11841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp__vol2io(struct ncp_server *server, unsigned char *iname, unsigned int *ilen, 11851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const unsigned char *vname, unsigned int vlen, int cc) 11861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct nls_table *in = server->nls_vol; 11881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct nls_table *out = server->nls_io; 11891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const unsigned char *vname_end; 11901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char *iname_start; 11911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char *iname_end; 11921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char *vname_cc; 11931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 11941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vname_cc = NULL; 11961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cc) { 11981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 11991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* this is wrong! */ 12011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vname_cc = kmalloc(vlen, GFP_KERNEL); 12021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!vname_cc) 12031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 12041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < vlen; i++) 12051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vname_cc[i] = ncp_tolower(in, vname[i]); 12061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vname = vname_cc; 12071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iname_start = iname; 12101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iname_end = iname + *ilen - 1; 12111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vname_end = vname + vlen; 12121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (vname < vname_end) { 12141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wchar_t ec; 12151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int chl; 12161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ( (chl = in->char2uni(vname, vname_end - vname, &ec)) < 0) { 12181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = chl; 12191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto quit; 12201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vname += chl; 12221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* unitolower should be here! */ 12241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (NCP_IS_FLAG(server, NCP_FLAG_UTF8)) { 12261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int k; 12271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 122874675a58507e769beee7d949dbed788af3c4139dAlan Stern k = utf32_to_utf8(ec, iname, iname_end - iname); 12291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (k < 0) { 12301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = -ENAMETOOLONG; 12311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto quit; 12321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iname += k; 12341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 12351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ( (chl = out->uni2char(ec, iname, iname_end - iname)) >= 0) { 12361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iname += chl; 12371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 12381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int k; 12391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (iname_end - iname < 5) { 12411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = -ENAMETOOLONG; 12421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto quit; 12431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *iname = NCP_ESC; 12451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (k = 4; k > 0; k--) { 12461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char v; 12471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds v = (ec & 0xF) + '0'; 12491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (v > '9') { 12501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds v += 'A' - '9' - 1; 12511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iname[k] = v; 12531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ec >>= 4; 12541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iname += 5; 12561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *iname = 0; 12611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ilen = iname - iname_start; 12621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = 0; 12631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsquit:; 12641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cc) 12651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(vname_cc); 12661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 12671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 12701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 12721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp__io2vol(unsigned char *vname, unsigned int *vlen, 12731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const unsigned char *iname, unsigned int ilen, int cc) 12741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 12761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (*vlen <= ilen) 12781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENAMETOOLONG; 12791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cc) 12811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < ilen; i++) { 12821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *vname = toupper(*iname); 12831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vname++; 12841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iname++; 12851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 12871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memmove(vname, iname, ilen); 12881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vname += ilen; 12891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *vlen = ilen; 12921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *vname = 0; 12931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 12941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint 12971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsncp__vol2io(unsigned char *iname, unsigned int *ilen, 12981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const unsigned char *vname, unsigned int vlen, int cc) 12991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 13011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (*ilen <= vlen) 13031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENAMETOOLONG; 13041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cc) 13061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < vlen; i++) { 13071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *iname = tolower(*vname); 13081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iname++; 13091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vname++; 13101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 13121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memmove(iname, vname, vlen); 13131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iname += vlen; 13141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ilen = vlen; 13171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *iname = 0; 13181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 13191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 1322