#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/inotify.h>
#include <sys/types.h>
#include <limits.h>
#define BUF_SIZE (10 * (sizeof(struct inotify_event) + NAME_MAX + 1))
int debug=0;
char *path2name( char *s )
{
int i;
size_t len = strlen(s);
char *p=NULL;
char *name=NULL;
if ( s == NULL )
return NULL;
i = len;
while ( i > 0 )
{
if ( s[len-i] == '/' )
{
p = &s[len-i];
break;
}
i--;
}
name = malloc( len-i+1 );
if ( name == NULL )
return NULL;
memcpy( name, p, len-i );
name[ len-i ] = 0;
return name;
}
// filename with use to upload plain filename
// url of dir where to upload with ending "/"
void ftp_curl_upload( char *fpath, char *fevent, const char *u )
{
const int buf_size = 1024;
char buf[buf_size];
if ( fpath == NULL )
{
printf("file NULL\n" );
return;
}
if ( fevent == NULL )
{
printf("file event NULL\n");
return;
}
if ( u == NULL )
{
printf("url NULL\n");
return;
}
//printf("%s\n", path2name(f));
snprintf(buf, buf_size,"curl -T %s %s%s\n", fpath, u, fevent);
system( buf );
if (debug)
printf( "%s", buf );
}
//takes str1+str2 and create new string with str1+str2
//should be freed after
char *strncat_n( size_t len, const char *str1, const char *str2)
{
int i,j;
//join all to one nice while loop?
size_t s1_l = strlen( str1 );
size_t s2_l = strlen( str2 );
size_t tot_l = s1_l + s2_l;
char *res = NULL;
if ( tot_l >= len ) tot_l = len-1;
res = malloc( tot_l+1 ); memset( res,0,tot_l);
if ( res == NULL )
return NULL;
i = 0;
while( i < s1_l )
{
res[i] = str1[i];
i++;
}
printf("%s\n",res);
j = 0;
while ( j <= s2_l )
{
res[i+j] = str2[j];
j++;
}
printf("%s\n",res);
res[tot_l] = 0x0;
return res;
}
int main( int argc, char **argv )
{
int fret;
int i; //cycle counter
int notify_fd; //inotudy fd
char ev_buffer[BUF_SIZE]; //buffer for events
struct inotify_event *event;
char *p;
ssize_t num_read;
pid_t pid;
int daemonise=1;
//options to ge from argv
char *watch_dir=NULL;
char *send_url=NULL;
FILE *pid_f=NULL;
//getopt stuff
int c;
opterr = 0;
while ( (c = getopt(argc, argv, "w:u:fd")) != -1 )
{
switch ( c )
{
//dir path to watch
case 'w':
watch_dir = optarg;
break;
//url to upload with curl
case 'u':
send_url = optarg;
break;
//dont daemonise
case 'f':
daemonise = 0;
break;
//debuging add some extra stuff to print
case 'd':
debug = 1;
break;
case '?':
printf("Run: %s [OPTIONS] ... \n", argv[0]);
printf("-w [DIR] watch dir\n");
printf("-u [URL] url to upload\n");
printf("-f foreground mode\n");
printf("-d debug info\n");
printf("-? show help\n");
return -1;
break;
case ':':
printf("Missing options be carefull\n");
break;
default:
printf("Unknown option\n");
return -1;
}
}
if ( watch_dir == NULL )
{
printf("Need -w option\n");
return -1;
}
if ( send_url == NULL )
{
printf("Needed -u option\n");
return -1;
}
//make process daemon
if ( daemonise == 1 )
{
if ( access( "/tmp/dirwatch.pid", F_OK ) != -1 )
{
printf("PID file allready excists kill da process or rm file\n ");
return -1;
}
if ( daemon(1,0) < -1 )
{
printf("Cannot become daemon\n");
return -1;
}
pid_f = fopen("/tmp/dirwatch.pid","w");
fprintf( pid_f, "%d", getpid() );
fclose( pid_f );
}
notify_fd = inotify_init();
if ( notify_fd == -1 )
{
printf("Cannot init inotify\n");
return -1;
}
//register dir to watch
fret = inotify_add_watch( notify_fd, watch_dir, IN_CREATE|IN_MOVED_TO );
if ( fret == -1 )
{
printf("Cannot add inotify watch %s\n", watch_dir);
return -1;
}
for (;;)
{
num_read = read( notify_fd, ev_buffer, BUF_SIZE );
if ( num_read == 0 )
{
printf("inotify read 0!\n");
break;
}
if ( num_read == -1 )
{
printf("error while read inotify\n" );
break;
}
for (p = ev_buffer;
p < ev_buffer+num_read;)
{
event = (struct inotify_event *)p;
//if someone added file notify that
if ((event->mask & IN_CREATE) ||
(event->mask & IN_MOVED_TO) )
{
if ( !(event->mask & IN_ISDIR) )
{
if (debug)
printf("CREATE_FILE|MOVED_TO %s \n", event->name);
char *fpath = strncat_n( 1024, watch_dir, event->name );
if ( fpath != NULL )
ftp_curl_upload( fpath, event->name, send_url );
free( fpath );
}
}
p += sizeof( struct inotify_event ) + event->len;
}
}
close( notify_fd );
return 0;
}