rmtaccessserver.c

来自「一个用在mips体系结构中的操作系统」· C语言 代码 · 共 629 行 · 第 1/2 页

C
629
字号
            fprintf(stderr, "  Security error. Can't open %s\n", argbuf);            if (verbose) printf("  Request from %s exiting\n", from);            ERRCmd(fd, errno);            exit(1);        }        file_fd = open(argbuf, O_RDONLY);        if (file_fd < 0) {            perror("serviceRequest -- open");            fprintf(stderr, "  Can't open file %s\n", argbuf);            if (verbose) printf("  Request from %s exiting\n", from);            ERRCmd(fd,errno);            exit(1);        }        if (verbose)             printf("  OPEN(%s)\n", argbuf);        ACKCmd(fd);        if (verbose) printf("  Sending file %s....", argbuf);        fflush(stdout);        (void) CopyFile(file_fd,fd);        if (verbose) printf("Done.\n");        if (verbose) printf("  Request from %s exiting\n", from);        exit(0);    }    case SIMRMT_DISKINIT: {        argbuf[req.arglen] = 0;  /* Null terminate */        if (DiskInit(argbuf) < 0) {            if (verbose) printf("  DiskInit failed. Request from %s exiting\n", from);            ERRCmd(fd, 1);            exit(1);        }        ACKCmd(fd);        if (verbose) printf("  DiskInit from %s successful -- processing requests.\n", from);        ProcessDiskRequest(fd);        break;    }    default:        fprintf(stderr, "  Unknown command %d\n", req.cmd);        if (verbose) printf("  Request from %s exiting\n", from);        exit(1);    }    exit(0);}	voidACKCmd(int fd) {    if (write(fd, "OK\n", 3) != 3) {        perror("ACKCmd -- write");        exit(1);    } }voidERRCmd(int fd, int err) {    char str[8];    sprintf(str, "E%02d", err);    if (write(fd, str, 3) != 3) {        perror("ERRCmd -- write");        exit(1);    } }intCopyFile(int infd, int outfd){    char buf[8192];    int cnt, cnt2;    while(1) {        cnt = read(infd, buf, sizeof(buf));        if (cnt == 0)             break;        if (cnt < 0) {            perror("CopyFile -- read");            exit(1);        }        cnt2 = write(outfd, buf, cnt);        if (cnt2 != cnt) {            perror("CopyFile -- write");            exit(1);        }    }    return 0;}intCopySizedFile(int infd, int outfd, int size){  char buf[8192];  int cnt, cnt2;  while(size > 0) {    int getsize = (size < sizeof(buf) ? size : sizeof(buf));    cnt = readforsure(infd, buf, getsize);    if (cnt != getsize) {      perror("CopySizedFile -- read");      exit(1);    }    cnt2 = write(outfd, buf, cnt);    if (cnt2 != cnt) {      perror("CopySizedFile -- write");      exit(1);    }    size -= cnt;  }  return 0;}intDiskInit(char *arg){    int i;    for (i = 0; i < NETDISK_MAX_DISKS; i++) {         diskInfo[i].fd = -1;    }    if (getwd(cwd) == 0) return -1;    if (gethostname(hostname, MAX_PATH_LENGTH) != 0) return -1;    else {      char *c = strchr(hostname, '.');      if (c != NULL) *c = 0;    }    return 0;}intProcessDiskRequest(int fd){    int   n;    int xfersize;    NetDiskHdr *hdrPtr;     while(1) {        n = readforsure(fd, curPacket, sizeof(NetDiskHdr));        if (n != sizeof(NetDiskHdr)) {            if (n == 0) exit(0);            perror("ProcessDiskRequest -- read");            exit(1);        }        hdrPtr = (NetDiskHdr *) curPacket;         if ((hdrPtr->op == NETDISK_WRITE) || (hdrPtr->op == NETDISK_ATTACH)) {            xfersize =  hdrPtr->sizeInBytes;            n = readforsure(fd, curPacket + sizeof(NetDiskHdr), xfersize);            if (n != xfersize) {                if (n == 0) exit(0);                perror("ProcessDiskRequest -- read");                exit(1);            }        }         hdrPtr = (NetDiskHdr *) curPacket;        if ((hdrPtr->retVal = DoDiskRequest(hdrPtr->op,					    hdrPtr->ctrl, hdrPtr->unit,                                            hdrPtr->sectorNum, hdrPtr->sizeInBytes,                                            (char *) (hdrPtr+1))) == -1 ) {           /* Exiting here leaves SimOS hanging for a response header --            Instead return a header with size -1 and let SimOS deal */#ifdef notdef           exit(1);#endif        }                if ((hdrPtr->op == NETDISK_READ) || (hdrPtr->op == NETDISK_ATTACH)) {           n = hdrPtr->retVal;           if (n < 0) n = 0;        } else {           n = 0;        }        xfersize = write(fd, curPacket, n + sizeof(*hdrPtr));        if (xfersize !=  n + sizeof(*hdrPtr)) {            perror("ProcessDiskRequest -- write");            exit(1);        }    }    return 0;}int64DoDiskRequest(int op, int ctrl, int unit, int64 sectorNum, int64 sizeInBytes, char *buffer){ 	   DiskFileInfo *hd;   DiskFileInfo *df = (DiskFileInfo *) buffer;   unsigned long transferSize, bytesRemaining;     if ((ctrl < 0) || (ctrl >= SIM_DISK_DEV_MAX_CTRL)) {     if (verbose) printf("  Bad controller number %d in request from %s\n",			 ctrl, source);     return -1;   }   if ((unit < 0) || (unit >= SIM_DISK_DEV_MAX_UNIT)) {     if (verbose) printf("  Bad unit number %d in request from %s\n",			 unit, source);     return -1;   }   hd = &(diskInfo[CU2DISK(ctrl,unit)]);      if (op == NETDISK_ATTACH) {      if (hd->fd > 0) {         if (verbose) printf("  Trying to reattach disk %d.%d in request from %s\n",                             ctrl, unit, source);         return -1;      }      /* If we're restoring from a checkpoint, then SimOS will provide         the full pathname of the disk file in the buffer; if not, then         SimOS simply provides the disk number and we use the devices in          the CWD of the rmtaccess process. */      /* In any case, we return to SimOS the relevant file info for the          disk file: filename, size, and last modified time -- these are          needed by SimOS to take a checkpoint */      if (sizeInBytes > 0) {         strcpy(hd->filename, df->filename);      }      else {         sprintf(hd->filename, "%s/DISK%d.%d", cwd, ctrl, unit);         strcpy(df->filename, hd->filename);      }      hd->fd = open(hd->filename, O_RDONLY , 0);      if (hd->fd > 0) {          long size;         struct stat filestats;                  if (verbose) printf("  Attach disk %s for %s\n", hd->filename,                             source);                  if ((size = lseek(hd->fd, 0, SEEK_END)) < 0 ) {            perror("Lseeking disk in netdiskserver");         }         if (fstat(hd->fd, &filestats) < 0) {            perror("stat");         }         df->fileSize = hd->fileSize = size;         size = (SIM_DISK_SHADOW_BLKSIZE)            *((size+(SIM_DISK_SHADOW_BLKSIZE))/(SIM_DISK_SHADOW_BLKSIZE));         df->modifyTime = hd->modifyTime = filestats.st_mtime;      } else {          perror(hd->filename);         return -1;      }      return sizeof(DiskFileInfo);   }      if (hd->fd <= 0) {      if (verbose) printf("  Failed request for DISK%d.%d for %s\n",			  ctrl, unit, source);      return -1;   }   if (op == NETDISK_PROBE) {       return hd->fileSize;   }   if (sectorNum*SectorSize + sizeInBytes > hd->fileSize) {      sizeInBytes = hd->fileSize - sectorNum*SectorSize;      if (verbose) printf("  Out of range request for DISK%d.%d for %s\n",			  ctrl, unit, source);          }   if (sizeInBytes < 0)       sizeInBytes = 0;	   bytesRemaining = sizeInBytes;   while(bytesRemaining) {      transferSize = bytesRemaining > SectorSize ? SectorSize : bytesRemaining;      lseek (hd->fd, sectorNum*SectorSize, SEEK_SET);      if (op == NETDISK_READ) {         if (read (hd->fd, (void *)buffer, transferSize ) != transferSize) {            if (verbose) printf("Can't read from file for DISK%d.%d\n",				ctrl, unit);            return -1;         }      } else {         if (verbose) printf("Can't write to rmtaccess disk for DISK%d.%d\n",			     ctrl, unit);         return -1;      }      buffer += transferSize;      sectorNum++;      bytesRemaining -= transferSize;   }   return sizeInBytes;}static intreadforsure(int fd, char *buf, int size){    int a;    for(a = 0; a < size;) {        int ret = read(fd, buf + a, size-a);        if (ret <= 0)            return ret;        a += ret;    }    return size;}static voidchilddone(int sig){   int pid, status;   pid = wait(&status);   /*    * Now reinstall handler & cause SIGCLD to be re-raised    * if any more children exited while we were in here.    */   sigset(SIGCLD, childdone);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?