aboutsummaryrefslogtreecommitdiffstats
path: root/cache.c
diff options
context:
space:
mode:
authorJohn Keeping2013-04-06 10:28:57 +0100
committerJason A. Donenfeld2013-04-08 16:12:52 +0200
commitfb3655df3bf85bd405c5921bbd4b3a54c705c839 (patch)
tree419a962a0b82f5ba3023791549044ff462229250 /cache.c
parent42d5476f258e7909682f1b611da00d64507d45c6 (diff)
downloadcgit-fb3655df3bf85bd405c5921bbd4b3a54c705c839.tar.gz
cgit-fb3655df3bf85bd405c5921bbd4b3a54c705c839.tar.bz2
cgit-fb3655df3bf85bd405c5921bbd4b3a54c705c839.zip
use struct strbuf instead of static buffers
Use "struct strbuf" from Git to remove the limit on file path length. Notes on scan-tree: This is slightly involved since I decided to pass the strbuf into add_repo() and modify if whenever a new file name is required, which should avoid any extra allocations within that function. The pattern there is to append the filename, use it and then reset the buffer to its original length (retaining a trailing '/'). Notes on ui-snapshot: Since write_archive modifies the argv array passed to it we copy the argv_array values into a new array of char* and then free the original argv_array structure and the new array without worrying about what the values now look like. Signed-off-by: John Keeping <john@keeping.me.uk>
Diffstat (limited to 'cache.c')
-rw-r--r--cache.c57
1 files changed, 20 insertions, 37 deletions
diff --git a/cache.c b/cache.c
index 3127fc2..c1d777b 100644
--- a/cache.c
+++ b/cache.c
@@ -312,9 +312,9 @@ int cache_process(int size, const char *path, const char *key, int ttl,
312 cache_fill_fn fn, void *cbdata) 312 cache_fill_fn fn, void *cbdata)
313{ 313{
314 unsigned long hash; 314 unsigned long hash;
315 int len, i; 315 int i;
316 char filename[1024]; 316 struct strbuf filename = STRBUF_INIT;
317 char lockname[1024 + 5]; /* 5 = ".lock" */ 317 struct strbuf lockname = STRBUF_INIT;
318 struct cache_slot slot; 318 struct cache_slot slot;
319 319
320 /* If the cache is disabled, just generate the content */ 320 /* If the cache is disabled, just generate the content */
@@ -329,32 +329,22 @@ int cache_process(int size, const char *path, const char *key, int ttl,
329 fn(cbdata); 329 fn(cbdata);
330 return 0; 330 return 0;
331 } 331 }
332 len = strlen(path);
333 if (len > sizeof(filename) - 10) { /* 10 = "/01234567\0" */
334 cache_log("[cgit] Cache path too long, caching is disabled: %s\n",
335 path);
336 fn(cbdata);
337 return 0;
338 }
339 if (!key) 332 if (!key)
340 key = ""; 333 key = "";
341 hash = hash_str(key) % size; 334 hash = hash_str(key) % size;
342 strcpy(filename, path); 335 strbuf_addstr(&filename, path);
343 if (filename[len - 1] != '/') 336 strbuf_ensure_end(&filename, '/');
344 filename[len++] = '/';
345 for (i = 0; i < 8; i++) { 337 for (i = 0; i < 8; i++) {
346 sprintf(filename + len++, "%x", 338 strbuf_addf(&filename, "%x", (unsigned char)(hash & 0xf));
347 (unsigned char)(hash & 0xf));
348 hash >>= 4; 339 hash >>= 4;
349 } 340 }
350 filename[len] = '\0'; 341 strbuf_addbuf(&lockname, &filename);
351 strcpy(lockname, filename); 342 strbuf_addstr(&lockname, ".lock");
352 strcpy(lockname + len, ".lock");
353 slot.fn = fn; 343 slot.fn = fn;
354 slot.cbdata = cbdata; 344 slot.cbdata = cbdata;
355 slot.ttl = ttl; 345 slot.ttl = ttl;
356 slot.cache_name = filename; 346 slot.cache_name = strbuf_detach(&filename, NULL);
357 slot.lock_name = lockname; 347 slot.lock_name = strbuf_detach(&lockname, NULL);
358 slot.key = key; 348 slot.key = key;
359 slot.keylen = strlen(key); 349 slot.keylen = strlen(key);
360 return process_slot(&slot); 350 return process_slot(&slot);
@@ -381,18 +371,13 @@ int cache_ls(const char *path)
381 struct dirent *ent; 371 struct dirent *ent;
382 int err = 0; 372 int err = 0;
383 struct cache_slot slot; 373 struct cache_slot slot;
384 char fullname[1024]; 374 struct strbuf fullname = STRBUF_INIT;
385 char *name; 375 size_t prefixlen;
386 376
387 if (!path) { 377 if (!path) {
388 cache_log("[cgit] cache path not specified\n"); 378 cache_log("[cgit] cache path not specified\n");
389 return -1; 379 return -1;
390 } 380 }
391 if (strlen(path) > 1024 - 10) {
392 cache_log("[cgit] cache path too long: %s\n",
393 path);
394 return -1;
395 }
396 dir = opendir(path); 381 dir = opendir(path);
397 if (!dir) { 382 if (!dir) {
398 err = errno; 383 err = errno;
@@ -400,30 +385,28 @@ int cache_ls(const char *path)
400 path, strerror(err), err); 385 path, strerror(err), err);
401 return err; 386 return err;
402 } 387 }
403 strcpy(fullname, path); 388 strbuf_addstr(&fullname, path);
404 name = fullname + strlen(path); 389 strbuf_ensure_end(&fullname, '/');
405 if (*(name - 1) != '/') { 390 prefixlen = fullname.len;
406 *name++ = '/';
407 *name = '\0';
408 }
409 slot.cache_name = fullname;
410 while ((ent = readdir(dir)) != NULL) { 391 while ((ent = readdir(dir)) != NULL) {
411 if (strlen(ent->d_name) != 8) 392 if (strlen(ent->d_name) != 8)
412 continue; 393 continue;
413 strcpy(name, ent->d_name); 394 strbuf_setlen(&fullname, prefixlen);
395 strbuf_addstr(&fullname, ent->d_name);
414 if ((err = open_slot(&slot)) != 0) { 396 if ((err = open_slot(&slot)) != 0) {
415 cache_log("[cgit] unable to open path %s: %s (%d)\n", 397 cache_log("[cgit] unable to open path %s: %s (%d)\n",
416 fullname, strerror(err), err); 398 fullname.buf, strerror(err), err);
417 continue; 399 continue;
418 } 400 }
419 printf("%s %s %10"PRIuMAX" %s\n", 401 printf("%s %s %10"PRIuMAX" %s\n",
420 name, 402 fullname.buf,
421 sprintftime("%Y-%m-%d %H:%M:%S", 403 sprintftime("%Y-%m-%d %H:%M:%S",
422 slot.cache_st.st_mtime), 404 slot.cache_st.st_mtime),
423 (uintmax_t)slot.cache_st.st_size, 405 (uintmax_t)slot.cache_st.st_size,
424 slot.buf); 406 slot.buf);
425 close_slot(&slot); 407 close_slot(&slot);
426 } 408 }
409 slot.cache_name = strbuf_detach(&fullname, NULL);
427 closedir(dir); 410 closedir(dir);
428 return 0; 411 return 0;
429} 412}