152153Sbp/*
252153Sbp * Copyright (c) 1999, Boris Popov
352153Sbp * All rights reserved.
452153Sbp *
552153Sbp * Redistribution and use in source and binary forms, with or without
652153Sbp * modification, are permitted provided that the following conditions
752153Sbp * are met:
852153Sbp * 1. Redistributions of source code must retain the above copyright
952153Sbp *    notice, this list of conditions and the following disclaimer.
1052153Sbp * 2. Redistributions in binary form must reproduce the above copyright
1152153Sbp *    notice, this list of conditions and the following disclaimer in the
1252153Sbp *    documentation and/or other materials provided with the distribution.
13165920Simp * 3. Neither the name of the author nor the names of any co-contributors
1452153Sbp *    may be used to endorse or promote products derived from this software
1552153Sbp *    without specific prior written permission.
1652153Sbp *
1752153Sbp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1852153Sbp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1952153Sbp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2052153Sbp * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2152153Sbp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2252153Sbp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2352153Sbp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2452153Sbp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2552153Sbp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2652153Sbp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2752153Sbp * SUCH DAMAGE.
2852153Sbp *
2952153Sbp * calls that don't fit to any other category
3052153Sbp */
3184213Sdillon
3284213Sdillon#include <sys/cdefs.h>
3384213Sdillon__FBSDID("$FreeBSD$");
3484213Sdillon
3552153Sbp#include <sys/types.h>
3652153Sbp#include <sys/time.h>
3790868Smike#include <arpa/inet.h>
3852153Sbp#include <errno.h>
3952153Sbp#include <stdio.h>
40162486Skan#include <string.h>
4152153Sbp#include <strings.h>
4252153Sbp
4352153Sbp#include <netncp/ncp_lib.h>
4452153Sbp
4552153Sbpstatic time_t
4652153Sbpncp_nw_to_ctime(struct nw_time_buffer *source) {
4752153Sbp	struct tm u_time;
4852153Sbp
4952153Sbp	bzero(&u_time,sizeof(struct tm));
5052153Sbp	/*
5152153Sbp	 * XXX: NW 4.x tracks daylight automatically
5252153Sbp	 */
5352153Sbp	u_time.tm_isdst = -1;
5452153Sbp	u_time.tm_sec = source->second;
5552153Sbp	u_time.tm_min = source->minute;
5652153Sbp	u_time.tm_hour = source->hour;
5752153Sbp	u_time.tm_mday = source->day;
5852153Sbp	u_time.tm_mon = source->month - 1;
5952153Sbp	u_time.tm_year = source->year;
6052153Sbp
6152153Sbp	if (u_time.tm_year < 80) {
6252153Sbp		u_time.tm_year += 100;
6352153Sbp	}
6452153Sbp	return mktime(&u_time);
6552153Sbp}
6652153Sbp
6752153Sbpint
6852704Sbpncp_get_file_server_information(NWCONN_HANDLE connid,
6952704Sbp	struct ncp_file_server_info *target)
7052153Sbp{
7152153Sbp	int error;
7252153Sbp	DECLARE_RQ;
7352153Sbp
7452153Sbp	ncp_init_request_s(conn, 17);
7552153Sbp	if ((error = ncp_request(connid, 23, conn)) != 0)
7652153Sbp		return error;
7752153Sbp	memcpy(target, ncp_reply_data(conn, 0), sizeof(*target));
7852153Sbp	target->MaximumServiceConnections
7952153Sbp	    = htons(target->MaximumServiceConnections);
8052153Sbp	target->ConnectionsInUse
8152153Sbp	    = htons(target->ConnectionsInUse);
8252153Sbp	target->MaxConnectionsEverUsed
8352153Sbp	    = htons(target->MaxConnectionsEverUsed);
8452153Sbp	target->NumberMountedVolumes
8552153Sbp	    = htons(target->NumberMountedVolumes);
8652153Sbp	return 0;
8752153Sbp}
8852153Sbp
8952153Sbpint
9052704Sbpncp_get_stations_logged_info(NWCONN_HANDLE connid, u_int32_t connection,
9152704Sbp	struct ncp_bindery_object *target, time_t *login_time)
9252153Sbp{
9352153Sbp	int error;
9452153Sbp	DECLARE_RQ;
9552153Sbp
9652153Sbp	ncp_init_request_s(conn, 28);
9752153Sbp	ncp_add_dword_lh(conn, connection);
9852153Sbp
9952153Sbp	if ((error = ncp_request(connid, 23, conn)) != 0)
10052153Sbp		return error;
10152153Sbp	bzero(target, sizeof(*target));
10252153Sbp	target->object_id = ncp_reply_dword_hl(conn, 0);
10352153Sbp	target->object_type = ncp_reply_word_hl(conn, 4);
10452153Sbp	memcpy(target->object_name, ncp_reply_data(conn, 6),
10552153Sbp	       sizeof(target->object_name));
10652153Sbp	*login_time = ncp_nw_to_ctime((struct nw_time_buffer *)ncp_reply_data(conn, 54));
10752153Sbp	return 0;
10852153Sbp}
10952153Sbp
11052153Sbpint
11152704Sbpncp_get_internet_address(NWCONN_HANDLE connid, u_int32_t connection,
11252704Sbp	struct ipx_addr *target, u_int8_t * conn_type)
11352704Sbp{
11452153Sbp	int error;
11552153Sbp	DECLARE_RQ;
11652153Sbp
11752153Sbp	ncp_init_request_s(conn, 26);
11852153Sbp	ncp_add_dword_lh(conn, connection);
11952153Sbp	error = ncp_request(connid, 23, conn);
12052153Sbp	if (error) return error;
12152153Sbp	bzero(target, sizeof(*target));
12252153Sbp	ipx_netlong(*target) = ncp_reply_dword_lh(conn, 0);
12352153Sbp	memcpy(&(target->x_host), ncp_reply_data(conn, 4), 6);
12452153Sbp	target->x_port = ncp_reply_word_lh(conn, 10);
12552153Sbp	*conn_type = ncp_reply_byte(conn, 12);
12652153Sbp	return 0;
12752153Sbp}
12852153Sbp
12952153SbpNWCCODE
13052153SbpNWGetObjectConnectionNumbers(NWCONN_HANDLE connHandle,
13152153Sbp		pnstr8 pObjName, nuint16 objType,
13252153Sbp		pnuint16 pNumConns, pnuint16 pConnHandleList,
13352153Sbp		nuint16 maxConns)
13452153Sbp{
13552626Sbp	int error, i, n;
13652626Sbp	nuint32 lastconn;
13752153Sbp	DECLARE_RQ;
13852626Sbp
13952626Sbp	lastconn = 0;
14052626Sbp	ncp_init_request_s(conn, 27);
14152626Sbp	ncp_add_dword_lh(conn, lastconn);
14252153Sbp	ncp_add_word_hl(conn, objType);
14352153Sbp	ncp_add_pstring(conn, pObjName);
14452153Sbp	if ((error = ncp_request(connHandle, 23, conn)) != 0) return error;
14552626Sbp	n = min(ncp_reply_byte(conn, 0), maxConns);
14652626Sbp	*pNumConns = n;
14752626Sbp	for (i = 0; i < n ; i++) {
14852626Sbp		*pConnHandleList++ = ncp_reply_dword_lh(conn, i * 4 + 1);
14952153Sbp	}
15052153Sbp	return 0;
15152153Sbp}
15252153Sbp
15352153Sbpvoid
15452153SbpNWUnpackDateTime(nuint32 dateTime, NW_DATE *sDate, NW_TIME *sTime) {
15552153Sbp	NWUnpackDate(dateTime >> 16, sDate);
15652153Sbp	NWUnpackTime(dateTime & 0xffff, sTime);
15752153Sbp}
15852153Sbp
15952153Sbpvoid
16052153SbpNWUnpackDate(nuint16 date, NW_DATE *sDate) {
16152153Sbp	sDate->day = date & 0x1f;
16252153Sbp	sDate->month = (date >> 5) & 0xf;
16352153Sbp	sDate->year = ((date >> 9) & 0x7f) + 1980;
16452153Sbp}
16552153Sbp
16652153Sbpvoid
16752153SbpNWUnpackTime(nuint16 time, NW_TIME *sTime) {
16852153Sbp	sTime->seconds = time & 0x1f;
16952153Sbp	sTime->minutes = (time >> 5) & 0x3f;
17052153Sbp	sTime->hours = (time >> 11) & 0x1f;
17152153Sbp}
17252153Sbp
17352153Sbpnuint32
17452153SbpNWPackDateTime(NW_DATE *sDate, NW_TIME *sTime) {
17552153Sbp	return 0;
17652153Sbp}
17752153Sbp
17852153Sbpnuint16
17952153SbpNWPackDate(NW_DATE *sDate) {
18052153Sbp	return 0;
18152153Sbp}
18252153Sbp
18352153Sbpnuint16
18452153SbpNWPackTime(NW_TIME *sTime) {
18552153Sbp	return 0;
18652153Sbp}
18752153Sbp
18852153Sbptime_t
18952153Sbpncp_UnpackDateTime(nuint32 dateTime) {
19052153Sbp	struct tm u_time;
19152153Sbp	NW_DATE d;
19252153Sbp	NW_TIME t;
19352153Sbp
19452153Sbp	NWUnpackDateTime(dateTime, &d, &t);
19552153Sbp	bzero(&u_time,sizeof(struct tm));
19652153Sbp	u_time.tm_isdst = -1;
19752153Sbp	u_time.tm_sec = t.seconds;
19852153Sbp	u_time.tm_min = t.minutes;
19952153Sbp	u_time.tm_hour = t.hours;
20052153Sbp	u_time.tm_mday = d.day;
20152153Sbp	u_time.tm_mon = d.month - 1;
20252153Sbp	u_time.tm_year = d.year - 1900;
20352153Sbp
20452153Sbp	return mktime(&u_time);
20552153Sbp}
20652153Sbp
20752153Sbpint
20852153Sbpncp_GetFileServerDateAndTime(NWCONN_HANDLE cH, time_t *target) {
20952153Sbp	int error;
21052153Sbp	DECLARE_RQ;
21152153Sbp
21252153Sbp	ncp_init_request(conn);
21352153Sbp	if ((error = ncp_request(cH, 20, conn)) != 0)
21452153Sbp		return error;
21552153Sbp	*target = ncp_nw_to_ctime((struct nw_time_buffer *) ncp_reply_data(conn, 0));
21652153Sbp	return 0;
21752153Sbp}
21852153Sbp
21952153Sbpint
22052153Sbpncp_SetFileServerDateAndTime(NWCONN_HANDLE cH, time_t * source) {
22152153Sbp	int year;
22252153Sbp	struct tm *utime = localtime(source);
22352153Sbp	DECLARE_RQ;
22452153Sbp
22552153Sbp	year = utime->tm_year;
22652153Sbp	if (year > 99) {
22752153Sbp		year -= 100;
22852153Sbp	}
22952153Sbp	ncp_init_request_s(conn, 202);
23052153Sbp	ncp_add_byte(conn, year);
23152153Sbp	ncp_add_byte(conn, utime->tm_mon + 1);
23252153Sbp	ncp_add_byte(conn, utime->tm_mday);
23352153Sbp	ncp_add_byte(conn, utime->tm_hour);
23452153Sbp	ncp_add_byte(conn, utime->tm_min);
23552153Sbp	ncp_add_byte(conn, utime->tm_sec);
23652153Sbp	return ncp_request(cH, 23, conn);
23752153Sbp}
23852153Sbp
23952153SbpNWCCODE
24052153SbpNWDownFileServer(NWCONN_HANDLE cH, int force) {
24152153Sbp	DECLARE_RQ;
24252153Sbp
24352153Sbp	ncp_init_request_s(conn, 211);
24452153Sbp	ncp_add_byte(conn, force ? 0 : 0xff);
24552153Sbp	return ncp_request(cH, 23, conn);
24652153Sbp}
24752153Sbp
24852153SbpNWCCODE
24952153SbpNWCloseBindery(NWCONN_HANDLE cH) {
25052153Sbp	DECLARE_RQ;
25152153Sbp
25252153Sbp	ncp_init_request_s(conn, 68);
25352153Sbp	return ncp_request(cH, 23, conn);
25452153Sbp}
25552153Sbp
25652153SbpNWCCODE
25752153SbpNWOpenBindery(NWCONN_HANDLE cH) {
25852153Sbp	DECLARE_RQ;
25952153Sbp
26052153Sbp	ncp_init_request_s(conn, 69);
26152153Sbp	return ncp_request(cH, 23, conn);
26252153Sbp}
26352153Sbp
26452153SbpNWCCODE
26552153SbpNWDisableTTS(NWCONN_HANDLE cH) {
26652153Sbp	DECLARE_RQ;
26752153Sbp
26852153Sbp	ncp_init_request_s(conn, 207);
26952153Sbp	return ncp_request(cH, 23, conn);
27052153Sbp}
27152153Sbp
27252153SbpNWCCODE
27352153SbpNWEnableTTS(NWCONN_HANDLE cH) {
27452153Sbp	DECLARE_RQ;
27552153Sbp
27652153Sbp	ncp_init_request_s(conn, 208);
27752153Sbp	return ncp_request(cH, 23, conn);
27852153Sbp}
27952153Sbp
28052153SbpNWCCODE
28152153SbpNWDisableFileServerLogin(NWCONN_HANDLE cH) {
28252153Sbp	DECLARE_RQ;
28352153Sbp
28452153Sbp	ncp_init_request_s(conn, 203);
28552153Sbp	return ncp_request(cH, 23, conn);
28652153Sbp}
28752153Sbp
28852153SbpNWCCODE
28952153SbpNWEnableFileServerLogin(NWCONN_HANDLE cH) {
29052153Sbp	DECLARE_RQ;
29152153Sbp
29252153Sbp	ncp_init_request_s(conn, 204);
29352153Sbp	return ncp_request(cH, 23, conn);
29452153Sbp}
295