📄 copymove.c
字号:
/* Zgv v3.1 - GIF, JPEG and PBM/PGM/PPM viewer, for VGA PCs running Linux. * Copyright (C) 1993-1998 Russell Marks. See README for license details. * * copymove.c - guts of the code related to copying/moving files in * the file selector. */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/stat.h>#include <sys/types.h>#include <unistd.h>#include <utime.h>#include <errno.h>#include <vga.h>#include "3deffects.h"#include "font.h"#include "readnbkey.h"#include "zgv.h"#include "copymove.h"#define TRANSFER_BUF_SIZE 8192static int cm_isdir(char *filename){struct stat sbuf;return(stat(filename,&sbuf)!=-1 && S_ISDIR(sbuf.st_mode));}/* copy file, returns 0 if failed * src must be in the current directory (though this isn't checked) * and dstdir must be a directory (fails if it isn't) */int copyfile(char *src,char *dstdir){static unsigned char copybuf[TRANSFER_BUF_SIZE];FILE *in,*out;char *dst;int siz;if(!cm_isdir(dstdir)) return(0);if((in=fopen(src,"rb"))==NULL) return(0);if((dst=malloc(strlen(dstdir)+strlen(src)+2))==NULL) /* +2 for / and NUL */ return(0);strcpy(dst,dstdir);strcat(dst,"/");strcat(dst,src);/* check it doesn't already exist */if((out=fopen(dst,"rb"))!=NULL) { fclose(out); fclose(in); free(dst); return(0); }if((out=fopen(dst,"wb"))==NULL) { fclose(in); free(dst); return(0); }free(dst);/* so now both files are open. * copy from file to file, up to TRANSFER_BUF_SIZE bytes at a time. */while((siz=fread(copybuf,1,TRANSFER_BUF_SIZE,in))>0) { if(fwrite(copybuf,1,siz,out)!=siz) { fclose(out); fclose(in); return(0); } }fclose(out);fclose(in);return(1);}/* move file, returns 0 if failed * src must be in the current directory (though this isn't checked) * and dstdir must be a directory (fails if it isn't) */int movefile(char *src,char *dstdir){struct stat sbuf;struct utimbuf utbuf;char *dst;if(!cm_isdir(dstdir)) return(0);if((dst=malloc(strlen(dstdir)+strlen(src)+2))==NULL) /* +2 for / and NUL */ return(0);strcpy(dst,dstdir);strcat(dst,"/");strcat(dst,src);/* fail if dest file already exists */if(stat(dst,&sbuf)==0) { free(dst); return(0); }/* first try a rename() */if(rename(src,dst)==0) { /* it worked */ free(dst); return(1); }if(errno!=EXDEV) { /* if the reason it failed wasn't because it couldn't `rename' * between filesystems, we should fail too. */ free(dst); return(0); }/* resort to copying then deleting */if(!copyfile(src,dstdir)) { free(dst); return(0); }/* try to copy file times/owner/group/perms. * I don't consider this important enough to give an error if * it screws up (esp. 'cos setting owner might in some cases screw up * quite reasonably if we're not root :-)), but it's worth doing I * think - not least for consistency with the case where rename() works * (where everything is preserved). */if(stat(src,&sbuf)==0) { /* set times */ utbuf.actime=sbuf.st_atime; utbuf.modtime=sbuf.st_mtime; utime(dst,&utbuf); /* don't much care if it fails */ /* set owner/group and perms - these don't change the times set above */ chown(dst,sbuf.st_uid,sbuf.st_gid); chmod(dst,sbuf.st_mode); /* again, not too bothered if they fail */ }/* the copy worked, delete the original */if(remove(src)==0) { /* the delete worked, all done */ free(dst); return(1); }/* if we couldn't delete the original, delete the copy instead, * because the overall move failed and it would be messy to leave * it there. However, we're not really that bothered if *this* * delete fails. :-) */remove(dst);free(dst);return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -