/* $Date: 2010-09-30 15:40:39 -0300 (Thu, 30 Sep 2010) $ */ /* $Revision: 1364 $ */ #define _GNU_SOURCE #define FUSE_USE_VERSION 26 #include #include #include #include #include #include #include #include #include #include "medianin.h" #include "log.h" /* Variable global que contiene el SimpleFS */ medianin *fs = NULL; /* * Operaciones Básicas */ static int fs_getattr(const char *path, struct stat *stbuf) { int rta = 0; debug3("[%li] ", time(NULL)); debug1("getattr:%s", path); rta = medianin_getattr(fs, path, stbuf); debug2(" -> mode:%o size:%li", stbuf->st_mode, (long)stbuf->st_size); debug3(" returns:%i", rta); debug1("\n"); return rta; } static int fs_readlink(const char *path, char *buf, size_t size) { int rta = 0; debug3("[%li] ", time(NULL)); debug1("readlink:%s size:%li", path, (long)size); rta = medianin_readlink(fs, path, buf, size); debug2(" -> returns:%i", rta); debug1("\n"); return rta; } static int fs_mknod(const char *path, mode_t mode, dev_t rdev) { int rta = 0; debug3("[%li] ", time(NULL)); debug1("mknod:%s mode:%o", path, mode); rta = medianin_mknod(fs, path, mode); debug3(" -> returns:%i", rta); debug1("\n"); return rta; } static int fs_unlink(const char *path) { int rta = 0; debug3("[%li] ", time(NULL)); debug1("unlink_file:%s", path); rta = medianin_unlink(fs, path); debug3(" -> returns:%i", rta); debug1("\n"); return rta; } static int fs_symlink(const char *from, const char *to) { int rta = 0; debug3("[%li] ", time(NULL)); debug1("symlink from:%s to:%s", from, to); rta = medianin_symlink(fs, from, to); debug3(" -> returns:%i", rta); debug1("\n"); return rta; } static int fs_rename(const char *from, const char *to) { int rta = 0; debug3("[%li] ", time(NULL)); debug1("rename from:%s to:%s", from, to); rta = medianin_rename(fs, from, to); debug3(" -> returns:%i", rta); debug1("\n"); return rta; } static int fs_link(const char *from, const char *to) { int rta = 0; debug3("[%li] ", time(NULL)); debug1("link from:%s to:%s", from, to); rta = medianin_link(fs, from, to); debug3(" -> returns:%i", rta); debug1("\n"); return rta; } static int fs_chmod(const char *path, mode_t mode) { int rta = 0; debug3("[%li] ", time(NULL)); debug1("chmod:%s modo:%o", path, mode); rta = medianin_chmod(fs, path, mode); debug3(" -> returns:%i", rta); debug1("\n"); return rta; } static int fs_chown(const char *path, uid_t uid, gid_t gid) { int rta = 0; debug3("[%li] ", time(NULL)); debug1("chown:%s uid:%i gid:%i", path, uid, gid); rta = medianin_chown(fs, path, uid, gid); debug3(" -> returns:%i", rta); debug1("\n"); return rta; } static int fs_truncate(const char *path, off_t size) { int rta = 0; debug3("[%li] ", time(NULL)); debug1("truncate:%s size:%li", path, (long)size); rta = medianin_truncate(fs, path, size); debug1("\n"); return rta; } static int fs_utime(const char *path, struct utimbuf *utb) { int rta = 0; struct timespec tv[2]; tv[0].tv_sec = utb->actime; tv[0].tv_nsec = 0; tv[1].tv_sec = utb->modtime; tv[1].tv_nsec = 0; debug3("[%li] ", time(NULL)); debug1("utime:%s atime:%li mtime:%li", path, (long)utb->actime, (long)utb->modtime); rta = medianin_utimens(fs, path, tv); debug3(" -> returns:%i", rta); debug1("\n"); return rta; } static int fs_open(const char *path, struct fuse_file_info *fi) { int rta = 0; debug3("[%li] ", time(NULL)); debug1("*open:%s flags:%i", path, fi->flags); debug1("\n"); return rta; } static int fs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { int rta = 0; (void) fi; debug3("[%li] ", time(NULL)); debug1("read:%s size:%li offset:%li", path, (long)size, (long)offset); rta = medianin_read(fs, path, buf, size, offset); debug2(" -> returns:%i", rta); debug1("\n"); return rta; } static int fs_write(const char *path, const char *buf, size_t size,off_t offset, struct fuse_file_info *fi) { int rta = 0; (void) fi; debug3("[%li] ", time(NULL)); debug1("write:%s size:%li offset:%li", path, (long)size, (long)offset); rta = medianin_write(fs, path, buf, size, offset); debug2(" -> returns:%i", rta); debug1("\n"); return rta; } static int fs_statfs(const char *path, struct statvfs *stbuf) { int rta = 0; debug3("[%li] ", time(NULL)); debug1("statfs:%s", path); rta = medianin_statfs(fs, path, stbuf); debug2(" -> returns:%i", rta); debug1("\n"); return rta; } static int fs_release(const char *path, struct fuse_file_info *fi) { int rta = 0; debug3("[%li] ", time(NULL)); debug1("*release:%s flags:%i", path, fi->flags); debug1("\n"); return rta; } static int fs_utimens(const char *path, const struct timespec tv[2]) { int rta = 0; debug3("[%li] ", time(NULL)); debug1("utimens:%s atime:%li mtime:%li", path, (long)tv[0].tv_sec, (long)tv[1].tv_sec); rta = medianin_utimens(fs, path, tv); debug3(" -> returns:%i", rta); debug1("\n"); return rta; } /* * Operaciones sobre Directorios */ static int fs_mkdir(const char *path, mode_t mode) { int rta = 0; debug3("[%li] ", time(NULL)); debug1("mkdir:%s mode:%o", path, mode); rta = medianin_mkdir(fs, path, mode); debug3(" -> returns:%i", rta); debug1("\n"); return rta; } static int fs_rmdir(const char *path) { int rta = 0; debug3("[%li] ", time(NULL)); debug1("rmdir:%s", path); rta = medianin_rmdir(fs, path); debug3(" -> returns:%i", rta); debug1("\n"); return rta; } static int fs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { int rta = 0; (void) fi; /* Para que no diga que la variable está sin usar */ debug3("[%li] ", time(NULL)); debug1("readdir:%s", path); rta = medianin_readdir(fs, path, buf, filler); debug3(" -> returns:%i", rta); debug1("\n"); return rta; } static struct fuse_operations fs_oper = { /* Operaciones sobre archivos, NI = no implementada */ .getattr = fs_getattr, /* Done */ .readlink = fs_readlink, .mknod = fs_mknod, /* Done */ .unlink = fs_unlink, .symlink = fs_symlink, .rename = fs_rename, .link = fs_link, .chmod = fs_chmod, /* Almost done */ .chown = fs_chown, /* Almost done */ .truncate = fs_truncate, .utime = fs_utime, /* Almost done */ .open = fs_open, /* NI */ .read = fs_read, .write = fs_write, .statfs = fs_statfs, /* Done */ .release = fs_release, /* NI */ .utimens = fs_utimens, /* Almost done */ /* Operaciones sobre directorios */ .mkdir = fs_mkdir, .rmdir = fs_rmdir, .readdir = fs_readdir, }; /* !! end Rafa !! */ int main(int argc, char *argv[]) { /* Cheat es una variable al estilo de argv pero solo con argumentos * parseados como validos. La uso para trabajar menos */ char *cheat[10]; /* 10 es un indice que nunca se alcanza */ int i = 1; int argi = 1; char *logfilename = NULL; char *mountpoint = NULL; char *tailptr = NULL; /* Variable temporal usada pora strtol */ int loglevel = 3; /* default loglevel */ fs_oper.utimens = 0; cheat[0] = argv[0]; /* i==1 && argi == 1 i se usa con cheat y argi con argv */ /* cuando consumo un argumento aumento argi */ /* cuando agrego uno para fusemain aumento i */ while (argi < argc) { if (strcmp(argv[argi], "-h") == 0) { printf("uso: %s [opciones] mountpoint\n" "opciones:\n" "\t-h\t\tImprime esta ayuda.\n\n" "\t-logfile file\n" "\t-l file\t\tGuarda los logs en el archivo" " especificado.\n\n" "\t-loglevel num\n" "\t-n num\t\tEspecifica el nivel de log. " "Por defecto es 3.\n\n" , argv[0]); return 1; } else if (strcmp(argv[argi], "-logfile") == 0 || strcmp(argv[argi], "-l") == 0) { argi++; if(argi < argc) logfilename = argv[argi]; else { fprintf(stderr, "Se debe especificar un nombre" " de archivo\n"); return 1; } loglevel=1; /* Para evitar malos usos */ } else if (strcmp(argv[argi], "-loglevel") == 0 || strcmp(argv[argi], "-n") == 0) { argi++; if (argi < argc) { loglevel = (int)strtol(argv[argi], &tailptr, 10); if (tailptr == argv[argi]) { fprintf(stderr, "El nivel de log debe" "ser ún numero\n"); return 1; } if (loglevel < 0) { fprintf(stderr, "El nivel de log debe" "ser un número natural\n"); return 1; } } else { fprintf(stderr, "Se debe especificar un nivel" " de log\n"); return 1; } } else if (argv[argi][0] == '-') { fprintf(stderr, "Opción no reconocida:" "%s\n",argv[argi]); return 1; } else if (mountpoint == NULL) { mountpoint = argv[argi]; } argi++; } if(mountpoint == NULL) { fprintf(stderr, "Argumentos insuficientes: " "hace falta un mountpoint\n"); return 1; } cheat[i++] = mountpoint; if (loglevel != 0) { cheat[i++] = "-f"; } cheat[i] = NULL; if (log_open(logfilename, loglevel)!=0) { fprintf(stderr, "Advertencia! no se pudo inicializar el log\n"); } debug3("Los numeros a la izquierda indican el momento en que la " "llamada a la\nfunción se efectuó según time(NULL).\n"); fs = medianin_create(); if (fs == NULL) { return ENOMEM; } fuse_main(i, cheat, &fs_oper, NULL); /* El corazón del programa */ medianin_destroy(fs); log_close(); return 0; }