fixmydownloads/src/main.c

133 lines
3.2 KiB
C

/*This is the sample program to notify us for the file creation and file deletion takes place in “/tmp” directory*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <pwd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/inotify.h>
#define EVENT_SIZE (sizeof(struct inotify_event))
#define EVENT_BUF_LEN (1024 * (EVENT_SIZE + 16))
static const char downloads_dir_default[] = "Downloads";
static char *downloads_dir;
static const char documents_dir_default[] = "Documents";
static char *documents_dir;
static int inotify_instance = -1;
static char event_buffer[EVENT_BUF_LEN];
static int watch_list;
char *get_directory(const char *param);
char *get_extension(const char *name);
void move(const char *name);
int main(int argc, char *argv[])
{
/* Get Downloads directory Location */
downloads_dir = get_directory("DOWNLOAD");
/* Get Documents directory Location */
documents_dir = get_directory("DOCUMENTS");
/* Initialize inotify instance */
inotify_instance = inotify_init();
if (!inotify_instance)
perror("Failed initializing inotify library!");
/* Add wanted Downloads to watchlist */
watch_list =
inotify_add_watch(inotify_instance, downloads_dir, IN_CREATE);
if (!watch_list)
perror("Failed to add downloads folder to watchlist!");
while (1) {
/* Get events*/
int length =
read(inotify_instance, event_buffer, EVENT_BUF_LEN);
if (!length)
perror("Failed to read inotify buffer!");
/* Process events */
int i = 0;
while (i < length) {
struct inotify_event *event =
(struct inotify_event *)&event_buffer[i];
if (event->len) {
if (event->mask & IN_CREATE)
move(event->name);
}
i += EVENT_SIZE + event->len;
}
}
inotify_rm_watch(inotify_instance, watch_list);
close(inotify_instance);
}
char *get_extension(const char *name)
{
char *ext = (char *)malloc(sizeof(char));
int ext_len = 0;
for (int i = 0; i < strlen(name); i++) {
if (name[i] == '.') {
for (int j = i + 1; j < strlen(name); j++) {
ext = (char *)realloc(ext, ++ext_len);
ext[ext_len - 1] = name[j];
}
ext = (char *)realloc(ext, ++ext_len);
ext[ext_len - 1] = '\0';
break;
}
}
return ext;
}
void move(const char *name)
{
char *ext = get_extension(name);
printf("Moving: %s Extension: %s\n", name, ext);
}
char *get_directory(const char *name)
{
char *result = (char *)malloc(4096 * sizeof(char));
FILE *xdg_cmd = NULL;
char *cmd = (char *)malloc(20 * sizeof(char));
sprintf(cmd, "xdg-user-dir %s", name);
xdg_cmd = popen(cmd, "r");
if (!xdg_cmd) {
char *home_dir = getenv("HOME");
if (!home_dir) {
struct passwd *pw = getpwuid(getuid());
if (!pw)
perror("Failed to get home directory!");
home_dir = pw->pw_dir;
if (!home_dir)
perror("Failed miserably to get a directory path!");
}
strcat(result, home_dir);
strcat(result, "/");
if (strcmp(name, "DOWNLOAD"))
strcat(result, downloads_dir_default);
else if (strcmp(name, "DOCUMENTS"))
strcat(result, documents_dir_default);
} else {
/* Read path from output of xdg */
int c, n = 0;
while ((c = fgetc(xdg_cmd)) != EOF) {
if (c == '\n')
result[n++] = '\0';
else
result[n++] = (char)c;
}
result[n] = '\0';
pclose(xdg_cmd);
}
return result;
}