Subject: Re: [netatalk-admins] Can't stop CR/LF translation...

From: [email-masked]
Date: Tue, 24 Mar 98 18:57:05 PST

Original message sent on Tue, Mar 24  10:12 AM by [email-masked] (David
Welton) :

> I first noticed this when I used the server I have set up to transfer
> some gif's from my boss.  He created them on his windoze box, then
> placed them in a shared directory hosted by a Mac appletalk server.
> From there I moved them to my own netatalk server, clicking and
> dragging with a mac...  At this point I went to open an image, and, lo
> and behold, corruption!
>
> ...So I went to change AppleVolumes.system in /etc/netatalk, and I
> restarted the server (first I tried hupping it twice, to no effect),
> after having edited it to the following:
>
> .         BINA    UNIX
> # .       TEXT    UNIX      

The AppleVolumes.system mappings apply only to files that do not already have a
type and creator (i.e. files created from the Unix side).  Any file copied to a
netatalk volume from the Mac will already have a type and creator, and the
AppleVolumes.system mappings will not "override" those.  In your case it sounds
like the file types were set to "TEXT" when the files were copied from the
Windows machine, so the file types will remain "TEXT" no matter what you do to
the AppleVolumes.system file and netatalk will continue to translate the files.

There are two possible solutions, one would be to prevent the files from being
typed as "TEXT" to start with.  This would depend on the software being used to
copy the files from the Windows machine to the AppleShare server; that is where
the file type is being defined in this case.

The other solution is to completely disable netatalk's CR/LF translation, which
is simply a matter of re-compiling netatalk after removing the "-DCRLF" option
from etc/afpd/Makefile.

Hope this helps!

Bob Smith
Hammett & Edison, Inc.
[email-masked]

---

From: David Welton <[email-masked]>
Date: Wed, 25 Mar 1998 17:58:19 -0800

On Tue, Mar 24, 1998 at 06:57:05PM -0800, [email-masked] wrote:

> There are two possible solutions, one would be to prevent the files
> from being typed as "TEXT" to start with.  This would depend on the
> software being used to copy the files from the Windows machine to
> the AppleShare server; that is where the file type is being defined
> in this case.

They are using PC Maclan, but I don't really care to delve into
windoze problems..  The software seems broken in other ways as well.

> The other solution is to completely disable netatalk's CR/LF
> translation, which is simply a matter of re-compiling netatalk after
> removing the "-DCRLF" option from etc/afpd/Makefile.

Actually, I went one better (I hope it's seen that way at least!) and
hacked a new command line option into afpd so that you can turn off
CR/LF translation by starting it with '-e'.  I did this by adding a
variable in afp_options.  I hope this was the right place to put it.

Everything seems to work great now :-)

Anyway, I have attached my diffs for review.

-- 
David Welton                          http://www.efn.org/~davidw 

	Debian GNU/Linux - www.debian.org
--- netatalk-asun-2.0a18.2/man/man8/afpd.8	Sun Mar 31 10:35:39 1996
+++ debian7/netatalk-asun-2.0a18.2/man/man8/afpd.8	Wed Mar 25 12:46:30 1998
@@ -7,6 +7,9 @@
 .B -d
 ]
 [
+.B -e
+]
+[
 .B -f
 .I defaultvolumes
 ]
@@ -96,6 +99,12 @@
 .B \-d
 Specifies that the daemon not fork, and that a trace of all AFP
 commands be written to stdout.
+.TP
+.B \-e
+Command line switch to turn on/off CR/LF translation.  The default
+behaviour remains the same, with this switch turning 
+.B off
+CR/LF translation.
 .TP
 .BI \-f " defaultvolumes"
 Specifies that
diff -u netatalk-asun-2.0a18.2/etc/afpd/Makefile debian7/netatalk-asun-2.0a18.2/etc/afpd/Makefile
--- netatalk-asun-2.0a18.2/etc/afpd/Makefile	Tue Feb 17 16:51:38 1998
+++ debian7/netatalk-asun-2.0a18.2/etc/afpd/Makefile	Wed Mar 25 10:37:13 1998
@@ -14,7 +14,7 @@
 INCPATH=	-I../../include ${AFSINCPATH} ${KRBINCPATH} ${DESINCPATH} \
 	${PAMINCPATH}
 CFLAGS=	${DEFS} ${AFSDEFS} ${KRBDEFS} ${DESDEFS} ${OPTOPTS} ${INCPATH} \
