aboutsummaryrefslogblamecommitdiffstats
path: root/dirwatch.c
blob: 023791c4a92bf3f99a06a96d91f21d7cc5baa8ca (plain) (tree)
1
2
3
4
5
6
7
8
9
10









                        

                                                                     

            









                               









































                                                                      

                                    















































                                                                
                        
 
                                 


                             







                                                          
         

































                                                                            

         




                                           
 




                                             

                             
                             
         












                                                                                          









                                                
                                                                                

                         
                                                                   






















                                                                  

                                                             


                                                                

                                                                                                  










                                                                                                



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