-
Notifications
You must be signed in to change notification settings - Fork 0
/
watcher.c
202 lines (168 loc) · 6.57 KB
/
watcher.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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
/*
* this little pgm watches a number of (max 200) directories for newly appearing files
* appearing files are assumed to be jpg images from a webcam
*
* Once a new file is detected a thumbnail is generated and called whatever is defined in THUMB
* and a file (name defined in BIGPIC) is generated.
* if no blurring is needed for the full picture, BIGPIC is generated by a copy
* if blurring is needed, BIGPIC is generated by blurring the original
* Blurring is determined by the existence of a filename defined in BLURMASK containing a boolean
* blurmask to be used in convert commands
*
* So if you need to blur (portions of) an image before using it publicly, create a boolean
* blurmask (jpeg) for that image and place it in the directory where your webcams put new images
*
* A lot of sanity checks are missing and risky things are done. So make sure you run this
* in a controlled and safe environment:
* - it is assumed new file are jpeg images
* - copy and convert commands are issued using system()
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/inotify.h>
#include <limits.h>
#include <dirent.h>
#include <unistd.h>
#define MAX_EVENTS 1024 /*Max. number of events to process at one go*/
#define LEN_NAME 16 /*Assuming that the length of the filename won't exceed 16 bytes*/
#define EVENT_SIZE ( sizeof (struct inotify_event) ) /*size of one event*/
#define BUF_LEN ( MAX_EVENTS * ( EVENT_SIZE + LEN_NAME )) /*buffer to store the data of events*/
#define BIGPIC "bigpic.jpg" /* name of big picture grabbed from wordpress */
#define THUMB "thumbnail.jpg" /* name of thumbnail file */
#define CONVERT "/usr/bin/convert " /* jpeg image converter */
#define CONVERTOPTIONS " -scale 35% " /* Option for image converter to reduct image to 35% size */
#define CP "/bin/cp " /* Copy Shell Command plus blank at the end */
#define BLURMASK "blurmask.jpg" /* blur mask if image needs blurred areas */
#define BLUROPTIONS "-compose blur -define compose:args=3 -composite"
#define BLURREDIMG "blurredimg.jpg"
int main( int argc, char **argv )
{
int length, i = 0, wd, j;
int fd;
char buffer[BUF_LEN];
char command[200];
char blurcmd[200];
char dirnames[200][200];
char blurmask[200][200];
int blurcheck[200];
char blurfile[200];
struct stat statbuf;
if (argc < 2 || strcmp(argv[1], "--help") == 0) {
printf ("%s pathname ....\n", argv[0]);
exit(-1);
}
/* Initialize Inotify*/
fd = inotify_init();
if ( fd < 0 ) {
perror( "Couldn't initialize inotify");
}
/* add watch to a directory, remember directory and check blurring */
for (j=1; j< argc; j++) {
wd = inotify_add_watch(fd, argv[j], IN_CLOSE_WRITE);
if (wd == -1) {
printf("Couldn't add watch to %s\n",argv[j]);
}
else {
strcpy ( dirnames[wd], argv[j]);
printf("Watching:: %s wd=%d\n",dirnames[wd],wd);
/* check for blurring, by trying to open a a file with the blurmask */
strcpy ( blurfile, argv[j]);
strcat (blurfile, "/");
strcat ( blurfile, BLURMASK);
blurcheck[wd] = 0;
/* if open succeeds, remember full path of blurmask for later use */
if (stat (blurfile, &statbuf) == 0) {
blurcheck[wd] = 1;
strcpy (blurmask[wd], blurfile);
printf ("file needs blurring\n");
}
}
}
/* do it forever*/
while(1) {
i = 0;
length = read( fd, buffer, BUF_LEN );
if ( length < 0 ) {
perror( "read" );
}
while ( i < length ) {
/* wait for something to happen */
struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];
if ( event->mask & IN_CLOSE_WRITE) {
if (event->mask & IN_ISDIR) {
printf( "Someone wrote to directory %s.\n", event->name );
}
else {
if (strcmp(event->name,BIGPIC) == 0 || strcmp(event->name,THUMB) == 0
|| strcmp( event->name, BLURMASK) == 0 || strcmp (event->name, BLURREDIMG) == 0) {
printf("Skipping self generated file %s \n", event->name);
}
else {
/* a new image was written and closed, lets go */
printf( "writing to %s completed\n", event->name );
/* create thumbnail - for the moment ignore blurring for thumbnails */
strcpy (command,CONVERT);
strcat (command, dirnames[event->wd]);
strcat (command, "/");
strcat (command, event->name);
strcat (command, CONVERTOPTIONS);
strcat (command, dirnames[event->wd]);
strcat (command, "/");
strcat (command, THUMB);
printf( "Executing %s\n", command);
system (command);
/* check if we need to blur this image */
if (blurcheck[event->wd]) {
/* issue blur command */
strcpy (blurcmd,CONVERT);
strcat (blurcmd, dirnames[event->wd]);
strcat (blurcmd, "/");
strcat (blurcmd, event->name);
strcat (blurcmd, " ");
strcat (blurcmd, blurmask[event->wd]);
strcat (blurcmd, " ");
strcat (blurcmd, BLUROPTIONS);
strcat (blurcmd, " ");
strcat (blurcmd, dirnames[event->wd]);
strcat (blurcmd, "/");
strcat (blurcmd, BLURREDIMG);
printf ("We need to blur the image, executing %s\n", blurcmd);
system (blurcmd);
strcpy (command, CP);
strcat (command, dirnames[event->wd]);
strcat (command, "/");
strcat (command, BLURREDIMG);
strcat (command, " ");
strcat (command, dirnames[event->wd]);
strcat (command, "/");
strcat (command, BIGPIC);
}
else {
/* no blurring needed - just copy new file to bigpic */
strcpy (command,CP);
strcat (command, dirnames[event->wd]);
strcat (command, "/");
strcat (command, event->name);
strcat (command, " ");
strcat (command, dirnames[event->wd]);
strcat (command, "/");
strcat (command, BIGPIC);
}
printf ("Executing %s\n", command);
system (command);
}
}
}
i += EVENT_SIZE + event->len;
}
}
/* Clean up*/
inotify_rm_watch( fd, wd );
close( fd );
return 0;
}