hacking the server
[reposerve] / server / src / main.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <limits.h>
5 #include <time.h>
6 #include "repo.h"
7
8 #include "md5.h"
9
10 static const char *guess_repo_name(const char *path);
11 static int parse_args(int argc, char **argv);
12
13 static const char *repo_path, *repo_name;
14
15 int main(int argc, char **argv)
16 {
17         if(parse_args(argc, argv) == -1) {
18                 return 1;
19         }
20
21         if(repo_init(repo_path) == -1) {
22                 return 1;
23         }
24         /* repo_cleanup(); */
25
26         if(!repo_name) {
27                 if(!(repo_name = guess_repo_name(repo_path))) {
28                         return 1;
29                 }
30         }
31
32         printf("Serving %s from %s\n", repo_name, repo_path);
33
34         /* DBG */
35         {
36                 struct md5_state sum;
37                 int i, count = repo_num_files();
38                 for(i=0; i<count; i++) {
39                         struct repo_file *file = repo_file(i);
40                         memcpy(sum.sum, file->chksum, sizeof sum.sum);
41                         printf("%s\tmd5:%s size:%lu mtime:%s", file->path, md5_sumstr(&sum),
42                                         (unsigned long)file->size, ctime(&file->mtime));
43                 }
44         }
45
46         return 0;
47 }
48
49 static const char *guess_repo_name(const char *path)
50 {
51         static char pathbuf[PATH_MAX];
52         char *last_slash;
53         int len;
54
55         if(!realpath(path, pathbuf)) {
56                 goto fail;
57         }
58         len = strlen(pathbuf);
59
60         if(len > 0 && pathbuf[len - 1] == '/') {
61                 pathbuf[--len] = 0;
62         }
63         if(len <= 0) goto fail;
64
65         if((last_slash = strrchr(pathbuf, '/'))) {
66                 return last_slash + 1;
67         }
68         return pathbuf;
69
70 fail:
71         fprintf(stderr, "failed to resolve path %s while determining the repo name. Please specify an explicit name with -id\n", repo_path);
72         return 0;
73 }
74
75 static void print_usage(const char *argv0)
76 {
77         printf("Usage: %s [options] [repo path]\n", argv0);
78         printf("options:\n");
79         printf("  -id <name>: repo identifier (defaults to directory name)\n");
80         printf("  -h,-help: print help and exit\n");
81 }
82
83 static int parse_args(int argc, char **argv)
84 {
85         int i;
86
87         for(i=1; i<argc; i++) {
88                 if(argv[i][0] == '-') {
89                         if(strcmp(argv[i], "-id") == 0) {
90                                 repo_name = argv[++i];
91                         } else if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-help") == 0) {
92                                 print_usage(argv[0]);
93                                 exit(0);
94                         } else {
95                                 fprintf(stderr, "invalid option: %s\n", argv[i]);
96                                 return -1;
97                         }
98                 } else {
99                         if(repo_path) {
100                                 fprintf(stderr, "unexpected argument: %s\n", argv[i]);
101                                 return -1;
102                         }
103                         repo_path = argv[i];
104                 }
105         }
106
107         if(!repo_path) repo_path = ".";
108         return 0;
109 }