|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* File functions for the CUPS scheduler.
|
|
Packit |
2fc92b |
*
|
|
Packit |
2fc92b |
* Copyright 2007-2014 by Apple Inc.
|
|
Packit |
2fc92b |
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
|
|
Packit |
2fc92b |
*
|
|
Packit |
2fc92b |
* These coded instructions, statements, and computer programs are the
|
|
Packit |
2fc92b |
* property of Apple Inc. and are protected by Federal copyright
|
|
Packit |
2fc92b |
* law. Distribution and use rights are outlined in the file "LICENSE.txt"
|
|
Packit |
2fc92b |
* "LICENSE" which should have been included with this file. If this
|
|
Packit |
2fc92b |
* file is missing or damaged, see the license at "http://www.cups.org/".
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* Include necessary headers...
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
#include "cupsd.h"
|
|
Packit |
2fc92b |
#include <cups/dir.h>
|
|
Packit |
2fc92b |
#include <fnmatch.h>
|
|
Packit |
2fc92b |
#ifdef HAVE_REMOVEFILE
|
|
Packit |
2fc92b |
# include <removefile.h>
|
|
Packit |
2fc92b |
#else
|
|
Packit |
2fc92b |
static int overwrite_data(int fd, const char *buffer, int bufsize,
|
|
Packit |
2fc92b |
int filesize);
|
|
Packit |
2fc92b |
#endif /* HAVE_REMOVEFILE */
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* 'cupsdCleanFiles()' - Clean out old files.
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
void
|
|
Packit |
2fc92b |
cupsdCleanFiles(const char *path, /* I - Directory to clean */
|
|
Packit |
2fc92b |
const char *pattern) /* I - Filename pattern or NULL */
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
cups_dir_t *dir; /* Directory */
|
|
Packit |
2fc92b |
cups_dentry_t *dent; /* Directory entry */
|
|
Packit |
2fc92b |
char filename[1024]; /* Filename */
|
|
Packit |
2fc92b |
int status; /* Status from unlink/rmdir */
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
cupsdLogMessage(CUPSD_LOG_DEBUG,
|
|
Packit |
2fc92b |
"cupsdCleanFiles(path=\"%s\", pattern=\"%s\")", path,
|
|
Packit |
2fc92b |
pattern ? pattern : "(null)");
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
if ((dir = cupsDirOpen(path)) == NULL)
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open directory \"%s\" - %s",
|
|
Packit |
2fc92b |
path, strerror(errno));
|
|
Packit |
2fc92b |
return;
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
cupsdLogMessage(CUPSD_LOG_INFO, "Cleaning out old files in \"%s\".", path);
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
while ((dent = cupsDirRead(dir)) != NULL)
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
if (pattern && fnmatch(pattern, dent->filename, 0))
|
|
Packit |
2fc92b |
continue;
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
snprintf(filename, sizeof(filename), "%s/%s", path, dent->filename);
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
if (S_ISDIR(dent->fileinfo.st_mode))
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
cupsdCleanFiles(filename, pattern);
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
status = rmdir(filename);
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
else
|
|
Packit |
2fc92b |
status = cupsdUnlinkOrRemoveFile(filename);
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
if (status)
|
|
Packit |
2fc92b |
cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to remove \"%s\" - %s", filename,
|
|
Packit |
2fc92b |
strerror(errno));
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
cupsDirClose(dir);
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* 'cupsdCloseCreatedConfFile()' - Close a created configuration file and move
|
|
Packit |
2fc92b |
* into place.
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
int /* O - 0 on success, -1 on error */
|
|
Packit |
2fc92b |
cupsdCloseCreatedConfFile(
|
|
Packit |
2fc92b |
cups_file_t *fp, /* I - File to close */
|
|
Packit |
2fc92b |
const char *filename) /* I - Filename */
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
char newfile[1024], /* filename.N */
|
|
Packit |
2fc92b |
oldfile[1024]; /* filename.O */
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* Synchronize changes to disk if SyncOnClose is enabled.
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
if (SyncOnClose)
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
if (cupsFileFlush(fp))
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to write changes to \"%s\": %s",
|
|
Packit |
2fc92b |
filename, strerror(errno));
|
|
Packit |
2fc92b |
cupsFileClose(fp);
|
|
Packit |
2fc92b |
return (-1);
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
if (fsync(cupsFileNumber(fp)))
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to sync changes to \"%s\": %s",
|
|
Packit |
2fc92b |
filename, strerror(errno));
|
|
Packit |
2fc92b |
cupsFileClose(fp);
|
|
Packit |
2fc92b |
return (-1);
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* First close the file...
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
if (cupsFileClose(fp))
|
|
Packit |
2fc92b |
return (-1);
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* Then remove "filename.O", rename "filename" to "filename.O", and rename
|
|
Packit |
2fc92b |
* "filename.N" to "filename".
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
snprintf(newfile, sizeof(newfile), "%s.N", filename);
|
|
Packit |
2fc92b |
snprintf(oldfile, sizeof(oldfile), "%s.O", filename);
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
if ((cupsdUnlinkOrRemoveFile(oldfile) && errno != ENOENT) ||
|
|
Packit |
2fc92b |
(rename(filename, oldfile) && errno != ENOENT) ||
|
|
Packit |
2fc92b |
rename(newfile, filename))
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to finalize \"%s\": %s",
|
|
Packit |
2fc92b |
filename, strerror(errno));
|
|
Packit |
2fc92b |
return (-1);
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
return (0);
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* 'cupsdClosePipe()' - Close a pipe as necessary.
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
void
|
|
Packit |
2fc92b |
cupsdClosePipe(int *fds) /* I - Pipe file descriptors (2) */
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* Close file descriptors as needed...
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
if (fds[0] >= 0)
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
close(fds[0]);
|
|
Packit |
2fc92b |
fds[0] = -1;
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
if (fds[1] >= 0)
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
close(fds[1]);
|
|
Packit |
2fc92b |
fds[1] = -1;
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* 'cupsdCreateConfFile()' - Create a configuration file safely.
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
cups_file_t * /* O - File pointer */
|
|
Packit |
2fc92b |
cupsdCreateConfFile(
|
|
Packit |
2fc92b |
const char *filename, /* I - Filename */
|
|
Packit |
2fc92b |
mode_t mode) /* I - Permissions */
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
cups_file_t *fp; /* File pointer */
|
|
Packit |
2fc92b |
char newfile[1024]; /* filename.N */
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
snprintf(newfile, sizeof(newfile), "%s.N", filename);
|
|
Packit |
2fc92b |
if ((fp = cupsFileOpen(newfile, "w")) == NULL)
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create \"%s\": %s", newfile,
|
|
Packit |
2fc92b |
strerror(errno));
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
else
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
if (!getuid() && fchown(cupsFileNumber(fp), getuid(), Group))
|
|
Packit |
2fc92b |
cupsdLogMessage(CUPSD_LOG_WARN, "Unable to change group for \"%s\": %s",
|
|
Packit |
2fc92b |
newfile, strerror(errno));
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
if (fchmod(cupsFileNumber(fp), mode))
|
|
Packit |
2fc92b |
cupsdLogMessage(CUPSD_LOG_WARN,
|
|
Packit |
2fc92b |
"Unable to change permissions for \"%s\": %s",
|
|
Packit |
2fc92b |
newfile, strerror(errno));
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
return (fp);
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* 'cupsdOpenConfFile()' - Open a configuration file.
|
|
Packit |
2fc92b |
*
|
|
Packit |
2fc92b |
* This function looks for "filename.O" if "filename" does not exist and does
|
|
Packit |
2fc92b |
* a rename as needed.
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
cups_file_t * /* O - File pointer */
|
|
Packit |
2fc92b |
cupsdOpenConfFile(const char *filename) /* I - Filename */
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
cups_file_t *fp; /* File pointer */
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
if ((fp = cupsFileOpen(filename, "r")) == NULL)
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
if (errno == ENOENT)
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* Try opening the backup file...
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
char oldfile[1024]; /* filename.O */
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
snprintf(oldfile, sizeof(oldfile), "%s.O", filename);
|
|
Packit |
2fc92b |
fp = cupsFileOpen(oldfile, "r");
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
else
|
|
Packit |
2fc92b |
cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open \"%s\": %s", filename,
|
|
Packit |
2fc92b |
strerror(errno));
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
return (fp);
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* 'cupsdOpenPipe()' - Create a pipe which is closed on exec.
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
int /* O - 0 on success, -1 on error */
|
|
Packit |
2fc92b |
cupsdOpenPipe(int *fds) /* O - Pipe file descriptors (2) */
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* Create the pipe...
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
if (pipe(fds))
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
fds[0] = -1;
|
|
Packit |
2fc92b |
fds[1] = -1;
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
return (-1);
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* Set the "close on exec" flag on each end of the pipe...
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
if (fcntl(fds[0], F_SETFD, fcntl(fds[0], F_GETFD) | FD_CLOEXEC))
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
close(fds[0]);
|
|
Packit |
2fc92b |
close(fds[1]);
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
fds[0] = -1;
|
|
Packit |
2fc92b |
fds[1] = -1;
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
return (-1);
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
if (fcntl(fds[1], F_SETFD, fcntl(fds[1], F_GETFD) | FD_CLOEXEC))
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
close(fds[0]);
|
|
Packit |
2fc92b |
close(fds[1]);
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
fds[0] = -1;
|
|
Packit |
2fc92b |
fds[1] = -1;
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
return (-1);
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* Return 0 indicating success...
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
return (0);
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* 'cupsdRemoveFile()' - Remove a file securely.
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
int /* O - 0 on success, -1 on error */
|
|
Packit |
2fc92b |
cupsdRemoveFile(const char *filename) /* I - File to remove */
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
#ifdef HAVE_REMOVEFILE
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* See if the file exists...
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
if (access(filename, 0))
|
|
Packit |
2fc92b |
return (0);
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
cupsdLogMessage(CUPSD_LOG_DEBUG, "Securely removing \"%s\".", filename);
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* Remove the file...
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
return (removefile(filename, NULL, REMOVEFILE_SECURE_1_PASS));
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
#else
|
|
Packit |
2fc92b |
int fd; /* File descriptor */
|
|
Packit |
2fc92b |
struct stat info; /* File information */
|
|
Packit |
2fc92b |
char buffer[512]; /* Data buffer */
|
|
Packit |
2fc92b |
int i; /* Looping var */
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* See if the file exists...
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
if (access(filename, 0))
|
|
Packit |
2fc92b |
return (0);
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
cupsdLogMessage(CUPSD_LOG_DEBUG, "Securely removing \"%s\".", filename);
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* First open the file for writing in exclusive mode.
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
if ((fd = open(filename, O_WRONLY | O_EXCL)) < 0)
|
|
Packit |
2fc92b |
return (-1);
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* Delete the file now - it will still be around as long as the file is
|
|
Packit |
2fc92b |
* open...
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
if (unlink(filename))
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
close(fd);
|
|
Packit |
2fc92b |
return (-1);
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* Then get the file size...
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
if (fstat(fd, &info))
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
close(fd);
|
|
Packit |
2fc92b |
return (-1);
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* Overwrite the file with random data.
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
CUPS_SRAND(time(NULL));
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
for (i = 0; i < sizeof(buffer); i ++)
|
|
Packit |
2fc92b |
buffer[i] = CUPS_RAND();
|
|
Packit |
2fc92b |
if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size))
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
close(fd);
|
|
Packit |
2fc92b |
return (-1);
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* Close the file, which will lead to the actual deletion, and return...
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
return (close(fd));
|
|
Packit |
2fc92b |
#endif /* HAVE_REMOVEFILE */
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* 'cupsdUnlinkOrRemoveFile()' - Unlink or securely remove a file depending
|
|
Packit |
2fc92b |
* on the configuration.
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
int /* O - 0 on success, -1 on error */
|
|
Packit |
2fc92b |
cupsdUnlinkOrRemoveFile(
|
|
Packit |
2fc92b |
const char *filename) /* I - Filename */
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
if (Classification)
|
|
Packit |
2fc92b |
return (cupsdRemoveFile(filename));
|
|
Packit |
2fc92b |
else
|
|
Packit |
2fc92b |
return (unlink(filename));
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
#ifndef HAVE_REMOVEFILE
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* 'overwrite_data()' - Overwrite the data in a file.
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
static int /* O - 0 on success, -1 on error */
|
|
Packit |
2fc92b |
overwrite_data(int fd, /* I - File descriptor */
|
|
Packit |
2fc92b |
const char *buffer, /* I - Buffer to write */
|
|
Packit |
2fc92b |
int bufsize, /* I - Size of buffer */
|
|
Packit |
2fc92b |
int filesize) /* I - Size of file */
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
int bytes; /* Bytes to write/written */
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* Start at the beginning of the file...
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
if (lseek(fd, 0, SEEK_SET) < 0)
|
|
Packit |
2fc92b |
return (-1);
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* Fill the file with the provided data...
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
while (filesize > 0)
|
|
Packit |
2fc92b |
{
|
|
Packit |
2fc92b |
if (filesize > bufsize)
|
|
Packit |
2fc92b |
bytes = bufsize;
|
|
Packit |
2fc92b |
else
|
|
Packit |
2fc92b |
bytes = filesize;
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
if ((bytes = write(fd, buffer, (size_t)bytes)) < 0)
|
|
Packit |
2fc92b |
return (-1);
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
filesize -= bytes;
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
/*
|
|
Packit |
2fc92b |
* Force the changes to disk...
|
|
Packit |
2fc92b |
*/
|
|
Packit |
2fc92b |
|
|
Packit |
2fc92b |
return (fsync(fd));
|
|
Packit |
2fc92b |
}
|
|
Packit |
2fc92b |
#endif /* HAVE_REMOVEFILE */
|