]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/file.c
* Add Apple II boot support for Appl IIe (with workstation card) and
[netatalk.git] / etc / afpd / file.c
index b9a5507fda2b2108a5facf03a36c84da340a7578..32073ad87fcd1cfd0f39bcf13aba5a666e00eb43 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: file.c,v 1.64 2002-10-12 04:02:46 didg Exp $
+ * $Id: file.c,v 1.71 2003-01-11 17:26:06 jmarcus Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -106,19 +106,8 @@ void *get_finderinfo(const char *mpath, struct adouble *adp, void *data)
     return data;
 }
 
-/*
- * FIXME: PDINFO is UTF8 and doesn't need adp
+/* ---------------------
 */
-#define PARAM_NEED_ADP(b) ((b) & ((1 << FILPBIT_ATTR)  |\
-                                 (1 << FILPBIT_CDATE) |\
-                                 (1 << FILPBIT_MDATE) |\
-                                 (1 << FILPBIT_BDATE) |\
-                                 (1 << FILPBIT_FINFO) |\
-                                 (1 << FILPBIT_RFLEN) |\
-                                 (1 << FILPBIT_EXTRFLEN) |\
-                                 (1 << FILPBIT_PDINFO)))
-
-
 char *set_name(char *data, const char *name, u_int32_t utf8) 
 {
     u_int32_t           aint;
@@ -126,6 +115,9 @@ char *set_name(char *data, const char *name, u_int32_t utf8)
     aint = strlen( name );
 
     if (!utf8) {
+        if (afp_version >= 30) {
+            /* the name is in utf8 */
+        }
         if (aint > MACFILELEN)
             aint = MACFILELEN;
         *data++ = aint;
@@ -151,6 +143,19 @@ char *set_name(char *data, const char *name, u_int32_t utf8)
     return data;
 }
 
+/*
+ * FIXME: PDINFO is UTF8 and doesn't need adp
+*/
+#define PARAM_NEED_ADP(b) ((b) & ((1 << FILPBIT_ATTR)  |\
+                                 (1 << FILPBIT_CDATE) |\
+                                 (1 << FILPBIT_MDATE) |\
+                                 (1 << FILPBIT_BDATE) |\
+                                 (1 << FILPBIT_FINFO) |\
+                                 (1 << FILPBIT_RFLEN) |\
+                                 (1 << FILPBIT_EXTRFLEN) |\
+                                 (1 << FILPBIT_PDINFO)))
+
+
 /* -------------------------- */
 int getmetadata(struct vol *vol,
                  u_int16_t bitmap,
@@ -160,7 +165,8 @@ int getmetadata(struct vol *vol,
 #ifndef USE_LASTDID
     struct stat                lst, *lstp;
 #endif /* USE_LASTDID */
-    char               *data, *nameoff = NULL, *upath;
+    char               *data, *l_nameoff = NULL, *upath;
+    char                *utf_nameoff = NULL;
     int                        bit = 0;
     u_int32_t          aint;
     u_int16_t          ashort;
@@ -250,7 +256,7 @@ int getmetadata(struct vol *vol,
             break;
 
         case FILPBIT_LNAME :
-            nameoff = data;
+            l_nameoff = data;
             data += sizeof( u_int16_t );
             break;
 
@@ -351,11 +357,15 @@ int getmetadata(struct vol *vol,
                us what the PD file code should be.  Everything gets a
                subtype of 0x0000 unless the original value was hashed
                to "pXYZ" when we created it.  See IA, Ver 2.
-               <shirsch@ibm.net> */
+               <shirsch@adelphia.net> */
         case FILPBIT_PDINFO :
             if (afp_version >= 30) { /* UTF8 name */
                 utf8 = kTextEncodingUTF8;
+                utf_nameoff = data;
                 data += sizeof( u_int16_t );
+                aint = 0;
+                memcpy(data, &aint, sizeof( aint ));
+                data += sizeof( aint );
             }
             else {
                 if ( adp ) {
@@ -424,9 +434,14 @@ int getmetadata(struct vol *vol,
         bitmap = bitmap>>1;
         bit++;
     }
-    if ( nameoff ) {
+    if ( l_nameoff ) {
         ashort = htons( data - buf );
-        memcpy(nameoff, &ashort, sizeof( ashort ));
+        memcpy(l_nameoff, &ashort, sizeof( ashort ));
+        data = set_name(data, path, 0);
+    }
+    if ( utf_nameoff ) {
+        ashort = htons( data - buf );
+        memcpy(utf_nameoff, &ashort, sizeof( ashort ));
         data = set_name(data, path, utf8);
     }
     *buflen = data - buf;
@@ -531,11 +546,11 @@ int               ibuflen, *rbuflen;
     ibuf += sizeof( did );
 
     if (( dir = dirlookup( vol, did )) == NULL ) {
-        return( AFPERR_NOOBJ );
+        return afp_errno;
     }
 
     if (( s_path = cname( vol, dir, &ibuf )) == NULL ) {
-        return( AFPERR_NOOBJ );
+        return afp_errno;
     }
 
     if ( *s_path->m_name == '\0' ) {
@@ -593,6 +608,7 @@ int         ibuflen, *rbuflen;
     ad_close( adp, ADFLAGS_DF|ADFLAGS_HF );
 
 createfile_done:
+    curdir->offcnt++;
 
 #ifdef DROPKLUDGE
     if (vol->v_flags & AFPVOL_DROPBOX) {
@@ -647,7 +663,7 @@ int         ibuflen, *rbuflen;
     ibuf += sizeof( bitmap );
 
     if (( s_path = cname( vol, dir, &ibuf )) == NULL ) {
-        return( AFPERR_NOOBJ );
+        return afp_errno;
     }
 
     if ( *s_path->m_name == '\0' ) {
@@ -784,43 +800,24 @@ int setfilparams(struct vol *vol,
             break;
 
             /* Client needs to set the ProDOS file info for this file.
-               Use defined strings for the simple cases, and convert
-               all else into pXYY per Inside Appletalk.  Always set
-               the creator as "pdos". <shirsch@ibm.net> */
+               Use a defined string for TEXT to support crlf
+               translations and convert all else into pXYY per Inside
+               Appletalk.  Always set the creator as "pdos".  Changes
+               from original by Marsha Jackson. */
         case FILPBIT_PDINFO :
             achar = *buf;
             buf += 2;
-            memcpy(&ashort, buf, sizeof( ashort ));
-            ashort = ntohs( ashort );
-            buf += 2;
-
-            switch ( (unsigned int) achar )
-            {
-            case 0x04 :
-                fdType = ( u_char *) "TEXT";
-                break;
-
-            case 0xff :
-                fdType = ( u_char *) "PSYS";
-                break;
-
-            case 0xb3 :
-                fdType = ( u_char *) "PS16";
-                break;
-
-            case 0x00 :
-                fdType = ( u_char *) "BINA";
-                break;
-
-            default :
-                xyy[0] = ( u_char ) 'p';
-                xyy[1] = achar;
-                xyy[2] = ( u_char ) ( ashort >> 8 ) & 0xff;
-                xyy[3] = ( u_char ) ashort & 0xff;
-                fdType = xyy;
-                break;
-            }
-
+            /* Keep special case to support crlf translations */
+            if ((unsigned int) achar == 0x04) {
+               fdType = (u_char *)"TEXT";
+               buf += 2;
+            } else {
+               xyy[0] = ( u_char ) 'p';
+               xyy[1] = achar;
+               xyy[3] = *buf++;
+               xyy[2] = *buf++;
+               fdType = xyy;
+           }
             memcpy(ad_entry( adp, ADEID_FINDERI ), fdType, 4 );
             memcpy(ad_entry( adp, ADEID_FINDERI ) + 4, "pdos", 4 );
             break;
@@ -897,7 +894,7 @@ struct adouble    *adp;
     LOG(log_info, logtype_afpd, "begin renamefile:");
 #endif /* DEBUG */
 
-    if ( rename( src, dst ) < 0 ) {
+    if ( unix_rename( src, dst ) < 0 ) {
         switch ( errno ) {
         case ENOENT :
             return( AFPERR_NOOBJ );
@@ -920,7 +917,7 @@ struct adouble    *adp;
     strcpy( adsrc, ad_path( src, 0 ));
     rc = 0;
 rename_retry:
-    if (rename( adsrc, ad_path( dst, 0 )) < 0 ) {
+    if (unix_rename( adsrc, ad_path( dst, 0 )) < 0 ) {
         struct stat st;
 
         switch ( errno ) {
@@ -969,6 +966,49 @@ rename_retry:
     return( AFP_OK );
 }
 
+int copy_path_name(char *newname, char *ibuf)
+{
+char        type = *ibuf;
+size_t      plen = 0;
+u_int16_t   len16;
+u_int32_t   hint;
+
+    if ( type != 2 && !(afp_version >= 30 && type == 3) ) {
+        return -1;
+    }
+    ibuf++;
+    switch (type) {
+    case 2:
+        if (( plen = (unsigned char)*ibuf++ ) != 0 ) {
+            strncpy( newname, ibuf, plen );
+            newname[ plen ] = '\0';
+            if (strlen(newname) != plen) {
+                /* there's \0 in newname, e.g. it's a pathname not
+                 * only a filename. 
+                */
+               return -1;
+            }
+        }
+        break;
+    case 3:
+        memcpy(&hint, ibuf, sizeof(hint));
+        ibuf += sizeof(hint);
+           
+        memcpy(&len16, ibuf, sizeof(len16));
+        ibuf += sizeof(len16);
+        plen = ntohs(len16);
+        if (plen) {
+            strncpy( newname, ibuf, plen );
+            newname[ plen ] = '\0';
+            if (strchr(newname,'/')) {
+               return -1;
+            }
+        }
+        break;
+    }
+    return plen;
+}
+
 /* -----------------------------------
 */
 int afp_copyfile(obj, ibuf, ibuflen, rbuf, rbuflen )
@@ -981,7 +1021,6 @@ int                ibuflen, *rbuflen;
     char       *newname, *p, *upath;
     struct path *s_path;
     u_int32_t  sdid, ddid;
-    size_t      plen;
     int         err, retvalue = AFP_OK;
     u_int16_t  svid, dvid;
 
@@ -1001,7 +1040,7 @@ int               ibuflen, *rbuflen;
     memcpy(&sdid, ibuf, sizeof( sdid ));
     ibuf += sizeof( sdid );
     if (( dir = dirlookup( vol, sdid )) == NULL ) {
-        return( AFPERR_PARAM );
+        return afp_errno;
     }
 
     memcpy(&dvid, ibuf, sizeof( dvid ));
@@ -1010,7 +1049,7 @@ int               ibuflen, *rbuflen;
     ibuf += sizeof( ddid );
 
     if (( s_path = cname( vol, dir, &ibuf )) == NULL ) {
-        return( AFPERR_NOOBJ );
+        return afp_errno;
     }
     if ( *s_path->m_name == '\0' ) {
         return( AFPERR_BADTYPE );
@@ -1040,34 +1079,26 @@ int             ibuflen, *rbuflen;
         return AFPERR_VLOCK;
 
     if (( dir = dirlookup( vol, ddid )) == NULL ) {
-        return( AFPERR_PARAM );
+        return afp_errno;
     }
 
     if (( s_path = cname( vol, dir, &ibuf )) == NULL ) {
-        return( AFPERR_NOOBJ );
+        return afp_errno;
     }
     if ( *s_path->m_name != '\0' ) {
         return( AFPERR_BADTYPE ); /* not a directory. AFPERR_PARAM? */
     }
 
     /* one of the handful of places that knows about the path type */
-    if ( *ibuf++ != 2 ) {
+    if (copy_path_name(newname, ibuf) < 0) {
         return( AFPERR_PARAM );
     }
-    if (( plen = (unsigned char)*ibuf++ ) != 0 ) {
-        strncpy( newname, ibuf, plen );
-        newname[ plen ] = '\0';
-        if (strlen(newname) != plen) {
-            /* there's \0 in newname, e.g. it's a pathname not
-             * only a filename. 
-            */
-            return( AFPERR_PARAM );
-        }
-    }
+
     upath = mtoupath(vol, newname);
     if ( (err = copyfile(p, upath , newname, vol_noadouble(vol))) < 0 ) {
         return err;
     }
+    curdir->offcnt++;
 
 #ifdef DROPKLUDGE
     if (vol->v_flags & AFPVOL_DROPBOX) {