| Current Path : /home/mudbot/eggdrop/src/ |
| Current File : //home/mudbot/eggdrop/src/misc_file.c |
/*
* misc_file.c -- handles:
* copyfile() movefile() file_readable()
*/
/*
* Copyright (C) 1999 - 2019 Eggheads Development Team
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "main.h"
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include "stat.h"
/* Copy a file from one place to another (possibly erasing old copy).
*
* returns: 0 if OK
* 1 if can't open original file
* 2 if can't open new file
* 3 if original file isn't normal
* 4 if ran out of disk space
*/
int copyfile(char *oldpath, char *newpath)
{
int fi, fo, x;
char buf[512];
struct stat st;
#ifndef CYGWIN_HACKS
fi = open(oldpath, O_RDONLY, 0);
#else
fi = open(oldpath, O_RDONLY | O_BINARY, 0);
#endif
if (fi < 0)
return 1;
fstat(fi, &st);
if (!(st.st_mode & S_IFREG)) {
close(fi);
return 3;
}
fo = creat(newpath, (int) (st.st_mode & 0777));
if (fo < 0) {
close(fi);
return 2;
}
for (x = 1; x > 0;) {
x = read(fi, buf, 512);
if (x > 0) {
if (write(fo, buf, x) < x) { /* Couldn't write */
close(fo);
close(fi);
unlink(newpath);
return 4;
}
}
}
fsync(fo);
close(fo);
close(fi);
return 0;
}
/* Copy a file from one place to another (possibly erasing old copy).
* Variant with newfile being a FILE* (most notably for use with tmpfile())
* which must already be fopen'd.
*
* returns: 0 if OK
* 1 if can't open original file
* 3 if original file isn't normal
* 4 if ran out of disk space
*/
int copyfilef(char *oldpath, FILE *newfile)
{
int fi, x;
char buf[512];
struct stat st;
long oripos;
#ifndef CYGWIN_HACKS
fi = open(oldpath, O_RDONLY, 0);
#else
fi = open(oldpath, O_RDONLY | O_BINARY, 0);
#endif
if (fi < 0)
return 1;
fstat(fi, &st);
if (!(st.st_mode & S_IFREG)) {
close(fi);
return 3;
}
oripos = ftell(newfile);
rewind(newfile);
for (x = 1; x > 0;) {
x = read(fi, buf, sizeof buf);
if (x > 0) {
if (fwrite(buf, 1, x, newfile) < x) { /* Couldn't write */
close(fi);
fseek(newfile, oripos, SEEK_SET);
return 4;
}
}
}
fsync(fileno(newfile));
close(fi);
fseek(newfile, oripos, SEEK_SET);
return 0;
}
/* Copy a file from one place to another (possibly erasing old copy).
* Variant with oldfile being a FILE* (most notably for use with tmpfile())
* which must already be fopen'd.
*
* returns: 0 if OK
* 2 if can't open new file
* 3 if original file isn't normal
* 4 if ran out of disk space
*/
int fcopyfile(FILE *oldfile, char *newpath)
{
int fo;
size_t x;
char buf[512];
struct stat st;
long oripos;
if (fstat(fileno(oldfile), &st) || !(st.st_mode & S_IFREG)) {
return 3;
}
fo = creat(newpath, (int) (st.st_mode & 0777));
if (fo < 0) {
return 2;
}
oripos = ftell(oldfile);
rewind(oldfile);
for (x = 1; x > 0;) {
x = fread(buf, 1, sizeof buf, oldfile);
if (x > 0) {
if (write(fo, buf, x) < x) { /* Couldn't write */
close(fo);
unlink(newpath);
fseek(oldfile, oripos, SEEK_SET);
return 4;
}
}
}
fsync(fo);
close(fo);
fseek(oldfile, oripos, SEEK_SET);
return 0;
}
int movefile(char *oldpath, char *newpath)
{
int ret;
/* Try to use rename first */
if (!rename(oldpath, newpath))
return 0;
/* If that fails, fall back to just copying and then
* deleting the file.
*/
ret = copyfile(oldpath, newpath);
if (!ret)
unlink(oldpath);
return ret;
}
int file_readable(char *file)
{
FILE *fp;
if (!(fp = fopen(file, "r")))
return 0;
fclose(fp);
return 1;
}