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 + -
显示快捷键?