-
Notifications
You must be signed in to change notification settings - Fork 0
/
cluf_main.c
174 lines (161 loc) · 4.5 KB
/
cluf_main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/*
* @author Matthias P. Nowak
* @copyright LGPL 3.0 https://opensource.org/licenses/lgpl-3.0.html
*/
#include "cluf.h"
struct cluf_global _cluf;
void print_usage(char *progname) {
/**
* @brief prints out the usage for the program
*/
printf("Copy linked used files\n"
"usage: %s [options] <watched directory>\n"
" or: %s [options] <watched directory> <target directory>\n\n"
"Options:\n"
" -f <record file> record all encountered accessed to that file\n"
" -d after initialization, start daemon mode\n"
" -v increase verbosity\n"
" -s shorten symlinks (source inside target)\n"
" -p <pid file> record pid into that file\n"
" -t silly test option\n\n"
"\n", progname, progname);
exit(EXIT_SUCCESS);
}
void handle_signal(int signal) {
/**
* actually, pulling out the hard way, let the OS do the clean-up
*/
fprintf(stderr, "shutting down cluf\n");
exit(EXIT_SUCCESS);
}
void cluf_exit(char *msg) {
perror(msg);
exit(EXIT_FAILURE);
}
void record_pid(char *pidFile) {
fprintf(stderr,"pid=%d\n",getpid());
FILE *f=fopen(pidFile,"w");
if(!f)
cluf_exit("file couldn't be opened");
fprintf(f,"%d",getpid());
fclose(f);
}
void * startUpdatingSymlinks(void *dummy){
if(_cluf.debug>3){
fprintf(stderr,"start updating symlinks\n");
}
dev_t device;
{
struct stat statbuf;
if(lstat(_cluf.targetName,&statbuf))
cluf_exit("lstat on the target failed");
device=statbuf.st_dev;
}
cluf_updateSymlinks(_cluf.targetName,device);
return NULL;
}
int main(int argc, char **argv) {
/**
*
*/
// initializing the global structure
memset(&_cluf,0,sizeof(_cluf));
// *************************
if (argc <= 1) {
print_usage(argv[0]);
}
char *srcDir = NULL;
int daemonMode = 0;
char *recFile = NULL;
{
int opt;
while ((opt = getopt(argc, argv, "dtsvp:f:")) != -1) {
switch (opt) {
case 'd':
daemonMode = 1;
if(_cluf.debug>0)
fprintf(stderr,"setting debug mode\n");
break;
case 't':
fprintf(stderr, "testing options\n");
break;
case 's':
fprintf(stderr, "turning to short links (source inside target)\n");
_cluf.shortenLinks=true;
break;
case 'v':
++_cluf.debug;
fprintf(stderr,"setting verbose to %d\n",_cluf.debug);
break;
case 'f':
recFile = optarg;
if(_cluf.debug>0)
fprintf(stderr,"setting recording file to %s\n",recFile);
break;
case 'p':
record_pid(optarg);
break;
default:
print_usage(argv[0]);
}
}
char * runArg[argc];
for (int i = 0; i < argc; ++i)
runArg[i] = NULL;
for (int i = optind, j = 0; i < argc; ++i, ++j) {
if(_cluf.debug>3)
fprintf(stderr, "argv[%d]=%s\n", i, argv[i]);
runArg[j] = argv[i];
}
if (argc > 1)
_cluf.sourceName = runArg[0];
if (argc > 2)
_cluf.targetName = runArg[1];
}
// *************************
// add signal handler
signal(SIGTERM, handle_signal);
signal(SIGQUIT,handle_signal);
// *************************
cluf_setup(recFile);
if(_cluf.debug>2)
fprintf(stderr,"doen with setup\n");
// *************************
if (daemonMode) {
if (fork()) {
if(_cluf.debug>0)
fprintf(stderr, "daemon started\n");
exit(EXIT_SUCCESS);
}
}
// *************************
if(_cluf.targetName){
if(_cluf.debug>2){
const size_t myStackSize=16*1024*1024; // 16 MByte
fprintf(stderr,"starting symlink updating thread\n");
pthread_t bgUpdateSymlink;
pthread_attr_t attr;
if(pthread_attr_init(&attr)){
cluf_exit("thread initialization");
}
size_t stacksize;
if(pthread_attr_getstacksize(&attr,&stacksize)){
cluf_exit("getting stacksize failed");
}
if(stacksize < myStackSize){
if(_cluf.debug>3)
fprintf(stderr," increasing stack from %ld to %ld\n",stacksize,myStackSize);
if(pthread_attr_setstacksize(&attr,myStackSize))
cluf_exit("setting stack size");
}
if(pthread_create(&bgUpdateSymlink,&attr,startUpdatingSymlinks,NULL))
cluf_exit("creating background symlink thread");
}
}
cluf_handle_events();
// ***** should not arrive here *****
// the signal handler has an exit
if(_cluf.debug>0)
printf("all done\n");
exit(EXIT_SUCCESS);
}