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