diff -r -C2 -N mount-2.5p/Makefile mount-2.5tcfs/Makefile
*** mount-2.5p/Makefile	Mon Aug 19 00:38:27 1996
--- mount-2.5tcfs/Makefile	Mon Feb 17 12:35:20 1997
***************
*** 2,6 ****
  
  # you need rpcgen and libc-4.2 or rpclib to compile in the NFS support
! DEFINES = -DHAVE_NFS -DFSTYPE_DEFAULT=$(DEFAULT_FSTYPE)
  
  # ifeq (../MCONFIG,$(wildcard ../MCONFIG))
--- 2,6 ----
  
  # you need rpcgen and libc-4.2 or rpclib to compile in the NFS support
! DEFINES = -DHAVE_TCFS -DHAVETCFS -DHAVE_NFS -DFSTYPE_DEFAULT=$(DEFAULT_FSTYPE)
  
  # ifeq (../MCONFIG,$(wildcard ../MCONFIG))
***************
*** 10,14 ****
  # For now: a standalone version
  
! CC = gcc
  OPTFLAGS= -O2 -fomit-frame-pointer
  #CFLAGS = -pipe $(OPTFLAGS)
--- 10,14 ----
  # For now: a standalone version
  
! CC = gcc 
  OPTFLAGS= -O2 -fomit-frame-pointer
  #CFLAGS = -pipe $(OPTFLAGS)
***************
*** 45,48 ****
--- 45,52 ----
  # comment these out if you are not compiling in NFS support
  NFS_OBJS = nfsmount.o nfsmount_xdr.o nfsmount_clnt.o
+ 
+ # comment these out if you are not compiling in TCFS support
+ TCFS_OBJS = tcfsmount.o nfsmount_xdr.o nfsmount_clnt.o
+ 
  # uncomment this if you don't have libc-4.2 but do have the rpclib
  GEN_FILES = nfsmount.x nfsmount.h nfsmount_xdr.c nfsmount_clnt.c
***************
*** 65,69 ****
  	$(COMPILE) $<
  
! mount: mount.o fstab.o sundries.o realpath.o version.o $(NFS_OBJS) $(LO_OBJS)
  	$(LINK) $^ $(LDLIBS) -o $@
  
--- 69,73 ----
  	$(COMPILE) $<
  
! mount: mount.o fstab.o sundries.o realpath.o version.o $(NFS_OBJS) $(TCFS_OBJS) $(LO_OBJS)
  	$(LINK) $^ $(LDLIBS) -o $@
  
diff -r -C2 -N mount-2.5p/conftest.c mount-2.5tcfs/conftest.c
*** mount-2.5p/conftest.c	Thu Jan  1 01:00:00 1970
--- mount-2.5tcfs/conftest.c	Mon Feb 17 12:33:30 1997
***************
*** 0 ****
--- 1,2 ----
+ #include <unistd.h>
+ main(){ exit(0); swapon("/dev/null", 0); }
diff -r -C2 -N mount-2.5p/mount.8 mount-2.5tcfs/mount.8
*** mount-2.5p/mount.8	Mon Jul  8 00:58:35 1996
--- mount-2.5tcfs/mount.8	Mon Feb 17 12:48:10 1997
***************
*** 234,238 ****
  .IR fat ", " msdos ", " umsdos ", " vfat ,
  .IR proc ", " nfs ", " iso9660 ", " smb ", " ncp ", " affs ", " ufs ,
! .IR sysv ", " xenix ", " coherent .
  Note that the last three are equivalent and that
  .I xenix
--- 234,238 ----
  .IR fat ", " msdos ", " umsdos ", " vfat ,
  .IR proc ", " nfs ", " iso9660 ", " smb ", " ncp ", " affs ", " ufs ,
! .IR sysv ", " xenix ", " coherent ", " tcfs  .
  Note that the last three are equivalent and that
  .I xenix
***************
*** 256,262 ****
  exists, then all of the filesystems listed there will be tried,
  except for those that are labeled "nodev" (e.g.,
! .I proc
  and
! .IR nfs ).
  
  Note that the
