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. Neither the name of the author nor the names of any co-contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h> 31__FBSDID("$FreeBSD$"); 32 33#include <sys/param.h> 34#include <sys/ioctl.h> 35#include <arpa/inet.h> 36#include <errno.h> 37#include <stdio.h> 38#include <fcntl.h> 39#include <unistd.h> 40#include <string.h> 41 42#include <netncp/ncp_lib.h> 43#include <netncp/ncp_file.h> 44#include <fs/nwfs/nwfs.h> 45 46int 47ncp_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 64int 65ncp_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 84int 85ncp_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 95int 96ncp_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 104int 105ncp_DeallocateDirHandle(NWDIR_HANDLE dh) { 106 close(dh); 107 return 0; 108} 109 110int 111ncp_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 119NWCCODE 120ncp_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 160NWCCODE 161ncp_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 177static void 178ncp_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 191NWCCODE 192ncp_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 228int 229ncp_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 248NWCCODE 249NWGetVolumeName(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} 264