/* $Id: file_utils.c,v 1.2 2002/01/11 08:44:55 fors Exp $ * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * COPYRIGHT (c) 2001 European Southern Observatory * LICENSE: GNU General Public License version 2 or later * * PROJECT: VLT Data Flow System * AUTHOR: Ralf Palsa -- ESO/DMD/DPG * SUBSYSTEM: Instrument pipelines * * PURPOSE: * DESCRIPTION: * * $Name: fsmosaic-1_0 $ * $Revision: 1.2 $ * ---------------------------------------------------------------------------- */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include /** * @memo * Copy a file. * * @return The function returns 0 if no error occurred, otherwise -1 is * returned and errno is set appropriately. * * @param srcpath Source file name. * @param dstpath Destination file name. * * @doc * The function provides a very basic way to copy the source file * \textbf{srcpath} to a destination file \textbf{dstpath}. * The implementation just uses \textbf{read()} and \textbf{write()} * to do the job. It is by far not comparable with the \textbf{cp} * shell command. Actually it just writes the source file contents into * a new file with the appropriate output name. * * If an error occurs the destination file is removed before the function * returns. * * @author R. Palsa */ int copy(const char *srcpath, const char *dstpath) { int src, dst; struct stat sb, db; char *buf; ssize_t rbytes = 0, wbytes = 0, blksize = 4096; if ((src = open(srcpath, O_RDONLY)) == -1) return -1; else { if (fstat(src, &sb) == -1 || !S_ISREG(sb.st_mode)) { close(src); return -1; } if ((dst = open(dstpath, O_CREAT | O_WRONLY | O_TRUNC, sb.st_mode)) == -1) { close(src); return -1; } else if (fstat(dst, &db) == -1 || !S_ISREG(db.st_mode)) { close(src); close(dst); unlink(dstpath); return -1; } } #ifdef HAVE_ST_BLOCKS blksize = db.st_blksize; #else #ifdef DEV_BSIZE blksize = DEV_BSIZE; #endif #endif if ((buf = (char *)malloc(blksize)) == NULL) { close(src); close(dst); unlink(dstpath); return -1; } while ((rbytes = read(src, buf, blksize)) > 0) if ((wbytes = write(dst, buf, rbytes)) != rbytes) { wbytes = -1; break; } close(src); close(dst); free(buf); if (rbytes == -1 || wbytes == -1) { unlink(dstpath); return -1; } return 0; } /* * @memo * Strip non-directory suffix from a filename. * * @return Pointer to the stripped filename, or #NULL# in case an error * occurred. * * @param filename Path to the file. * * @doc * The function removes the trailing directory component from * \textbf{filename}. If filename does not contain any slashes the * result is the current working directory. The input string must * not contain more than PATHNAME_MAX characters. * * The result is stored in a static, internal buffer, i.e. it is * overwritten by the next call to \textbf{dir_name()}. * * @author R. Palsa */ char *dir_name(const char *filename) { static char dirname[PATHNAME_MAX + 1]; size_t sz; char *s; /* * Is there any slash? */ if (!(s = strrchr(filename, '/'))) { if (!getcwd(dirname, PATHNAME_MAX)) return NULL; } else { if ((sz = s - filename) > PATHNAME_MAX) return NULL; else { strncpy(dirname, filename, sz); dirname[sz + 1] = '\0'; } } return dirname; } /*@}*/