/* * Write data to one or more blocks of the tar file. * The data is always padded out to a multiple of TAR_BLOCK_SIZE. * The errorFlag static variable is set on an error. */ static void writeTarBlock(const char * buf, int len) { int partialLength; int completeLength; char fullBlock[TAR_BLOCK_SIZE]; /* * If we had a write error before, then do nothing more. */ if (errorFlag) return; /* * Get the amount of complete and partial blocks. */ partialLength = len % TAR_BLOCK_SIZE; completeLength = len - partialLength; /* * Write all of the complete blocks. */ if ((completeLength > 0) && !fullWrite(tarFd, buf, completeLength)) { perror(tarName); errorFlag = TRUE; return; } /* * If there are no partial blocks left, we are done. */ if (partialLength == 0) return; /* * Copy the partial data into a complete block, and pad the rest * of it with zeroes. */ memcpy(fullBlock, buf + completeLength, partialLength); memset(fullBlock + partialLength, 0, TAR_BLOCK_SIZE - partialLength); /* * Write the last complete block. */ if (!fullWrite(tarFd, fullBlock, TAR_BLOCK_SIZE)) { perror(tarName); errorFlag = TRUE; } }
static sys_return_t sud_set_common (az_allocid_t allocid, const char *name, const char *buf, size_t len) { char fname[256]; char tmpfname[256]; int rv = 0; ssize_t sz = 0; int fd; snprintf (fname, sizeof(fname)-1, "%s/%ld/%s", SUD_DIR, allocid, name); snprintf (tmpfname, sizeof(tmpfname)-1, "%s/%ld/%s.tmp", SUD_DIR, allocid, name); int flags = OPEN_CREATE_FLAGS; fd = MY_OPEN (tmpfname, flags, 0644); if (fd < 0) { int e = errno; perror ("sud open"); syslog (LOG_ERR, "ERROR: sud open, %d", e); return SYSERR_NO_PRIVILEGE; } sz = fullWrite (fd, buf, len); if ((size_t)sz != len) { perror ("sud write"); syslog (LOG_ERR, "ERROR: sud write"); rv = MY_CLOSE (fd); if (rv < 0) { perror ("close"); syslog (LOG_ERR, "ERROR: sud close"); } return SYSERR_NO_PRIVILEGE; } rv = MY_CLOSE (fd); if (rv < 0) { perror ("sud close"); syslog (LOG_ERR, "ERROR: sud close"); return SYSERR_NO_PRIVILEGE; } rv = MY_RENAME (tmpfname, fname); if (rv < 0) { perror ("sud rename"); syslog (LOG_ERR, "ERROR: sud rename"); return SYSERR_NO_PRIVILEGE; } return SYSERR_NONE; }
/* * Handle a data block of some specified size that was read. */ static void readData(const char * cp, int count) { /* * Reduce the amount of data left in this file. * If there is no more data left, then we need to read * the header again. */ dataCc -= count; if (dataCc <= 0) inHeader = TRUE; /* * If we aren't extracting files or this file is being * skipped then do nothing more. */ if (!extractFlag || skipFileFlag) return; /* * Write the data to the output file. */ if (fullWrite(outFd, cp, count) < 0) { perror(outName); (void) close(outFd); outFd = -1; skipFileFlag = TRUE; return; } /* * If the write failed, close the file and disable further * writes to this file. */ if (dataCc <= 0) { if (close(outFd)) perror(outName); outFd = -1; } }
/* * Copy all of the file data from the archive to the specified * open file. Returns TRUE on success. */ static BOOL writeFile(const Archive * arch, int outfd) { unsigned char buf[BUF_SIZE]; off_t n; n = arch->size; while (n > 0) { ssize_t cc; cc = read((int)arch->fd, (void *)buf, (size_t)MIN(n,(int) sizeof(buf))); if (cc == -1) { fprintf(stderr, "Error reading archive member: %s\n", strerror(errno)); return FALSE; } if (cc == 0) { fprintf(stderr, "Unexpected end of file\n"); return FALSE; } if (fullWrite(outfd,(const char *)buf,(int) cc) < 0) { fprintf(stderr, "Write error: %s\n", strerror(errno)); return FALSE; } n -= cc; } if (!skipPadding(arch->fd, arch->pad)) return FALSE; return TRUE; }
/* * Copy one file to another, while possibly preserving its modes, times, * and modes. Returns TRUE if successful, or FALSE on a failure with an * error message output. (Failure is not indicted if the attributes cannot * be set.) */ BOOL copyFile( const char * srcName, const char * destName, BOOL setModes ) { int rfd; int wfd; int rcc; char buf[BUF_SIZE]; struct stat statBuf1; struct stat statBuf2; struct utimbuf times; if (stat(srcName, &statBuf1) < 0) { perror(srcName); return FALSE; } if (stat(destName, &statBuf2) < 0) { statBuf2.st_ino = -1; statBuf2.st_dev = -1; } if ((statBuf1.st_dev == statBuf2.st_dev) && (statBuf1.st_ino == statBuf2.st_ino)) { fprintf(stderr, "Copying file \"%s\" to itself\n", srcName); return FALSE; } rfd = open(srcName, O_RDONLY); if (rfd < 0) { perror(srcName); return FALSE; } wfd = creat(destName, statBuf1.st_mode); if (wfd < 0) { perror(destName); close(rfd); return FALSE; } while ((rcc = read(rfd, buf, sizeof(buf))) > 0) { if (intFlag) { close(rfd); close(wfd); return FALSE; } if (fullWrite(wfd, buf, rcc) < 0) goto error_exit; } if (rcc < 0) { perror(srcName); goto error_exit; } (void) close(rfd); if (close(wfd) < 0) { perror(destName); return FALSE; } if (setModes) { (void) chmod(destName, statBuf1.st_mode); (void) chown(destName, statBuf1.st_uid, statBuf1.st_gid); times.actime = statBuf1.st_atime; times.modtime = statBuf1.st_mtime; (void) utime(destName, ×); } return TRUE; error_exit: close(rfd); close(wfd); return FALSE; }