mirror of https://github.com/mabam/CAP.git
3802 lines
100 KiB
Diff
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;
|
|
|
|
|