]> arthur.barton.de Git - netatalk.git/blob - etc/afpd/mangle.c
add utf8 support for AFP3
[netatalk.git] / etc / afpd / mangle.c
1 /* 
2  * $Id: mangle.c,v 1.15 2003-03-09 19:55:35 didg Exp $ 
3  *
4  * Copyright (c) 2002. Joe Marcus Clarke (marcus@marcuscom.com)
5  * All Rights Reserved.  See COPYRIGHT.
6  *
7  * mangle, demangle (filename):
8  * mangle or demangle filenames if they are greater than the max allowed
9  * characters for a given version of AFP.
10  */
11
12 #ifdef HAVE_CONFIG_H
13 #include "config.h"
14 #endif /* HAVE_CONFIG_H */
15
16 #ifdef FILE_MANGLING
17 #include "mangle.h"
18
19 char *
20 demangle(const struct vol *vol, char *mfilename) {
21         char *filename = NULL;
22         char *ext = NULL;
23         int ext_len = 0;
24         char *mangle;
25
26         /* Is this really a mangled file? */
27         mangle = strstr(mfilename, MANGLE_CHAR);
28         if (!mangle) {
29             return mfilename;
30         }
31
32         if (NULL != (ext = strrchr(mfilename, '.')) ) {
33             ext_len = strlen(ext);
34         }
35         if (strlen(mangle) != strlen(MANGLE_CHAR) + MANGLE_LENGTH + ext_len) {
36             return mfilename;
37         }
38
39         filename = cnid_mangle_get(vol->v_db, mfilename);
40
41         /* No unmangled filename was found. */
42         if (filename == NULL) {
43 #ifdef DEBUG
44             LOG(log_debug, logtype_afpd, "demangle: Unable to lookup %s in the mangle database", mfilename);
45 #endif
46             return mfilename;
47         }
48         return filename;
49 }
50
51 /* -----------------------
52    with utf8 filename not always round trip
53    filename   mac filename too long or with unmatchable utf8 replaced with _
54    uname      unix filename 
55 */
56 char *
57 mangle(const struct vol *vol, char *filename, char *uname, int flags) {
58     char *ext = NULL;
59     char *tf = NULL;
60     char *m = NULL;
61     static char mfilename[MAX_LENGTH + 1];
62     char mangle_suffix[MANGLE_LENGTH + 1];
63     int ext_len = 0;
64     int mangle_suffix_int = 0;
65
66     /* Do we really need to mangle this filename? */
67     if (!flags && strlen(filename) <= vol->max_filename) {
68         return filename;
69     }
70     /* First, attempt to locate a file extension. */
71     if (NULL != (ext = strrchr(filename, '.')) ) {
72         ext_len = strlen(ext);
73         if (ext_len > MAX_EXT_LENGTH) {
74             /* Do some bounds checking to prevent an extension overflow. */
75             ext_len = MAX_EXT_LENGTH;
76         }
77     }
78
79     /* Check to see if we already have a mangled filename by this name. */
80     while (1) {
81         m = mfilename;
82         strncpy(m, filename, MAX_LENGTH - strlen(MANGLE_CHAR) - MANGLE_LENGTH - ext_len);
83         m[MAX_LENGTH - strlen(MANGLE_CHAR) - MANGLE_LENGTH - ext_len] = '\0';
84
85         strcat(m, MANGLE_CHAR);
86         (void)sprintf(mangle_suffix, "%03d", mangle_suffix_int);
87         strcat(m, mangle_suffix);
88
89         if (ext) {
90                 strncat(m, ext, ext_len);
91         }
92
93         tf = cnid_mangle_get(vol->v_db, m);
94         if (tf == NULL || (strcmp(tf, uname)) == 0) {
95             break;
96         }
97         else {
98             if (++mangle_suffix_int > MAX_MANGLE_SUFFIX_LENGTH) {
99                 LOG(log_error, logtype_afpd, "mangle: Failed to find a free mangle suffix; returning original filename");
100                 return filename;
101             }
102         }
103     }
104
105     if (cnid_mangle_add(vol->v_db, m, uname) < 0) {
106         return filename;
107     }
108
109     return m;
110 }
111 #endif /* FILE_MANGLING */