Handle extended URL specification. Implemented three hash schemes.
Showing
2 changed files
with
144 additions
and
3 deletions
... | @@ -34,16 +34,104 @@ url_mbox_destroy (url_t url) | ... | @@ -34,16 +34,104 @@ url_mbox_destroy (url_t url) |
34 | (void) url; | 34 | (void) url; |
35 | } | 35 | } |
36 | 36 | ||
37 | /* Default mailbox path generator */ | ||
38 | static char * | ||
39 | _url_path_default (const char *spooldir, const char *user, int unused) | ||
40 | { | ||
41 | char *mbox = malloc (sizeof(spooldir) + strlen(user) + 2); | ||
42 | if (!mbox) | ||
43 | errno = ENOMEM; | ||
44 | else | ||
45 | sprintf (mbox, "%s/%s", spooldir, user); | ||
46 | return mbox; | ||
47 | } | ||
48 | |||
49 | /* Hashed indexing */ | ||
50 | static char * | ||
51 | _url_path_hashed (const char *spooldir, const char *user, int param) | ||
52 | { | ||
53 | int i; | ||
54 | int ulen = strlen (user); | ||
55 | char *mbox; | ||
56 | unsigned hash; | ||
57 | |||
58 | if (param > ulen) | ||
59 | param = ulen; | ||
60 | for (i = 0, hash = 0; i < param; i++) | ||
61 | hash += user[i]; | ||
62 | |||
63 | mbox = malloc (ulen + strlen (spooldir) + 5); | ||
64 | sprintf (mbox, "%s/%02X/%s", spooldir, hash % 256, user); | ||
65 | return mbox; | ||
66 | } | ||
67 | |||
68 | /* Forward Indexing */ | ||
69 | static char * | ||
70 | _url_path_index (const char *spooldir, const char *user, int index_depth) | ||
71 | { | ||
72 | int i, ulen = strlen (user); | ||
73 | char *mbox, *p; | ||
74 | |||
75 | if (ulen == 0) | ||
76 | return NULL; | ||
77 | |||
78 | mbox = malloc (ulen + strlen (spooldir) + 2*index_depth + 1); | ||
79 | strcpy (mbox, spooldir); | ||
80 | p = mbox + strlen (mbox); | ||
81 | for (i = 0; i < index_depth && i < ulen; i++) | ||
82 | { | ||
83 | *p++ = '/'; | ||
84 | *p++ = user[i]; | ||
85 | } | ||
86 | for (; i < index_depth; i++) | ||
87 | { | ||
88 | *p++ = '/'; | ||
89 | *p++ = user[ulen-1]; | ||
90 | } | ||
91 | *p++ = '/'; | ||
92 | strcpy (p, user); | ||
93 | return mbox; | ||
94 | } | ||
95 | |||
96 | /* Reverse Indexing */ | ||
97 | static char * | ||
98 | _url_path_rev_index (const char *spooldir, const char *user, int index_depth) | ||
99 | { | ||
100 | int i, ulen = strlen (user); | ||
101 | char *mbox, *p; | ||
102 | |||
103 | if (ulen == 0) | ||
104 | return NULL; | ||
105 | |||
106 | mbox = malloc (ulen + strlen (spooldir) + 2*index_depth + 1); | ||
107 | strcpy (mbox, spooldir); | ||
108 | p = mbox + strlen (mbox); | ||
109 | for (i = 0; i < index_depth && i < ulen; i++) | ||
110 | { | ||
111 | *p++ = '/'; | ||
112 | *p++ = user[ulen - i - 1]; | ||
113 | } | ||
114 | for (; i < index_depth; i++) | ||
115 | { | ||
116 | *p++ = '/'; | ||
117 | *p++ = user[0]; | ||
118 | } | ||
119 | *p++ = '/'; | ||
120 | strcpy (p, user); | ||
121 | return mbox; | ||
122 | } | ||
123 | |||
37 | /* | 124 | /* |
38 | UNIX Mbox | 125 | UNIX Mbox |
39 | mbox:path | 126 | mbox:path[;type=TYPE][;param=PARAM][;user=USERNAME] |
40 | */ | 127 | */ |
41 | int | 128 | int |
42 | _url_mbox_init (url_t url) | 129 | _url_mbox_init (url_t url) |
43 | { | 130 | { |
44 | const char *name = url_to_string (url); | 131 | const char *name = url_to_string (url); |
45 | size_t len = strlen (name); | 132 | size_t len = strlen (name); |
46 | 133 | char *p; | |
134 | |||
47 | /* reject the obvious */ | 135 | /* reject the obvious */ |
48 | if (name == NULL || strncmp (MU_MBOX_SCHEME, name, MU_MBOX_SCHEME_LEN) != 0 | 136 | if (name == NULL || strncmp (MU_MBOX_SCHEME, name, MU_MBOX_SCHEME_LEN) != 0 |
49 | || len < (MU_MBOX_SCHEME_LEN + 1) /* (scheme)+1(path)*/) | 137 | || len < (MU_MBOX_SCHEME_LEN + 1) /* (scheme)+1(path)*/) |
... | @@ -70,6 +158,59 @@ _url_mbox_init (url_t url) | ... | @@ -70,6 +158,59 @@ _url_mbox_init (url_t url) |
70 | url_mbox_destroy (url); | 158 | url_mbox_destroy (url); |
71 | return ENOMEM; | 159 | return ENOMEM; |
72 | } | 160 | } |
161 | p = strchr (url->path, ';'); | ||
162 | if (p) | ||
163 | { | ||
164 | char *(*fun)() = _url_path_default; | ||
165 | char *user = NULL; | ||
166 | int param = 0; | ||
167 | |||
168 | *p++ = 0; | ||
169 | while (p) | ||
170 | { | ||
171 | char *q = strchr (p, ';'); | ||
172 | if (q) | ||
173 | *q++ = 0; | ||
174 | if (strncasecmp (p, "type=", 5) == 0) | ||
175 | { | ||
176 | char *type = p + 5; | ||
177 | |||
178 | if (strcmp (type, "hash") == 0) | ||
179 | fun = _url_path_hashed; | ||
180 | else if (strcmp (type, "index") == 0) | ||
181 | fun = _url_path_index; | ||
182 | else if (strcmp (type, "rev-index") == 0) | ||
183 | fun = _url_path_rev_index; | ||
184 | else | ||
185 | { | ||
186 | url_mbox_destroy (url); | ||
187 | return ENOENT; | ||
188 | } | ||
189 | } | ||
190 | else if (strncasecmp (p, "user=", 5) == 0) | ||
191 | { | ||
192 | user = p + 5; | ||
193 | } | ||
194 | else if (strncasecmp (p, "param=", 6) == 0) | ||
195 | { | ||
196 | param = strtoul (p+6, NULL, 0); | ||
197 | } | ||
198 | p = q; | ||
199 | } | ||
200 | |||
201 | if (user) | ||
202 | { | ||
203 | p = fun (url->path, user, param); | ||
204 | free (url->path); | ||
205 | url->path = p; | ||
206 | } | ||
207 | else | ||
208 | { | ||
209 | url_mbox_destroy (url); | ||
210 | return ENOENT; | ||
211 | } | ||
212 | } | ||
73 | 213 | ||
74 | return 0; | 214 | return 0; |
75 | } | 215 | } |
216 | ... | ... |
-
Please register or sign in to post a comment