]> arthur.barton.de Git - netatalk.git/blob - etc/afpd/mangle.c
Add support for long filename mangling. Basically, tis code will take
[netatalk.git] / etc / afpd / mangle.c
1 /* 
2  * $Id: mangle.c,v 1.1 2002-05-29 18:02:59 jmarcus 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         char dir[MAXPATHLEN+1];
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         ext = strrchr(mfilename, '.');
33         if (strlen(mangle) != strlen(MANGLE_CHAR) + MANGLE_LENGTH + strlen(ext)) {
34             return mfilename;
35         }
36
37         getcwd(dir, MAXPATHLEN);
38
39         if (strlen(dir) > MAXPATHLEN - strlen(mfilename) - 1) {
40             LOG(log_error, logtype_default, "demangle: Path is too large");
41             return mfilename;
42         }
43
44         strcat(dir, "/");
45         strcat(dir, mfilename);
46
47         filename = cnid_mangle_get(vol->v_db, dir);
48
49         /* No unmangled filename was found. */
50         if (filename == NULL) {
51             LOG(log_debug, logtype_default, "demangle: Unable to lookup %s in the mangle database", dir);
52             return mfilename;
53         }
54
55         return filename;
56 }
57 char *
58 mangle(const struct vol *vol, char *filename) {
59     char *ext = NULL;
60     char mfilename[MAX_LENGTH+1];
61     char mangle_suffix[MANGLE_LENGTH+1];
62     char dir[MAXPATHLEN+1];
63     char tmp[MAXPATHLEN+1];
64     int mangle_suffix_int = 0;
65
66     /* Do we really need to mangle this filename? */
67     if (strlen(filename) <= MAX_LENGTH) {
68         return filename;
69     }
70
71     /* First, attmept to locate a file extension. */
72     ext = strrchr(filename, '.');
73
74     getcwd(dir, MAXPATHLEN);
75
76     if (strlen(dir) > MAXPATHLEN - strlen(filename) - 1) {
77         LOG(log_error, logtype_default, "mangle: path is too large");
78         return filename;
79     }
80
81     /* Check to see if we already have a mangled filename by this name. */
82     while (1) {
83         strcpy(tmp, dir);
84         strncpy(mfilename, filename, MAX_LENGTH - strlen(MANGLE_CHAR) - MANGLE_LENGTH - ((ext != NULL)?strlen(ext):0));
85         strcat(mfilename, MANGLE_CHAR);
86         (void)sprintf(mangle_suffix, "%03d", mangle_suffix_int);
87         strcat(mfilename, mangle_suffix);
88
89         if (ext) {
90                 strcat(mfilename, ext);
91         }
92         
93         strcat(tmp, "/");
94         strcat(tmp, mfilename);
95
96         if (!cnid_mangle_get(vol->v_db, tmp)) {
97             break;
98         }
99         else {
100             if (++mangle_suffix_int > MAX_MANGLE_SUFFIX_LENGTH) {
101                 LOG(log_error, logtype_default, "mangle: Failed to find a free mangle suffix; returning original filename");
102                 return filename;
103             }
104         }
105     }
106
107     if (cnid_mangle_add(vol->v_db, mfilename, tmp) < 0) {
108         return filename;
109     }
110
111     filename = mfilename;
112
113     return filename;
114 }
115 #endif /* FILE_MANGLING */