1/*
2   Unix SMB/CIFS implementation.
3   client trans2 calls
4   Copyright (C) James J Myers 2003	<myersjj@samba.org>
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 3 of the License, or
9   (at your option) any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program.  If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#include "includes.h"
21#include "libcli/raw/libcliraw.h"
22#include "libcli/libcli.h"
23
24/****************************************************************************
25send a qpathinfo call
26****************************************************************************/
27NTSTATUS smbcli_qpathinfo(struct smbcli_tree *tree, const char *fname,
28		       time_t *c_time, time_t *a_time, time_t *m_time,
29		       size_t *size, uint16_t *mode)
30{
31	union smb_fileinfo parms;
32	TALLOC_CTX *mem_ctx;
33	NTSTATUS status;
34
35	mem_ctx = talloc_init("smbcli_qpathinfo");
36	if (!mem_ctx) return NT_STATUS_NO_MEMORY;
37
38	parms.standard.level = RAW_FILEINFO_STANDARD;
39	parms.standard.in.file.path = fname;
40
41	status = smb_raw_pathinfo(tree, mem_ctx, &parms);
42	talloc_free(mem_ctx);
43	if (!NT_STATUS_IS_OK(status))
44		return status;
45
46	if (c_time) {
47		*c_time = parms.standard.out.create_time;
48	}
49	if (a_time) {
50		*a_time = parms.standard.out.access_time;
51	}
52	if (m_time) {
53		*m_time = parms.standard.out.write_time;
54	}
55	if (size) {
56		*size = parms.standard.out.size;
57	}
58	if (mode) {
59		*mode = parms.standard.out.attrib;
60	}
61
62	return status;
63}
64
65/****************************************************************************
66send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level
67****************************************************************************/
68NTSTATUS smbcli_qpathinfo2(struct smbcli_tree *tree, const char *fname,
69			time_t *c_time, time_t *a_time, time_t *m_time,
70			time_t *w_time, size_t *size, uint16_t *mode,
71			ino_t *ino)
72{
73	union smb_fileinfo parms;
74	TALLOC_CTX *mem_ctx;
75	NTSTATUS status;
76
77	mem_ctx = talloc_init("smbcli_qfilename");
78	if (!mem_ctx) return NT_STATUS_NO_MEMORY;
79
80	parms.all_info.level = RAW_FILEINFO_ALL_INFO;
81	parms.all_info.in.file.path = fname;
82
83	status = smb_raw_pathinfo(tree, mem_ctx, &parms);
84	talloc_free(mem_ctx);
85	if (!NT_STATUS_IS_OK(status))
86		return status;
87
88	if (c_time) {
89		*c_time = nt_time_to_unix(parms.all_info.out.create_time);
90	}
91	if (a_time) {
92		*a_time = nt_time_to_unix(parms.all_info.out.access_time);
93	}
94	if (m_time) {
95		*m_time = nt_time_to_unix(parms.all_info.out.change_time);
96	}
97	if (w_time) {
98		*w_time = nt_time_to_unix(parms.all_info.out.write_time);
99	}
100	if (size) {
101		*size = parms.all_info.out.size;
102	}
103	if (mode) {
104		*mode = parms.all_info.out.attrib;
105	}
106
107	return status;
108}
109
110
111/****************************************************************************
112send a qfileinfo QUERY_FILE_NAME_INFO call
113****************************************************************************/
114NTSTATUS smbcli_qfilename(struct smbcli_tree *tree, int fnum, const char **name)
115{
116	union smb_fileinfo parms;
117	TALLOC_CTX *mem_ctx;
118	NTSTATUS status;
119
120	mem_ctx = talloc_init("smbcli_qfilename");
121	if (!mem_ctx) return NT_STATUS_NO_MEMORY;
122
123	parms.name_info.level = RAW_FILEINFO_NAME_INFO;
124	parms.name_info.in.file.fnum = fnum;
125
126	status = smb_raw_fileinfo(tree, mem_ctx, &parms);
127	if (!NT_STATUS_IS_OK(status)) {
128		talloc_free(mem_ctx);
129		*name = NULL;
130		return status;
131	}
132
133	*name = strdup(parms.name_info.out.fname.s);
134
135	talloc_free(mem_ctx);
136
137	return status;
138}
139
140
141/****************************************************************************
142send a qfileinfo call
143****************************************************************************/
144NTSTATUS smbcli_qfileinfo(struct smbcli_tree *tree, int fnum,
145		       uint16_t *mode, size_t *size,
146		       time_t *c_time, time_t *a_time, time_t *m_time,
147		       time_t *w_time, ino_t *ino)
148{
149	union smb_fileinfo parms;
150	TALLOC_CTX *mem_ctx;
151	NTSTATUS status;
152
153	mem_ctx = talloc_init("smbcli_qfileinfo");
154	if (!mem_ctx)
155		return NT_STATUS_NO_MEMORY;
156
157	parms.all_info.level = RAW_FILEINFO_ALL_INFO;
158	parms.all_info.in.file.fnum = fnum;
159
160	status = smb_raw_fileinfo(tree, mem_ctx, &parms);
161	talloc_free(mem_ctx);
162	if (!NT_STATUS_IS_OK(status)) {
163		return status;
164	}
165
166	if (c_time) {
167		*c_time = nt_time_to_unix(parms.all_info.out.create_time);
168	}
169	if (a_time) {
170		*a_time = nt_time_to_unix(parms.all_info.out.access_time);
171	}
172	if (m_time) {
173		*m_time = nt_time_to_unix(parms.all_info.out.change_time);
174	}
175	if (w_time) {
176		*w_time = nt_time_to_unix(parms.all_info.out.write_time);
177	}
178	if (mode) {
179		*mode = parms.all_info.out.attrib;
180	}
181	if (size) {
182		*size = (size_t)parms.all_info.out.size;
183	}
184	if (ino) {
185		*ino = 0;
186	}
187
188	return status;
189}
190
191
192/****************************************************************************
193send a qpathinfo SMB_QUERY_FILE_ALT_NAME_INFO call
194****************************************************************************/
195NTSTATUS smbcli_qpathinfo_alt_name(struct smbcli_tree *tree, const char *fname,
196				const char **alt_name)
197{
198	union smb_fileinfo parms;
199	TALLOC_CTX *mem_ctx;
200	NTSTATUS status;
201
202	parms.alt_name_info.level = RAW_FILEINFO_ALT_NAME_INFO;
203	parms.alt_name_info.in.file.path = fname;
204
205	mem_ctx = talloc_init("smbcli_qpathinfo_alt_name");
206	if (!mem_ctx) return NT_STATUS_NO_MEMORY;
207
208	status = smb_raw_pathinfo(tree, mem_ctx, &parms);
209	if (!NT_STATUS_IS_OK(status)) {
210		talloc_free(mem_ctx);
211		*alt_name = NULL;
212		return smbcli_nt_error(tree);
213	}
214
215	if (!parms.alt_name_info.out.fname.s) {
216		*alt_name = strdup("");
217	} else {
218		*alt_name = strdup(parms.alt_name_info.out.fname.s);
219	}
220
221	talloc_free(mem_ctx);
222
223	return NT_STATUS_OK;
224}
225