]> arthur.barton.de Git - netatalk.git/blob - etc/afpd/mangle.c
Fix problem with last commit not being able to demangle filenames
[netatalk.git] / etc / afpd / mangle.c
1 /* 
2  * $Id: mangle.c,v 1.4 2002-05-31 02:19:41 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 + ((ext != NULL)?strlen(ext):0)) {
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
58 char *
59 mangle(const struct vol *vol, char *filename) {
60     char *ext = NULL;
61     char *tf = NULL;
62     char *m = NULL;
63     static char mfilename[MAX_LENGTH + 1];
64     char mangle_suffix[MANGLE_LENGTH + 1];
65     char dir[MAXPATHLEN + 1];
66     char tmp[MAXPATHLEN + 1];
67     int mangle_suffix_int = 0;
68
69     /* Do we really need to mangle this filename? */
70     if (strlen(filename) <= MAX_LENGTH) {
71         return filename;
72     }
73
74     /* First, attmept to locate a file extension. */
75     ext = strrchr(filename, '.');
76
77     getcwd(dir, MAXPATHLEN);
78
79     if (strlen(dir) > MAXPATHLEN - strlen(filename) - 1) {
80         LOG(log_error, logtype_default, "mangle: path is too large");
81         return filename;
82     }
83
84 /*    if ((mfilename = malloc(MAX_LENGTH + 1)) == NULL) {
85         LOG(log_error, logtype_default, "mangle: Failed to allocate memory to hold the mangled filename");
86         return filename;
87     }*/
88
89     m = mfilename;
90
91     /* Check to see if we already have a mangled filename by this name. */
92     while (1) {
93         strcpy(tmp, dir);
94
95         strncpy(m, filename, MAX_LENGTH - strlen(MANGLE_CHAR) - MANGLE_LENGTH - ((ext != NULL)?strlen(ext):0));
96         m[MAX_LENGTH - strlen(MANGLE_CHAR) - MANGLE_LENGTH - ((ext != NULL)?strlen(ext):0)] = '\0';
97
98         strcat(m, MANGLE_CHAR);
99         (void)sprintf(mangle_suffix, "%03d", mangle_suffix_int);
100         strcat(m, mangle_suffix);
101
102         if (ext) {
103                 strcat(m, ext);
104         }
105
106         strcat(tmp, "/");
107         strcat(tmp, m);
108
109         tf = cnid_mangle_get(vol->v_db, tmp);
110         if (tf == NULL || (strcmp(tf, filename)) == 0) {
111             break;
112         }
113         else {
114             if (++mangle_suffix_int > MAX_MANGLE_SUFFIX_LENGTH) {
115                 LOG(log_error, logtype_default, "mangle: Failed to find a free mangle suffix; returning original filename");
116                 return filename;
117             }
118         }
119     }
120
121     strcat(dir, "/");
122     strcat(dir, filename);
123
124     if (cnid_mangle_add(vol->v_db, tmp, dir) < 0) {
125         return filename;
126     }
127
128     return mfilename;
129 }
130 #endif /* FILE_MANGLING */