/*
 *  ncplib.h
 *
 *  Copyright (C) 1995, 1996 by Volker Lendecke
 *
 */

#ifndef _NCPLIB_H
#define _NCPLIB_H

#include <linux/types.h>
#include <linux/ncp.h>
#include <linux/ncp_fs.h>
#include <linux/ipx.h>
#include <sys/param.h>
#include <stdio.h>
#include <time.h>

#include "ipxlib.h"
#include "com_err.h"

#ifndef memzero
#include <string.h>
#define memzero(object) memset(&(object), 0, sizeof(object))
#endif

void
str_upper(char *name);

enum connect_state {
	NOT_CONNECTED = 0,
	CONN_PERMANENT,
	CONN_TEMPORARY
};

struct ncp_conn {

	enum connect_state is_connected;

	char server[NCP_BINDERY_NAME_LEN];
	char user  [NCP_BINDERY_NAME_LEN];

	struct ncp_fs_info i;

	/* Fields for use with permanent connections */
	int mount_fid;
	char mount_point[MAXPATHLEN];

	/* Fields for use with temporary connections */
	int ncp_sock;
	int wdog_sock;
	int wdog_pid;
	__u8 sequence;
	int completion;
	int conn_status;
	int reply_size;

	/* Fields used to setup ncp requests */
	int current_size;
	int has_subfunction;
	int verbose;
	int ncp_reply_size;

	int lock;

	char packet[NCP_PACKET_SIZE];
};

struct ncp_conn_spec {
	char server[NCP_BINDERY_NAME_LEN];
	char user[NCP_BINDERY_NAME_LEN];
	uid_t uid;
	int login_type;		/* NCP_BINDERY_USER / NCP_BINDERY_PSERVER */
	char password[NCP_BINDERY_NAME_LEN];
};

struct ncp_property_info {
	__u8 property_name[16];
	__u8 property_flags;
	__u8 property_security;
	__u32 search_instance;
	__u8 value_available_flag;
	__u8 more_properties_flag;
};

/* ncp_initialize is the main entry point for user programs which want
   to connect to a NetWare Server. It looks for -S, -U, -P and -n in
   the argument list, opens the connection and removes the arguments
   from the list. It was designed after the X Windows init
   functions. */
struct ncp_conn *
ncp_initialize(int *argc, char **argv,
	       int login_necessary, long *err);

/* You can login as another object by this procedure. As a first use
   pserver comes to mind. */
struct ncp_conn *
ncp_initialize_as(int *argc, char **argv,
		  int login_necessary, int login_type, long *err);


/* Open a connection */
struct ncp_conn *
ncp_open(struct ncp_conn_spec *spec, long *err);

/* Open a connection on an existing mount point */
struct ncp_conn *
ncp_open_mount(const char *mount_point, long *err);

/* Find a permanent connection that fits the spec, return NULL if
 * there is none. */
char *
ncp_find_permanent(const struct ncp_conn_spec *spec);

/* Find the address of a file server */
struct sockaddr_ipx *
ncp_find_fileserver(char *server_name, long *err);

/* Find the address of a server */
struct sockaddr_ipx *
ncp_find_server(char **server_name, int type, long *err);

/* Detach from a permanent connection or destroy a temporary
   connection */
long
ncp_close(struct ncp_conn *conn);

/* like getmntent, get_ncp_conn_ent scans /etc/mtab for usable
   connections */

struct ncp_conn_ent {
	char server[NCP_BINDERY_NAME_LEN];
	char user[NCP_BINDERY_NAME_LEN];
	uid_t uid;
	char mount_point[MAXPATHLEN];
};

struct ncp_conn_ent *
ncp_get_conn_ent(FILE *filep);

#define NWCLIENT (".nwclient")
#define NWC_NOPASSWORD ("-")

/* find an appropriate connection */

struct ncp_conn_spec *
ncp_find_conn_spec(const char *server, const char *user, const char *password,
		   int login_necessary, uid_t uid, long *err);

long
ncp_get_encryption_key(struct ncp_conn *conn,
		       char *target);

struct ncp_station_addr {
    __u32   NetWork __attribute__ ((packed));
    __u8    Node[6] __attribute__ ((packed));
    __u16   Socket  __attribute__ ((packed));
};

struct ncp_prop_login_control {
    __u8    AccountExpireDate[3]     __attribute__ ((packed));
    __u8    Disabled                 __attribute__ ((packed));
    __u8    PasswordExpireDate[3]    __attribute__ ((packed));
    __u8    GraceLogins              __attribute__ ((packed));
    __u16   PasswordExpireInterval   __attribute__ ((packed));
    __u8    MaxGraceLogins           __attribute__ ((packed));
    __u8    MinPasswordLength        __attribute__ ((packed));
    __u16   MaxConnections           __attribute__ ((packed));
    __u8    ConnectionTimeMask[42]   __attribute__ ((packed));
    __u8    LastLogin[6]             __attribute__ ((packed));
    __u8    RestrictionMask          __attribute__ ((packed));
    __u8    reserved                 __attribute__ ((packed));
    __u32   MaxDiskUsage             __attribute__ ((packed));
    __u16   BadLoginCount            __attribute__ ((packed));
    __u32   BadLoginCountDown        __attribute__ ((packed));
    struct ncp_station_addr LastIntruder  __attribute__ ((packed));
};	

long
ncp_read_property_value(struct ncp_conn *conn,
			int object_type, const char *object_name,
			int segment, const char *prop_name,
			struct nw_property *target);

#define NCP_GRACE_PERIOD (0xdf)

long
ncp_get_bindery_object_id(struct ncp_conn *conn,
			  __u16 object_type,
			  const char *object_name,
			  struct ncp_bindery_object *target);

long
ncp_login_user(struct ncp_conn *conn,
	       const unsigned char *username,
	       const unsigned char *password);

#endif /* _NCPLIB_H */