-	${PAMDEFS} -DAPPLCNAME -DCRLF # -DDOWNCASE
+	${PAMDEFS} -DAPPLCNAME # -DCRLF # -DDOWNCASE
 LIBS =	-latalk ${AFSLIBS} ${KRBLIBS} ${DESLIBS} ${ADDLIBS} ${AFPLIBS} \
 	${TCPWRAPLIBS} ${PAMLIBS}
 LIBDIRS=	-L../../libatalk ${AFSLIBDIRS} ${KRBLIBDIRS} \
diff -u netatalk-asun-2.0a18.2/etc/afpd/afp_options.c debian7/netatalk-asun-2.0a18.2/etc/afpd/afp_options.c
--- netatalk-asun-2.0a18.2/etc/afpd/afp_options.c	Tue Feb 17 16:51:38 1998
+++ debian7/netatalk-asun-2.0a18.2/etc/afpd/afp_options.c	Wed Mar 25 16:38:25 1998
@@ -24,7 +24,7 @@
 #define MIN(a, b)  ((a) < (b) ? (a) : (b))
 #endif
 
-#define OPTIONS "dn:f:s:uc:g:ACKGP:pDS:TL:F:t"
+#define OPTIONS "den:f:s:uc:g:ACKGP:pDS:TL:F:t"
 #define LENGTH 512
 
 /* return an option. this uses an internal array, so it's necessary
@@ -91,6 +91,7 @@
   options->transports = AFPTRANS_ALL;
   options->authbits = AU_ALL;
   options->passwdfile = _NAME_AFPDPWFILE;
+  options->crlfbool = 1;
 }
 
 /* parse an afpd.conf line. i'm doing it this way because it's
@@ -217,6 +218,9 @@
 	case 'd' :
 	    options->debug++;
 	    break;
+	case 'e' :
+	    options->crlfbool = 0;
+	    break;
 	case 'n' :
 	    options->server = optarg;
 	    break;
@@ -281,7 +285,7 @@
     }
     if ( err || optind != ac ) {
 	fprintf( stderr,
-		"Usage:\t%s [ -dGKCApDTt ] [ -n nbpname ] [ -f defvols ] \
+		"Usage:\t%s [ -deGKCApDTt ] [ -n nbpname ] [ -f defvols ] \
 [ -P pidfile ] [ -s sysvols ] \n", p );
 	fprintf( stderr,
 		"\t[ -u ] [ -c maxconn ] [ -g guest ] \
diff -u netatalk-asun-2.0a18.2/etc/afpd/fork.c debian7/netatalk-asun-2.0a18.2/etc/afpd/fork.c
--- netatalk-asun-2.0a18.2/etc/afpd/fork.c	Tue Feb 17 16:51:38 1998
+++ debian7/netatalk-asun-2.0a18.2/etc/afpd/fork.c	Wed Mar 25 16:49:37 1998
@@ -403,31 +403,37 @@
 #undef LOCKBIT

-#ifdef CRLF
-static __inline__ int crlf( of )
-    struct ofork	*of;
-{
-    struct extmap	*em;
-
+/* #ifdef CRLF  */ 
+static __inline__ int crlf( of)
+     struct ofork	*of;
+{ 
+  struct extmap	*em;
+  
+  /* if we are doing translations, do all this stuff - davidw  */ 
+  if (default_options.crlfbool) {
     if ( ad_hfileno( &of->of_ad ) == -1 ||
-	 memcmp( ufinderi, ad_entry( &of->of_ad, ADEID_FINDERI ), 
-		 8) == 0 ) {
-	if (( em = getextmap( of->of_name )) == NULL ||
-		bcmp( "TEXT", em->em_type, sizeof( em->em_type )) == 0 ) {
-	    return( 1 );
-	} else {
-	    return( 0 );
+	memcmp( ufinderi, ad_entry( &of->of_ad, ADEID_FINDERI ), 
+	       8) == 0 ) {
+      if (( em = getextmap( of->of_name )) == NULL ||
+	  bcmp( "TEXT", em->em_type, sizeof( em->em_type )) == 0 ) {
+	return( 1 );
+      } else {
+	  return( 0 );
 	}
     } else {
       if ( memcmp( ufinderi, 
-		   ad_entry( &of->of_ad, ADEID_FINDERI ), 4 ) == 0 ) {
-	    return( 1 );
-	} else {
-	    return( 0 );
-	}
+		  ad_entry( &of->of_ad, ADEID_FINDERI ), 4 ) == 0 ) {
+	return( 1 );
+      } else {
+	return( 0 );
+      }
     }
+  } else {
+    /* if we are not doing translations, simply set xlate to 0  */ 
+    return 0;
+  }
 }
