Commit 2fd00a89 2fd00a89aad95ea5070dcfeb38227874da1fad5f by Sergey Poznyakoff

Handle extended URL specification. Implemented three hash schemes.

1 parent 27354151
...@@ -347,7 +347,7 @@ url_parse0 (url_t u, char *name) ...@@ -347,7 +347,7 @@ url_parse0 (url_t u, char *name)
347 *p++ = 0; 347 *p++ = 0;
348 u->path = p; 348 u->path = p;
349 } 349 }
350 350
351 return 0; 351 return 0;
352 } 352 }
353 353
......
...@@ -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
......