/* file utilites */ #include #include #include #include #include #include #include #include #include #include #include "config.h" int access_via_stat(char *name,int mode) /* check F_OK (exist) ok * check R_OK (readable) same as F_OK (buggy but ...) * assert violation if mode == W_OK (writeable) * */ { struct stat stat_buf; ass(mode==F_OK || mode==R_OK); return(stat(name,&stat_buf)); } /* ln, cp, mv, find_file_by_size_and_crc */ /* all functions returns 0 when success */ void rm_by_mask(char *dirname,char *mask) /* delete files by mask (dirname/mask) */ { char *p; struct stat stat_buf; DIR *dir; struct dirent *dirp; dir=opendir(dirname); if(dir==NULL) return; while(1) { dirp=readdir(dir); if(!dirp) break; if(wildmat_icase(dirp->d_name,mask)) { p=xstrcpy(dirname); p=xstrcat(p,"/"); p=xstrcat(p,dirp->d_name); if(stat(p,&stat_buf)) continue; if(!(stat_buf.st_mode & S_IFREG)) continue; l_printf("%s deleted by %s",p,mask); remove(p); xfree(p); } } closedir(dir); } static int cp_(char *oldname,char *newname,int add); int cp(char *oldname,char *newname) { return cp_(oldname,newname,FALSE); } int cp_add(char *oldname,char *newname) { return cp_(oldname,newname,TRUE); } #define CP_BUFSIZE (1024*1024) /* 1mb blocks */ static int cp_(char *oldname,char *newname,int add) /* copy oldname to newname use mmap with maximal buffer size = CP_BUFSIZE mmap fails on big size files */ { struct stat stbuf; int r,fd_in,fd_out; ssize_t write_return; char *data; struct utimbuf utbuf; unsigned long a,b,i; if((r=stat(oldname,&stbuf))) return r; fd_in=open(oldname,O_RDONLY|O_BINARY); if(fd_in==-1) return -1; if(add==FALSE) fd_out=open(newname,O_BINARY|O_WRONLY|O_TRUNC|O_CREAT,stbuf.st_mode); else fd_out=open(newname,O_BINARY|O_WRONLY|O_CREAT|O_APPEND,stbuf.st_mode); if(fd_out==-1) { close(fd_in); return -1; } a=stbuf.st_size / CP_BUFSIZE; /* how many blocks */ b=stbuf.st_size % CP_BUFSIZE; /* last block size */ for(i=0;id_name,origname)) continue; snprintf(buff,sizeof(buff)-1,"%s/%s",dirname,dirp->d_name); if(stat(buff,&stat_buf)) continue; if(!(stat_buf.st_mode & S_IFREG)) continue; strcpy(outbuff,dirp->d_name); closedir(dir); return 0; } closedir(dir); /* opendir and try to find filename by size and crc32 */ j=strlen(origname); pattern[0]=0; for(i=0;id_name,pattern)) continue; snprintf(buff,sizeof(buff)-1,"%s/%s",dirname,dirp->d_name); if(stat(buff,&stat_buf)) continue; if(!(stat_buf.st_mode & S_IFREG)) continue; if(size!=(unsigned long)(-1) && size!=stat_buf.st_size) continue; if(crc32!=filecrc32(buff)) continue; strcpy(outbuff,dirp->d_name); closedir(dir); return 0; } closedir(dir); return 1; } int dirmode(int filemode) { int result; result=filemode; if(filemode & 0400) result|=0100; if(filemode & 0040) result|=0010; if(filemode & 0004) result|=0001; return result; } void write_flag_tab_to_FILE(FILE *fp,int flags,struct flag_tab *tab) /* write flag_tab structure to fp (comma list)*/ { int no_comma=TRUE; while(1) { if(tab->text==NULL) break; if(tab->bitmask & flags) { if(no_comma==FALSE) fprintf(fp,","); no_comma=FALSE; fprintf(fp,"%s",tab->text); } tab++; } } #ifdef TEST int main(int argc,char *argv[]) { if(argc<4) return -1; if(!strcmp(argv[1],"ln")) printf("ln(%s,%s)=%d\n",argv[2],argv[3],ln(argv[2],argv[3])); if(!strcmp(argv[1],"mv")) printf("mv(%s,%s)=%d\n",argv[2],argv[3],mv(argv[2],argv[3])); if(!strcmp(argv[1],"cp")) printf("cp(%s,%s)=%d\n",argv[2],argv[3],cp(argv[2],argv[3])); if(!strcmp(argv[1],"zz")) { char b1[999],b2[999],b3[999]; unsigned long crc32,size; strcpy(b1,argv[2]); strcpy(b3,argv[3]); crc32=strtoul(argv[4],NULL,16); size=atol(argv[5]); printf("crc32 of %s = %lX\n",b3,filecrc32(b3)); printf("find_file(%s,(b2),%s,%X,%lu)=%d\n",b1,b2,crc32,size, find_file(b1,b2,b3,crc32,size)); printf("b2=%s\n",b2); } return 0; } #endif