-#endif CRLF
+/* #endif CRLF  */ 

 static __inline__ int read_file(struct ofork *ofork, int eid, int offset,
@@ -462,19 +468,20 @@
 	}
     }
 
-#ifdef CRLF
+    /* #ifdef CRLF  */ 
     /*
      * If this file is of type TEXT, then swap \012 to \015.
      */
+    
     if (xlate) {
-	for ( p = rbuf, q = p + cc; p < q; p++ ) {
-	    if ( *p == '\012' ) {
-		*p = '\015';
-	    }
+      for ( p = rbuf, q = p + cc; p < q; p++ ) {
+	if ( *p == '\012' ) {
+	  *p = '\015';
 	}
+      }
     }
-#endif CRLF
-
+    /* #endif CRLF  */ 
+    
     *rbuflen = cc;
     if ( eof ) {
 	return( AFPERR_EOF );
@@ -515,9 +522,11 @@
 
     if ( ad_dfileno( &ofork->of_ad ) != -1 ) {
 	eid = ADEID_DFORK;
-#ifdef CRLF
+ /* #ifdef CRLF
 	xlate = crlf(ofork);
-#endif
+#endif  */ 
+	xlate = crlf(ofork);
+
     } else if (ad_hfileno( &ofork->of_ad ) != -1 ) {
 	eid = ADEID_RFORK;
     } else {
@@ -734,18 +743,19 @@
     char *p, *q;
     int cc;
 
-#ifdef CRLF
+ /* #ifdef CRLF  */ 
     /*
      * If this file is of type TEXT, swap \015 to \012.
      */
     if (xlate) {
-	for ( p = rbuf, q = p + rbuflen; p < q; p++ ) {
-	    if ( *p == '\015' ) {
-		*p = '\012';
-	    }
+      for ( p = rbuf, q = p + rbuflen; p < q; p++ ) {
+	  if ( *p == '\015' ) {
+	    *p = '\012';
+	  }
 	}
     }
-#endif CRLF
+    
+    /* #endif CRLF  */ 
 
     if (( cc = ad_write(&ofork->of_ad, eid, offset, endflag, 
 			 rbuf, rbuflen)) < 0 ) {
@@ -803,9 +813,11 @@
 
     if ( ad_dfileno( &ofork->of_ad ) != -1 ) {
 	eid = ADEID_DFORK;
-#ifdef CRLF
+ /* #ifdef CRLF
 	xlate = crlf(ofork);
-#endif
+#endif  */ 
+	xlate = crlf(ofork);
+
     } else if (ad_hfileno(&ofork->of_ad) != -1) {
 	eid = ADEID_RFORK;
     } else 
diff -u netatalk-asun-2.0a18.2/etc/afpd/globals.h debian7/netatalk-asun-2.0a18.2/etc/afpd/globals.h
--- netatalk-asun-2.0a18.2/etc/afpd/globals.h	Tue Feb 17 16:51:38 1998
+++ debian7/netatalk-asun-2.0a18.2/etc/afpd/globals.h	Wed Mar 25 17:22:36 1998
@@ -29,6 +29,7 @@
   char hostname[MAXHOSTNAMELEN + 1], *server, *address, *configfile;
   char *pidfile, *defaultvol, *systemvol;
   char *guest, *loginmesg, *passwdfile;
+  int crlfbool;  /* davidw - global to toggle CRLF stuff  */ 
 };
 
 typedef struct AFPObj {
@@ -53,5 +54,7 @@
 extern void afp_options_free __P((struct afp_options *, 
 				  const struct afp_options *));
 extern void setmessage __P((const char *));
+
+struct afp_options default_options;
 
 #endif /* globals.h */
diff -u netatalk-asun-2.0a18.2/etc/afpd/main.c debian7/netatalk-asun-2.0a18.2/etc/afpd/main.c
--- netatalk-asun-2.0a18.2/etc/afpd/main.c	Tue Feb 17 16:51:38 1998
+++ debian7/netatalk-asun-2.0a18.2/etc/afpd/main.c	Wed Mar 25 16:54:50 1998
@@ -40,7 +40,7 @@
 
 unsigned char	nologin = 0;
 
-static struct afp_options default_options;
+ /* static struct afp_options default_options;  */ 
 static AFPConfig *configs;
 static server_child *server_children;
 static fd_set save_rfds;