--- 256,270 ----
  exists, then all of the filesystems listed there will be tried,
  except for those that are labeled "nodev" (e.g.,
! .I proc,
! .IR nfs 
  and
! .IR tcfs ).
! 
! For more infos about
! .I TCFS
! try 
! .B man 8 tcfs_intro 
! or
! .B man 8 tcfs.
  
  Note that the
***************
*** 837,840 ****
--- 845,851 ----
  and is not maintained. Probably one shouldn't use it.
  
+ .SH "Mount options for tcfs"
+ See mount options for nfs.
+ 
  .SH "THE LOOP DEVICE"
  One further possible type is a mount via the loop device. For example,
***************
*** 883,887 ****
  .BR mke2fs (8),
  .BR tune2fs (8),
! .BR losetup (8)
  .SH BUGS
  It is possible for a corrupted file system to cause a crash.
--- 894,899 ----
  .BR mke2fs (8),
  .BR tune2fs (8),
! .BR losetup (8),
! .BR tcfs_intro (8)
  .SH BUGS
  It is possible for a corrupted file system to cause a crash.
***************
*** 911,912 ****
--- 923,926 ----
  .B mount
  command appeared in Version 6 AT&T UNIX.
+ 
+ Added TCFS support by E. Mauriello <ermmau@mikonos.dia.unisa.it>
diff -r -C2 -N mount-2.5p/mount.c mount-2.5tcfs/mount.c
*** mount-2.5p/mount.c	Tue Oct 15 23:30:38 1996
--- mount-2.5tcfs/mount.c	Mon Feb 17 12:34:52 1997
***************
*** 582,585 ****
--- 582,593 ----
    }
  
+   if (!fake && type && streq (type, "tcfs"))
+ #ifdef HAVETCFS
+     if (tcfsmount (spec, node, &flags, &extra_opts, &mount_opts) != 0)
+       return 1;
+ #else
+     die (1, "mount: this version was compiled without support for the type `tcfs'");
+ #endif
+ 
    if (!fake && type && streq (type, "nfs"))
  #ifdef HAVE_NFS
diff -r -C2 -N mount-2.5p/sundries.h mount-2.5tcfs/sundries.h
*** mount-2.5p/sundries.h	Mon Aug 19 00:41:16 1996
--- mount-2.5tcfs/sundries.h	Mon Feb 17 12:34:44 1997
***************
*** 88,91 ****
--- 88,96 ----
  #endif
  
+ #ifdef HAVETCFS
+ int tcfsmount (const char *spec, const char *node, int *flags,
+                char **orig_opts, char **opt_args);
+ #endif
+ 
  #define mount5(special, dir, type, flags, data) \
    mount (special, dir, type, 0xC0ED0000 | (flags), data)
