#include #include #include #include #include #include #include #include #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; }