| /* |
| * This file is subject to the terms and conditions of the GNU General Public |
| * License. See the file "COPYING" in the main directory of this archive |
| * for more details. |
| * |
| * Copyright (C) Hewlett-Packard (Paul Bame) paul_bame@hp.com |
| */ |
| #include <unistd.h> |
| #include <stdio.h> |
| #include <errno.h> |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include "palo.h" |
| |
| int |
| seekwrite(int fd, char *buf, unsigned size, unsigned where) |
| { |
| char check[1024]; |
| int n = size < sizeof check ? size : sizeof check; |
| int r = 0; |
| off_t off; |
| |
| if (0) printf("seekwrite(%d, %p, %u, %u)\n", fd, buf, size, where); |
| |
| if (where & 0x80000000) |
| { |
| r = -1; |
| } |
| |
| fsync(fd); |
| if (r != -1 && lseek(fd, where, SEEK_SET) != where) |
| { |
| perror("lseek"); |
| r = -1; |
| } |
| |
| if (r != -1 && (r = write(fd, buf, size)) == -1) |
| { |
| perror("write"); |
| r = -1; |
| } |
| |
| if (r != -1 && (off = lseek(fd, 0, SEEK_CUR)) != where + size) |
| { |
| fprintf(stderr, "position %ld not %u\n", off, where + size); |
| r = -1; |
| } |
| |
| fsync(fd); |
| |
| /* readback */ |
| if (r != -1 && lseek(fd, where, SEEK_SET) != where) |
| { |
| perror("lseek2"); |
| r = -1; |
| } |
| |
| if (r != -1 && read(fd, check, n) != n) |
| { |
| perror("readback(check)"); |
| r = -1; |
| } |
| |
| if (r != -1 && memcmp(check, buf, n) != 0) |
| { |
| fprintf(stderr, "readback failed!\n"); |
| r = -1; |
| } |
| |
| /* leave the file positioned where expected */ |
| if (r != -1 && lseek(fd, where + size, SEEK_SET) != where + size) |
| { |
| perror("lseek3"); |
| r = -1; |
| } |
| |
| return r; |
| } |
| |
| int |
| seekread(int fd, char *buf, unsigned size, unsigned where) |
| { |
| off_t off; |
| int r = 0; |
| if (0) printf("seekread(%d, %p, %x, %x)\n", fd, buf, size, where); |
| |
| if (where & 0x80000000) |
| { |
| r = -1; |
| } |
| |
| if (r != -1 && lseek(fd, where, SEEK_SET) != where) |
| { |
| perror("lseek"); |
| r = -1; |
| } |
| |
| if (r != -1 && (r = read(fd, buf, size)) != size) |
| { |
| perror("read"); |
| r = -1; |
| } |
| |
| if (r != -1 && (off = lseek(fd, 0, SEEK_CUR)) != where + size) |
| { |
| fprintf(stderr, "lseek said %ld not %u\n", off, where + size); |
| r = -1; |
| } |
| if (0) printf("returning %x\n", size); |
| |
| return r; |
| } |
| |
| int |
| cat(int out, int in) |
| { |
| char buf[FW_BLOCKSIZE]; |
| int n; |
| unsigned total = 0; |
| |
| while ((n = read(in, buf, sizeof buf)) > 0) |
| { |
| write(out, buf, n); |
| total += n; |
| } |
| |
| if (0) printf("cat() wrote %u bytes\n", total); |
| return total; |
| } |
| |
| int |
| fsize(int fd) |
| { |
| struct stat st; |
| |
| if (fstat(fd, &st) == -1) |
| { |
| perror("stat()"); |
| return -1; |
| } |
| return st.st_size; |
| } |