patch-2.0.34 linux/fs/smbfs/proc.c
Next file: linux/fs/super.c
Previous file: linux/fs/smbfs/inode.c
Back to the patch index
Back to the overall index
- Lines: 214
- Date:
Wed Jun 3 15:17:49 1998
- Orig file:
v2.0.33/linux/fs/smbfs/proc.c
- Orig date:
Mon Sep 15 10:02:41 1997
diff -u --recursive --new-file v2.0.33/linux/fs/smbfs/proc.c linux/fs/smbfs/proc.c
@@ -570,6 +570,8 @@
smb_unlock_server(server);
return error;
}
+ /* N.B. Packet may change after request */
+ buf = server->packet;
p = smb_setup_header(server, SMBopen, 2, 0);
WSET(buf, smb_vwv0, 0x40); /* read only */
WSET(buf, smb_vwv1, o_attr);
@@ -589,6 +591,8 @@
}
/* We should now have data in vwv[0..6]. */
+ /* N.B. Packet may change after request */
+ buf = server->packet;
entry->fileid = WVAL(buf, smb_vwv0);
entry->attr = WVAL(buf, smb_vwv1);
entry->f_ctime = entry->f_atime =
@@ -646,7 +650,7 @@
smb_unlock_server(server);
return error;
}
- returned_count = WVAL(buf, smb_vwv0);
+ returned_count = WVAL(server->packet, smb_vwv0);
smb_decode_data(SMB_BUF(server->packet), data, &data_len, fs);
@@ -682,7 +686,7 @@
if ((res = smb_request_ok(server, SMBwrite, 1, 0)) >= 0)
{
- res = WVAL(buf, smb_vwv0);
+ res = WVAL(server->packet, smb_vwv0);
}
smb_unlock_server(server);
@@ -718,7 +722,7 @@
smb_unlock_server(server);
return error;
}
- fileid = WVAL(buf, smb_vwv0);
+ fileid = WVAL(server->packet, smb_vwv0);
smb_unlock_server(server);
smb_proc_close(server, fileid, CURRENT_TIME);
@@ -1345,6 +1349,10 @@
entry);
}
+/*
+ * This version uses the core protocol to get the attribute info.
+ * It works OK with Win 3.11, 95 and NT 3.51, but NOT with NT 4 (bad mtime).
+ */
static int
smb_proc_getattr_core(struct inode *dir, const char *name, int len,
struct smb_dirent *entry)
@@ -1356,7 +1364,7 @@
smb_lock_server(server);
- DDPRINTK("smb_proc_getattr: %s\n", name);
+ DDPRINTK("smb_proc_getattr_core: %s\n", name);
retry:
buf = server->packet;
@@ -1374,15 +1382,105 @@
smb_unlock_server(server);
return result;
}
+ /* N.B. Packet may change after request */
+ buf = server->packet;
entry->attr = WVAL(buf, smb_vwv0);
entry->f_ctime = entry->f_atime =
entry->f_mtime = local2utc(DVAL(buf, smb_vwv1));
+ DDPRINTK("smb_proc_getattr_core: mtime=%ld\n", entry->f_mtime);
+
entry->f_size = DVAL(buf, smb_vwv3);
smb_unlock_server(server);
return 0;
}
+/*
+ * This version uses the trans2 findfirst to get the attribute info.
+ * It works fine with NT 3.51 and NT 4 (any SP), but not with Win95 (ERRerror).
+ */
+static int
+smb_proc_getattr_ff(struct inode *dir, const char *name, int len,
+ struct smb_dirent *entry)
+{
+ unsigned char *resp_data = NULL;
+ unsigned char *resp_param = NULL;
+ int resp_data_len = 0;
+ int resp_param_len = 0;
+
+ char param[SMB_MAXPATHLEN + 1 + 12];
+ int mask_len;
+ unsigned char *mask = &(param[12]);
+
+ int result;
+ char *p;
+ struct smb_server *server = SMB_SERVER(dir);
+
+ mask_len = smb_encode_path(server, mask,
+ SMB_INOP(dir), name, len) - mask;
+
+ mask[mask_len] = 0;
+
+ DDPRINTK("smb_proc_getattr_ff: mask=%s\n", mask);
+
+ smb_lock_server(server);
+
+ retry:
+
+ WSET(param, 0, aSYSTEM | aHIDDEN | aDIR);
+ WSET(param, 2, 1); /* max count */
+ WSET(param, 4, 2 + 1); /* close on end + close after this call */
+ WSET(param, 6, 1); /* info level */
+ DSET(param, 8, 0);
+
+ result = smb_trans2_request(server, TRANSACT2_FINDFIRST,
+ 0, NULL, 12 + mask_len + 1, param,
+ &resp_data_len, &resp_data,
+ &resp_param_len, &resp_param);
+
+ if (result < 0)
+ {
+ if (smb_retry(server))
+ {
+ DPRINTK("smb_proc_getattr_ff: error=%d, retrying\n",
+ result);
+ goto retry;
+ }
+ goto out;
+ }
+ if (server->rcls != 0)
+ {
+ result = -smb_errno(server->rcls, server->err);
+ if (result != -ENOENT)
+ DPRINTK("smb_proc_getattr_ff: rcls=%d, err=%d\n",
+ server->rcls, server->err);
+ goto out;
+ }
+ /* Make sure we got enough data ... */
+ result = -EINVAL; /* WVAL(resp_param, 2) is ff_searchcount */
+ if (resp_data_len < 22 || WVAL(resp_param, 2) != 1)
+ {
+ DPRINTK("smb_proc_getattr_ff: bad result, len=%d, count=%d\n",
+ resp_data_len, WVAL(resp_param, 2));
+ goto out;
+ }
+ /* Decode the response (info level 1, as in smb_decode_long_dirent) */
+ p = resp_data;
+ entry->f_ctime = date_dos2unix(WVAL(p, 2), WVAL(p, 0));
+ entry->f_atime = date_dos2unix(WVAL(p, 6), WVAL(p, 4));
+ entry->f_mtime = date_dos2unix(WVAL(p, 10), WVAL(p, 8));
+ entry->f_size = DVAL(p, 12);
+ entry->attr = WVAL(p, 20);
+
+ DDPRINTK("smb_proc_getattr_ff: attr=%x\n", entry->attr);
+
+ result = 0;
+
+out:
+ smb_unlock_server(server);
+ return result;
+}
+
int
smb_proc_getattr(struct inode *dir, const char *name, int len,
struct smb_dirent *entry)
@@ -1391,7 +1489,17 @@
int result;
smb_init_dirent(server, entry);
- result = smb_proc_getattr_core(dir, name, len, entry);
+
+ /* Use trans2 for NT, use core protocol for others (Win95/3.11/...).
+ * We distinguish NT from Win95 by looking at the capabilities,
+ * in the same way as in Samba 1.9.18p2's reply.c.
+ */
+ if ((server->protocol >= PROTOCOL_LANMAN2)
+ && (server->blkmode & (CAP_NT_SMBS | CAP_STATUS32)))
+ result = smb_proc_getattr_ff(dir, name, len, entry);
+ else
+ result = smb_proc_getattr_core(dir, name, len, entry);
+
smb_finish_dirent(server, entry);
entry->len = len;
@@ -1612,12 +1720,12 @@
word passlen = strlen(server->m.password);
word userlen = strlen(server->m.username);
+#ifdef DEBUG_SMB_PASSWORD
DPRINTK("smb_proc_connect: password = %s\n",
server->m.password);
+#endif
DPRINTK("smb_proc_connect: usernam = %s\n",
server->m.username);
- DPRINTK("smb_proc_connect: blkmode = %d\n",
- WVAL(server->packet, smb_vwv5));
if (server->protocol >= PROTOCOL_NT1)
{
@@ -1634,6 +1742,8 @@
server->blkmode = WVAL(server->packet, smb_vwv5);
server->sesskey = DVAL(server->packet, smb_vwv6);
}
+ DPRINTK("smb_proc_connect: blkmode (capabilities) = %x\n",
+ server->blkmode);
if (server->max_xmit < given_max_xmit)
{
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov