/*1* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 20092* The President and Fellows of Harvard College.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12* 3. Neither the name of the University nor the names of its contributors13* may be used to endorse or promote products derived from this software14* without specific prior written permission.15*16* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND17* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE18* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE19* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE20* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL21* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS22* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)23* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT24* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY25* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF26* SUCH DAMAGE.27*/2829#include <sys/types.h>30#include <sys/stat.h>31#include <unistd.h>32#include <assert.h>33#include <stdint.h>34#include <string.h>35#include <errno.h>36#include <fcntl.h>37#include <err.h>3839#include "support.h"40#include "disk.h"4142#define HOSTSTRING "System/161 Disk Image"43#define BLOCKSIZE 5124445#ifndef EINTR46#define EINTR 047#endif4849static int fd=-1;50static uint32_t nblocks;5152void53opendisk(const char *path)54{55struct stat statbuf;5657assert(fd<0);58fd = open(path, O_RDWR);59if (fd<0) {60err(1, "%s", path);61}62if (fstat(fd, &statbuf)) {63err(1, "%s: fstat", path);64}6566nblocks = statbuf.st_size / BLOCKSIZE;6768#ifdef HOST69nblocks--;7071{72char buf[64];73int len;7475do {76len = read(fd, buf, sizeof(buf)-1);77if (len < 0 && (errno==EINTR || errno==EAGAIN)) {78continue;79}80} while (0);8182buf[len] = 0;83buf[strlen(HOSTSTRING)] = 0;8485if (strcmp(buf, HOSTSTRING)) {86errx(1, "%s: Not a System/161 disk image", path);87}88}89#endif90}9192uint32_t93diskblocksize(void)94{95assert(fd>=0);96return BLOCKSIZE;97}9899uint32_t100diskblocks(void)101{102assert(fd>=0);103return nblocks;104}105106void107diskwrite(const void *data, uint32_t block)108{109const char *cdata = data;110uint32_t tot=0;111int len;112113assert(fd>=0);114115#ifdef HOST116// skip over disk file header117block++;118#endif119120if (lseek(fd, block*BLOCKSIZE, SEEK_SET)<0) {121err(1, "lseek");122}123124while (tot < BLOCKSIZE) {125len = write(fd, cdata + tot, BLOCKSIZE - tot);126if (len < 0) {127if (errno==EINTR || errno==EAGAIN) {128continue;129}130err(1, "write");131}132if (len==0) {133err(1, "write returned 0?");134}135tot += len;136}137}138139void140diskread(void *data, uint32_t block)141{142char *cdata = data;143uint32_t tot=0;144int len;145146assert(fd>=0);147148#ifdef HOST149// skip over disk file header150block++;151#endif152153if (lseek(fd, block*BLOCKSIZE, SEEK_SET)<0) {154err(1, "lseek");155}156157while (tot < BLOCKSIZE) {158len = read(fd, cdata + tot, BLOCKSIZE - tot);159if (len < 0) {160if (errno==EINTR || errno==EAGAIN) {161continue;162}163err(1, "read");164}165if (len==0) {166err(1, "unexpected EOF in mid-sector");167}168tot += len;169}170}171172void173closedisk(void)174{175assert(fd>=0);176if (close(fd)) {177err(1, "close");178}179fd = -1;180}181182183