Initial import from FreeBSD RELENG_4:
[dragonfly.git] / lib / libncp / ncpl_file.c
1 /*
2  * Copyright (c) 1999, Boris Popov
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *    This product includes software developed by Boris Popov.
16  * 4. Neither the name of the author nor the names of any co-contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  * $FreeBSD: src/lib/libncp/ncpl_file.c,v 1.2 1999/10/31 03:39:03 bp Exp $
33  */
34 #include <sys/param.h>
35 #include <sys/ioctl.h>
36 #include <errno.h>
37 #include <stdio.h>
38 #include <fcntl.h>
39 #include <unistd.h>
40 #include <strings.h>
41
42 #include <netncp/ncp_lib.h>
43 #include <netncp/ncp_file.h>
44 #include <nwfs/nwfs.h>
45
46 int
47 ncp_read(NWCONN_HANDLE connid, ncp_fh *fh, off_t offset, size_t count, char *target) {
48         int result;
49         struct ncp_rw rwrq;
50         DECLARE_RQ;
51
52         ncp_init_request(conn);
53         ncp_add_byte(conn, NCP_CONN_READ);
54         rwrq.nrw_fh = *fh;
55         rwrq.nrw_base = target;
56         rwrq.nrw_cnt = count;
57         rwrq.nrw_offset = offset;
58         ncp_add_mem(conn, &rwrq, sizeof(rwrq));
59         if ((result = ncp_conn_request(connid, conn)) < 0) 
60                 return -1;
61         return result;
62 }
63
64 int
65 ncp_write(NWCONN_HANDLE connid, ncp_fh *fh, off_t offset, size_t count, char *source)
66 {
67         int result;
68         struct ncp_rw rwrq;
69         DECLARE_RQ;
70
71         ncp_init_request(conn);
72         ncp_add_byte(conn, NCP_CONN_WRITE);
73         rwrq.nrw_fh = *fh;
74         rwrq.nrw_base = source;
75         rwrq.nrw_cnt = count;
76         rwrq.nrw_offset = offset;
77         ncp_add_mem(conn, &rwrq, sizeof(rwrq));
78
79         if ((result = ncp_conn_request(connid, conn)) < 0)
80                 return -1;
81         return result;
82 }
83
84 int
85 ncp_geteinfo(char *path, struct nw_entry_info *fi) {
86         int d, error;
87
88         if ((d = open(path, O_RDONLY)) < 0) return errno;
89         if ((error = ioctl(d, NWFSIOC_GETEINFO, fi)) != 0) return errno;
90         close(d);
91         return 0;
92 }
93
94
95 int
96 ncp_AllocTempDirHandle(char *path, NWDIR_HANDLE *pdh) {
97         int d;
98
99         if ((d = open(path, O_RDONLY)) < 0) return errno;
100         *pdh = d;
101         return 0;
102 }
103
104 int
105 ncp_DeallocateDirHandle(NWDIR_HANDLE dh) {
106         close(dh);
107         return 0;
108 }
109
110 int
111 ncp_GetNSEntryInfo(NWDIR_HANDLE dh, struct nw_entry_info *fi, int *ns) {
112         int error;
113
114         if ((error = ioctl(dh, NWFSIOC_GETEINFO, fi)) != 0) return errno;
115         if ((error = ioctl(dh, NWFSIOC_GETNS, ns)) != 0) return errno;
116         return 0;
117 }
118
119 NWCCODE
120 ncp_ScanForDeletedFiles(NWCONN_HANDLE cH, pnuint32 iterHandle, 
121         pnuint32 volNum, pnuint32 dirBase, nuint8 ns,
122         NWDELETED_INFO *entryInfo)
123 {
124         int error;
125         struct nw_entry_info *pfi;
126         DECLARE_RQ;
127 #define UNITEDT(d,t)    (((d) << 16) | (t))
128
129         bzero(entryInfo, sizeof(NWDELETED_INFO));
130         ncp_init_request(conn);
131         ncp_add_byte(conn, 16);
132         ncp_add_byte(conn, ns);
133         ncp_add_byte(conn, 0);          /* data stream */
134         ncp_add_dword_lh(conn, IM_ALL & ~(IM_SPACE_ALLOCATED | IM_TOTAL_SIZE | IM_EA | IM_DIRECTORY));
135         ncp_add_dword_lh(conn, *iterHandle);
136
137         ncp_add_byte(conn, *volNum);
138         ncp_add_dword_lh(conn, *dirBase);
139         ncp_add_byte(conn, NCP_HF_DIRBASE);     /* dirBase */
140         ncp_add_byte(conn, 0);                  /* no component */
141         if ((error = ncp_request(cH, 87, conn)) != 0) {
142                 return error;
143         }
144         if (conn->rpsize < 0x61) {
145                 return EBADRPC; /* EACCES ? */
146         }
147         *iterHandle = entryInfo->sequence = ncp_reply_dword_lh(conn, 0x00);
148         entryInfo->deletedTime = ncp_reply_word_lh(conn, 0x04);
149         entryInfo->deletedDateAndTime = UNITEDT(ncp_reply_word_lh(conn, 0x06), entryInfo->deletedTime);
150         entryInfo->deletorID = ncp_reply_dword_hl(conn, 0x08);
151         *volNum = ncp_reply_dword_lh(conn, 0x0C);
152         *dirBase = ncp_reply_dword_lh(conn, 0x10);
153         entryInfo->parent = ncp_reply_dword_lh(conn, 0x10);
154         pfi = (struct nw_entry_info*) ncp_reply_data(conn, 0x14);
155         entryInfo->nameLength = pfi->nameLen;
156         memcpy(entryInfo->name, pfi->entryName, pfi->nameLen);
157         return error;
158 }
159
160 NWCCODE
161 ncp_PurgeDeletedFile(NWCONN_HANDLE cH, nuint32 iterHandle, 
162         nuint32 volNum, nuint32 dirBase, nuint8 ns)
163 {
164         DECLARE_RQ;
165
166         ncp_init_request(conn);
167         ncp_add_byte(conn, 18);
168         ncp_add_byte(conn, ns);
169         ncp_add_byte(conn, 0);          /* reserved */
170         ncp_add_dword_lh(conn, iterHandle);
171         ncp_add_dword_lh(conn, volNum);
172         ncp_add_dword_lh(conn, dirBase);
173         return ncp_request(cH, 87, conn);
174 }
175
176
177 static void 
178 ncp_extract_entryInfo(char *data, NW_ENTRY_INFO *entry) {
179         u_char l;
180         const int info_struct_size = sizeof(NW_ENTRY_INFO) - 257;
181
182         memcpy(entry, data, info_struct_size);
183         data += info_struct_size;
184         l = *data++;
185         entry->nameLen = l;
186         memcpy(entry->entryName, data, l);
187         entry->entryName[l] = '\0';
188         return;
189 }
190
191 NWCCODE
192 ncp_ScanNSEntryInfo(NWCONN_HANDLE cH,
193         nuint8 namSpc, nuint16 attrs, SEARCH_SEQUENCE *seq,
194         pnstr8 searchPattern, nuint32 retInfoMask, NW_ENTRY_INFO *entryInfo) 
195 {
196         int error, l;
197         DECLARE_RQ;
198
199         if (seq->searchDirNumber == -1) {
200                 seq->searchDirNumber = 0;
201                 ncp_init_request(conn);
202                 ncp_add_byte(conn, 2);
203                 ncp_add_byte(conn, namSpc);
204                 ncp_add_byte(conn, 0);
205                 ncp_add_handle_path(conn, seq->volNumber, seq->dirNumber, 
206                     NCP_HF_DIRBASE, NULL);
207                 error = ncp_request(cH, 87, conn);
208                 if (error) return error;
209                 memcpy(seq, ncp_reply_data(conn, 0), 9);
210         }
211         ncp_init_request(conn);
212         ncp_add_byte(conn, 3);
213         ncp_add_byte(conn, namSpc);
214         ncp_add_byte(conn, 0);          /* dataStream */
215         ncp_add_word_lh(conn, attrs);   /* SearchAttributes */
216         ncp_add_dword_lh(conn, retInfoMask);
217         ncp_add_mem(conn, seq, sizeof(*seq));
218         l = strlen(searchPattern);
219         ncp_add_byte(conn, l);
220         ncp_add_mem(conn, searchPattern, l);
221         error = ncp_request(cH, 87, conn);
222         if (error) return error;
223         memcpy(seq, ncp_reply_data(conn, 0), sizeof(*seq));
224         ncp_extract_entryInfo(ncp_reply_data(conn, 10), entryInfo);
225         return 0;
226 }
227
228 int
229 ncp_NSEntryInfo(NWCONN_HANDLE cH, nuint8 ns, nuint8 vol, nuint32 dirent,
230     NW_ENTRY_INFO *entryInfo)
231 {
232         DECLARE_RQ;
233         int error;
234
235         ncp_init_request(conn);
236         ncp_add_byte(conn, 6);
237         ncp_add_byte(conn, ns);
238         ncp_add_byte(conn, ns); /* DestNameSpace */
239         ncp_add_word_lh(conn, htons(0xff00));   /* get all */
240         ncp_add_dword_lh(conn, IM_ALL);
241         ncp_add_handle_path(conn, vol, dirent, NCP_HF_DIRBASE, NULL);
242         error = ncp_request(cH, 87, conn);
243         if (error) return error;
244         ncp_extract_entryInfo(ncp_reply_data(conn, 0), entryInfo);
245         return 0;
246 }
247
248 NWCCODE
249 NWGetVolumeName(NWCONN_HANDLE cH, u_char volume, char *name) {
250         int error, len;
251         DECLARE_RQ;
252
253         ncp_init_request_s(conn, 44);
254         ncp_add_byte(conn, volume);
255         error = ncp_request(cH, 22, conn);
256         if (error) return error;
257         len = ncp_reply_byte(conn, 29);
258         if (len == 0)
259                 return ENOENT;
260         bcopy(ncp_reply_data(conn, 30), name, len);
261         name[len] = 0;
262         return 0;
263 }