ses: SUN plugin doesn't actually need libnvfru
[unleashed.git] / usr / src / lib / libsmbfs / smb / subr.c
blob0b81606f2c3e1582b6585a4f2164e5dda5c04512
1 /*
2 * Copyright (c) 2000, Boris Popov
3 * All rights reserved.
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.
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.
32 * $Id: subr.c,v 1.19 2005/02/09 00:23:45 lindak Exp $
35 #include <sys/types.h>
36 #include <sys/errno.h>
37 #include <sys/time.h>
39 #include <unistd.h>
40 #include <ctype.h>
41 #include <string.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <stdarg.h>
45 #include <errno.h>
46 #include <sysexits.h>
47 #include <libintl.h>
49 #include <netsmb/netbios.h>
50 #include <netsmb/smb_lib.h>
51 #include <netsmb/nb_lib.h>
53 #include <err.h>
55 #include "private.h"
57 static int smblib_initialized;
59 int
60 smb_lib_init(void)
62 int error;
64 if (smblib_initialized)
65 return (0);
66 if ((error = nls_setlocale("")) != 0) {
67 fprintf(stdout, dgettext(TEXT_DOMAIN,
68 "%s: can't initialise locale\n"), __progname);
69 return (error);
71 smblib_initialized++;
72 return (0);
75 int
76 smb_getlocalname(char **namepp)
78 char buf[SMBIOC_MAX_NAME], *cp;
80 if (gethostname(buf, sizeof (buf)) != 0)
81 return (errno);
82 cp = strchr(buf, '.');
83 if (cp)
84 *cp = '\0';
85 cp = strdup(buf);
86 if (cp == NULL)
87 return (ENOMEM);
88 *namepp = cp;
89 return (0);
93 * Private version of strerror(3C) that
94 * knows our special error codes.
96 char *
97 smb_strerror(int err)
99 char *msg;
101 switch (err) {
102 case EBADRPC:
103 msg = dgettext(TEXT_DOMAIN,
104 "remote call failed");
105 break;
106 case EAUTH:
107 msg = dgettext(TEXT_DOMAIN,
108 "authentication failed");
109 break;
110 default:
111 msg = strerror(err);
112 break;
115 return (msg);
119 * Print a (descriptive) error message
120 * error values:
121 * 0 - no specific error code available;
122 * 1..32767 - system error
124 void
125 smb_error(const char *fmt, int error, ...) {
126 va_list ap;
127 const char *cp;
128 int errtype;
130 fprintf(stderr, "%s: ", __progname);
131 va_start(ap, error);
132 vfprintf(stderr, fmt, ap);
133 va_end(ap);
134 if (error == -1) {
135 error = errno;
136 errtype = SMB_SYS_ERROR;
137 } else {
138 errtype = error & SMB_ERRTYPE_MASK;
139 error &= ~SMB_ERRTYPE_MASK;
141 switch (errtype) {
142 case SMB_SYS_ERROR:
143 if (error)
144 fprintf(stderr, ": syserr = %s\n", smb_strerror(error));
145 else
146 fprintf(stderr, "\n");
147 break;
148 case SMB_RAP_ERROR:
149 fprintf(stderr, ": raperr = %d (0x%04x)\n", error, error);
150 break;
151 case SMB_NB_ERROR:
152 cp = nb_strerror(error);
153 if (cp == NULL)
154 fprintf(stderr, ": nberr = unknown (0x%04x)\n", error);
155 else
156 fprintf(stderr, ": nberr = %s\n", cp);
157 break;
158 default:
159 fprintf(stderr, "\n");
163 char *
164 smb_printb(char *dest, int flags, const struct smb_bitname *bnp) {
165 int first = 1;
167 strcpy(dest, "<");
168 for (; bnp->bn_bit; bnp++) {
169 if (flags & bnp->bn_bit) {
170 strcat(dest, bnp->bn_name);
171 first = 0;
173 if (!first && (flags & bnp[1].bn_bit))
174 strcat(dest, "|");
176 strcat(dest, ">");
177 return (dest);
180 void
181 smb_simplecrypt(char *dst, const char *src)
183 int ch, pos;
185 *dst++ = '$';
186 *dst++ = '$';
187 *dst++ = '1';
188 pos = 27;
189 while (*src) {
190 ch = *src++;
191 if (isascii(ch))
192 ch = (isupper(ch) ? ('A' + (ch - 'A' + 13) % 26) :
193 islower(ch) ? ('a' + (ch - 'a' + 13) % 26) : ch);
194 ch ^= pos;
195 pos += 13;
196 sprintf(dst, "%02x", ch);
197 dst += 2;
199 *dst = 0;
203 smb_simpledecrypt(char *dst, const char *src)
205 char *ep, hexval[3];
206 int len, ch, pos;
208 if (strncmp(src, "$$1", 3) != 0)
209 return (EINVAL);
210 src += 3;
211 len = strlen(src);
212 if (len & 1)
213 return (EINVAL);
214 len /= 2;
215 hexval[2] = 0;
216 pos = 27;
217 while (len--) {
218 hexval[0] = *src++;
219 hexval[1] = *src++;
220 ch = strtoul(hexval, &ep, 16);
221 if (*ep != 0)
222 return (EINVAL);
223 ch ^= pos;
224 pos += 13;
225 if (isascii(ch))
226 ch = (isupper(ch) ? ('A' + (ch - 'A' + 13) % 26) :
227 islower(ch) ? ('a' + (ch - 'a' + 13) % 26) : ch);
228 *dst++ = ch;
230 *dst = 0;
231 return (0);
235 * Number of seconds between 1970 and 1601 year
236 * (134774 * 24 * 60 * 60)
238 static const uint64_t DIFF1970TO1601 = 11644473600ULL;
240 void
241 smb_time_local2server(struct timeval *tsp, int tzoff, long *seconds)
243 *seconds = tsp->tv_sec - tzoff * 60;
246 void
247 smb_time_server2local(ulong_t seconds, int tzoff, struct timeval *tsp)
249 tsp->tv_sec = seconds + tzoff * 60;
250 tsp->tv_usec = 0;
254 * Time from server comes as UTC, so no need to use tz
256 /*ARGSUSED*/
257 void
258 smb_time_NT2local(uint64_t nsec, int tzoff, struct timeval *tsp)
260 smb_time_server2local(nsec / 10000000 - DIFF1970TO1601, 0, tsp);
263 /*ARGSUSED*/
264 void
265 smb_time_local2NT(struct timeval *tsp, int tzoff, uint64_t *nsec)
267 long seconds;
269 smb_time_local2server(tsp, 0, &seconds);
270 *nsec = (((uint64_t)(seconds) & ~1) + DIFF1970TO1601) *
271 (uint64_t)10000000;
274 void
275 smb_hexdump(const void *buf, int len)
277 const uchar_t *p = buf;
278 int ofs = 0;
280 while (len--) {
281 if (ofs % 16 == 0)
282 fprintf(stderr, "%02X: ", ofs);
283 fprintf(stderr, "%02x ", *p++);
284 ofs++;
285 if (ofs % 16 == 0)
286 fprintf(stderr, "\n");
288 if (ofs % 16 != 0)
289 fprintf(stderr, "\n");
292 void
293 dprint(const char *fname, const char *fmt, ...)
295 va_list ap;
297 va_start(ap, fmt);
299 if (smb_debug) {
300 fprintf(stderr, "%s: ", fname);
301 vfprintf(stderr, fmt, ap);
302 fprintf(stderr, "\n");
304 va_end(ap);
307 #undef __progname
309 char *__progname = NULL;
311 char *
312 smb_getprogname()
314 char *p;
316 if (__progname == NULL) {
317 __progname = (char *)getexecname();
318 if ((p = strrchr(__progname, '/')) != 0)
319 __progname = p + 1;
321 return (__progname);