/* This script setup a directory with makefile.dat's so that it mirrors an existing directory hierarchy. One usage would be to create a new version of a project (software) using very few disk space. */ #include #include #include #include #include #include #include #include #include #include static void usage() { fprintf (stderr, "vfssetup reference-dir work-dir\n" "\n" "reference-dir: Existing directory with files and sub-directories\n" " (may already contain makefile.dat)\n" "work-dir: Directory to create and populate with makefile.dat\n" ); } class MAKEFILE_FILE: public ARRAY_OBJ{ public: SSTRING path,rest; /*~PROTOBEG~ MAKEFILE_FILE */ public: MAKEFILE_FILE (const char *_path, const char *_rest); /*~PROTOEND~ MAKEFILE_FILE */ }; PUBLIC MAKEFILE_FILE::MAKEFILE_FILE(const char *_path, const char *_rest) { path.setfrom (_path); rest.setfrom (_rest); } class MAKEFILE: public ARRAY{ /*~PROTOBEG~ MAKEFILE */ public: MAKEFILE_FILE *getitem (int no)const; /*~PROTOEND~ MAKEFILE */ }; PUBLIC MAKEFILE_FILE *MAKEFILE::getitem(int no) const { return (MAKEFILE_FILE*)ARRAY::getitem(no); } static int process ( const char *refdir, // Reference dir (inside srcdir) const char *srcdir, // base path for the reference dir const char *dstdir) // base path dest dir to populate { SSTRING fulldstdir; int len = strlen(srcdir); fulldstdir.setfromf ("%s/%s",dstdir,refdir+len); printf (":%s: -> :%s:\n",refdir,fulldstdir.get()); int ret = -1; if (mkdir (fulldstdir.get(),0755)!=-1){ SSTRING mdat; mdat.setfromf ("%s/makefile.dat",fulldstdir.get()); FILE *fout = fopen (mdat.get(),"w"); if (fout != NULL){ MAKEFILE mkf; // First we copy the source makefile.dat if available mdat.setfromf ("%s/makefile.dat",refdir); FILE *fin = fopen (mdat.get(),"r"); if (fin != NULL){ char buf[1000]; while (fgets_strip(buf,sizeof(buf)-1,fin,NULL)!=NULL){ char path[PATH_MAX]; char *pt = str_copyword (path,buf,sizeof(path)-1); if (path[0] != '\0'){ mkf.add (new MAKEFILE_FILE(path,pt)); } } fclose (fin); } DIR *d = opendir (refdir); if (d != NULL){ struct dirent *ent; ret = 0; while ((ent=readdir(d))!=NULL){ SSTRING fpath; fpath.setfromf ("%s/%s",refdir,ent->d_name); struct stat st; if (stat(fpath.get(),&st)==-1){ fprintf (stderr,"Can't stat %s (%s)\n",fpath.get(),strerror(errno)); ret = -1; break; }else if (!S_ISDIR(st.st_mode)){ // Remove it from the old makefile.dat for (int i=0; ipath.cmp(ent->d_name)==0){ mkf.remove_del(i); break; } } struct tm *t = localtime (&st.st_mtime); fprintf (fout,"%s %02d/%02d/%04d %02d:%02d:%02d %s\n" ,ent->d_name ,t->tm_mday,t->tm_mon+1,t->tm_year+1900 ,t->tm_hour,t->tm_min,t->tm_sec ,fpath.get()); } } closedir (d); // Output the rest of the makefile.dat at the end for (int i=0; ipath.get(),f->rest.get()); } } fclose (fout); } } return ret; } int main (int argc, char *argv[]) { int ret = -1; struct stat st; if (argc != 3){ usage(); }else if (stat(argv[2],&st)!=-1){ fprintf (stderr,"Directory %s already exist\n",argv[2]); }else{ const char *srcdir = argv[1]; SSTRING abssrcdir; if (srcdir[0] != '/'){ char cwd[PATH_MAX]; abssrcdir.setfromf ("%s/%s",getcwd(cwd,sizeof(cwd)),srcdir); srcdir = abssrcdir.get(); } const char *dstdir = argv[2]; SSTRING cmd; cmd.setfromf("find %s -type d",srcdir); FILE *fin = popen (cmd.get(),"r"); if (fin != NULL){ char line[PATH_MAX]; ret = 0; while (ret == 0 && fscanf(fin,"%s\n",line)==1){ ret = process (line,srcdir,dstdir); } pclose (fin); } } return ret; }