CAP/cap60.patches/asip1.patch

3802 lines
100 KiB
Diff

Patch #: none yet
Type: operational change
Priority: none
Modification: add support for AppleShareIP (AFP via TCP/IP)
Submitted: David Hornsby <djh@munnari.OZ.AU>
IMPORTANT:
IMPORTANT: This patch assumes CAP at patch level 198
IMPORTANT: This is an interim patch only. You will need to keep this
IMPORTANT: patch file in order to reverse the code changes before patch
IMPORTANT: 199 can be applied without error. When reversing this patch,
IMPORTANT: you also need to manually remove the following files:
IMPORTANT: rm cap60/applications/aufs/afpdsi.h
IMPORTANT: rm cap60/applications/aufs/afpdsi.c
IMPORTANT: rm cap60/etc/aufsIPFilter
IMPORTANT:
IMPORTANT: To use the TCP/IP functionality, you will require AppleShare
IMPORTANT: Client version 3.7 or later, obtainable from Apple web sites
IMPORTANT:
IMPORTANT: http://appleshareip.apple.com/appleshareip/text/downloads.html
IMPORTANT:
File: cap60/applications/aufs/afpdsi.h
File: cap60/applications/aufs/afpdsi.c
File: cap60/applications/aufs/afpdt.c
File: cap60/applications/aufs/afpfork.c
File: cap60/applications/aufs/afpos.c
File: cap60/applications/aufs/afps.h
File: cap60/applications/aufs/afpserver.c
File: cap60/applications/aufs/aufs.c
File: cap60/applications/aufs/Makefile.m4
File: cap60/lib/afp/afppacks.c
File: cap60/lib/cap/abasp.c
File: cap60/lib/cap/absched.c
File: cap60/etc/aufsIPFilter
File: cap60/samples/ash.c
File: cap60/man/AUFS.8
File: cap60/netat/afp.h
File: cap60/netat/afpcmd.h
*** applications/aufs/afpdsi.h.orig Mon Jul 14 12:20:23 1997
--- applications/aufs/afpdsi.h Fri Jul 11 20:07:07 1997
***************
*** 0 ****
--- 1,108 ----
+ /*
+ * $Author: djh $ $Date: 91/03/14 13:45:20 $
+ * $Header: afpdsi.h,v 2.2 91/03/14 13:45:20 djh Exp $
+ * $Revision: 2.2 $
+ *
+ */
+
+ /*
+ * afpdsi.h - Data Stream Interface Includes
+ *
+ * AFP via a Transport Protocol (eg: TCP/IP)
+ *
+ * AppleTalk package for UNIX
+ *
+ * The following routines implement a lightweight extra
+ * layer between AFP (as embodied in the AUFS code), the
+ * original ASP via ATP layer, and delivery via other
+ * Transport Protocol layers, currently only TCP/IP.
+ *
+ * Refer: "AppleTalk Filing Protocol 2.2 &
+ * AFP over TCP/IP Specification"
+ *
+ * SSS == Server Session Socket
+ * SLS == Session Listening Socket
+ * WSS == Workstation Session Socket
+ *
+ * Copyright (c) 1997 The University of Melbourne
+ * David Hornsby <djh@munnari.OZ.AU>
+ *
+ */
+
+ /*
+ * options
+ *
+ */
+ #define DSI_OPT_REQQ 0x00
+ #define DSI_OPT_ATTQ 0x01
+
+ #define DSI_OPT_REQLEN 4
+ #define DSI_OPT_ATTLEN 4
+
+ /*
+ * quantum sizes
+ *
+ */
+ #define DSI_ATTN_SIZ 2
+ #define DSI_SRVR_CMD 1500
+ #define DSI_SRVR_MAX 64*1024
+
+ /*
+ * the DSI header will be inserted in front of
+ * every AFP request or reply packet
+ *
+ */
+
+ struct dsi_hdr {
+ byte dsi_flags; /* used to determine packet type */
+ #define DSI_REQ_FLAG 0x00
+ #define DSI_REP_FLAG 0x01
+ byte dsi_command; /* similar to ASP commands, except WrtCont */
+ #define DSICloseSession 1
+ #define DSICommand 2
+ #define DSIGetStatus 3
+ #define DSIOpenSession 4
+ #define DSITickle 5
+ #define DSIWrite 6
+ #define DSIAttention 8
+ word dsi_requestID; /* req ID on per-session basis, wraps */
+ dword dsi_err_offset; /* error for reply, offset for write, else 0 */
+ dword dsi_data_len; /* total data length following dsi_hdr */
+ dword dsi_reserved; /* reserved for future, should be zero */
+ };
+
+ /*
+ * per-session demux info
+ *
+ */
+ struct dsi_sess {
+ int sesstype;
+ #define DSI_SESSION_ATALK 0x01
+ #define DSI_SESSION_TCPIP 0x02
+ int state; /* type of DSI data expected */
+ #define DSI_STATE_HDR 0x01
+ #define DSI_STATE_AFP 0x02
+ #define DSI_STATE_DAT 0x03
+ #define DSI_STATE_REP 0x04
+ char *ptr; /* where we have to put incoming data */
+ int lenleft; /* amount of data expected to arrive */
+ int timeout; /* per-session tickle timer */
+ #define DSI_TIMEOUT 5*4
+ word sess_id_out; /* outgoing session ID (0-65535) */
+ word sess_id_in; /* incoming session ID (0-65535) */
+ struct dsi_hdr hdr; /* current incoming header (for reply) */
+ ASPQE *aspqe; /* callback data for GetRequest etc. */
+ };
+
+ /*
+ * IP filter list
+ *
+ */
+ #define MAXIPFILTERS 100
+ #define MAXIPFILTSIZ sizeof(struct ipFilter)
+
+ struct ipFilter {
+ sword perm;
+ dword mask;
+ dword addr;
+ };
*** applications/aufs/afpdsi.c.orig Mon Jul 14 14:04:28 1997
--- applications/aufs/afpdsi.c Sun Apr 19 19:21:07 1998
***************
*** 0 ****
--- 1,2029 ----
+ /*
+ * $Author: djh $ $Date: 91/03/14 13:45:20 $
+ * $Header: afpdsi.c,v 2.2 91/03/14 13:45:20 djh Exp $
+ * $Revision: 2.2 $
+ *
+ */
+
+ /*
+ * afpdsi.c - Data Stream Interface
+ *
+ * AFP via a Transport Protocol (eg: TCP/IP)
+ *
+ * AppleTalk package for UNIX
+ *
+ * The following routines implement a lightweight extra
+ * layer between AFP (as embodied in the AUFS code), the
+ * original ASP via ATP layer, and delivery via other
+ * Transport Protocol layers, currently only TCP/IP.
+ *
+ * Refer: "AppleTalk Filing Protocol 2.2 &
+ * AFP over TCP/IP Specification"
+ *
+ * SSS == Server Session Socket
+ * SLS == Session Listening Socket
+ * WSS == Workstation Session Socket
+ *
+ * Copyright (c) 1997 The University of Melbourne
+ * David Hornsby <djh@munnari.OZ.AU>
+ *
+ */
+
+ #include <stdio.h>
+ #include <ctype.h>
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <netinet/tcp.h>
+ #include <netdb.h>
+ #include <netat/appletalk.h>
+ #include "../../lib/cap/abasp.h" /* urk */
+ #include "afpdsi.h"
+
+ #ifdef HAVE_WRITEV
+ #include <sys/uio.h>
+ #endif /* HAVE_WRITEV */
+
+ /*
+ * aufs AFP routines
+ *
+ */
+ int dsiInit();
+ int dsiGetSession();
+ int dsiFork();
+ int dsiTickleUserRoutine();
+ int dsiGetRequest();
+ int dsiWrtContinue();
+ int dsiWrtReply();
+ int dsiCmdReply();
+ int dsiAttention();
+ int dsiGetNetworkInfo();
+ int dsiGetParms();
+ int dsiCloseSession();
+ int dsiShutdown();
+ int dsiTCPIPCloseSLS();
+
+ /*
+ * AppleTalk Session Protocol routines
+ * (including some formerly 'private')
+ *
+ */
+ int SPInit();
+ int SPGetSession();
+ int SPFork();
+ int SPTickleUserRoutine();
+ int SPGetRequest();
+ int SPWrtContinue();
+ int SPWrtReply();
+ int SPCmdReply();
+ int SPAttention();
+ int SPGetNetworkInfo();
+ int SPGetParms();
+ int SPCloseSession();
+ int SPShutdown();
+
+ ASPSSkt *aspsskt_find_slsrefnum();
+ ASPSkt *aspskt_find_sessrefnum();
+ ASPSkt *aspskt_find_active();
+ ASPQE *create_aq();
+
+ void stopasptickle();
+ void stop_ttimer();
+ void delete_aq();
+ void Timeout();
+
+ /*
+ * local TCP/IP routines
+ *
+ */
+ int dsiTCPIPInit();
+ int dsiTCPIPFork();
+ int dsiTCPIPGetRequest();
+ int dsiTCPWrtContinue();
+ int dsiTCPIPWrtReply();
+ int dsiTCPIPCmdReply();
+ int dsiTCPIPReply();
+ int dsiTCPIPTickleUserRoutine();
+ int dsiTCPIPCloseSession();
+ int dsiTCPIPAttention();
+ int dsiTCPIPGetNetworkInfo();
+ int dsiTCPIPWrite();
+ int dsiTCPIPCloseSLS();
+
+ /*
+ * globals
+ *
+ */
+ #ifdef DEBUG_AFP_CMD
+ extern FILE *dbg;
+ #endif /* DEBUG_AFP_CMD */
+
+ extern int errno;
+ extern int asip_enable;
+ extern char *dsiTCPIPFilter;
+ private struct dsi_sess *dsi_session = NULL;
+
+ /*
+ * DSI transport-layer demultiplexing
+ *
+ */
+
+ /*
+ * Set up a Server Listening Socket (SLS) for both
+ * ASP/ATP and TCP/IP.
+ *
+ * SLSEntityIdentifier - server AppleTalk address
+ * ServiceStatusBlock - pointer to ServerInfo data
+ * ServiceStatusBlockSize - ServerInfo data size
+ * SLSRefNum - return a session RefNum
+ *
+ */
+
+ int
+ dsiInit(SLSEntityIdentifier, ServiceStatusBlock,
+ ServiceStatusBlockSize, SLSRefNum)
+ AddrBlock *SLSEntityIdentifier; /* SLS Net id */
+ char *ServiceStatusBlock; /* block with status info */
+ int ServiceStatusBlockSize; /* size of status info */
+ int *SLSRefNum; /* sls ref num return place */
+ {
+ int result;
+ extern int numasp;
+
+ /*
+ * allocate & initialise space for DSI session data
+ *
+ */
+ if (numasp <= 0)
+ return(-1);
+
+ if ((dsi_session = (struct dsi_sess *)
+ malloc(sizeof(struct dsi_sess)*numasp)) == NULL)
+ return(-1);
+
+ bzero((char *)dsi_session, sizeof(struct dsi_sess)*numasp);
+
+ /*
+ * allocate SLSRefNum, initialise AppleTalk Session Protocol SLS
+ *
+ */
+ result = SPInit(SLSEntityIdentifier, ServiceStatusBlock,
+ ServiceStatusBlockSize, SLSRefNum);
+
+ #ifdef DEBUG_AFP_CMD
+ if (dbg != NULL) {
+ fprintf(dbg, "** SPInit(): (PID %d)\n", getpid());
+ fprintf(dbg, "\tSLSRefNum: %d\n", *SLSRefNum);
+ fprintf(dbg, "\tServiceStatusBlockSize: %d\n", ServiceStatusBlockSize);
+ fprintf(dbg, "\tresult: %d\n", result);
+ fprintf(dbg, "\n\n");
+ fflush(dbg);
+ }
+ #endif /* DEBUG_AFP_CMD */
+
+ if (result != noErr)
+ return(result);
+
+ /*
+ * if enabled, setup TCP/IP SLS (uses same SLSRefNum)
+ *
+ */
+ if (asip_enable)
+ if (dsiTCPIPInit(SLSEntityIdentifier, ServiceStatusBlock,
+ ServiceStatusBlockSize, SLSRefNum) != noErr)
+ asip_enable = 0;
+
+ return(noErr);
+ }
+
+ /*
+ * set up to wait for a new session to start
+ *
+ * SLSRefNum - Session Listening Socket RefNum
+ * SessRefNum - returns new session reference number
+ * comp - completion flag/error
+ *
+ */
+
+ int
+ dsiGetSession(SLSRefNum, SessRefNum, comp)
+ int SLSRefNum;
+ int *SessRefNum;
+ int *comp;
+ {
+ int result;
+
+ /*
+ * get a session reference number,
+ *
+ */
+ result = SPGetSession(SLSRefNum, SessRefNum, comp);
+
+ #ifdef DEBUG_AFP_CMD
+ if (dbg != NULL) {
+ fprintf(dbg, "** SPGetSession(): (PID %d)\n", getpid());
+ fprintf(dbg, "\tSLSRefNum: %d\n", SLSRefNum);
+ fprintf(dbg, "\tSessRefNum: %d\n", *SessRefNum);
+ fprintf(dbg, "\tcomp: %d\n", *comp);
+ fprintf(dbg, "\tresult: %d\n", result);
+ fprintf(dbg, "\n\n");
+ fflush(dbg);
+ }
+ #endif /* DEBUG_AFP_CMD */
+
+ if (result != noErr)
+ return(result);
+
+ /*
+ * assume that this session is going to be
+ * AppleTalk, until we find out otherwise
+ * (this depends on what type of OpenSession
+ * packet actually arrives)
+ *
+ */
+ dsi_session[*SessRefNum].sesstype = DSI_SESSION_ATALK;
+
+ /*
+ * initialise data structure for DSI state
+ *
+ */
+ dsi_session[*SessRefNum].timeout = 0;
+ dsi_session[*SessRefNum].aspqe = NULL;
+ dsi_session[*SessRefNum].sess_id_in = 0;
+ dsi_session[*SessRefNum].sess_id_out = 0;
+ dsi_session[*SessRefNum].state = DSI_STATE_HDR;
+ dsi_session[*SessRefNum].lenleft = sizeof(struct dsi_hdr);
+ dsi_session[*SessRefNum].ptr = (char *)&dsi_session[*SessRefNum].hdr;
+
+ return(noErr);
+ }
+
+ /*
+ * fork and create new process to handle session
+ *
+ * SessRefNum - session reference number
+ * stickle - want server tickle
+ * ctickle - want client tickle
+ *
+ */
+
+ int
+ dsiFork(SessRefNum, stickle, ctickle)
+ int SessRefNum;
+ int stickle;
+ int ctickle;
+ {
+ /*
+ * if AppleTalk, hand off to Session Protocol
+ *
+ */
+ if (dsi_session[SessRefNum].sesstype == DSI_SESSION_ATALK)
+ return(SPFork(SessRefNum, stickle, ctickle));
+
+ /*
+ * handle locally for TCP/IP
+ *
+ */
+ if (dsi_session[SessRefNum].sesstype == DSI_SESSION_TCPIP)
+ return(dsiTCPIPFork(SessRefNum, stickle, ctickle));
+
+ return(ParamErr);
+ }
+
+ /*
+ * set the user-timeout routine and argument
+ *
+ * this needs to be handled in the parent
+ * process for AppleTalk connections and in
+ * the child process for TCP/IP connections
+ *
+ * 'pid' was obtained from the approriate fork()
+ *
+ */
+
+ int
+ dsiTickleUserRoutine(SessRefNum, routine, pid)
+ int SessRefNum;
+ int (*routine)();
+ int pid;
+ {
+ /*
+ * AppleTalk
+ *
+ */
+ if (pid)
+ if (dsi_session[SessRefNum].sesstype == DSI_SESSION_ATALK)
+ return(SPTickleUserRoutine(SessRefNum, routine, pid));
+
+ /*
+ * TCP/IP
+ *
+ */
+ if (!pid)
+ if (dsi_session[SessRefNum].sesstype == DSI_SESSION_TCPIP)
+ return(dsiTCPIPTickleUserRoutine(SessRefNum, routine, getpid()));
+
+ return(noErr);
+ }
+
+ /*
+ * set up to wait for a request on SSS
+ *
+ * SessRefNum - session reference number
+ * ReqBuff - request command buffer
+ * ReqBuffSize - request command buffer size
+ * ReqRefNum - pointer to a special command block
+ * SPReqType - returns command request type
+ * ActRcvdReqLen - returns command length
+ * comp - completion flag/error
+ *
+ */
+
+ int
+ dsiGetRequest(SessRefNum, ReqBuff, ReqBuffSize,
+ ReqRefNum, SPReqType, ActRcvdReqLen, comp)
+ int SessRefNum;
+ char *ReqBuff;
+ int ReqBuffSize;
+ ASPQE **ReqRefNum;
+ int *SPReqType;
+ int *ActRcvdReqLen;
+ int *comp;
+ {
+ /*
+ * AppleTalk
+ *
+ */
+ if (dsi_session[SessRefNum].sesstype == DSI_SESSION_ATALK)
+ return(SPGetRequest(SessRefNum, ReqBuff, ReqBuffSize,
+ ReqRefNum, SPReqType, ActRcvdReqLen, comp));
+
+ /*
+ * TCP/IP
+ *
+ */
+ if (dsi_session[SessRefNum].sesstype == DSI_SESSION_TCPIP)
+ return(dsiTCPIPGetRequest(SessRefNum, ReqBuff, ReqBuffSize,
+ ReqRefNum, SPReqType, ActRcvdReqLen, comp));
+
+ return(ParamErr);
+ }
+
+ /*
+ * 'read' data sent by client
+ *
+ * SessRefNum - session reference number
+ * ReqRefNum - client connection details (addr, TID)
+ * Buffer - final location for data
+ * BufferSize - maximum amount of data we can handle
+ * ActLenRcvd - actual amount of date received
+ * atptimeout - ATP get data timeout
+ * comp - completion flag/error
+ *
+ */
+
+ int
+ dsiWrtContinue(SessRefNum, ReqRefNum, Buffer, BufferSize,
+ ActLenRcvd, atptimeout, comp)
+ int SessRefNum;
+ ASPQE *ReqRefNum;
+ char *Buffer;
+ int BufferSize;
+ int *ActLenRcvd;
+ int atptimeout;
+ int *comp;
+ {
+ /*
+ * AppleTalk
+ *
+ */
+ if (dsi_session[SessRefNum].sesstype == DSI_SESSION_ATALK)
+ return(SPWrtContinue(SessRefNum, ReqRefNum, Buffer,
+ BufferSize, ActLenRcvd, atptimeout, comp));
+
+ /*
+ * TCP/IP
+ *
+ */
+ if (dsi_session[SessRefNum].sesstype == DSI_SESSION_TCPIP)
+ return(dsiTCPIPWrtContinue(SessRefNum, ReqRefNum, Buffer,
+ BufferSize, ActLenRcvd, atptimeout, comp));
+
+ return(ParamErr);
+ }
+
+ /*
+ * reply to a write request sent to our SSS
+ *
+ * SessRefNum - session reference number
+ * ReqRefNum - client connection details (addr, TID)
+ * CmdResult - return result
+ * CmdReplyData - return data
+ * CmdReplyDataSize - return data size
+ * comp - completion flag/error
+ *
+ */
+
+ int
+ dsiWrtReply(SessRefNum, ReqRefNum, CmdResult,
+ CmdReplyData, CmdReplyDataSize, comp)
+ int SessRefNum;
+ ASPQE *ReqRefNum;
+ dword CmdResult;
+ char *CmdReplyData;
+ int CmdReplyDataSize;
+ int *comp;
+ {
+ /*
+ * AppleTalk
+ *
+ */
+ if (dsi_session[SessRefNum].sesstype == DSI_SESSION_ATALK)
+ return(SPWrtReply(SessRefNum, ReqRefNum, CmdResult,
+ CmdReplyData, CmdReplyDataSize, comp));
+
+ /*
+ * TCP/IP
+ *
+ */
+ if (dsi_session[SessRefNum].sesstype == DSI_SESSION_TCPIP)
+ return(dsiTCPIPWrtReply(SessRefNum, ReqRefNum, CmdResult,
+ CmdReplyData, CmdReplyDataSize, comp));
+
+ return(ParamErr);
+ }
+
+ /*
+ * Reply to a command request sent to our SSS
+ *
+ * SessRefNum - session reference number
+ * ReqRefNum - client connection details (addr, TID)
+ * CmdResult - return result
+ * CmdReplyData - return data
+ * CmdReplyDataSize - return data size
+ * comp - completion flag/error
+ *
+ */
+
+ int
+ dsiCmdReply(SessRefNum, ReqRefNum, CmdResult,
+ CmdReplyData, CmdReplyDataSize, comp)
+ int SessRefNum;
+ ASPQE *ReqRefNum;
+ dword CmdResult;
+ char *CmdReplyData;
+ int CmdReplyDataSize;
+ int *comp;
+ {
+ /*
+ * AppleTalk
+ *
+ */
+ if (dsi_session[SessRefNum].sesstype == DSI_SESSION_ATALK)
+ return(SPCmdReply(SessRefNum, ReqRefNum, CmdResult,
+ CmdReplyData, CmdReplyDataSize, comp));
+
+ /*
+ * TCP/IP
+ *
+ */
+ if (dsi_session[SessRefNum].sesstype == DSI_SESSION_TCPIP)
+ return(dsiTCPIPCmdReply(SessRefNum, ReqRefNum, CmdResult,
+ CmdReplyData, CmdReplyDataSize, comp));
+
+ return(ParamErr);
+ }
+
+ /*
+ * send an Attention signal to WSS
+ *
+ * SessRefNum - session reference number
+ * AttentionCode - attention message
+ * atpretries - ATP Retries
+ * atptimeout - ATP Timeout
+ * comp - completion falg/error
+ *
+ */
+
+ int
+ dsiAttention(SessRefNum, AttentionCode, atpretries, atptimeout, comp)
+ int SessRefNum;
+ word AttentionCode;
+ int atpretries;
+ int *comp;
+ {
+ /*
+ * AppleTalk
+ *
+ */
+ if (dsi_session[SessRefNum].sesstype == DSI_SESSION_ATALK)
+ return(SPAttention(SessRefNum, AttentionCode,
+ atpretries, atptimeout, comp));
+
+ /*
+ * TCP/IP
+ *
+ */
+ if (dsi_session[SessRefNum].sesstype == DSI_SESSION_TCPIP)
+ return(dsiTCPIPAttention(SessRefNum, AttentionCode,
+ atpretries, atptimeout, comp));
+
+ return(ParamErr);
+ }
+
+ /*
+ * return remote address of session client
+ *
+ */
+
+ int
+ dsiGetNetworkInfo(SessRefNum, addr)
+ int SessRefNum;
+ AddrBlock *addr;
+ {
+ /*
+ * AppleTalk
+ *
+ */
+ if (dsi_session[SessRefNum].sesstype == DSI_SESSION_ATALK)
+ return(SPGetNetworkInfo(SessRefNum, addr));
+
+ /*
+ * TCP/IP
+ *
+ */
+ if (dsi_session[SessRefNum].sesstype == DSI_SESSION_TCPIP)
+ return(dsiTCPIPGetNetworkInfo(SessRefNum, addr));
+
+ return(ParamErr);
+ }
+
+ /*
+ * Get server operating parameters (these numbers are used
+ * to malloc() the appropriate amount of buffer space).
+ *
+ * MaxCmdSize - maximum single packet size
+ * QuantumSize - maximum outstanding data
+ *
+ * For ASP/ATP:
+ * MaxCmdSize = atpMaxData (578)
+ * QuantumSize = atpMaxData*atpMaxNum (578*8)
+ *
+ * For TCP/IP:
+ * MaxCmdSize = AFP Command Size (1500)
+ * QuantumSize = Data Chunk Size (65536)
+ *
+ */
+
+ int
+ dsiGetParms(MaxCmdSize, QuantumSize)
+ int *MaxCmdSize;
+ int *QuantumSize;
+ {
+ if (asip_enable) {
+ *MaxCmdSize = DSI_SRVR_CMD;
+ *QuantumSize = DSI_SRVR_MAX;
+ return(noErr);
+ }
+
+ return(SPGetParms(MaxCmdSize, QuantumSize));
+ }
+
+ /*
+ * Close down a SSS
+ *
+ * SessRefNum - Session reference number
+ * atpretries - ATP Retries
+ * atptimeout - ATP Timeout
+ * comp - completion flag/error
+ *
+ */
+
+ int
+ dsiCloseSession(SessRefNum, atpretries, atptimeout, comp)
+ int SessRefNum;
+ int atpretries;
+ int atptimeout;
+ int *comp;
+ {
+ /*
+ * AppleTalk
+ *
+ */
+ if (dsi_session[SessRefNum].sesstype == DSI_SESSION_ATALK)
+ return(SPCloseSession(SessRefNum, atpretries, atptimeout, comp));
+
+ /*
+ * TCP/IP
+ *
+ */
+ if (dsi_session[SessRefNum].sesstype == DSI_SESSION_TCPIP)
+ return(dsiTCPIPCloseSession(SessRefNum, atpretries, atptimeout, comp));
+
+ return(ParamErr);
+ }
+
+ /*
+ * shutdown session
+ *
+ * SessRefNum - session reference number
+ *
+ */
+
+ int
+ dsiShutdown(SessRefNum)
+ int SessRefNum;
+ {
+ /*
+ * clean up our session data
+ *
+ */
+ if (dsi_session[SessRefNum].aspqe != NULL)
+ delete_aspaqe(dsi_session[SessRefNum].aspqe);
+
+ dsi_session[SessRefNum].timeout = 0;
+ dsi_session[SessRefNum].aspqe = NULL;
+ dsi_session[SessRefNum].sess_id_in = 0;
+ dsi_session[SessRefNum].sess_id_out = 0;
+ dsi_session[SessRefNum].state = DSI_STATE_HDR;
+ dsi_session[SessRefNum].sesstype = DSI_SESSION_ATALK;
+ dsi_session[SessRefNum].lenleft = sizeof(struct dsi_hdr);
+ dsi_session[SessRefNum].ptr = (char *)&dsi_session[SessRefNum].hdr;
+
+ /*
+ * then clean up the ASP stuff
+ *
+ */
+ return(SPShutdown(SessRefNum));
+ }
+
+ #ifdef DEBUG_AFP_CMD
+ /*
+ * return descriptive command name string
+ *
+ */
+ char *
+ dsi_cmd(cmd)
+ int cmd;
+ {
+ switch (cmd) {
+ case DSIGetStatus:
+ return("DSIGetStatus");
+ break;
+ case DSIOpenSession:
+ return("DSIOpenSession");
+ break;
+ case DSICommand:
+ return("DSICommand");
+ break;
+ case DSIWrite:
+ return("DSIWrite");
+ break;
+ case DSIAttention:
+ return("DSIAttention");
+ break;
+ case DSITickle:
+ return("DSITickle");
+ break;
+ case DSICloseSession:
+ return("DSICloseSession");
+ break;
+ }
+ return("UNKNOWN");
+ }
+ #endif /* DEBUG_AFP_CMD */
+
+ /*
+ * TCP/IP related routines
+ *
+ */
+
+ /*
+ * open and initialise TCP/IP SLS port
+ *
+ * "The interface will register the AFP server on a well-known
+ * (static) data stream port. In case of TCP, it will be TCP
+ * port number 548".
+ *
+ */
+
+ private int slsskt = -1;
+ private struct sockaddr_in lsin;
+
+ int
+ dsiTCPIPInit(SLSEntityIdentifier, ServiceStatusBlock,
+ ServiceStatusBlockSize, SLSRefNum)
+ AddrBlock *SLSEntityIdentifier; /* SLS Net id */
+ char *ServiceStatusBlock; /* block with status info */
+ int ServiceStatusBlockSize; /* size of status info */
+ int *SLSRefNum; /* sls ref num return place */
+ {
+ int aport, len;
+ extern u_int asip_addr;
+ extern u_short asip_port;
+ private int dsiTCPIPSLSListener();
+ struct protoent *t, *getprotobyname();
+
+ /*
+ * open a stream socket
+ *
+ */
+ if ((slsskt = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ return(slsskt);
+
+ bzero((char *)&lsin, sizeof(lsin));
+
+ lsin.sin_family = AF_INET;
+ lsin.sin_port = htons(asip_port);
+ lsin.sin_addr.s_addr = htonl(asip_addr);
+
+ /*
+ * want to send data as it becomes available
+ *
+ */
+ len = 1;
+ t = getprotobyname("tcp");
+ aport = (t == NULL) ? IPPROTO_TCP : t->p_proto;
+ setsockopt(slsskt, aport, TCP_NODELAY, (char *)&len, sizeof(int));
+
+ /*
+ * bind to ipaddr:port selected by AUFS -B option
+ * (defaults to INADDR_ANY:548)
+ *
+ */
+ if (bind(slsskt, (struct sockaddr *)&lsin, sizeof(lsin)) != 0) {
+ close(slsskt);
+ return(-1);
+ }
+
+ /*
+ * start listening for connection attempts
+ *
+ */
+ if (listen(slsskt, 5) != 0) {
+ close(slsskt);
+ return(-1);
+ }
+
+ /*
+ * register a callback routine to handle SLS connection requests
+ *
+ */
+ fdlistener(slsskt, dsiTCPIPSLSListener, NULL, *SLSRefNum);
+
+ return(noErr);
+ }
+
+ /*
+ * fdlistener() callback routine for TCP/IP connection attempts
+ *
+ * accept() the connection and register a data listener for
+ * incoming connection/getstatus packets.
+ *
+ */
+
+ private int
+ dsiTCPIPSLSListener(fd, none, SLSRefNum)
+ int fd;
+ caddr_t none;
+ int SLSRefNum;
+ {
+ int len, acc;
+ int illegal = 0;
+ struct sockaddr_in rsin;
+ extern u_short asip_port;
+ private int dsiTCPIPIllegalIP();
+ private int dsiTCPIPSSSListener();
+
+ len = sizeof(struct sockaddr_in);
+ if ((acc = accept(fd, (struct sockaddr *)&rsin, &len)) < 0)
+ return(acc);
+
+ /*
+ * check our IP address filter for
+ * a disallowed source IP address
+ *
+ */
+ if (!dsiTCPIPIllegalIP(&rsin))
+ fdlistener(acc, dsiTCPIPSSSListener, NULL, SLSRefNum);
+ else
+ close(acc), illegal = 1;
+
+ #ifdef DEBUG_AFP_CMD
+ if (dbg != NULL) {
+ fprintf(dbg,
+ "** AppleShareIP connection attempt to port %d from %s:%d (PID %d)\n",
+ asip_port, inet_ntoa(rsin.sin_addr), ntohs(rsin.sin_port), getpid());
+ if (illegal)
+ fprintf(dbg, "** Rejected by IP address filter (%s)\n", dsiTCPIPFilter);
+ fprintf(dbg, "\n\n");
+ fflush(dbg);
+ }
+ #endif /* DEBUG_AFP_CMD */
+
+ return(noErr);
+ }
+
+ /*
+ * fdlistener() callback routine for incoming DSI requests
+ *
+ * "An AFP server expects two command types, that is, DSIOpenSession
+ * or DSIGetStatus after the data stream connection establishment.
+ * DSIOpenSession command confirms the clients commitment to open an
+ * actual DSI session. There is a 1-to-1 mapping between the data
+ * stream connection and a DSI session. DSIGetSTatus command replies
+ * the server status followed by the connection tear down by an AFP
+ * server".
+ *
+ * This handler is interested only in DSIGetStatus or DSIOpenSession
+ * requests. Once the session is open, we unregister the fd with this
+ * handler and re-register it with the generic session handler.
+ *
+ */
+
+ private int
+ dsiTCPIPSSSListener(fd, none, SLSRefNum)
+ int fd;
+ caddr_t none;
+ int SLSRefNum;
+ {
+ int len;
+ int optlen;
+ ASPSkt *as;
+ ASPSSkt *sas;
+ int SessRefNum;
+ char reply_opt[8];
+ struct dsi_hdr hdr;
+ char *optptr, *reqst_opt;
+ private int dsiTCPIPSessListener();
+
+ /*
+ * hopefully there are at least sizeof(hdr) bytes available to read
+ * (of course, there may not be, but the extra trouble of keeping a
+ * per stream partial header for just DSIGetStatus and DSIOpenSession
+ * isn't really worth it).
+ *
+ */
+ if ((len = read(fd, (char *)&hdr, sizeof(hdr))) != sizeof(hdr)) {
+ fdunlisten(fd);
+ close(fd);
+ return(-1);
+ }
+
+ #ifdef DEBUG_AFP_CMD
+ if (dbg != NULL) {
+ char *dsi_cmd();
+ fprintf(dbg, "<< AppleShareIP DSI header (PID %d, session startup):\n",
+ getpid());
+ fprintf(dbg, "\tFlags: %02x (%s)\n", hdr.dsi_flags,
+ (hdr.dsi_flags == DSI_REQ_FLAG) ? "Request" : "REPLY!!");
+ fprintf(dbg, "\tCommand: %02x (%s)\n", hdr.dsi_command,
+ dsi_cmd(hdr.dsi_command));
+ fprintf(dbg, "\tRequestID: %d\n", ntohs(hdr.dsi_requestID));
+ fprintf(dbg, "\tErrCode/DataOffset: %d\n", ntohl(hdr.dsi_err_offset));
+ fprintf(dbg, "\tDataLength: %d\n", ntohl(hdr.dsi_data_len));
+ fprintf(dbg, "\tReserved: %d\n\n\n", ntohl(hdr.dsi_reserved));
+ fflush(dbg);
+ }
+ #endif /* DEBUG_AFP_CMD */
+
+ /*
+ * not interested in Replies
+ * (should be none)
+ *
+ */
+ if (hdr.dsi_flags != DSI_REQ_FLAG)
+ return(noErr);
+
+ /*
+ * process the request
+ *
+ */
+ switch (hdr.dsi_command) {
+ case DSIGetStatus:
+ /* dig out saved server status info for this SLS */
+ if ((sas = aspsskt_find_slsrefnum(SLSRefNum)) != NULL) {
+ hdr.dsi_flags = DSI_REP_FLAG;
+ hdr.dsi_err_offset = htonl(noErr);
+ hdr.dsi_data_len = htonl(sas->ssbl);
+ hdr.dsi_reserved = htonl(0x00000000);
+ /* send server status information */
+ dsiTCPIPWrite(fd, &hdr, (char *)sas->ssb, sas->ssbl);
+ }
+ /* fall through */
+ default: /* tear down connection */
+ fdunlisten(fd);
+ close(fd);
+ break;
+ case DSIOpenSession:
+ /* search for SLS next waiting session */
+ if ((as = aspskt_find_active(SLSRefNum)) == NULL) {
+ hdr.dsi_flags = DSI_REP_FLAG;
+ hdr.dsi_err_offset = htonl(ServerBusy);
+ hdr.dsi_data_len = htonl(0x00000000);
+ hdr.dsi_reserved = htonl(0x00000000);
+ dsiTCPIPWrite(fd, &hdr, NULL, 0);
+ fdunlisten(fd);
+ close(fd);
+ break;
+ }
+ /* check for incoming OpenSession options */
+ if ((optlen = ntohl(hdr.dsi_data_len)) > 0) {
+ if ((reqst_opt = (char *)malloc(optlen)) != NULL) {
+ optptr = reqst_opt;
+ while (optlen > 0) {
+ if ((len = read(fd, optptr, optlen)) < 0) {
+ fdunlisten(fd);
+ close(fd);
+ break;
+ }
+ optlen -= len;
+ optptr += len;
+ }
+ /*
+ * one day we might actually care
+ *
+ dsi_parse_option(optptr);
+ *
+ */
+ free(reqst_opt);
+ }
+ }
+ /* start session */
+ as->ss = fd;
+ as->state = SP_STARTED;
+ SessRefNum = as->SessRefNum;
+ /* mark this session as type TCP/IP */
+ dsi_session[SessRefNum].sesstype = DSI_SESSION_TCPIP;
+ /* set up state for this session */
+ dsi_session[SessRefNum].state = DSI_STATE_HDR;
+ dsi_session[SessRefNum].lenleft = sizeof(struct dsi_hdr);
+ dsi_session[SessRefNum].ptr = (char *)&dsi_session[SessRefNum].hdr;
+ dsi_session[SessRefNum].sess_id_in = ntohs(hdr.dsi_requestID)+1;
+ dsi_session[SessRefNum].sess_id_out = 0;
+ dsi_session[SessRefNum].aspqe = NULL;
+ dsi_session[SessRefNum].timeout = 0;
+ /* set OpenSession reply option */
+ optlen = DSI_OPT_REQLEN+2;
+ reply_opt[0] = DSI_OPT_REQQ;
+ reply_opt[1] = DSI_OPT_REQLEN;
+ reply_opt[2] = (DSI_SRVR_MAX >> 24) & 0xff;
+ reply_opt[3] = (DSI_SRVR_MAX >> 16) & 0xff;
+ reply_opt[4] = (DSI_SRVR_MAX >> 8) & 0xff;
+ reply_opt[5] = (DSI_SRVR_MAX) & 0xff;
+ /* setup response header */
+ hdr.dsi_flags = DSI_REP_FLAG;
+ hdr.dsi_err_offset = htonl(noErr);
+ hdr.dsi_data_len = htonl(optlen);
+ hdr.dsi_reserved = htonl(0x00000000);
+ /* send OpenSession Reply */
+ dsiTCPIPWrite(fd, &hdr, reply_opt, optlen);
+ /* move fd to session handler */
+ fdunlisten(fd);
+ fdlistener(fd, dsiTCPIPSessListener, (caddr_t)as, SessRefNum);
+ *as->comp = noErr;
+ return(noErr);
+ break;
+ }
+
+ return(noErr);
+ }
+
+ /*
+ * data listener for opened sessions
+ *
+ * At any time the data listener can be in one of four states,
+ * waiting until the expected amount of data has arrived, or a
+ * reply has been sent, freeing the header for re-use:
+ *
+ * DSI_STATE_HDR - reading the 16-byte DSI header
+ * DSI_STATE_AFP - reading the AFP command data
+ * DSI_STATE_DAT - reading the DSIWrite data
+ * DSI_STATE_REP - waiting until reply is sent
+ *
+ */
+
+ private int
+ dsiTCPIPSessListener(fd, as, SessRefNum)
+ int fd;
+ ASPSkt *as;
+ int SessRefNum;
+ {
+ int len;
+ int comp;
+ char *ptr;
+ ASPQE *aspqe;
+ atpProto *ap;
+ struct dsi_hdr *hdr;
+
+ /*
+ * better have a waiting request
+ *
+ */
+ if ((aspqe = dsi_session[SessRefNum].aspqe) == NULL) {
+ logit(0, "Incoming TCP/IP data but no pending request");
+ dsiTCPIPCloseSession(SessRefNum, 0, 0, &comp);
+ return(-1);
+ }
+
+ /*
+ * ignore available data until reply is sent
+ * (reply uses the sessionID in DSI header) or
+ * dsiTCPIPWrtContinue() changes the state to
+ * DSI_STATE_DAT
+ *
+ */
+ if (dsi_session[SessRefNum].state == DSI_STATE_REP)
+ return(noErr);
+
+ /*
+ * read DSI header or data from the
+ * tcp/ip stream as it comes in
+ *
+ */
+ len = dsi_session[SessRefNum].lenleft;
+ ptr = dsi_session[SessRefNum].ptr;
+
+ if ((len = read(fd, ptr, len)) < 0) {
+ logit(0, "TCP/IP read() returned %d (errno %d)", len, errno);
+ dsiTCPIPCloseSession(SessRefNum, 0, 0, &comp);
+ *aspqe->comp = SessClosed;
+ return(len);
+ }
+
+ dsi_session[SessRefNum].lenleft -= len;
+ dsi_session[SessRefNum].ptr += len;
+
+ if (dsi_session[SessRefNum].lenleft > 0)
+ return(noErr);
+
+ /*
+ * sanity check
+ *
+ */
+ if (dsi_session[SessRefNum].lenleft < 0) {
+ logit(0, "mismatch in expected amount of read data");
+ dsiTCPIPCloseSession(SessRefNum, 0, 0, &comp);
+ *aspqe->comp = SessClosed;
+ return(-1);
+ }
+
+ hdr = &dsi_session[SessRefNum].hdr;
+
+ /*
+ * finished reading something, deal with it
+ *
+ */
+ switch (dsi_session[SessRefNum].state) {
+ case DSI_STATE_HDR:
+ /* now have a complete DSI hdr */
+ if (ntohl(hdr->dsi_data_len) > 0) {
+ /* and AFP hdr to follow */
+ ap = &aspqe->abr.proto.atp;
+ dsi_session[SessRefNum].ptr = ap->atpDataPtr;
+ if (hdr->dsi_command == DSIWrite && ntohl(hdr->dsi_err_offset) != 0)
+ dsi_session[SessRefNum].lenleft = ntohl(hdr->dsi_err_offset);
+ else
+ dsi_session[SessRefNum].lenleft = ntohl(hdr->dsi_data_len);
+ dsi_session[SessRefNum].state = DSI_STATE_AFP;
+ return(noErr);
+ break;
+ }
+ /* fall through */
+ case DSI_STATE_AFP:
+ /* have DSI hdr and optional AFP header */
+ dsi_session[SessRefNum].ptr = (char *)hdr;
+ dsi_session[SessRefNum].lenleft = sizeof(struct dsi_hdr);
+ if (hdr->dsi_flags == DSI_REQ_FLAG)
+ dsi_session[SessRefNum].state = DSI_STATE_REP;
+ else
+ dsi_session[SessRefNum].state = DSI_STATE_HDR;
+ break;
+ case DSI_STATE_DAT:
+ /* have all DSIWrite data, reset state, tell client */
+ dsi_session[SessRefNum].aspqe = NULL;
+ dsi_session[SessRefNum].ptr = (char *)hdr;
+ dsi_session[SessRefNum].lenleft = sizeof(struct dsi_hdr);
+ dsi_session[SessRefNum].state = DSI_STATE_REP;
+ *aspqe->ActRcvdReqLen = ntohl(hdr->dsi_data_len);
+ *aspqe->ActRcvdReqLen -= ntohl(hdr->dsi_err_offset);
+ *aspqe->comp = noErr;
+ delete_aspaqe(aspqe);
+ return(noErr);
+ break;
+ default:
+ /* huh ? */
+ break;
+ }
+
+ /*
+ * process DSI header and optional AFP data
+ *
+ */
+
+ #ifdef DEBUG_AFP_CMD
+ if (dbg != NULL) {
+ char *dsi_cmd();
+ fprintf(dbg, "<< AppleShareIP DSI header (PID %d, session #%d):\n",
+ getpid(), SessRefNum);
+ fprintf(dbg, "\tFlags: %02x (%s)\n", hdr->dsi_flags,
+ (hdr->dsi_flags == DSI_REQ_FLAG) ? "Request" : "Reply");
+ fprintf(dbg, "\tCommand: %02x (%s)\n", hdr->dsi_command,
+ dsi_cmd(hdr->dsi_command));
+ fprintf(dbg, "\tRequestID: %d\n", ntohs(hdr->dsi_requestID));
+ fprintf(dbg, "\tErrCode/DataOffset: %d\n", ntohl(hdr->dsi_err_offset));
+ fprintf(dbg, "\tDataLength: %d\n", ntohl(hdr->dsi_data_len));
+ fprintf(dbg, "\tReserved: %d\n\n\n", ntohl(hdr->dsi_reserved));
+ fflush(dbg);
+ }
+ #endif /* DEBUG_AFP_CMD */
+
+ /*
+ * reset tickle timer
+ *
+ */
+ dsi_session[SessRefNum].timeout = 0;
+
+ /*
+ * ignore packet replies, rely on TCP to
+ * deliver in-order, that's what it's for.
+ *
+ */
+ if (hdr->dsi_flags == DSI_REP_FLAG)
+ return(noErr);
+
+ /*
+ * must be request, check if incoming
+ * session ID is what we are expecting
+ *
+ */
+ if (ntohs(hdr->dsi_requestID) != dsi_session[SessRefNum].sess_id_in) {
+ logit(0, "unexpected incoming TCP/IP session ID");
+ *aspqe->comp = ParamErr;
+ return(-1);
+ }
+ dsi_session[SessRefNum].sess_id_in++;
+
+ /*
+ * only 3 valid commands to pass on to client
+ * handle DSITickle locally, 'cause it's simple
+ *
+ */
+ switch (hdr->dsi_command) {
+ case DSICommand:
+ case DSIWrite:
+ *aspqe->comp = noErr;
+ break;
+ case DSICloseSession:
+ *aspqe->comp = SessClosed;
+ break;
+ case DSITickle:
+ hdr->dsi_flags = DSI_REP_FLAG;
+ dsiTCPIPWrite(fd, hdr, NULL, 0);
+ dsi_session[SessRefNum].state = DSI_STATE_HDR;
+ return(noErr);
+ break;
+ default:
+ logit(0, "unexpected incoming DSI cond (%d)", hdr->dsi_command);
+ *aspqe->comp = ParamErr;
+ break;
+ }
+
+ /*
+ * tell the client how much data
+ * came in and the command type
+ *
+ */
+ if (hdr->dsi_command == DSIWrite && ntohl(hdr->dsi_err_offset) != 0)
+ *aspqe->ActRcvdReqLen = ntohl(hdr->dsi_err_offset);
+ else
+ *aspqe->ActRcvdReqLen = ntohl(hdr->dsi_data_len);
+ *aspqe->SPReqType = hdr->dsi_command;
+ *aspqe->ReqRefNum = aspqe;
+
+ /*
+ * free previous GetRequest aspqe
+ *
+ */
+ delete_aspaqe(aspqe);
+ dsi_session[SessRefNum].aspqe = NULL;
+
+ return(noErr);
+ }
+
+ /*
+ * fork and create new process to handle TCP/IP session
+ *
+ * SessRefNum - session reference number
+ * stickle - want server tickle
+ * ctickle - want client tickle
+ *
+ * In the server code (parent) close all but SLS
+ * In the child code forget about SLS, just listen
+ * for SSS requests
+ *
+ */
+
+ int
+ dsiTCPIPFork(SessRefNum, stickle, ctickle)
+ int SessRefNum;
+ int stickle;
+ int ctickle;
+ {
+ int i, pid;
+ ASPSSkt *sas;
+ extern int sqs;
+ ASPSkt *as, *bs;
+ extern int numasp;
+ private void dsiTCPIPTimer();
+
+ if ((as = aspskt_find_sessrefnum(SessRefNum)) == NULL)
+ return(-1);
+
+ if (as->state != SP_STARTED)
+ return(-1);
+
+ /*
+ * make a new process
+ *
+ */
+ if ((pid = fork()) < 0)
+ return(pid);
+
+ /*
+ * if in parent process:
+ * close SSS
+ *
+ * if in child process:
+ * close both SLS (AppleTalk and TCP/IP)
+ * start tickle timer for our client session
+ * stop tickle timers for sibling ATALK sessions
+ *
+ */
+ if (pid) {
+ /* close SSS */
+ if (as->ss != -1) {
+ fdunlisten(as->ss);
+ close(as->ss);
+ as->ss = -1;
+ }
+ as->state = SP_HALFCLOSED;
+ } else { /* in child */
+ if (as->type != SP_SERVER)
+ return(noErr);
+ /* close TCP/IP SLS */
+ dsiTCPIPCloseSLS();
+ /* kill sibling AT timeouts */
+ for (i = 0; i < numasp; i++) {
+ if (i != SessRefNum) {
+ if ((bs = aspskt_find_sessrefnum(i)) != NULL) {
+ if (bs->tickling)
+ stopasptickle(bs);
+ stop_ttimer(bs);
+ }
+ }
+ }
+ /* close AppleTalk SLS */
+ if ((sas = aspsskt_find_slsrefnum(as->SLSRefNum)) != NULL)
+ ATPCloseSocket(sas->addr.skt);
+ /* set a new read quantum */
+ sqs = DSI_SRVR_MAX;
+ /* start our tickle timer */
+ Timeout(dsiTCPIPTimer, numasp, DSI_TIMEOUT);
+ }
+
+ return(pid);
+ }
+
+ /*
+ * set up to wait for a request on TCP/IP SSS
+ *
+ * SessRefNum - session reference number
+ * ReqBuff - request command buffer
+ * ReqBuffSize - request command buffer size
+ * ReqRefNum - pointer to a special command block
+ * SPReqType - returns command request type
+ * ActRcvdReqLen - returns command length
+ * comp - completion flag/error
+ *
+ */
+
+ int
+ dsiTCPIPGetRequest(SessRefNum, ReqBuff, ReqBuffSize,
+ ReqRefNum, SPReqType, ActRcvdReqLen, comp)
+ int SessRefNum;
+ char *ReqBuff;
+ int ReqBuffSize;
+ ASPQE **ReqRefNum;
+ int *SPReqType;
+ int *ActRcvdReqLen;
+ int *comp;
+ {
+ ASPSkt *as;
+ atpProto *ap;
+ ASPQE *aspqe;
+
+ /*
+ * check state of connection
+ * and validity of descriptor
+ *
+ */
+ if ((as = aspskt_find_sessrefnum(SessRefNum)) == NULL) {
+ *comp = ParamErr;
+ return(ParamErr);
+ }
+ if (as->state != SP_STARTED) {
+ *comp = SessClosed;
+ return(SessClosed);
+ }
+ if (as->ss == -1) {
+ *comp = ParamErr;
+ return(ParamErr);
+ }
+
+ /*
+ * subsequent GetRequests from TREL_TIMEOUT code
+ * on this SessRefNum will never get a callback
+ * (because we don't need them for TCP/IP use)
+ *
+ */
+ if (dsi_session[SessRefNum].aspqe != NULL) {
+ *comp = 1;
+ return(noErr);
+ }
+
+ /*
+ * save GetRequest args for data arrival
+ *
+ */
+ aspqe = create_aspaqe();
+
+ aspqe->type = tSPGetRequest;
+ aspqe->SessRefNum = SessRefNum;
+ aspqe->ReqRefNum = ReqRefNum;
+ aspqe->SPReqType = SPReqType;
+ aspqe->ActRcvdReqLen = ActRcvdReqLen;
+ aspqe->comp = comp;
+
+ ap = &aspqe->abr.proto.atp;
+ ap->atpReqCount = ReqBuffSize;
+ ap->atpDataPtr = ReqBuff;
+
+ dsi_session[SessRefNum].aspqe = aspqe;
+
+ *comp = 1;
+ return(noErr);
+ }
+
+ /*
+ * arrange to put the 'read' data into Buffer
+ *
+ * SessRefNum - session reference number
+ * ReqRefNum - client connection details (addr, TID)
+ * Buffer - final location for data
+ * BufferSize - maximum amount of data we can handle
+ * ActLenRcvd - actual amount of date received
+ * atptimeout - ATP get data timeout
+ * comp - completion flag/error
+ *
+ */
+
+ dsiTCPIPWrtContinue(SessRefNum, ReqRefNum, Buffer,
+ BufferSize, ActLenRcvd, atptimeout, comp)
+ int SessRefNum;
+ ASPQE *ReqRefNum;
+ char *Buffer;
+ int BufferSize;
+ int *ActLenRcvd;
+ int atptimeout;
+ int *comp;
+ {
+ ASPSkt *as;
+ ASPQE *aspqe;
+ struct dsi_hdr *hdr;
+
+ /*
+ * sanity checks
+ *
+ */
+ if (BufferSize < 0) {
+ *comp = ParamErr;
+ return(ParamErr);
+ }
+ if ((as = aspskt_find_sessrefnum(SessRefNum)) == NULL) {
+ *comp = ParamErr;
+ return(ParamErr);
+ }
+ if (as->state != SP_STARTED) {
+ *comp = SessClosed;
+ return(SessClosed);
+ }
+ if (as->ss == -1) {
+ *comp = ParamErr;
+ return(ParamErr);
+ }
+
+ /*
+ * save WrtContinue args for
+ * completion of data arrival
+ *
+ */
+ aspqe = create_aspaqe();
+
+ aspqe->type = tSPWrtContinue;
+ aspqe->SessRefNum = SessRefNum;
+ aspqe->ActRcvdReqLen = ActLenRcvd;
+ aspqe->comp = comp;
+
+ /*
+ * reset state & continue data reads
+ *
+ */
+ hdr = &dsi_session[SessRefNum].hdr;
+ dsi_session[SessRefNum].aspqe = aspqe;
+ dsi_session[SessRefNum].state = DSI_STATE_DAT;
+ dsi_session[SessRefNum].lenleft = ntohl(hdr->dsi_data_len);
+ dsi_session[SessRefNum].lenleft -= ntohl(hdr->dsi_err_offset);
+ dsi_session[SessRefNum].ptr = Buffer;
+
+ *comp = 1;
+ return(noErr);
+ }
+
+ /*
+ * reply to a write request sent to our TCP/IP SSS
+ *
+ * SessRefNum - session reference number
+ * ReqRefNum - client connection details (addr, TID)
+ * CmdResult - return result
+ * CmdReplyData - return data
+ * CmdReplyDataSize - return data size
+ * comp - completion flag/error
+ *
+ */
+
+ int
+ dsiTCPIPWrtReply(SessRefNum, ReqRefNum, CmdResult,
+ CmdReplyData, CmdReplyDataSize, comp)
+ int SessRefNum;
+ ASPQE *ReqRefNum;
+ dword CmdResult;
+ char *CmdReplyData;
+ int CmdReplyDataSize;
+ int *comp;
+ {
+ return(dsiTCPIPReply(DSIWrite, SessRefNum, ReqRefNum,
+ CmdResult, CmdReplyData, CmdReplyDataSize, comp));
+ }
+
+ /*
+ * Reply to a command request sent to our TCP/IP SSS
+ *
+ * SessRefNum - session reference number
+ * ReqRefNum - client connection details (addr, TID)
+ * CmdResult - return result
+ * CmdReplyData - return data
+ * CmdReplyDataSize - return data size
+ * comp - completion flag/error
+ *
+ */
+
+ int
+ dsiTCPIPCmdReply(SessRefNum, ReqRefNum, CmdResult,
+ CmdReplyData, CmdReplyDataSize, comp)
+ int SessRefNum;
+ ASPQE *ReqRefNum;
+ dword CmdResult;
+ char *CmdReplyData;
+ int CmdReplyDataSize;
+ int *comp;
+ {
+ return(dsiTCPIPReply(DSICommand, SessRefNum, ReqRefNum,
+ CmdResult, CmdReplyData, CmdReplyDataSize, comp));
+ }
+
+ /*
+ * common reply code
+ *
+ */
+
+ int
+ dsiTCPIPReply(dsiType, SessRefNum, ReqRefNum, CmdResult,
+ CmdReplyData, CmdReplyDataSize, comp)
+ int dsiType;
+ int SessRefNum;
+ ASPQE *ReqRefNum;
+ dword CmdResult;
+ char *CmdReplyData;
+ int CmdReplyDataSize;
+ int *comp;
+ {
+ ASPSkt *as;
+ struct dsi_hdr hdr;
+
+ /*
+ * some sanity checking
+ *
+ */
+ if (CmdReplyDataSize < 0) {
+ *comp = ParamErr;
+ return(ParamErr);
+ }
+ if (CmdReplyDataSize > DSI_SRVR_MAX) {
+ *comp = SizeErr;
+ return(SizeErr);
+ }
+ if ((as = aspskt_find_sessrefnum(SessRefNum)) == NULL) {
+ *comp = ParamErr;
+ return(ParamErr);
+ }
+ if (as->state != SP_STARTED) {
+ *comp = ParamErr;
+ return(ParamErr);
+ }
+ if (as->ss == -1) {
+ *comp = ParamErr;
+ return(ParamErr);
+ }
+
+ /*
+ * setup DSI response header
+ * (the requestID is already
+ * in network byte order)
+ *
+ */
+ hdr.dsi_flags = DSI_REP_FLAG;
+ hdr.dsi_command = dsiType;
+ hdr.dsi_requestID = dsi_session[SessRefNum].hdr.dsi_requestID;
+ hdr.dsi_err_offset = htonl(CmdResult);
+ hdr.dsi_data_len = htonl(CmdReplyDataSize);
+ hdr.dsi_reserved = htonl(0x00000000);
+
+ /*
+ * session hdr can be re-used now
+ *
+ */
+ dsi_session[SessRefNum].state = DSI_STATE_HDR;
+
+ /*
+ * send it ...
+ *
+ */
+ if (dsiTCPIPWrite(as->ss, &hdr, CmdReplyData, CmdReplyDataSize) < 0) {
+ *comp = ParamErr;
+ return(ParamErr);
+ }
+
+ *comp = noErr;
+ return(noErr);
+ }
+
+ /*
+ * setup tickle timeout callback
+ *
+ */
+
+ int
+ dsiTCPIPTickleUserRoutine(SessRefNum, routine, arg)
+ int SessRefNum;
+ int (*routine)();
+ int arg;
+ {
+ ASPSkt *as;
+
+ if ((as = aspskt_find_sessrefnum(SessRefNum)) == NULL)
+ return(ParamErr);
+
+ as->tickle_timeout_user = routine;
+ as->ttu_arg = arg;
+
+ return(noErr);
+ }
+
+ /*
+ * Close down a TCP/IP Service Socket socket
+ *
+ * SessRefNum - Session reference number
+ * atpretries - ATP Retries
+ * atptimeout - ATP Timeout
+ * comp - completion flag/error
+ *
+ */
+
+ private struct dsi_hdr shut_hdr;
+
+ int
+ dsiTCPIPCloseSession(SessRefNum, atpretries, atptimeout, comp)
+ int SessRefNum;
+ int atpretries;
+ int atptimeout;
+ int *comp;
+ {
+ ASPSkt *as;
+
+ if ((as = aspskt_find_sessrefnum(SessRefNum)) == NULL) {
+ *comp = ParamErr;
+ return(ParamErr);
+ }
+
+ switch (as->state) {
+ case SP_STARTED:
+ break;
+ case SP_HALFCLOSED:
+ break;
+ default:
+ as->active = FALSE; /* aspskt_free(as); */
+ return(noErr);
+ break;
+ }
+
+ /*
+ * set up the DSI header
+ *
+ */
+ shut_hdr.dsi_flags = DSI_REQ_FLAG;
+ shut_hdr.dsi_command = DSICloseSession;
+ shut_hdr.dsi_requestID = htons(dsi_session[SessRefNum].sess_id_out++);
+ shut_hdr.dsi_err_offset = htonl(0x00000000);
+ shut_hdr.dsi_data_len = htonl(0x00000000);
+ shut_hdr.dsi_reserved = htonl(0x00000000);
+
+ /*
+ * and send it ...
+ *
+ */
+ if (dsiTCPIPWrite(as->ss, &shut_hdr, NULL, 0) < 0) {
+ *comp = ParamErr;
+ return(ParamErr);
+ }
+
+ as->state = SP_INACTIVE;
+ as->active = FALSE; /* aspskt_free(as); */
+
+ if (as->ss != -1) {
+ fdunlisten(as->ss);
+ close(as->ss);
+ as->ss = -1;
+ }
+
+ *comp = noErr;
+ return(noErr);
+ }
+
+ /*
+ * send a TCP/IP Attention signal to WSS
+ *
+ * SessRefNum - session reference number
+ * AttentionCode - attention message
+ * atpretries - ATP Retries
+ * atptimeout - ATP Timeout
+ * comp - completion falg/error
+ *
+ */
+
+ private struct dsi_hdr attn_hdr;
+
+ int
+ dsiTCPIPAttention(SessRefNum, AttentionCode, atpretries, atptimeout, comp)
+ int SessRefNum;
+ word AttentionCode;
+ int atpretries;
+ int *comp;
+ {
+ ASPSkt *as;
+ char attn[2];
+
+ /*
+ * some sanity checking
+ *
+ */
+ if (AttentionCode == 0x00) {
+ *comp = ParamErr;
+ return(ParamErr);
+ }
+ if ((as = aspskt_find_sessrefnum(SessRefNum)) == NULL) {
+ *comp = ParamErr;
+ return(ParamErr);
+ }
+ if (as->state == SP_STARTING) {
+ *comp = ParamErr;
+ return(ParamErr);
+ }
+
+ /*
+ * set up the DSI attention header,
+ *
+ */
+ attn_hdr.dsi_flags = DSI_REQ_FLAG;
+ attn_hdr.dsi_command = DSIAttention;
+ attn_hdr.dsi_requestID = htons(dsi_session[SessRefNum].sess_id_out++);
+ attn_hdr.dsi_err_offset = htonl(0x00000000);
+ attn_hdr.dsi_data_len = htonl(sizeof(attn));
+ attn_hdr.dsi_reserved = htonl(0x00000000);
+
+ /*
+ * the attention field
+ *
+ */
+ attn[0] = AttentionCode >> 8;
+ attn[1] = AttentionCode & 0xff;
+
+ /*
+ * and send it ...
+ *
+ */
+ if (dsiTCPIPWrite(as->ss, &attn_hdr, attn, sizeof(attn)) < 0) {
+ *comp = ParamErr;
+ return(ParamErr);
+ }
+
+ *comp = noErr;
+ return(noErr);
+ }
+
+ /*
+ * return peer name of session client
+ *
+ * (NB: function return value is positive TCP/IP port number,
+ * to distinguish this from a real AppleTalk GetNetworkInfo
+ * call which returns noErr. The IP address is returned in
+ * the four bytes of the AddrBlock)
+ *
+ */
+
+ int
+ dsiTCPIPGetNetworkInfo(SessRefNum, addr)
+ int SessRefNum;
+ AddrBlock *addr;
+ {
+ ASPSkt *as;
+ struct sockaddr_in name;
+ int len = sizeof(struct sockaddr);
+
+ if ((as = aspskt_find_sessrefnum(SessRefNum)) == NULL)
+ return(ParamErr);
+
+ if (as->ss == -1)
+ return(ParamErr);
+
+ if (getpeername(as->ss, (struct sockaddr *)&name, &len) != 0)
+ return(ParamErr);
+
+ if (name.sin_family != AF_INET)
+ return(ParamErr);
+
+ name.sin_addr.s_addr = ntohl(name.sin_addr.s_addr);
+ addr->net = ((name.sin_addr.s_addr & 0xff000000) >> 16);
+ addr->net |= ((name.sin_addr.s_addr & 0x00ff0000) >> 16);
+ addr->node = ((name.sin_addr.s_addr & 0x0000ff00) >> 8);
+ addr->skt = (name.sin_addr.s_addr & 0x000000ff);
+
+ return(ntohs(name.sin_port));
+ }
+
+ /*
+ * write data to client via TCP/IP stream
+ *
+ * We deliberately don't use non-blocking I/O
+ * because the majority of the large data transfers
+ * happen in a process dedicated to a single client.
+ *
+ */
+
+ int
+ dsiTCPIPWrite(fd, hdr, data, len)
+ int fd;
+ struct dsi_hdr *hdr;
+ char *data;
+ int len;
+ {
+ int cc, cd;
+
+ #ifdef DEBUG_AFP_CMD
+ if (dbg != NULL) {
+ char *dsi_cmd();
+ fprintf(dbg, ">> AppleShareIP DSI header (PID %d)\n", getpid());
+ fprintf(dbg, "\tFlags: %02x (%s)\n", hdr->dsi_flags,
+ (hdr->dsi_flags == DSI_REQ_FLAG) ? "Request" : "Reply");
+ fprintf(dbg, "\tCommand: %02x (%s)\n", hdr->dsi_command,
+ dsi_cmd(hdr->dsi_command));
+ fprintf(dbg, "\tRequestID: %d\n", ntohs(hdr->dsi_requestID));
+ fprintf(dbg, "\tErrCode/DataOffset: %d\n", ntohl(hdr->dsi_err_offset));
+ fprintf(dbg, "\tDataLength: %d\n", ntohl(hdr->dsi_data_len));
+ fprintf(dbg, "\tReserved: %d\n", ntohl(hdr->dsi_reserved));
+ fflush(dbg);
+ }
+ #endif /* DEBUG_AFP_CMD */
+
+ /*
+ * writev() is more efficient but
+ * is less portable than write()
+ *
+ */
+ #ifdef HAVE_WRITEV
+ { struct iovec iov[2];
+ iov[0].iov_base = (caddr_t)hdr;
+ iov[0].iov_len = sizeof(struct dsi_hdr);
+ iov[1].iov_base = (caddr_t)data;
+ iov[1].iov_len = len;
+ cc = writev(fd, iov, (data == NULL) ? 1 : 2);
+ }
+ #else /* HAVE_WRITEV */
+ if ((cc = write(fd, (char *)hdr, sizeof(struct dsi_hdr))) >= 0) {
+ if (data != NULL) {
+ if ((cd = write(fd, data, len)) >= 0)
+ cc += cd;
+ else
+ cc = cd;
+ }
+ }
+ #endif /* HAVE_WRITEV */
+
+ #ifdef DEBUG_AFP_CMD
+ if (dbg != NULL) {
+ extern int errno;
+ if (cc < 0)
+ fprintf(dbg, "** dsiTCPIPWrite(): %d bytes returns %d (errno %d)",
+ len+sizeof(struct dsi_hdr), cc, errno);
+ fprintf(dbg, "\n\n\n");
+ fflush(dbg);
+ }
+ #endif /* DEBUG_AFP_CMD */
+
+ return(cc);
+ }
+
+ /*
+ * Tickle Timeout timer
+ *
+ */
+
+ private void
+ dsiTCPIPTimer(numsess)
+ int numsess;
+ {
+ int i;
+ ASPSkt *as;
+ static int inited = 0;
+ static struct dsi_hdr tick_hdr;
+ void Timeout();
+
+ /*
+ * set-up the invariant
+ * fields of the tickle hdr
+ *
+ */
+ if (!inited) {
+ tick_hdr.dsi_flags = DSI_REQ_FLAG;
+ tick_hdr.dsi_command = DSITickle;
+ tick_hdr.dsi_err_offset = htonl(0x00000000);
+ tick_hdr.dsi_data_len = htonl(0x00000000);
+ tick_hdr.dsi_reserved = htonl(0x00000000);
+ inited = 1;
+ }
+
+ /*
+ * check for idle TCP/IP sessions
+ *
+ */
+ for (i = 0; i < numsess; i++) {
+ if (dsi_session[i].sesstype == DSI_SESSION_TCPIP) {
+ dsi_session[i].timeout += DSI_TIMEOUT;
+ if (dsi_session[i].timeout >= ASPCONNECTIONTIMEOUT) {
+ if ((as = aspskt_find_sessrefnum(i)) != NULL) {
+ if (as->tickle_timeout_user != NULL)
+ (*as->tickle_timeout_user)(i, as->ttu_arg);
+ else { /* no user routine */
+ as->state = SP_INACTIVE;
+ as->active = FALSE; /* aspskt_free(as); */
+ dsiShutdown(i);
+ }
+ }
+ } else { /* not timed out, but time to send a tickle ? */
+ if ((dsi_session[i].timeout % (ASPTICKLETIMEOUT)) == 0) {
+ if ((as = aspskt_find_sessrefnum(i)) != NULL) {
+ tick_hdr.dsi_requestID = htons(dsi_session[i].sess_id_out++);
+ dsiTCPIPWrite(as->ss, &tick_hdr, NULL, 0);
+ }
+ }
+ }
+ }
+ }
+
+ Timeout(dsiTCPIPTimer, numsess, DSI_TIMEOUT);
+
+ return;
+ }
+
+ /*
+ * close the SLS (called from either the
+ * AppleTalk or TCP/IP child processes)
+ *
+ */
+
+ int
+ dsiTCPIPCloseSLS()
+ {
+ if (slsskt != -1) {
+ fdunlisten(slsskt);
+ close(slsskt);
+ slsskt = -1;
+ }
+
+ return(noErr);
+ }
+
+ /*
+ * IP address filter
+ *
+ * compatible with, and stolen from,
+ * the ARNS remote access package
+ *
+ * http://www.cs.mu.OZ.AU/appletalk/atalk.html
+ *
+ */
+
+ private int ipFilters = 0;
+ private struct ipFilter *ipFilter = NULL;
+
+ /*
+ * read the specified IP address filter file
+ *
+ */
+
+ private void
+ dsiTCPIPBuildFilterList()
+ {
+ FILE *fp;
+ char line[160];
+ char *mask, *addr;
+ unsigned long inet_addr();
+
+ ipFilters = 0;
+
+ if (dsiTCPIPFilter != NULL) {
+ if (ipFilter == NULL)
+ if ((ipFilter =
+ (struct ipFilter *)malloc(MAXIPFILTSIZ*MAXIPFILTERS)) == NULL)
+ return;
+ if ((fp = fopen(dsiTCPIPFilter, "r")) != NULL) {
+ while (fgets(line, sizeof(line), fp) != NULL) {
+ if (line[0] == '#')
+ continue;
+ if ((mask = (char *)index(line, '\n')) != NULL)
+ *mask = '\0';
+ mask = line+1;
+ while (*mask != '\0' && isspace(*mask))
+ mask++; /* skip spaces */
+ addr = mask;
+ while (*addr != '\0' && !isspace(*addr))
+ addr++; /* skip mask */
+ while (*addr != '\0' && isspace(*addr))
+ addr++; /* skip spaces */
+ if (line[0] == '+' || line[0] == '*' || line[0] == '-') {
+ ipFilter[ipFilters].perm = line[0];
+ ipFilter[ipFilters].addr = (*addr == '\0') ? 0L : inet_addr(addr);
+ ipFilter[ipFilters].mask = (*mask == '\0') ? 0L : inet_addr(mask);
+ if (++ipFilters >= MAXIPFILTERS)
+ break;
+ }
+ }
+ (void)fclose(fp);
+ }
+ }
+
+ return;
+ }
+
+ /*
+ * check the IP address filter, if any
+ *
+ */
+
+ private int
+ dsiTCPIPIllegalIP(from)
+ struct sockaddr_in *from;
+ {
+ int i;
+ u_long addr;
+
+ dsiTCPIPBuildFilterList();
+
+ if (ipFilters == 0
+ || ipFilter == NULL)
+ return(0);
+
+ addr = from->sin_addr.s_addr;
+
+ for (i = 0 ; i < ipFilters ; i++) {
+ if (ipFilter[i].addr != 0L) {
+ if ((addr & ipFilter[i].mask) == ipFilter[i].addr)
+ return(ipFilter[i].perm == '-');
+ } else {
+ if ((addr & ipFilter[i].mask) == addr)
+ return(ipFilter[i].perm == '-');
+ }
+ }
+
+ return(0);
+ }
*** applications/aufs/afpdt.c.orig Wed Sep 25 00:10:20 1996
--- applications/aufs/afpdt.c Mon Jul 7 17:01:14 1997
***************
*** 1170,1176 ****
PrintIconInfo(adi.adi_fcreator,adi.adi_ftype);
}
! err = SPWrtContinue(cno,reqref,icon,adi.adi_iconsize,&rcvlen,-1,&comp);
if (err != noErr) {
free((char *)icon);
return(err);
--- 1170,1176 ----
PrintIconInfo(adi.adi_fcreator,adi.adi_ftype);
}
! err = dsiWrtContinue(cno,reqref,icon,adi.adi_iconsize,&rcvlen,-1,&comp);
if (err != noErr) {
free((char *)icon);
return(err);
*** applications/aufs/afpfork.c.orig Wed Sep 25 00:09:33 1996
--- applications/aufs/afpfork.c Mon Jul 7 17:43:35 1997
***************
*** 585,591 ****
return(aeAccessDenied);
}
! err = SPWrtContinue(cno,reqref,r,n_rrpkts*atpMaxData,&rcvlen,-1,&comp);
if (err != noErr)
return(err);
do { abSleep(4,TRUE); } while (comp > 0);
--- 585,591 ----
return(aeAccessDenied);
}
! err = dsiWrtContinue(cno,reqref,r,n_rrpkts*atpMaxData,&rcvlen,-1,&comp);
if (err != noErr)
return(err);
do { abSleep(4,TRUE); } while (comp > 0);
*** applications/aufs/afpos.c.orig Wed Sep 25 00:10:24 1996
--- applications/aufs/afpos.c Wed Jul 9 11:39:02 1997
***************
*** 766,772 ****
--- 766,776 ----
msg[i] = '\r';
}
close(fd);
+ return(noErr);
}
+
+ sprintf(msg, "<no path to message file>");
+
return(noErr);
}
*** applications/aufs/afps.h.orig Wed Sep 25 00:10:19 1996
--- applications/aufs/afps.h Mon Mar 3 22:14:05 1997
***************
*** 247,252 ****
--- 247,253 ----
#define AFPVersion1DOT1 110
#define AFPVersion2DOT0 200
#define AFPVersion2DOT1 210
+ #define AFPVersion2DOT2 220
#ifdef APPLICATION_MANAGER
struct flist {
*** applications/aufs/afpserver.c.orig Wed Sep 25 00:10:23 1996
--- applications/aufs/afpserver.c Wed Jul 9 10:44:28 1997
***************
*** 47,52 ****
--- 47,54 ----
/* assume included by param.h */
# include <sys/types.h>
#endif
+ #include <sys/socket.h>
+ #include <netdb.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <netat/appletalk.h>
***************
*** 97,103 ****
private char *afpmtyp = "Unix";
! #define AFPVERSZ (5*16) /* room for IndStr hold all versions */
/* define 1 more than needed just in case */
struct afpversionstruct {
char *version_name;
--- 99,105 ----
private char *afpmtyp = "Unix";
! #define AFPVERSZ (6*16) /* room for IndStr hold all versions */
/* define 1 more than needed just in case */
struct afpversionstruct {
char *version_name;
***************
*** 107,112 ****
--- 109,115 ----
{"AFPVersion 1.1", AFPVersion1DOT1},
{"AFPVersion 2.0", AFPVersion2DOT0},
{"AFPVersion 2.1", AFPVersion2DOT1},
+ {"AFP2.2", AFPVersion2DOT2},
{NULL, AFPVersionUnknown}
};
***************
*** 216,221 ****
--- 219,229 ----
private DumpBuf(), clockstart(), clockend();
+ private struct sig {
+ byte filler[8];
+ struct timeval s_time;
+ } sig;
+
#ifdef LOGIN_AUTH_PROG
extern char *srvrname; /* NBP registered name of server */
extern char *login_auth_prog; /* name of authorization program */
***************
*** 254,259 ****
--- 262,271 ----
#ifdef STAT_CACHE
OSStatInit(); /* init stat cache */
#endif STAT_CACHE
+
+ /* init server signature */
+ bzero((char *)&sig, sizeof(struct sig));
+ gettimeofday(&sig.s_time, NULL);
}
/*
***************
*** 968,974 ****
fprintf(dbg, "\tMsgTyp: %04x\t", smrp.msgr_typ);
fprintf(dbg, "(%s)\n", (smrp.msgr_typ == 0) ? "Login" : "Server");
fprintf(dbg, "\tMsgBMp: %04x\n", smrp.msgr_bitmap);
! dbg_print_name("\tMsgStr:", smrp.msgr_data);
fflush(dbg);
}
#endif /* DEBUG_AFP_CMD */
--- 980,986 ----
fprintf(dbg, "\tMsgTyp: %04x\t", smrp.msgr_typ);
fprintf(dbg, "(%s)\n", (smrp.msgr_typ == 0) ? "Login" : "Server");
fprintf(dbg, "\tMsgBMp: %04x\n", smrp.msgr_bitmap);
! fprintf(dbg, "\tMsgStr: %s\n", smrp.msgr_data);
fflush(dbg);
}
#endif /* DEBUG_AFP_CMD */
***************
*** 1035,1040 ****
--- 1047,1055 ----
}
#endif
+ #define MAXNADSIZ 8 /* tag #2, IP addr & port */
+ #define NUMNAD 5 /* no more than 5 IP addr/host */
+
int
GetSrvrInfo(r,sname,icon,iconsize)
byte *r;
***************
*** 1042,1068 ****
byte icon[];
int iconsize;
{
int i,len;
extern int nopwdsave;
GetSrvrInfoReplyPkt sr;
byte avobuf[AFPVERSZ],uamobuf[AFPUAMSZ];
! OPTRType avo,uamo,vicono;
! strcpy(sr.sr_machtype,afpmtyp);
! cpyc2pstr(sr.sr_servername,sname);
! /* set server capabilities */
sr.sr_flags = SupportsFPCopyFile;
#ifdef DISTRIB_PASSWDS
sr.sr_flags |= SupportsChgPwd;
#endif DISTRIB_PASSWDS
sr.sr_flags |= SupportsServerMsgs;
if (nopwdsave)
sr.sr_flags |= DontAllowSavePwd;
vicono.optr_loc = icon;
vicono.optr_len = iconsize;
sr.sr_vicono = (char *) &vicono;
IniIndStr(avobuf);
for (i = 0; afpversions[i].version_name != NULL; i++)
AddIndStr(afpversions[i].version_name, avobuf);
--- 1057,1109 ----
byte icon[];
int iconsize;
{
+ byte *q;
int i,len;
extern int nopwdsave;
GetSrvrInfoReplyPkt sr;
+ OPTRType avo,uamo,vicono,sigo,nado;
byte avobuf[AFPVERSZ],uamobuf[AFPUAMSZ];
! byte nadbuf[MAXNADSIZ*NUMNAD+1];
! extern u_short asip_port;
! extern u_int asip_addr;
! extern int asip_enable;
! struct hostent *he;
! char hostname[128];
! /*
! * set server capabilities
! *
! */
sr.sr_flags = SupportsFPCopyFile;
#ifdef DISTRIB_PASSWDS
sr.sr_flags |= SupportsChgPwd;
#endif DISTRIB_PASSWDS
sr.sr_flags |= SupportsServerMsgs;
+ sr.sr_flags |= SupportsServerSig;
+ if (asip_enable)
+ sr.sr_flags |= SupportsTCPIP;
if (nopwdsave)
sr.sr_flags |= DontAllowSavePwd;
+ /*
+ * set Server Name & Machine Type
+ *
+ */
+ strcpy(sr.sr_machtype,afpmtyp);
+ cpyc2pstr(sr.sr_servername,sname);
+
+ /*
+ * set Volume Icon & Mask
+ *
+ */
vicono.optr_loc = icon;
vicono.optr_len = iconsize;
sr.sr_vicono = (char *) &vicono;
+ /*
+ * set AFP Versions
+ *
+ */
IniIndStr(avobuf);
for (i = 0; afpversions[i].version_name != NULL; i++)
AddIndStr(afpversions[i].version_name, avobuf);
***************
*** 1070,1075 ****
--- 1111,1120 ----
avo.optr_loc = avobuf;
sr.sr_avo = (byte *) &avo;
+ /*
+ * set UAMs
+ *
+ */
IniIndStr(uamobuf);
for (i=0 ; i < numuam; i++)
AddIndStr(afpuams[i].uamname, uamobuf);
***************
*** 1077,1082 ****
--- 1122,1191 ----
uamo.optr_loc = uamobuf;
sr.sr_uamo = (byte *) &uamo;
+ /*
+ * set server signature
+ *
+ */
+ sigo.optr_len = 16;
+ sigo.optr_loc = (byte *)&sig;
+ sr.sr_sigo = (byte *)&sigo;
+
+ /*
+ * set network address(es)
+ * use single bound address (-B <addr:port>)
+ * or all known addresses for this machine
+ *
+ */
+ q = nadbuf+1;
+ nadbuf[0] = 0;
+ if (asip_enable) {
+ if (asip_addr) {
+ nadbuf[0] = 1;
+ q[2] = (asip_addr >> 24) & 0xff;
+ q[3] = (asip_addr >> 16) & 0xff;
+ q[4] = (asip_addr >> 8) & 0xff;
+ q[5] = (asip_addr & 0xff);
+ if (asip_port == ASIP_PORT) {
+ q[0] = 0x06; /* len */
+ q[1] = 0x01; /* tag */
+ q += 6;
+ } else {
+ q[0] = 0x08; /* len */
+ q[1] = 0x02; /* tag */
+ q[6] = asip_port >> 8;
+ q[7] = asip_port & 0xff;
+ q += 8;
+ }
+ } else { /* list all known addresses */
+ if (gethostname(hostname, sizeof(hostname)) == 0) {
+ if ((he = gethostbyname(hostname)) != NULL) {
+ for (i = 0; he->h_addr_list[i] && i < NUMNAD; i++) {
+ bcopy(he->h_addr_list[i], q+2, 4); /* copy IP */
+ if (asip_port == ASIP_PORT) {
+ q[0] = 0x06; /* len */
+ q[1] = 0x01; /* tag */
+ q += 6;
+ } else {
+ q[0] = 0x08; /* len */
+ q[1] = 0x02; /* tag */
+ q[6] = asip_port >> 8;
+ q[7] = asip_port & 0xff;
+ q += 8;
+ }
+ }
+ nadbuf[0] = i;
+ }
+ }
+ }
+ }
+ nado.optr_len = q-nadbuf;
+ nado.optr_loc = nadbuf;
+ sr.sr_naddro = (byte *)&nado;
+
+ /*
+ * pack data for sending
+ *
+ */
len = htonPackX(ProtoSRP,(byte *) &sr,r);
#ifdef DEBUG_AFP_CMD
***************
*** 1389,1395 ****
int i;
byte *q = r;
u_short srvrflags;
! short machoff, afpoff, uamoff, vicnoff;
void dbg_print_name();
void dbg_print_sflg();
void dbg_print_icon();
--- 1498,1505 ----
int i;
byte *q = r;
u_short srvrflags;
! short machoff, afpoff, uamoff;
! short vicnoff, sigoff, nadoff;
void dbg_print_name();
void dbg_print_sflg();
void dbg_print_icon();
***************
*** 1402,1410 ****
fprintf(dbg, "\tUAMOff: %d\n", uamoff);
vicnoff = get2(q); q += 2;
fprintf(dbg, "\tICNOff: %d\n", vicnoff);
! fprintf(dbg, "\tVolFlg: %04x\t", (srvrflags = get2(q))); q += 2;
dbg_print_sflg(srvrflags);
dbg_print_name("\tSrvrNm:", q);
if (machoff != 0)
dbg_print_name("\tMchTyp:", r+machoff);
if (afpoff != 0) {
--- 1512,1528 ----
fprintf(dbg, "\tUAMOff: %d\n", uamoff);
vicnoff = get2(q); q += 2;
fprintf(dbg, "\tICNOff: %d\n", vicnoff);
! srvrflags = get2(q); q += 2;
! fprintf(dbg, "\tVolFlg: %04x\t", srvrflags);
dbg_print_sflg(srvrflags);
dbg_print_name("\tSrvrNm:", q);
+ q += ((*q)+1);
+ if ((u_long)q & 0x01)
+ q++; /* even */
+ sigoff = get2(q); q += 2;
+ fprintf(dbg, "\tSIGOff: %d\n", sigoff);
+ nadoff = get2(q); q += 2;
+ fprintf(dbg, "\tNADOff: %d\n", nadoff);
if (machoff != 0)
dbg_print_name("\tMchTyp:", r+machoff);
if (afpoff != 0) {
***************
*** 1412,1418 ****
fprintf(dbg, "\tVerCnt: %d\n", (int)(*q));
for (i = *q++; i > 0; i--) {
dbg_print_name("\tAFPVer:", q);
! q += ((*q) + 1);
}
} else
fprintf(dbg, "\t<no AFP>\n");
--- 1530,1536 ----
fprintf(dbg, "\tVerCnt: %d\n", (int)(*q));
for (i = *q++; i > 0; i--) {
dbg_print_name("\tAFPVer:", q);
! q += ((*q) + 1);
}
} else
fprintf(dbg, "\t<no AFP>\n");
***************
*** 1431,1436 ****
--- 1549,1588 ----
fprintf(dbg, "\n");
} else
fprintf(dbg, "\t<no ICON>\n");
+ if (sigoff != 0) {
+ q = r + sigoff;
+ fprintf(dbg, "\tSrvSIG: ");
+ for (i = 0; i < 16; i++)
+ fprintf(dbg, "%02x ", *(q+i));
+ fprintf(dbg, "\n");
+ } else
+ fprintf(dbg, "\t<no SIG>\n");
+ if (nadoff != 0) {
+ q = r + nadoff;
+ fprintf(dbg, "\tNADCnt: %d\n", (int)(*q));
+ for (i = *q++; i > 0; i--) {
+ fprintf(dbg, "\tAFPNAD: len %d tag %d ", q[0], q[1]);
+ switch (q[1]) {
+ case 0x01:
+ fprintf(dbg, "IP %d.%d.%d.%d\n",
+ q[2], q[3], q[4], q[5]);
+ break;
+ case 0x02:
+ fprintf(dbg, "IP %d.%d.%d.%d Port %d\n",
+ q[2], q[3], q[4], q[5], (q[6] << 8) | q[7]);
+ break;
+ case 0x03:
+ fprintf(dbg, "DDP net %d.%d node %d skt %d\n",
+ q[2], q[3], q[4], q[5]);
+ break;
+ default:
+ fprintf(dbg, "<unknown>\n");
+ break;
+ }
+ q += q[0];
+ }
+ } else
+ fprintf(dbg, "\t<no NAD>\n");
return;
}
***************
*** 1475,1485 ****
bmap &= ~(0x0001 << i);
switch (i) {
case 0:
! fprintf(dbg, "SuppCopyFile");
j++;
break;
case 1:
! fprintf(dbg, "SuppChngPass");
j++;
break;
case 2:
--- 1627,1637 ----
bmap &= ~(0x0001 << i);
switch (i) {
case 0:
! fprintf(dbg, "CopyFile");
j++;
break;
case 1:
! fprintf(dbg, "ChngPass");
j++;
break;
case 2:
***************
*** 1487,1497 ****
j++;
break;
case 3:
! fprintf(dbg, "SuppSrvrMesg");
j++;
break;
case 15:
! fprintf(dbg, "SuppMGetReqs");
j++;
break;
default:
--- 1639,1661 ----
j++;
break;
case 3:
! fprintf(dbg, "SrvrMesg");
! j++;
! break;
! case 4:
! fprintf(dbg, "SrvrSig");
! j++;
! break;
! case 5:
! fprintf(dbg, "TCP/IP");
! j++;
! break;
! case 6:
! fprintf(dbg, "SrvrNotf");
j++;
break;
case 15:
! fprintf(dbg, "MGetReqs");
j++;
break;
default:
*** applications/aufs/aufs.c.orig Wed Sep 25 00:10:19 1996
--- applications/aufs/aufs.c Fri Jul 11 19:29:43 1997
***************
*** 91,96 ****
--- 91,100 ----
export u_char *srvrtype = (u_char *)AFSTYPE; /* NBP registered type */
export char *messagefile = NULL; /* AFP2.1 GetSrvrMsg srvr msg filename */
export char *motdfile = NULL; /* AFP2.1 GetSrvrMsg login msg filename */
+ export char *dsiTCPIPFilter = NULL; /* AFP2.2 AppleShareIP address filter */
+ export u_int asip_addr = INADDR_ANY; /* AFP2.2 AppleShare over TCP/IP */
+ export u_short asip_port = ASIP_PORT; /* AFP2.2 AppleShare TCP/IP port */
+ export int asip_enable = FALSE; /* AFP2.2 AppleShare TCP/IP default off */
private char *sysvolfile = NULL; /* system afpvols file */
private char *passwdlookaside = NULL; /* local password file??? */
***************
*** 240,245 ****
--- 244,252 ----
fprintf(stderr,"\t-V VolsFile for server wide afp volumes\n");
fprintf(stderr,"\t-G <username> to set guest id for <anonymous> logins\n");
fprintf(stderr,"\t-P LookAsidePasswordFile for scrambled transactions\n");
+ fprintf(stderr,"\t-T enable AFP connections via TCP/IP (default addr)\n");
+ fprintf(stderr,"\t-B <addr[:port]> enable AFP over TCP/IP & set address\n");
+ fprintf(stderr,"\t-f <filterfile> set the AFP over TCP-IP address filter\n");
fprintf(stderr,"\t-U <number> to allow <number> sessions\n");
fprintf(stderr,"\t-m|M <file> specifies login or server message file\n");
#ifndef STAT_CACHE
***************
*** 297,307 ****
char **argv;
{
int c;
u_char *parsename();
extern char *optarg;
extern int optind;
extern boolean dochecksum;
! static char optlist[64] = "a:d:D:n:N:t:kpsuV:U:G:P:c:l:z:S:R:M:m:";
#ifdef ISO_TRANSLATE
void cISO2Mac();
#endif ISO_TRANSLATE
--- 304,315 ----
char **argv;
{
int c;
+ char *p;
u_char *parsename();
extern char *optarg;
extern int optind;
extern boolean dochecksum;
! static char optlist[100] = "a:B:d:f:D:n:N:t:kpsTuV:U:G:P:c:l:z:S:R:M:m:";
#ifdef ISO_TRANSLATE
void cISO2Mac();
#endif ISO_TRANSLATE
***************
*** 388,393 ****
--- 396,417 ----
if (!SetPktTrace(optarg))
usage(argv[0]);
break;
+ case 'f': /* AppleShareIP IP address filter */
+ dsiTCPIPFilter = optarg;
+ break;
+ case 'B': /* Bind AppleShare TCP/IP address */
+ if ((p = (char *)index(optarg, ':')) != NULL) {
+ asip_port = atoi(p+1);
+ *p = '\0';
+ }
+ if ((asip_addr = (u_int)ntohl(inet_addr(optarg))) == -1)
+ asip_addr = INADDR_ANY;
+ if (p != NULL)
+ *p = ':';
+ /* fall through */
+ case 'T': /* Enable AppleShare TCP/IP */
+ asip_enable = TRUE;
+ break;
case 'V': /* system afpvols file */
sysvolfile = optarg;
break;
***************
*** 688,693 ****
--- 712,722 ----
if ((ctp_stack = (int *)malloc(sizeof(int)*maxsess)) == NULL) {
logit(0,"couldn't malloc stack for pid recording, fatal!");
}
+ if (asip_enable)
+ if (asip_addr != INADDR_ANY)
+ logit(0,"AFP over TCP/IP enabled (IP %08x Port %d)",asip_addr,asip_port);
+ else
+ logit(0,"AFP over TCP/IP enabled (IP INADDR_ANY Port %d)", asip_port);
#ifdef LWSRV_AUFS_SECURITY
if (userlogindir != NULL) { /* budd... */
logit(0,"Aufs: user login database in %s", userlogindir);
***************
*** 725,731 ****
if (n_rrpkts < atpMaxNum)
logit(0,"remote limited to %d packet%s in a response", n_rrpkts,
n_rrpkts > 1 ? "s" : "");
! SPGetParms(&mcs, &qs);
if (DBDEB)
printf("Command buffer size is %d, Quantum size is %d\n", mcs, qs);
buf = (byte *)malloc(mcs);
--- 754,760 ----
if (n_rrpkts < atpMaxNum)
logit(0,"remote limited to %d packet%s in a response", n_rrpkts,
n_rrpkts > 1 ? "s" : "");
! dsiGetParms(&mcs, &qs);
if (DBDEB)
printf("Command buffer size is %d, Quantum size is %d\n", mcs, qs);
buf = (byte *)malloc(mcs);
***************
*** 783,798 ****
PrtSrvrInfo(srvinfo,srvinfolen);
/* Init asp */
! err = SPInit(&addr,srvinfo,srvinfolen,&slsref);
if (err != noErr) {
! logit(0,"SPInit failed with code %d, fatal",err);
exit(0);
}
logit(0,"Aufs Starting (%s)",srvrname);
if (sysvolfile)
logit(0,"System vols in '%s'",sysvolfile);
! logit(0,"SPInit Completed. Waiting for connection...");
#ifndef NOSHUTDOWNCODE
# ifndef NOPGRP
--- 812,827 ----
PrtSrvrInfo(srvinfo,srvinfolen);
/* Init asp */
! err = dsiInit(&addr,srvinfo,srvinfolen,&slsref);
if (err != noErr) {
! logit(0,"dsiInit failed with code %d, fatal",err);
exit(0);
}
logit(0,"Aufs Starting (%s)",srvrname);
if (sysvolfile)
logit(0,"System vols in '%s'",sysvolfile);
! logit(0,"dsiInit Completed. Waiting for connection...");
#ifndef NOSHUTDOWNCODE
# ifndef NOPGRP
***************
*** 819,825 ****
do {
pid = -1; /* make sure zero at start */
! SPGetSession(slsref,&cno,&comp);
if (comp > 0)
logit(0,"Waiting for session %d to activate", cno);
/* won't wait if we set comp above */
--- 848,854 ----
do {
pid = -1; /* make sure zero at start */
! dsiGetSession(slsref,&cno,&comp);
if (comp > 0)
logit(0,"Waiting for session %d to activate", cno);
/* won't wait if we set comp above */
***************
*** 848,855 ****
sesscount++;
logit(0,"New session %d started on server socket %d, count %d",
cno,slsref,sesscount);
! if ((err = SPGetNetworkInfo(cno, &addr)) != noErr) {
! logit(0,"Get Network info failed with error %d", err);
} else {
#ifdef AUTHENTICATE
err = (authenticate(ntohs(addr.net), addr.node)) ? noErr : ~noErr;
--- 877,889 ----
sesscount++;
logit(0,"New session %d started on server socket %d, count %d",
cno,slsref,sesscount);
! if ((err = dsiGetNetworkInfo(cno, &addr)) != noErr) {
! if (err > 0) { /* AppleShareIP session */
! logit(0,"Session %d from [IP addr %d.%d.%d.%d, port %d]",
! cno, addr.net>>8, addr.net&0xff, addr.node, addr.skt, err);
! err = noErr;
! } else
! logit(0,"Get Network info failed with error %d", err);
} else {
#ifdef AUTHENTICATE
err = (authenticate(ntohs(addr.net), addr.node)) ? noErr : ~noErr;
***************
*** 864,870 ****
}
#ifdef AUTHENTICATE
if(err != noErr) {
! SPCloseSession(cno, 1, 1, &comp2);
continue;
}
#endif AUTHENTICATE
--- 898,904 ----
}
#ifdef AUTHENTICATE
if(err != noErr) {
! dsiCloseSession(cno, 1, 1, &comp2);
continue;
}
#endif AUTHENTICATE
***************
*** 889,898 ****
# endif NOSHUTDOWNCODE;
#endif NOSIGMASK
/* fork on connection - only tickle from parent */
! if ((pid = SPFork(cno, TRUE, FALSE)) < 0) {
! logit(0,"SPFork failed on session %d, last system error %d",cno, errno);
/* try to close, but don't worry too much */
! SPCloseSession(cno, 1, 1, &comp2);
#ifdef NOSIGMASK
sigrelse(SIGCHLD);
sigrelse(SIGHUP);
--- 923,932 ----
# endif NOSHUTDOWNCODE;
#endif NOSIGMASK
/* fork on connection - only tickle from parent */
! if ((pid = dsiFork(cno, TRUE, FALSE)) < 0) {
! logit(0,"dsiFork failed on session %d, last system error %d",cno,errno);
/* try to close, but don't worry too much */
! dsiCloseSession(cno, 1, 1, &comp2);
#ifdef NOSIGMASK
sigrelse(SIGCHLD);
sigrelse(SIGHUP);
***************
*** 905,912 ****
#endif NOSIGMASK
continue;
}
if (pid) {
- SPTickleUserRoutine(cno, timedout, pid);
logit(0,"pid %d starting for session %d",pid, cno);
addinferior(cno, pid); /* addinferior scans (phew) */
} else {
--- 939,946 ----
#endif NOSIGMASK
continue;
}
+ dsiTickleUserRoutine(cno, timedout, pid);
if (pid) {
logit(0,"pid %d starting for session %d",pid, cno);
addinferior(cno, pid); /* addinferior scans (phew) */
} else {
***************
*** 997,1003 ****
umask(0); /* file creates have explict modes */
for (;;) {
#ifndef TREL_TIMEOUT
! SPGetRequest(cno,buf,mcs,&reqref,&type,&rlen,&comp);
while (comp > 0) {
abSleep(sectotick(60),TRUE);
#ifdef AUFS_IDLE_TIMEOUT
--- 1031,1037 ----
umask(0); /* file creates have explict modes */
for (;;) {
#ifndef TREL_TIMEOUT
! dsiGetRequest(cno,buf,mcs,&reqref,&type,&rlen,&comp);
while (comp > 0) {
abSleep(sectotick(60),TRUE);
#ifdef AUFS_IDLE_TIMEOUT
***************
*** 1016,1022 ****
}
if (comp1 <= 0) {
! SPGetRequest(cno,buf1,mcs,&reqref1,&type1,&rlen1,&comp1);
while (comp1 > 0) {
abSleep(sectotick(60),TRUE);
#ifdef AUFS_IDLE_TIMEOUT
--- 1050,1056 ----
}
if (comp1 <= 0) {
! dsiGetRequest(cno,buf1,mcs,&reqref1,&type1,&rlen1,&comp1);
while (comp1 > 0) {
abSleep(sectotick(60),TRUE);
#ifdef AUFS_IDLE_TIMEOUT
***************
*** 1034,1043 ****
}
#ifndef TREL_TIMEOUT
if (comp < 0) {
! logit(0,"SPGetRequest failed %d",comp);
#else TREL_TIMEOUT
if (comp1 < 0) {
! logit(0,"SPGetRequest failed %d",comp1);
#endif TREL_TIMEOUT
continue;
}
--- 1068,1077 ----
}
#ifndef TREL_TIMEOUT
if (comp < 0) {
! logit(0,"dsiGetRequest failed %d",comp);
#else TREL_TIMEOUT
if (comp1 < 0) {
! logit(0,"dsiGetRequest failed %d",comp1);
#endif TREL_TIMEOUT
continue;
}
***************
*** 1079,1108 ****
}
#ifndef TREL_TIMEOUT
if (type == aspWrite)
! SPWrtReply(cno,reqref,(dword) err,rspbuf,rsplen,&comp);
#else TREL_TIMEOUT
if (type1 == aspWrite)
! SPWrtReply(cno,reqref1,(dword) err,rspbuf1,rsplen1,&comp1);
#endif TREL_TIMEOUT
else
#ifndef TREL_TIMEOUT
! SPCmdReply(cno,reqref,(dword) err,rspbuf,rsplen,&comp);
while (comp > 0) {
abSleep(sectotick(60),TRUE);
}
if (DBSRV)
printf("done\n");
#else TREL_TIMEOUT
! SPCmdReply(cno,reqref1,(dword) err,rspbuf1,rsplen1,&comp1);
#endif TREL_TIMEOUT
break;
case aspCloseSession:
logit(0,"Closing ASP Session...");
#ifndef TREL_TIMEOUT
! SPCloseSession(cno,10,3,&comp); /* 5 times, .75 seconds */
while (comp > 0)
#else TREL_TIMEOUT
! SPCloseSession(cno,10,3,&comp1); /* 5 times, .75 seconds */
while (comp1 > 0)
#endif TREL_TIMEOUT
abSleep(1, TRUE);
--- 1113,1142 ----
}
#ifndef TREL_TIMEOUT
if (type == aspWrite)
! dsiWrtReply(cno,reqref,(dword) err,rspbuf,rsplen,&comp);
#else TREL_TIMEOUT
if (type1 == aspWrite)
! dsiWrtReply(cno,reqref1,(dword) err,rspbuf1,rsplen1,&comp1);
#endif TREL_TIMEOUT
else
#ifndef TREL_TIMEOUT
! dsiCmdReply(cno,reqref,(dword) err,rspbuf,rsplen,&comp);
while (comp > 0) {
abSleep(sectotick(60),TRUE);
}
if (DBSRV)
printf("done\n");
#else TREL_TIMEOUT
! dsiCmdReply(cno,reqref1,(dword) err,rspbuf1,rsplen1,&comp1);
#endif TREL_TIMEOUT
break;
case aspCloseSession:
logit(0,"Closing ASP Session...");
#ifndef TREL_TIMEOUT
! dsiCloseSession(cno,10,3,&comp); /* 5 times, .75 seconds */
while (comp > 0)
#else TREL_TIMEOUT
! dsiCloseSession(cno,10,3,&comp1); /* 5 times, .75 seconds */
while (comp1 > 0)
#endif TREL_TIMEOUT
abSleep(1, TRUE);
***************
*** 1133,1139 ****
#endif NOSHUTDOWNCODE;
#ifdef TREL_TIMEOUT
} else { /* comp2 */
! SPGetRequest(cno,buf2,mcs,&reqref2,&type2,&rlen2,&comp2);
while (comp2 > 0) {
abSleep(sectotick(60),TRUE);
#ifdef AUFS_IDLE_TIMEOUT
--- 1167,1173 ----
#endif NOSHUTDOWNCODE;
#ifdef TREL_TIMEOUT
} else { /* comp2 */
! dsiGetRequest(cno,buf2,mcs,&reqref2,&type2,&rlen2,&comp2);
while (comp2 > 0) {
abSleep(sectotick(60),TRUE);
#ifdef AUFS_IDLE_TIMEOUT
***************
*** 1149,1155 ****
return;
}
if (comp2 < 0) {
! logit(0,"SPGetRequest failed %d",comp2);
continue;
}
if (rlen2 == 0)
--- 1183,1189 ----
return;
}
if (comp2 < 0) {
! logit(0,"dsiGetRequest failed %d",comp2);
continue;
}
if (rlen2 == 0)
***************
*** 1173,1185 ****
fflush(stdout); /* force out */
}
if (type2 == aspWrite)
! SPWrtReply(cno,reqref2,(dword) err,rspbuf2,rsplen2,&comp2);
else
! SPCmdReply(cno,reqref2,(dword) err,rspbuf2,rsplen2,&comp2);
break;
case aspCloseSession:
logit(0,"Closing ASP Session...");
! SPCloseSession(cno,10,3,&comp2); /* 5 times, .75 seconds */
while (comp2 > 0)
abSleep(1, TRUE);
#ifndef NOSHUTDOWNCODE
--- 1207,1219 ----
fflush(stdout); /* force out */
}
if (type2 == aspWrite)
! dsiWrtReply(cno,reqref2,(dword) err,rspbuf2,rsplen2,&comp2);
else
! dsiCmdReply(cno,reqref2,(dword) err,rspbuf2,rsplen2,&comp2);
break;
case aspCloseSession:
logit(0,"Closing ASP Session...");
! dsiCloseSession(cno,10,3,&comp2); /* 5 times, .75 seconds */
while (comp2 > 0)
abSleep(1, TRUE);
#ifndef NOSHUTDOWNCODE
***************
*** 1300,1308 ****
logit(0,"process %d, session %d was suspended! gads what is happening?",
cp->pid, srn);
} else if (WIFSIGNALED(cp->status)) {
! SPAttention(srn, AFPSHUTDOWNNOW, 1, -1, &comp);
while (comp > 0) {abSleep(30, TRUE);} /* ignore error */
! SPCloseSession(srn, 3, 2, &comp); /* try 3 times every .5 seconds */
while (comp > 0) { abSleep(30, TRUE); } /* close down if we can */
logit(0,"process %d, session %d was terminated on signal %d",
cp->pid, srn, W_TERMSIG(cp->status));
--- 1334,1342 ----
logit(0,"process %d, session %d was suspended! gads what is happening?",
cp->pid, srn);
} else if (WIFSIGNALED(cp->status)) {
! dsiAttention(srn, AFPSHUTDOWNNOW, 1, -1, &comp);
while (comp > 0) {abSleep(30, TRUE);} /* ignore error */
! dsiCloseSession(srn, 3, 2, &comp); /* try 3 times every .5 seconds */
while (comp > 0) { abSleep(30, TRUE); } /* close down if we can */
logit(0,"process %d, session %d was terminated on signal %d",
cp->pid, srn, W_TERMSIG(cp->status));
***************
*** 1321,1327 ****
logit(0,"process %d, session %d terminated with exit code %d",
cp->pid, srn, W_RETCODE(cp->status));
}
! SPShutdown(srn);
nomoresessions = FALSE; /* if this was set, unset now */
#ifdef DORUSAGE
logit(0,"%d messages out, %d in, CPU %.2f user %.2f system",
--- 1355,1361 ----
logit(0,"process %d, session %d terminated with exit code %d",
cp->pid, srn, W_RETCODE(cp->status));
}
! dsiShutdown(srn);
nomoresessions = FALSE; /* if this was set, unset now */
#ifdef DORUSAGE
logit(0,"%d messages out, %d in, CPU %.2f user %.2f system",
***************
*** 1385,1391 ****
/* assume sigchild interlocked here */
if (ctp_tab[srn].state & CP_RUNNING)
ctp_tab[srn].state |= CP_TIMEDOUT;
! SPShutdown(srn); /* ignore errors */
kill(pid, SIGHUP); /* hangup inferior */
}
--- 1419,1425 ----
/* assume sigchild interlocked here */
if (ctp_tab[srn].state & CP_RUNNING)
ctp_tab[srn].state |= CP_TIMEDOUT;
! dsiShutdown(srn); /* ignore errors */
kill(pid, SIGHUP); /* hangup inferior */
}
***************
*** 1399,1408 ****
/* The following shouldn't really do anything since remote should be gone */
/* be in case it really isn't, let's go through this rigamorle */
/* Tell remote we are shutting down */
! SPAttention(cno, AFPSHUTDOWNNOW, 1, -1, &comp);
while (comp > 0) {abSleep(30, TRUE);} /* ignore error */
/* Try closing just in case */
! SPCloseSession(cno, 3, 2, &comp); /* 3 times, .5 seconds */
while (comp > 0) { abSleep(30, TRUE); } /* close down if we can */
#ifdef LWSRV_AUFS_SECURITY
clearuserlogin(); /* gtw: delete auth-file entry for dead users */
--- 1433,1442 ----
/* The following shouldn't really do anything since remote should be gone */
/* be in case it really isn't, let's go through this rigamorle */
/* Tell remote we are shutting down */
! dsiAttention(cno, AFPSHUTDOWNNOW, 1, -1, &comp);
while (comp > 0) {abSleep(30, TRUE);} /* ignore error */
/* Try closing just in case */
! dsiCloseSession(cno, 3, 2, &comp); /* 3 times, .5 seconds */
while (comp > 0) { abSleep(30, TRUE); } /* close down if we can */
#ifdef LWSRV_AUFS_SECURITY
clearuserlogin(); /* gtw: delete auth-file entry for dead users */
***************
*** 1431,1437 ****
/* Tell remote we are shutting down */
if (minutes_to_shutdown % 2) { /* all odd minutes */
/* there is a potential race condition here */
! SPAttention(cno, AFPSHUTDOWNTIME(minutes_to_shutdown), 1, -1, &comp);
while (comp > 0) {abSleep(30, TRUE);} /* ignore error */
}
minutes_to_shutdown--;
--- 1465,1471 ----
/* Tell remote we are shutting down */
if (minutes_to_shutdown % 2) { /* all odd minutes */
/* there is a potential race condition here */
! dsiAttention(cno, AFPSHUTDOWNTIME(minutes_to_shutdown), 1, -1, &comp);
while (comp > 0) {abSleep(30, TRUE);} /* ignore error */
}
minutes_to_shutdown--;
***************
*** 1465,1471 ****
int comp;
signal(SIGURG, SIG_IGN);
! SPAttention(cno, AFPSERVERMESG, 1, -1, &comp);
while (comp > 0)
abSleep(30, TRUE);
signal(SIGURG, msgavail);
--- 1499,1505 ----
int comp;
signal(SIGURG, SIG_IGN);
! dsiAttention(cno, AFPSERVERMESG, 1, -1, &comp);
while (comp > 0)
abSleep(30, TRUE);
signal(SIGURG, msgavail);
***************
*** 1893,1899 ****
if (cmp == 0 && *buf != 17) { /* periodic GetVolParms AFP call */
if (sentshutdown) {
logit(0, "Session %d: Aborting Idle Timeout", cno);
! SPAttention(cno, AFPSHUTDOWNCANCEL, 1, -1, &comp);
while (comp > 0) { abSleep(30, TRUE); } /* ignore error */
sentshutdown = 0;
}
--- 1927,1933 ----
if (cmp == 0 && *buf != 17) { /* periodic GetVolParms AFP call */
if (sentshutdown) {
logit(0, "Session %d: Aborting Idle Timeout", cno);
! dsiAttention(cno, AFPSHUTDOWNCANCEL, 1, -1, &comp);
while (comp > 0) { abSleep(30, TRUE); } /* ignore error */
sentshutdown = 0;
}
***************
*** 1922,1937 ****
case 12: /* shutdown in 3 min */
case 24: /* shutdown in 1 min */
logit(0, "Session %d: sending %d minute idle timeout warning",cno,5-i/6);
! SPAttention(cno, AFPSHUTDOWNTIME(5-i/6), 1, -1, &comp);
while (comp > 0) { abSleep(30, TRUE); } /* ignore error */
sentshutdown++;
return;
break;
case 30: /* shutdown now */
logit(0, "Session %d: Idle Timeout Shutdown", cno);
! SPAttention(cno, AFPSHUTDOWNNOW, 1, -1, &comp);
while (comp > 0) { abSleep(30, TRUE); } /* ignore error */
! SPCloseSession(cno, 3, 2, &comp); /* 3 times, .5 seconds */
while (comp > 0) { abSleep(30, TRUE); } /* close down if we can */
#ifdef LWSRV_AUFS_SECURITY
clearuserlogin(); /* gtw: delete auth-file entry for dead users */
--- 1956,1971 ----
case 12: /* shutdown in 3 min */
case 24: /* shutdown in 1 min */
logit(0, "Session %d: sending %d minute idle timeout warning",cno,5-i/6);
! dsiAttention(cno, AFPSHUTDOWNTIME(5-i/6), 1, -1, &comp);
while (comp > 0) { abSleep(30, TRUE); } /* ignore error */
sentshutdown++;
return;
break;
case 30: /* shutdown now */
logit(0, "Session %d: Idle Timeout Shutdown", cno);
! dsiAttention(cno, AFPSHUTDOWNNOW, 1, -1, &comp);
while (comp > 0) { abSleep(30, TRUE); } /* ignore error */
! dsiCloseSession(cno, 3, 2, &comp); /* 3 times, .5 seconds */
while (comp > 0) { abSleep(30, TRUE); } /* close down if we can */
#ifdef LWSRV_AUFS_SECURITY
clearuserlogin(); /* gtw: delete auth-file entry for dead users */
*** applications/aufs/Makefile.m4.orig Wed Sep 25 00:09:57 1996
--- applications/aufs/Makefile.m4 Mon Jul 7 02:03:26 1997
***************
*** 48,59 ****
afpmisc.c afpserver.c aufsicon.c abmisc2.c \
afpdt.c afpdid.c afposenum.c afpavl.c \
afposfi.c afpgc.c afppasswd.c afposlock.c aufsv.c \
! afpudb.c afposncs.c afpspd.c afpfid.c
OBJS=afpos.o afpvols.o afpfile.o \
afpmisc.o afpserver.o aufsicon.o abmisc2.o \
afpdt.o afpdir.o afpfork.o afpdid.o afposenum.o afpavl.o \
afposfi.o afpgc.o afppasswd.o aufsv.o \
! afpudb.o afposncs.o afpspd.o afpfid.o
SYMLINKS=att_getopt.c
all: aufs sizeserver afpidsrvr afpidlist afpidtool
--- 48,59 ----
afpmisc.c afpserver.c aufsicon.c abmisc2.c \
afpdt.c afpdid.c afposenum.c afpavl.c \
afposfi.c afpgc.c afppasswd.c afposlock.c aufsv.c \
! afpudb.c afposncs.c afpspd.c afpfid.c afpdsi.c
OBJS=afpos.o afpvols.o afpfile.o \
afpmisc.o afpserver.o aufsicon.o abmisc2.o \
afpdt.o afpdir.o afpfork.o afpdid.o afposenum.o afpavl.o \
afposfi.o afpgc.o afppasswd.o aufsv.o \
! afpudb.o afposncs.o afpspd.o afpfid.o afpdsi.o
SYMLINKS=att_getopt.c
all: aufs sizeserver afpidsrvr afpidlist afpidtool
***************
*** 189,191 ****
--- 189,193 ----
afppasswd.o: afppasswd.c $I/netat/sysvcompat.h afppasswd.h
afposncs.o: afposncs.c $I/netat/appletalk.h $I/netat/afp.h \
afposncs.h afps.h
+ afpdsi.o: afpdsi.c $I/netat/appletalk.h ../../lib/cap/abasp.h \
+ afpdsi.h
*** lib/afp/afppacks.c.orig Wed Sep 25 00:10:07 1996
--- lib/afp/afppacks.c Mon Mar 3 17:34:40 1997
***************
*** 615,620 ****
--- 615,622 ----
PAKB(GVPRPPtr,P_DWRD,gvpr_free,VP_FREE), /* free bytes */
PAKB(GVPRPPtr,P_DWRD,gvpr_size,VP_SIZE), /* size in bytes */
PKSB(GVPRPPtr,P_OSTR,gvpr_name,VP_NAME), /* name of volume */
+ PKSB(GVPRPPtr,P_BYTS,gvpr_efree,VP_EFREE), /* extended free bytes */
+ PKSB(GVPRPPtr,P_BYTS,gvpr_esize,VP_ESIZE), /* extended total bytes */
PACKEND()
};
***************
*** 663,668 ****
--- 665,673 ----
PACK(GSIRPPtr, P_OPTR, sr_vicono),
PACK(GSIRPPtr, P_WORD, sr_flags),
PAKS(GSIRPPtr, P_PATH, sr_servername),
+ PACKEVEN(),
+ PACK(GSIRPPtr, P_OPTR, sr_sigo),
+ PACK(GSIRPPtr, P_OPTR, sr_naddro),
PACKEND()
};
*** lib/cap/abasp.c.orig Thu Mar 14 13:47:51 1991
--- lib/cap/abasp.c Fri Jul 11 18:20:13 1997
***************
*** 18,25 ****
* Aug 4, 1986 CCKim Verified: level 0
*/
- /* PATCH: Moy@Berkeley/abasp.c.diff, djh@munnari.OZ.AU, 17/11/90 */
-
#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
--- 18,23 ----
***************
*** 61,78 ****
private void start_client_aspskt();
private void shutdown_aspskt();
! private ASPQE *create_aq();
private ASPQE *get_aq();
- private void delete_aq();
private boolean match_aspwe();
private ASPQE *find_aspawe();
private void startasptickle();
! private void stopasptickle();
private void ttimeout();
private void start_ttimer();
private void reset_ttimer();
! private void stop_ttimer();
int SPFork();
OSErr SPShutdown();
--- 59,76 ----
private void start_client_aspskt();
private void shutdown_aspskt();
! void delete_aq();
! ASPQE *create_aq();
private ASPQE *get_aq();
private boolean match_aspwe();
private ASPQE *find_aspawe();
private void startasptickle();
! void stopasptickle();
private void ttimeout();
private void start_ttimer();
private void reset_ttimer();
! void stop_ttimer();
int SPFork();
OSErr SPShutdown();
***************
*** 89,98 ****
#ifdef ASPPID
private ASPSkt *aspskt_find_pid();
#endif
- private ASPSkt *aspskt_find_active();
- private ASPSkt *aspskt_find_sessrefnum();
private OSErr aspsskt_new();
! private ASPSSkt *aspsskt_find_slsrefnum();
private boolean aspsskt_isactive();
private void sizeof_abr_bds_and_req();
--- 87,96 ----
#ifdef ASPPID
private ASPSkt *aspskt_find_pid();
#endif
private OSErr aspsskt_new();
! ASPSkt *aspskt_find_active();
! ASPSkt *aspskt_find_sessrefnum();
! ASPSSkt *aspsskt_find_slsrefnum();
private boolean aspsskt_isactive();
private void sizeof_abr_bds_and_req();
***************
*** 1896,1901 ****
--- 1894,1900 ----
stopasptickle(as);
}
ATPCloseSocket(sas->addr.skt); /* close down server listener here */
+ dsiTCPIPCloseSLS(); /* and the AppleShareIP SLS */
}
return(pid);
}
***************
*** 2093,2099 ****
}
#endif
! private ASPSkt *
aspskt_find_active(SLSRefNum)
int SLSRefNum;
{
--- 2092,2098 ----
}
#endif
! ASPSkt *
aspskt_find_active(SLSRefNum)
int SLSRefNum;
{
***************
*** 2106,2112 ****
return(NULL);
}
! private ASPSkt *
aspskt_find_sessrefnum(srn)
int srn;
{
--- 2105,2111 ----
return(NULL);
}
! ASPSkt *
aspskt_find_sessrefnum(srn)
int srn;
{
***************
*** 2137,2143 ****
}
! private ASPSSkt *
aspsskt_find_slsrefnum(sls)
int sls;
{
--- 2136,2148 ----
}
! /*
! * locate SLSRefNum structure
! * (non-private for DSI access)
! *
! */
!
! ASPSSkt *
aspsskt_find_slsrefnum(sls)
int sls;
{
***************
*** 2212,2218 ****
* stopasptickle - cancel the tickle on the specified connection
*
*/
! private void
stopasptickle(as)
ASPSkt *as;
{
--- 2217,2223 ----
* stopasptickle - cancel the tickle on the specified connection
*
*/
! void
stopasptickle(as)
ASPSkt *as;
{
***************
*** 2277,2283 ****
* cancel the remote tickle timeout
*
*/
! private void
stop_ttimer(as)
ASPSkt *as;
{
--- 2282,2288 ----
* cancel the remote tickle timeout
*
*/
! void
stop_ttimer(as)
ASPSkt *as;
{
***************
*** 2291,2297 ****
private ASPQE *aspqe_list;
private QElemPtr aspqe_free;
! private ASPQE *
create_aq(which, as)
int which;
ASPSkt *as;
--- 2296,2302 ----
private ASPQE *aspqe_list;
private QElemPtr aspqe_free;
! ASPQE *
create_aq(which, as)
int which;
ASPSkt *as;
***************
*** 2320,2326 ****
return(aspqe);
}
! private void
delete_aq(aspqe, which, as)
ASPQE *aspqe;
int which;
--- 2325,2331 ----
return(aspqe);
}
! void
delete_aq(aspqe, which, as)
ASPQE *aspqe;
int which;
*** lib/cap/absched.c.orig Wed Sep 25 00:10:17 1996
--- lib/cap/absched.c Wed Jul 9 16:07:49 1997
***************
*** 704,709 ****
--- 704,711 ----
}
if (dbug.db_skd)
fprintf(stderr,"%d ", rdy);
+ if (rdy < 0)
+ return(rdy);
if (rdy > 0) {
/* rdy should be # of set file descriptors in the masks */
/* since we only pass it the "read" bits, this loop */
*** etc/aufsIPFilter.orig Mon Jul 14 13:46:44 1997
--- etc/aufsIPFilter Mon Jul 14 13:49:11 1997
***************
*** 0 ****
--- 1,26 ----
+ #
+ # aufs/AppleShareIP Address Access Filter List
+ #
+ # NB: The filter file format is compatible with that used by the ARNS
+ # Remote Access package (http://www.cs.mu.OZ.AU/appletalk/atalk.html)
+ #
+ # The filter list consists of a single character mode, an IP mask and
+ # optional IP address. If the latter is included, the mask is applied
+ # to the incoming IP address and tested against the provided address.
+ # Otherwise the incoming IP address must be unchanged by the mask.
+ #
+ # Modes:
+ #
+ # * IP_MASK [ IP_ADDR ] permit access
+ # + IP_MASK [ IP_ADDR ] permit access
+ # - IP_MASK [ IP_ADDR ] deny access
+ #
+ #
+ # any mac on a specific subnet
+ + 255.255.255.0 192.43.207.0
+ # connections from ariel
+ * 128.250.255.255 128.250.20.3
+ # anybody on campus
+ + 128.243.255.255
+ # nobody else
+ - 255.255.255.255
*** samples/ash.c.orig Wed Sep 25 00:10:10 1996
--- samples/ash.c Mon Jul 14 14:27:33 1997
***************
*** 1090,1092 ****
--- 1090,1102 ----
*bp++ = '\0';
return(buf);
}
+
+ /*
+ * this is a dummy routine for abasp.c
+ *
+ */
+
+ dsiTCPIPCloseSLS()
+ {
+ return(noErr);
+ }
*** man/AUFS.8.orig Wed Sep 25 00:09:56 1996
--- man/AUFS.8 Mon Jul 14 13:53:02 1997
***************
*** 21,26 ****
--- 21,30 ----
] [
.BI \-F " <file type mapping>"
] [
+ .BI \-B " <IPaddress[:port]>"
+ ] [
+ .BI \-f " <IP filter file>"
+ ] [
.BI \-[i|I] " <idle timeout>"
] [
.BI \-c " <directory name>"
***************
*** 45,50 ****
--- 49,56 ----
] [
.BI \-u
] [
+ .BI \-T
+ ] [
.BI \-d " <flags>"
] [
.BI \-a " <flags>"
***************
*** 57,71 ****
]
.SH DESCRIPTION
.I aufs
! implements a file server on a UNIX host connected
! to an AppleTalk network, for client computers on AppleTalk that support AFP.
! Specifically, it works as a file server for Macintosh computers with
! the AppleShare client code.
This manual entry describes how to run the UNIX server daemon process.
See AUFS(1) for information about how to use the server.
.PP
.I aufs
! is normally started at boot time via a command in start-cap-servers (whic
is usually run from /etc/rc.local).
The CAP name information server daemon
.I atis
--- 63,77 ----
]
.SH DESCRIPTION
.I aufs
! implements a file server on a UNIX host for client computers on AppleTalk
! that support AFP,
! or Macintoshes on the internet that support AFP via TCP/IP using AppleShare
! client 3.7 or later.
This manual entry describes how to run the UNIX server daemon process.
See AUFS(1) for information about how to use the server.
.PP
.I aufs
! is normally started at boot time via a command in start-cap-servers (which
is usually run from /etc/rc.local).
The CAP name information server daemon
.I atis
***************
*** 148,153 ****
--- 154,186 ----
user may over-ride these mappings by having a .afpfile (or afpfile) file
in their home directory.
.TP 10
+ .BI \-T
+ enables AppleShareIP (AFP via TCP/IP) support in
+ .I aufs.
+ Note that the first
+ .I aufs
+ process defaults to the well-know port number 548. Subsequent incarnations
+ of
+ .I aufs
+ will require that the TCP/IP port number be specified using the \-B option.
+ Clients needing to connect to these servers, that are not also connected to
+ the same network via AppleTalk, must specify the port number in
+ the dialog box obtained by clicking on the Chooser "Server IP Address..."
+ button. The format is the same as for the \-B option, ie: 128.250.1.21:2169
+ to use port number 2169 on host 128.250.1.21.
+ .TP 10
+ .BI \-B " <IPaddress[:port]>"
+ tells
+ .I aufs
+ to listen for TCP/IP connections at the specified IP address and optional
+ port (defaults to any available interface address and port number 548).
+ This option implies \-T.
+ .TP 10
+ .BI \-f " <IP filter file>"
+ specifies the pathname of a file containing yes/no permissions for client
+ IP numbers or subnets wishing to connect using AFP via TCP/IP. See the file
+ cap60/etc/aufsIPFilter for details.
+ .TP 10
.BI \-c " <directory name>"
specifies a directory where
.I aufs
***************
*** 341,354 ****
.PP
Notes and warnings pertaining to client use and file system implementation
are documented in AUFS(1).
- .PP
- AUFS Version 3, released post 2/88, has a different .finderinfo and
- desktop format than previous releases of AUFS. Old format desktop
- files are automatically discarded and old format .finderinfo files are
- rewritten on sight (if possible). You should consider rebuilding your
- desktop if you had a volume created with AUFS Version 2 or previous to
- regain the applications mappings and to ensure that all .finderinfo
- files are rewritten.
.SH AUTHOR
AUFS was written by Bill Schilit, Computer Science Deparment and
Charlie C. Kim, User Services, Columbia University.
--- 374,379 ----
*** netat/afp.h.orig Wed Sep 25 00:09:55 1996
--- netat/afp.h Fri Aug 7 12:18:33 1998
***************
*** 192,207 ****
/* Volume Params */
! #define VP_ATTR 0001 /* attributes */
! #define VP_SIG 0002 /* signature byte */
! #define VP_CDATE 0004 /* creation date */
! #define VP_MDATE 0010 /* modification date */
! #define VP_BDATE 0020 /* backup date */
! #define VP_VOLID 0040 /* volume id */
! #define VP_FREE 0100 /* free bytes */
! #define VP_SIZE 0200 /* size in bytes */
! #define VP_NAME 0400 /* volume name */
! #define VP_ALL (0777)
#define VOL_VAR_DIRID 0x03 /* volume has variable dirids */
#define VOL_FIXED_DIRID 0x02 /* volume has fixed dirids */
--- 192,210 ----
/* Volume Params */
! #define VP_ATTR 00001 /* attributes */
! #define VP_SIG 00002 /* signature byte */
! #define VP_CDATE 00004 /* creation date */
! #define VP_MDATE 00010 /* modification date */
! #define VP_BDATE 00020 /* backup date */
! #define VP_VOLID 00040 /* volume id */
! #define VP_FREE 00100 /* free bytes */
! #define VP_SIZE 00200 /* size in bytes */
! #define VP_NAME 00400 /* volume name */
! #define VP_EFREE 01000 /* AFP2.2: extended free bytes */
! #define VP_ESIZE 02000 /* AFP2.2: extended total bytes */
! #define VP_ALLOC 04000 /* AFP2.2: allocation block size */
! #define VP_ALL (07777)
#define VOL_VAR_DIRID 0x03 /* volume has variable dirids */
#define VOL_FIXED_DIRID 0x02 /* volume has fixed dirids */
***************
*** 278,282 ****
--- 281,287 ----
#define UIP_PRIMARY_GID 0x2 /* primary group (dword) */
#define AFSTYPE "AFPServer" /* NBP type for AFS */
+
+ #define ASIP_PORT 548 /* AppleShare over TCP/IP well-known port */
char *afperr(); /* in afperr.c */
*** netat/afpcmd.h.orig Wed Sep 25 00:09:56 1996
--- netat/afpcmd.h Tue Mar 4 13:22:33 1997
***************
*** 279,285 ****
--- 279,290 ----
#define SupportsChgPwd 0x02 /* AFP2.0: can do change password */
#define DontAllowSavePwd 0x04 /* AFP2.1: user can't save password */
#define SupportsServerMsgs 0x08 /* AFP2.1: can send server messages */
+ #define SupportsServerSig 0x10 /* AFP2.2: can supply unique signature */
+ #define SupportsTCPIP 0x20 /* AFP2.2: AFP commands via TCP/IP stream */
+ #define SupportsSrvrNotif 0x40 /* AFP2.2: server to client messages */
byte sr_servername[33]; /* server name */
+ byte *sr_sigo; /* AFP2.2: offset to signature */
+ byte *sr_naddro; /* AFP2.2: offset to network address count */
} GetSrvrInfoReplyPkt, *GSIRPPtr;
typedef struct { /* FPGetSrvrParms */
***************
*** 319,324 ****
--- 324,331 ----
sdword gvpr_size; /* size of volume in bytes */
sdword gvpr_free; /* free bytes on volume */
byte gvpr_name[MAXVLEN]; /* advertised name */
+ byte gvpr_esize[8]; /* extended volume size */
+ byte gvpr_efree[8]; /* extended bytes free */
} GetVolParmsReplyPkt, *GVPRPPtr;