#ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include #include #include #include #include "perr.h" #include "pclt.h" #include "fi.h" #include "db.h" #include "fstrav.h" #include "configfile.h" #include "sha1.h" char * sha_file(filename, sha) const char *filename; char *sha; { SHA1Context ctx; char data[8192]; int fd; ssize_t n; if ((fd=open(filename, O_RDONLY)) < 0) return (NULL); SHA1Init(&ctx); while ((n=read(fd, data, 8192)) > 0) { SHA1Update(&ctx, data, n); } (void)close(fd); SHA1Final(&ctx, sha); if (n < 0) return (NULL); return (sha); } char * sha_data(data, size, sha) const char *data; unsigned int size; char *sha; { SHA1Context ctx; SHA1Init(&ctx); SHA1Update(&ctx, data, size); SHA1Final(&ctx, sha); return (sha); } int builddb(path, stat, opt, db) const char *path; const struct stat *stat; int opt; void *db; { char link[PATH_MAX+1], strsha[FI_STRCSUMSIZE], chfi[FI_CHFISIZE]; DBHEAD dbhead; FI fi; int n; (void)memset(&fi, 0x0, sizeof(FI)); fi.fi_mask=opt; if (PCL_ISSET(opt, FI_MINO)) fi.fi_ino=stat->st_ino; if (PCL_ISSET(opt, FI_MMODE)) fi.fi_mode=stat->st_mode; if (PCL_ISSET(opt, FI_MNLINK)) fi.fi_nlink=stat->st_nlink; if (PCL_ISSET(opt, FI_MUID)) fi.fi_uid=stat->st_uid; if (PCL_ISSET(opt, FI_MGID)) fi.fi_gid=stat->st_gid; if (PCL_ISSET(opt, FI_MCTIME)) fi.fi_ctime=stat->st_ctime; if (PCL_ISSET(opt, FI_MSIZE)) fi.fi_size=stat->st_size; #if ENABLE_STFLAGS if (PCL_ISSET(opt, FI_MFLAGS)) fi.fi_flags=stat->st_flags; #endif if (PCL_ISSET(opt, FI_MSHA)) { if (S_ISDIR(stat->st_mode) || S_ISREG(stat->st_mode)) { if (!sha_file(path, fi.fi_sha)) { pwarn2x("sha_file()", path); return (-1); } } else if (S_ISLNK(stat->st_mode)) { (void)memset(link, 0x0, PATH_MAX); if ((n=readlink(path, link, PATH_MAX)) < 0) { pwarn2("readlink()", path); return (-1); } link[PATH_MAX-1]=(char)0x0; sha_data(link, n, fi.fi_sha); } } (void)memset(&dbhead, 0x0, sizeof(DBHEAD)); (void)strncpy(dbhead.db_path, path, PATH_MAX-1); dbhead.db_datasize=FI_CHFISIZE; fi_stoch(&fi, chfi); if (db_put(db, &dbhead, chfi) < 0) { pwarn1("db_put()"); return (-1); } return (0); } void usage(void) { (void)fprintf(stderr, "usage: fswbuild [-c file1] [-d file2]\n"); exit (1); } int main(argc, argv) int argc; const char *const *argv; { char p_configfile[PATH_MAX+1], p_database[PATH_MAX+1]; DB *db; PCLT *pclt; int ch, st; time_t tloc; struct tm tm; (void)time(&tloc); (void)localtime_r(&tloc, &tm); (void)strncpy(p_configfile, "/usr/local/etc/fswatch.conf", PATH_MAX); p_configfile[PATH_MAX-1]=(char)0x0; (void)snprintf(p_database, PATH_MAX, "fswdb-%d-%.2d-%.2d-%.2d-%.2d-%.2d", tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); while ((ch=getopt(argc, (char *const *)argv, "c:d:"))!=-1) { switch(ch) { case 'c': (void)strncpy(p_configfile, optarg, PATH_MAX); p_configfile[PATH_MAX-1]=(char)0x0; break; case 'd': (void)strncpy(p_database, optarg, PATH_MAX); p_database[PATH_MAX-1]=(char)0x0; break; default: usage(); break; } } argc-=optind; argv+=optind; if (argc!=0) usage(); if (!(pclt=pclt_init())) perr1("pclt_init()"); if (configfile_read(p_configfile, pclt)!=0) { configfile_perror(); exit (1); } if (!(db=db_open(p_database, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR))) perr2("db_open()", p_database); if (fstrav(pclt, &builddb, db)!=0) exit (1); if (db_close(db)!= 0) perr2("db_close()", p_database); pclt_close(pclt); exit (0); }