rmtaccessserver.c

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

C
629
字号
/* * Copyright (C) 1996-1998 by the Board of Trustees *    of Leland Stanford Junior University. *  * This file is part of the SimOS distribution.  * See LICENSE file for terms of the license.  * *//*  * rmtacessserver.c * *   Support remote access to Simos files. *  */#include <sys/types.h>#include <sys/param.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <sys/file.h>#include <sys/wait.h>#include <sys/time.h>#include <sys/mman.h>#include <net/if.h>#include <netinet/in_systm.h>#include <netinet/in.h>#include <netinet/ip.h>#include <netinet/if_ether.h>#include <arpa/inet.h>#include <stdio.h>#include <signal.h>#include <pwd.h>#include <setjmp.h>#include <netdb.h>#include <errno.h>#include <fcntl.h>#include <strings.h>#include <varargs.h>#include <stropts.h>#include <poll.h>#include <search.h>#include <memory.h>#include <stdlib.h>#include <unistd.h>/* machine specific includes */#ifdef sgi#include <bstring.h>#else#include <sys/resource.h>#endif#include "simtypes.h"#if 0#include "syslimits.h"#endif/* * "obvious" defines needed for correct inclusion */#include "devices/controllers/rmtaccess.h"#include "devices/controllers/hd.h"#define MAX_PATH_LENGTH 128static int readforsure(int fd, char *buf, int size);void ERRCmd(int fd, int err);void ACKCmd (int fd);int CopyFile(int infd, int outfd);int CopySizedFile(int infd, int outfd, int size);int DiskInit(char *args);/* * Buffer to hold the current disk request  */char curPacket[sizeof(NetDiskHdr) + NETDISK_MAX_REQUEST_SIZE];char argbuf[16*1024];int verbose = 0;static char *source = "Unknown";#ifndef  SIM_DISK_DEV_MAX_UNIT/* * gross hack. bugnion */#define SIM_DISK_DEV_MAX_UNIT 128#define SIM_DISK_DEV_MAX_CTRL 128#endifstatic DiskFileInfo diskInfo[NETDISK_MAX_DISKS];#define CU2DISK(c,u) (c*SIM_DISK_DEV_MAX_UNIT + u)char hostname[MAX_PATH_LENGTH];char cwd[MAX_PATH_LENGTH];/* * Forward routine declartions. */int serviceRequest(int, char *);int ProcessDiskRequest(int fd);int64 DoDiskRequest(int op, int ctrl, int unit,                   int64 sectorNum, int64 sizeInBytes, char *buffer);static void childdone(int sig);/* *---------------------------------------------------------------------- * * main --  * *    Main routine and loop for remote checkpoint access * * Results: *   Only returns if an error occurs. * * Side effects: * *---------------------------------------------------------------------- */intmain(int argc, char *argv[]){    int	new_s, errflg;    struct sockaddr_in addr;    int	simfd;	    int port, num;    extern char *optarg;    extern int optind;    while ((num = getopt(argc, argv, "vs:")) != EOF) {        switch (num) {        case 'v': {            verbose++;            break;        }        default:            goto usage;        }    }    num = argc - optind;    if ((num < 1) || (num > 2)) {      usage:        fprintf(stderr, "usage: %s [-v] Port [CheckPointDir]\n", argv[0]);        exit(1);    }    port = atoi(argv[optind]);    if ((port < 1000) || (port > 0xffff)) {        fprintf(stderr, "Bad port number %s\n", argv[optind]);        goto usage;    }    if (num == 2) {        if (chdir(argv[optind+1]) < 0) {             perror(argv[optind+1]);            goto usage;        }    }     if (verbose) {        getwd(argbuf);        printf("Remote access enabled\nDirectory: %s\nPort: %d\n",               argbuf, port);        fflush(stdout);    }    simfd = -1;    errflg = 0;    /*     * Create the socket that recieves requests.      * The mostly likely     * cause of failure is another netdisk running causing the bind     * to fail with address in use.     */    simfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);    if (simfd < 0) {        perror("main: socket");        exit(1);    }    bzero((char *)&addr, sizeof(addr));    addr.sin_family = AF_INET;    addr.sin_addr.s_addr = INADDR_ANY;    addr.sin_port = htons((short)port);    if (bind(simfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {        perror("main: bind");        exit(2);    }    if (listen(simfd, 4) < 0) {        perror("main:listen");        exit(2);    }     if (sigset(SIGCLD, childdone) == (void(*)())-1) {       perror("sigset");       exit(1);    }    /*     * Loop waiting for packets to arrive.     */    while(1) {         struct sockaddr from;        int pid;        int fromlen = sizeof (from);        /* must accept connection from TCP */        fromlen = sizeof(from);        if((new_s = accept(simfd, &from, &fromlen)) < 0) {            if (errno == EINTR)                continue;            perror("main:accept");            exit(1);        }        pid = fork();        if (pid < 0) {            perror("main:fork");            exit(1);        }        if (pid == 0) {            close(simfd);            if (verbose) {                static char buf[256];                struct sockaddr_in *inet_from = (struct sockaddr_in *) &from;                sprintf(buf, "%s:%d", inet_ntoa(inet_from->sin_addr),                         inet_from->sin_port);                source = buf;            }            serviceRequest(new_s, source);            exit(1);        }        close(new_s);    }    exit(0);}/* *---------------------------------------------------------------------- * * serviceRequest --  * * Service a request that arrives at the simulated ethernet port. * * Results: *   -1 if problem occur with * * Side effects: * *---------------------------------------------------------------------- */intserviceRequest(int fd, char *from){    int	  n;    RmtAccessStartRequest  req;    if (verbose) {       printf("Processing request from %s...\n", from);    }    n = readforsure(fd, (char *) &req, sizeof(req));    if (n != sizeof(req)) {         perror("serviceRequest -- read");        if (verbose) printf("  Request from %s exiting\n", from);        exit(1);    }    if (req.magic != RMTACCESS_MAGIC) {        fprintf(stderr, "  Bad magic number in req\n");        if (verbose) printf("  Request from %s exiting\n", from);        exit(1);    }    if ((unsigned)req.arglen > sizeof(argbuf)-1) {        fprintf(stderr, "  Arg buffer too large %d\n", req.arglen);        req.arglen = sizeof(argbuf);    }    if (req.arglen > 0) {         n = readforsure(fd, argbuf, req.arglen);        if (n != req.arglen) {            fprintf(stderr, "  Can't read arg buffer\n");            if (verbose) printf("  Request from %s exiting\n", from);            exit(1);        }    }      switch (req.cmd) {    case SIMRMT_ACCESS: {      argbuf[req.arglen] = 0;  /* Null terminate */           if (argbuf[0] == '/' || (argbuf[0] =='.' && argbuf[1] =='.')) {         fprintf(stderr, "  Security error. Can't open %s\n", argbuf);        if (verbose) printf("  Request from %s exiting\n", from);        ERRCmd(fd, errno);        exit(1);      }      if (verbose) printf("  access(%s, R_OK) = %d\n", argbuf, access(argbuf, R_OK));      if (access(argbuf, R_OK) == 0)        ACKCmd(fd);      else        ERRCmd(fd, errno);      if (verbose) printf("  Request from %s exiting\n", from);      exit(1);    }    case SIMRMT_OPEN: {        int file_fd;        argbuf[req.arglen] = 0;  /* Null terminate */        if (argbuf[0] == '/' || (argbuf[0] =='.' && argbuf[1] =='.')) { 

⌨️ 快捷键说明

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