diff -r -C2 -N mount-2.5p/tcfsmount.c mount-2.5tcfs/tcfsmount.c
*** mount-2.5p/tcfsmount.c	Thu Jan  1 01:00:00 1970
--- mount-2.5tcfs/tcfsmount.c	Mon Feb 17 12:18:45 1997
***************
*** 0 ****
--- 1,518 ----
+ /*
+  * T.C.F.S. 2.0 Alpha 1 
+  *
+  *      	   This  program  handles  RPC  "NFS"  data  requests
+  *              adopting a secure transfer protocol.
+  *                 This   is  an  unsecure   and  unchecked  version,
+  *              use at your own risk.
+  *
+  *              Please, report Bugs to: <tcfs@edu-gw.dia.unisa.it>
+  *
+  * Authors:	Giuseppe Cattaneo, <cattaneo@udsab.dia.unisa.it>
+  *		Giuseppe Persiano, <giuper@udsab.dia.unisa.it>
+  *		Andrea Cozzolino, <andcoz@edu-gw.dia.unisa.it>
+  *		Angelo Celentano, <angcel@edu-gw.dia.unisa.it>
+  *		Aniello Del Sorbo, <anidel@edu-gw.dia.unisa.it>
+  *		Ermelindo Mauriello, <ermmau@edu-gw.dia.unisa.it>
+  *		Raffaele Pisapia, <rafpis@edu-gw.dia.unisa.it>
+  *
+  *   Permission to  use, copy, and modify  this software  without fee
+  * is hereby granted, provided that this entire notice is included in
+  * all copies  of  any  software  which  is  or  includes a  copy  or
+  * modification of this software and in all copies  of the supporting
+  * documentation for such software.
+  *
+  *   This  software is  distribuited  under  the  GNU General  Public
+  * License  (version  2, June  1991). Check  the  file  'COPYING'  for
+  * more  infos. Some  parts of  this  software  derive  from the  NFS
+  * implementation in the Linux kernel 2.0.x.
+  *
+  * This software  maybe be used  for any  purpose provided  the above
+  * copyright  notice  is retained.  It  is  supplied  as is,  with no
+  * warranty expressed or implied.
+  *
+  */
+ 
+ /* -+-_== */
+ 
+ /*
+  * tcfsmount.c -- Linux TCFS mount
+  * Copyright (C) 1993 Rick Sladkey <jrs@world.std.com>
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+  * the Free Software Foundation; either version 2, or (at your option)
+  * any later version.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  */
+ 
+ /*
+  * tcfsmount.c,v 1.1.1.1 1993/11/18 08:40:51 jrs Exp
+  */
+ 
+ #include <stdio.h>
+ #include <rpc/rpc.h>
+ #include <rpc/pmap_prot.h>
+ #include <rpc/pmap_clnt.h>
+ #include <sys/socket.h>
+ #include <sys/time.h>
+ #include <string.h>
+ #include <netdb.h>
+ #include <arpa/inet.h>
+ #include <errno.h>
+ 
+ #include "sundries.h"
+ 
+ #include "nfsmount.h"
+ #include "xattr_client.h"
+ 
+ #include <linux/fs.h>
+ #include <linux/tcfs.h>
+ #include <linux/tcfs_mount.h>
+ 
+ static char *strndup (char *str, int n) {
+   char *ret;
+   ret = malloc (n+1);
+   if (ret == NULL) {
+     perror ("malloc");
+     return (NULL);
+   }
+   strncpy (ret, str, n);
+   return (ret);
+ }
+ 
+ static char *tcfs_strerror(int stat);
+ 
+ int tcfsmount(const char *spec, const char *node, int *flags,
+ 	     char **extra_opts, char **mount_opts)
+ {
+ 	char hostdir[1024];
+ 	CLIENT *mclient;
+ 	char *hostname, *dirname, *old_opts, *mounthost=NULL, new_opts[1024];
+ 	fhandle root_fhandle;
+ 	struct timeval total_timeout;
+ 	enum clnt_stat clnt_stat;
+ 	static struct tcfs_mount_data data;
+ 	char *opt, *opteq;
+ 	int val;
+     	struct hostent *hp;
+ 	struct sockaddr_in server_addr,xattrd_server;
+ 	struct sockaddr_in mount_server_addr;
+ 	int msock, fsock;
+ 	struct timeval pertry_timeout;
+ 	struct fhstatus status;
+ 	char *s;
+ 	int port, mountport, bg,soft, intr, posix, nocto, noac, retry;
+ 	int tcp, mountprog, mountvers, tcfsprog, xattrprog, tcfsvers, xattrvers;
+ 	int xasock;
+ 	msock = fsock = xasock = -1;
+ 	mclient = NULL;
+ 	strcpy(hostdir, spec);
+ 	if ((s = (strchr(hostdir, ':')))) {
+ 		hostname = hostdir;
+ 		dirname = s + 1;
+ 		*s = '\0';
+ 	}
+ 	else {
+ 		fprintf(stderr, "mount: "
+ 			"directory to mount not in host:dir format\n");
+ 		goto fail;
+ 	}
+ 	if (hostname[0] >= '0' && hostname[0] <= '9') {
+ 		server_addr.sin_family = AF_INET;
+ 		xattrd_server.sin_family=AF_INET;
+ 		server_addr.sin_addr.s_addr = inet_addr(hostname);
+ 		xattrd_server.sin_addr.s_addr = inet_addr(hostname);
+ 	}
+ 	else if ((hp = gethostbyname(hostname)) == NULL) {
+ 		fprintf(stderr, "mount: can't get address for %s\n", hostname);
+ 		goto fail;
+ 	}
+ 	else {
+ 		server_addr.sin_family = AF_INET;
+ 		xattrd_server.sin_family=AF_INET;
+ 		memcpy(&server_addr.sin_addr, hp->h_addr, hp->h_length);
+ 		memcpy(&xattrd_server.sin_addr, hp->h_addr, hp->h_length);
+ 	}
+ 
+ 	memcpy (&mount_server_addr, &server_addr, sizeof (mount_server_addr));
+ 
+ 	/* add IP address to mtab options for use when unmounting */
+ 
+ 	old_opts = *extra_opts;
+ 	if (!old_opts)
+ 		old_opts = "";
+ 	sprintf(new_opts, "%s%saddr=%s",
+ 		old_opts, *old_opts ? "," : "",
+ 		inet_ntoa(server_addr.sin_addr));
+ 	*extra_opts = strdup(new_opts);
+ 
+ 	/* set default options */
+ 
+ 	data.rsize	= 0; /* let kernel decide */
+ 	data.wsize	= 0; /* let kernel decide */
+ 	data.timeo	= 7;
+ 	data.retrans	= 3;
+ 	data.acregmin	= 3;
+ 	data.acregmax	= 60;
+ 	data.acdirmin	= 30;
+ 	data.acdirmax	= 60;
+ #if TCFS_MOUNT_VERSION >= 2
+ 	data.namlen	= NAME_MAX;
+ #endif
+ 
+ 	bg = 0;
+ 	soft = 0;
+ 	intr = 0;
+ 	posix = 0;
+ 	nocto = 0;
+ 	noac = 0;
+ 	retry = 10000;
+ 	tcp = 0;
+ 
+ 	mountprog = MOUNTPROG;
+ 	mountvers = MOUNTVERS;
+ 	port = 0;
+ 	mountport = 0;
+ 	tcfsprog = TCFS_PROGRAM;
+ 	tcfsvers = TCFS_VERSION;
+ 	xattrprog = XATTR_PROGRAM;
+ 	xattrvers = XATTR_VERSION;
+ 
+ 	/* parse options */
+ 
+ 	for (opt = strtok(old_opts, ","); opt; opt = strtok(NULL, ",")) {
+ 		if ((opteq = strchr(opt, '='))) {
+ 			val = atoi(opteq + 1);	
+ 			*opteq = '\0';
+ 			if (!strcmp(opt, "rsize"))
+ 				data.rsize = val;
+ 			else if (!strcmp(opt, "wsize"))
+ 				data.wsize = val;
+ 			else if (!strcmp(opt, "timeo"))
+ 				data.timeo = val;
+ 			else if (!strcmp(opt, "retrans"))
+ 				data.retrans = val;
+ 			else if (!strcmp(opt, "acregmin"))
+ 				data.acregmin = val;
+ 			else if (!strcmp(opt, "acregmax"))
+ 				data.acregmax = val;
+ 			else if (!strcmp(opt, "acdirmin"))
+ 				data.acdirmin = val;
+ 			else if (!strcmp(opt, "acdirmax"))
+ 				data.acdirmax = val;
+ 			else if (!strcmp(opt, "actimeo")) {
+ 				data.acregmin = val;
+ 				data.acregmax = val;
+ 				data.acdirmin = val;
+ 				data.acdirmax = val;
+ 			}
+ 			else if (!strcmp(opt, "retry"))
+ 				retry = val;
+ 			else if (!strcmp(opt, "port"))
+ 				port = val;
+ 			else if (!strcmp(opt, "mountport"))
+ 			        mountport = val;
+ 			else if (!strcmp(opt, "mounthost"))
+ 			        mounthost=strndup(opteq+1,
+ 						  strcspn(opteq+1," \t\n\r,"));
+ 			else if (!strcmp(opt, "mountprog"))
+ 				mountprog = val;
+ 			else if (!strcmp(opt, "mountvers"))
+ 				mountvers = val;
+ 			else if (!strcmp(opt, "tcfsprog"))
+ 				tcfsprog = val;
+ 			else if (!strcmp(opt, "tcfsvers"))
+ 				tcfsvers = val;
+ 			else if (!strcmp(opt, "namlen")) {
+ #if TCFS_MOUNT_VERSION >= 2
+ 				data.namlen = val;
+ #else
+ 				printf("Warning: Option namlen is not supported.\n");
+ #endif
+ 			}
+ 			else if (!strcmp(opt, "addr"))
+ 				/* ignore */;
+ 			else {
+ 				printf("unknown tcfs mount parameter: "
+ 				       "%s=%d\n", opt, val);
+ 				goto fail;
+ 			}
+ 		}
+ 		else {
+ 			val = 1;
+ 			if (!strncmp(opt, "no", 2)) {
+ 				val = 0;
+ 				opt += 2;
+ 			}
+ 			if (!strcmp(opt, "bg")) 
+ 				bg = val;
+ 			else if (!strcmp(opt, "fg")) 
+ 				bg = !val;
+ 			else if (!strcmp(opt, "soft"))
+ 				soft = val;
+ 			else if (!strcmp(opt, "hard"))
+ 				soft = !val;
+ 			else if (!strcmp(opt, "intr"))
+ 				intr = val;
+ 			else if (!strcmp(opt, "posix"))
+ 				posix = val;
+ 			else if (!strcmp(opt, "cto"))
+ 				nocto = !val;
+ 			else if (!strcmp(opt, "ac"))
+ 				noac = !val;
+ 			else if (!strcmp(opt, "tcp"))
+ 				tcp = val;
+ 			else if (!strcmp(opt, "udp"))
+ 				tcp = !val;
+ 			else {
+ 				printf("unknown tcfs mount option: "
+ 				       "%s%s\n", val ? "" : "no", opt);
+ 				goto fail;
+ 			}
+ 		}
+ 	}
+ 	data.flags = (soft ? TCFS_MOUNT_SOFT : 0)
+ 		| (intr ? TCFS_MOUNT_INTR : 0)
+ 		| (posix ? TCFS_MOUNT_POSIX : 0)
+ 		| (nocto ? TCFS_MOUNT_NOCTO : 0)
+ 		| (noac ? TCFS_MOUNT_NOAC : 0);
+ #if TCFS_MOUNT_VERSION >= 2
+ 	data.flags |= (tcp ? TCFS_MOUNT_TCP : 0);
+ #endif
+ 
+ #ifdef TCFS_MOUNT_DEBUG
+ 	printf("rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
+ 		data.rsize, data.wsize, data.timeo, data.retrans);
+ 	printf("acreg (min, max) = (%d, %d), acdir (min, max) = (%d, %d)\n",
+ 		data.acregmin, data.acregmax, data.acdirmin, data.acdirmax);
+ 	printf("port = %d, bg = %d, retry = %d, flags = %.8x\n",
+ 		port, bg, retry, data.flags);
+ 	printf("mountprog = %d, mountvers = %d, tcfsprog = %d, tcfsvers = %d\n",
+ 		mountprog, mountvers, tcfsprog, tcfsvers);
+ 	printf("soft = %d, intr = %d, posix = %d, nocto = %d, noac = %d\n",
+ 		(data.flags & TCFS_MOUNT_SOFT) != 0,
+ 		(data.flags & TCFS_MOUNT_INTR) != 0,
+ 		(data.flags & TCFS_MOUNT_POSIX) != 0,
+ 		(data.flags & TCFS_MOUNT_NOCTO) != 0,
+ 		(data.flags & TCFS_MOUNT_NOAC) != 0);
+ #if TCFS_MOUNT_VERSION >= 2
+ 	printf("tcp = %d\n",
+ 		(data.flags & TCFS_MOUNT_TCP) != 0);
+ #endif
+ #if 0
+ 	goto fail;
+ #endif
+ #endif
+ 
+ 	data.version = TCFS_MOUNT_VERSION;
+ 	*mount_opts = (char *) &data;
+ 
+ 	if (*flags & MS_REMOUNT)
+ 		return 0;
+ 
+ 	/* create mount deamon client */
+ 	/* See if the tcfs host = mount host. */
+ 	if (mounthost) {
+ 	  if (mounthost[0] >= '0' && mounthost[0] <= '9') {
+ 	    mount_server_addr.sin_family = AF_INET;
+ 	    mount_server_addr.sin_addr.s_addr = inet_addr(hostname);
+ 	  }
+ 	  else if ((hp = gethostbyname(mounthost)) == NULL) {
+ 		fprintf(stderr, "mount: can't get address for %s\n", hostname);
+ 		goto fail;
+ 	  }
+ 	  else {
+ 	    mount_server_addr.sin_family = AF_INET;
+ 	    memcpy(&mount_server_addr.sin_addr, hp->h_addr, hp->h_length);
+ 	  }
+ 	}
+ 
+ 	mount_server_addr.sin_port = htons(mountport);
+ 	msock = RPC_ANYSOCK;
+ 	if ((mclient = clnttcp_create(&mount_server_addr,
+ 	    mountprog, mountvers, &msock, 0, 0)) == NULL) {
+ 		mount_server_addr.sin_port = htons(mountport);
+ 		msock = RPC_ANYSOCK;
+ 		pertry_timeout.tv_sec = 3;
+ 		pertry_timeout.tv_usec = 0;
+ 		if ((mclient = clntudp_create(&mount_server_addr,
+ 		    mountprog, mountvers, pertry_timeout, &msock)) == NULL) {
+ 			clnt_pcreateerror("mount clntudp_create");
+ 			goto fail;
+ 		}
+ #ifdef TCFS_MOUNT_DEBUG
+ 		printf("using UDP for mount deamon\n");
+ #endif
+ 	}
+ #ifdef TCFS_MOUNT_DEBUG
+ 	else
+ 		printf("using TCP for mount deamon\n");
+ #endif
+ 	mclient->cl_auth = authunix_create_default();
+ 	total_timeout.tv_sec = 20;
+ 	total_timeout.tv_usec = 0;
+ 
+ 	/* try to mount hostname:dirname */
+ 
+ 	clnt_stat = clnt_call(mclient, MOUNTPROC_MNT,
+ 		xdr_dirpath, &dirname,
+ 		xdr_fhstatus, &status,
+ 		total_timeout);
+ 	if (clnt_stat != RPC_SUCCESS) {
+ 		clnt_perror(mclient, "rpc mount");
+ 		goto fail;
+ 	}
+ 	if (status.fhs_status != 0) {
+ 		fprintf(stderr,
+ 			"mount: %s:%s failed, reason given by server: %s\n",
+ 			hostname, dirname, tcfs_strerror(status.fhs_status));
+ 		goto fail;
+ 	}
+ 	memcpy((char *) &root_fhandle, (char *) status.fhstatus_u.fhs_fhandle,
+ 		sizeof (root_fhandle));
+ 
+ 	/* create tcfs socket for kernel */
+ 
+ 	if (tcp) {
+ #if TCFS_MOUNT_VERSION >= 2
+ 		fsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ #else
+ 		printf("TCFS over TCP is not supported.\n");
+ 		goto fail;
+ #endif
+ 	}
+ 	else {
+ 		fsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ 		xasock= socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ 	}
+ 	if (fsock < 0) {
+ 		perror("tcfs socket");
+ 		goto fail;
+ 	}
+ 	if (xasock < 0) {
+ 		perror("xattrd socket");
+ 		goto fail;
+ 	}
+ 	if (bindresvport(fsock, 0) < 0) {
+ 		perror("tcfs bindresvport");
+ 		goto fail;
+ 	}
+ 	if (bindresvport(xasock,0)<0) {
+ 	  perror("tcfs bindrevport");
+ 	  goto fail;
+ 	}
+ 	if (port == 0) {
+ 		server_addr.sin_port = PMAPPORT;
+ 		port = pmap_getport(&server_addr, tcfsprog, tcfsvers,
+ 			tcp ? IPPROTO_TCP : IPPROTO_UDP);
+ 		if (port == 0)
+ 			port = TCFS_PORT;
+ #ifdef TCFS_MOUNT_DEBUG
+ 		else
+ 			printf("used portmapper to find TCFS port\n");
+ #endif
+ 	}
+ #ifdef TCFS_MOUNT_DEBUG
+ 	printf("using port %d for tcfs deamon\n", port);
+ #endif
+ 	server_addr.sin_port = htons(port);
+ 	if (connect(fsock, (struct sockaddr *) &server_addr,
+ 	    sizeof (server_addr)) < 0) {
+ 		perror("tcfs connect");
+ 		goto fail;
+ 	}
+ 	xattrd_server.sin_port = htons(XATTRDPORT);
+ 	if (connect(xasock, (struct sockaddr *) &xattrd_server, sizeof(xattrd_server)) <0 ) {
+ 	  perror("tcfs connect");
+ 	  goto fail;
+ 	}
+ 	/* prepare data structure for kernel */
+ 
+ 	data.fd = fsock;
+ 	data.xasock=xasock;
+ 	memcpy((char *) &data.root, (char *) &root_fhandle,
+ 		sizeof (root_fhandle));
+ 	memcpy((char *) &data.addr, (char *) &server_addr, sizeof(data.addr));
+ 	memcpy((char *) &data.xattraddr, (char *) &xattrd_server, sizeof(data.addr));
+ 	strncpy(data.hostname, hostname, sizeof(data.hostname));
+ 
+ 	/* clean up */
+ 	strcpy(data.remote,dirname);
+ 	auth_destroy(mclient->cl_auth);
+ 	clnt_destroy(mclient);
+ 	close(msock);
+ 	return 0;
+ 
+ 	/* abort */
+ 
+ fail:
+ 	if (msock != -1) {
+ 		auth_destroy(mclient->cl_auth);
+ 		clnt_destroy(mclient);
+ 		close(msock);
+ 	}
+ 	if (fsock != -1)
+ 		close(fsock);
+ 	if (xasock != -1)
+ 		close(xasock);
+ 	return 1;
+ }
+ 
+ /*
+  * We need to translate between tcfs status return values and
+  * the local errno values which may not be the same.
+  */
+ 
+ #ifndef EDQUOT
+ #define EDQUOT	ENOSPC
+ #endif
+ 
+ static struct {
+ 	enum tcfs_stat stat;
+ 	int errno;
+ } tcfs_errtbl[] = {
+ 	{ TCFS_OK,		0		},
+ 	{ TCFSERR_PERM,		EPERM		},
+ 	{ TCFSERR_NOENT,		ENOENT		},
+ 	{ TCFSERR_IO,		EIO		},
+ 	{ TCFSERR_NXIO,		ENXIO		},
+ 	{ TCFSERR_ACCES,		EACCES		},
+ 	{ TCFSERR_EXIST,		EEXIST		},
+ 	{ TCFSERR_NODEV,		ENODEV		},
+ 	{ TCFSERR_NOTDIR,	ENOTDIR		},
+ 	{ TCFSERR_ISDIR,		EISDIR		},
+ #ifdef TCFSERR_INVAL
+ 	{ TCFSERR_INVAL,		EINVAL		},	/* that Sun forgot */
+ #endif
+ 	{ TCFSERR_FBIG,		EFBIG		},
+ 	{ TCFSERR_NOSPC,		ENOSPC		},
+ 	{ TCFSERR_ROFS,		EROFS		},
+ 	{ TCFSERR_NAMETOOLONG,	ENAMETOOLONG	},
+ 	{ TCFSERR_NOTEMPTY,	ENOTEMPTY	},
+ 	{ TCFSERR_DQUOT,		EDQUOT		},
+ 	{ TCFSERR_STALE,		ESTALE		},
+ #ifdef EWFLUSH
+ 	{ TCFSERR_WFLUSH,	EWFLUSH		},
+ #endif
+ 	{ -1,			EIO		}
+ };
+ 
+ static char *tcfs_strerror(int stat)
+ {
+ 	int i;
+ 	static char buf[256];
+ 
+ 	for (i = 0; tcfs_errtbl[i].stat != -1; i++) {
+ 		if (tcfs_errtbl[i].stat == stat)
+ 			return strerror(tcfs_errtbl[i].errno);
+ 	}
+ 	sprintf(buf, "unknown tcfs status return value: %d", stat);
+ 	return buf;
+ }
+ 
diff -r -C2 -N mount-2.5p/xattr_client.h mount-2.5tcfs/xattr_client.h
*** mount-2.5p/xattr_client.h	Thu Jan  1 01:00:00 1970
--- mount-2.5tcfs/xattr_client.h	Mon Feb 17 12:19:05 1997
***************
*** 0 ****
--- 1,65 ----
+ /*
+  * T.C.F.S. 2.0 Alpha 1 
+  *
+  *      	   This  program  handles  RPC  "NFS"  data  requests
+  *              adopting a secure transfer protocol.
+  *                 This   is  an  unsecure   and  unchecked  version,
+  *              use at your own risk.
+  *
+  *              Please, report Bugs to: <tcfs@edu-gw.dia.unisa.it>
+  *
+  * Authors:	Giuseppe Cattaneo, <cattaneo@udsab.dia.unisa.it>
+  *		Giuseppe Persiano, <giuper@udsab.dia.unisa.it>
+  *		Andrea Cozzolino, <andcoz@edu-gw.dia.unisa.it>
+  *		Angelo Celentano, <angcel@edu-gw.dia.unisa.it>
+  *		Aniello Del Sorbo, <anidel@edu-gw.dia.unisa.it>
+  *		Ermelindo Mauriello, <ermmau@edu-gw.dia.unisa.it>
+  *		Raffaele Pisapia, <rafpis@edu-gw.dia.unisa.it>
+  *
+  *   Permission to  use, copy, and modify  this software  without fee
+  * is hereby granted, provided that this entire notice is included in
+  * all copies  of  any  software  which  is  or  includes a  copy  or
+  * modification of this software and in all copies  of the supporting
+  * documentation for such software.
+  *
+  *   This  software is  distribuited  under  the  GNU General  Public
+  * License  (version  2, June  1991). Check  the  file  'COPYING'  for
+  * more  infos. Some  parts of  this  software  derive  from the  NFS
+  * implementation in the Linux kernel 2.0.x.
+  *
+  * This software  maybe be used  for any  purpose provided  the above
+  * copyright  notice  is retained.  It  is  supplied  as is,  with no
+  * warranty expressed or implied.
+  *
+  */
+ 
+ /* -+-_== */
+ 
+ /*
+  * T.C.F.S. written by : Prof. Giuseppe  Cattaneo
+  *                       Prof. Giuseppe  Persiano
+  *                             Angelo    Celentano
+  *                             Andrea    Cozzolino
+  *                             Aniello   Del Sorbo
+  *                             Ermelindo Mauriello
+  *                             Raffaele  Pisapia
+  */
+ 
+ /*
+  * Generated with rpcgen from:
+  * $Header: /home/andcoz/C/xattrd/RCS/xattr.x,v 1.2 2036/02/07 06:30:39 andcoz Exp $
+  */
+ 
+ /* -+-_== */
+ #ifndef XATTR_H
+ #define XATTR_H
+ #define XATTRDPORT 4049
+ #define TCFS_MAXPATHLEN 1024
+ #endif /*XATTR_H*/
+ 
+ #define XATTR_PROGRAM ((u_long)200000)
+ #define XATTR_VERSION ((u_long)1)
+ #define XATTRPROC_NULL ((u_long)0)
+ #define XATTRPROC_GETEATTR ((u_long)1)
+ #define XATTRPROC_SETEATTR ((u_long)2)
+ 
