📄 netdrv.c
字号:
/* don't allow null filenames */ if (name[0] == EOS) { errnoSet (S_ioLib_NO_FILENAME); return (ERROR); } /* get directory and filename pointers and lengths */ pFileName = pathLastNamePtr (name); fileNameLen = strlen (pFileName); dirNameLen = pFileName - name; /* Some machines don't like to have a directory name terminated by "/" or * "\", unless is the root directory. This code clips the extra slash. */ if ((dirNameLen > 1) && (name[dirNameLen-1] == '/' || name[dirNameLen-1] == '\\')) dirNameLen--; /* allocate and initialize net file descriptor; * leave room for directory and file name and both EOSs */ if ((ptr = (char *) malloc ((unsigned) (sizeof (NET_FD) + fileNameLen + dirNameLen + 2))) == NULL) return (ERROR); pNetFd = (NET_FD *) ptr; pNetFd->pNetDev = pNetDev; pNetFd->filePtrByte = 0; pNetFd->endOfFile = 0; /* XXX should be determined when O_RDWR! */ pNetFd->options = FD_MODE & ((mode == O_WRONLY) ? O_WRONLY : O_RDWR); pNetFd->options |= FD_DIRTY; /* set dirty */ /* set remote directory name and file name */ pNetFd->remFileName = ptr + sizeof (NET_FD); (void) strcpy (pNetFd->remFileName, pFileName); pNetFd->remDirName = pNetFd->remFileName + fileNameLen + 1; (void) strncpy (pNetFd->remDirName, name, dirNameLen); pNetFd->remDirName [dirNameLen] = EOS; /* attach first empty datablock */ pData = (DATABLOCK *) malloc (sizeof (DATABLOCK)); pData->used = 0; pNetFd->filePtrBlock = pData; lstInit (&pNetFd->dataLst); lstAdd (&pNetFd->dataLst, (NODE *) pData); semMInit (&pNetFd->netFdSem, mutexOptionsNetDrv); return ((int) pNetFd); }/********************************************************************************* netDelete - delete a file from a remote machine via the network.** The remote shell daemon on the machine 'host' is used to delete* the given file. The remote userId should have been set previously* by a call to iam().** RETURNS: OK or ERROR.*/LOCAL STATUS netDelete ( NET_DEV *pNetDev, char *name /* remote file name */ ) { int dataSock; int ctrlSock; char buf [DATASIZE]; /* make buf the same size as NET_FD's databuf */ FAST int nBytes; char command[100]; STATUS status = OK; char usr [MAX_IDENTITY_LEN]; char passwd [MAX_IDENTITY_LEN]; char *pDirName = (char *) malloc ((unsigned) (strlen (name) + 1)); char *pFileName = (char *) malloc ((unsigned) (strlen (name) + 1)); remCurIdGet (usr, passwd); /* get directory name and file name */ pathSplit (name, pDirName, pFileName); if (pNetDev->protocol == PROTO_FTP) { if (ftpXfer (pNetDev->host, usr, passwd, "", "DELE %s", pDirName, pFileName, &ctrlSock, (int *) NULL) == ERROR) { free (pDirName); free (pFileName); return (ERROR); } } else { sprintf (command, "/bin/rm %s", name); dataSock = rcmd (pNetDev->host, RSHD, usr, usr, command, &ctrlSock); if (dataSock == ERROR) { free (pDirName); free (pFileName); return (ERROR); } close (dataSock); /* check control socket for error */ if ((nBytes = fioRead (ctrlSock, buf, sizeof (buf) - 1)) > 0) { /* print error message on standard error fd */ buf [nBytes] = EOS; /* insure string termination */ printErr ("%s:%s", pNetDev->host, buf); /* set the task's status according to the UNIX error */ getNetStatus (buf); status = ERROR; } } if (pNetDev->protocol == PROTO_FTP && ftpCommand (ctrlSock, "QUIT",0,0,0,0,0,0) != FTP_COMPLETE) { status = ERROR; } close (ctrlSock); free (pDirName); free (pFileName); return (status); }/********************************************************************************* netOpen - open a remote file** netOpen loads the remote file from the host into a network file descriptor.* If the file does not exist and the O_CREAT flag is not specifed, or the file* is not readable on the UNIX machine, then the UNIX error message is printed* on the standard error file descriptor and ERROR is returned.** Called only by the I/O system.** RETURNS: Pointer to open network file descriptor, or ERROR.*/LOCAL int netOpen ( FAST NET_DEV *pNetDev, /* pointer to network device */ char *name, /* remote file name to open */ int mode, /* O_RDONLY, O_WRONLY or O_RDWR, and O_CREAT */ int perm /* UNIX permissions, includes directory flag */ ) { STATUS status; FAST NET_FD *pNetFd = (NET_FD *) netCreate (pNetDev, name, mode); if (pNetFd == (NET_FD *) ERROR) return (ERROR); if ((mode & O_TRUNC) || /* Leave file at 0 length. */ ((mode & O_CREAT) && (netFileExists (pNetDev, name) == ERROR))) { return ((int) pNetFd); } semTake (&pNetFd->netFdSem, WAIT_FOREVER); /* netCreate sets a O_RDONLY mode to O_RDWR and sets dirty bit, * set it back to original mode. */ pNetFd->options = mode & FD_MODE; if (netGet (pNetFd) != OK) { /* not able to get file from host */ semGive (&pNetFd->netFdSem); releaseNetFd (pNetFd); return (ERROR); } /* netGet might have moved the file pointer, so reset to beginning */ status = netSeek (pNetFd, 0); semGive (&pNetFd->netFdSem); return (status == ERROR ? ERROR : (int) pNetFd); }/********************************************************************************* netClose - close a remote file. Copy it to the remote machine.** If the file is O_WRONLY or O_RDWR mode and it has been written to (it's* dirty bit is set), then the file is copied over to UNIX.** Called only by the I/O system.** RETURNS: OK or ERROR.*/LOCAL STATUS netClose ( FAST NET_FD *pNetFd ) { STATUS status = OK; semTake (&pNetFd->netFdSem, WAIT_FOREVER); /* if file has dirty bit set, it's been changed. Copy it to UNIX machine */ if (pNetFd->options & FD_DIRTY) status = netPut (pNetFd); semGive (&pNetFd->netFdSem); releaseNetFd (pNetFd); return (status); }/********************************************************************************* netLs - list a remote directory.** RETURNS: OK or ERROR.*/LOCAL STATUS netLs ( FAST NET_FD *pNetFd ) { int dataSock; int ctrlSock; char buf [DATASIZE]; /* make buf the same size as NET_FD's databuf */ FAST int nBytes = -1; char command[100]; char buffer [100]; STATUS status = OK; char usr [MAX_IDENTITY_LEN]; char passwd [MAX_IDENTITY_LEN]; remCurIdGet (usr, passwd); if (pNetFd->pNetDev->protocol == PROTO_FTP) { if (pNetFd->remFileName[0] == '.') { if (ftpXfer (pNetFd->pNetDev->host, usr, passwd, "", "NLST", pNetFd->remDirName, pNetFd->remFileName, &ctrlSock, &dataSock) == ERROR) { return (ERROR); } } else { if (ftpXfer (pNetFd->pNetDev->host, usr, passwd, "", "NLST %s", pNetFd->remDirName, pNetFd->remFileName, &ctrlSock, &dataSock) == ERROR) { return (ERROR); } } } else { if (pathCat (pNetFd->remDirName, pNetFd->remFileName, buffer) == ERROR) return (ERROR); sprintf (command, netLsStr, buffer); dataSock = rcmd (pNetFd->pNetDev->host, RSHD, usr, usr, command, &ctrlSock); if (dataSock == ERROR) return (ERROR); } /* read bytes from socket and write them * to standard out one block at a time */ while ((status == OK) && ((nBytes = read (dataSock, buf, sizeof (buf))) > 0)) { if (write (STD_OUT, buf, nBytes) != nBytes) status = ERROR; } if (nBytes < 0) /* recv error */ status = ERROR; close (dataSock); if (pNetFd->pNetDev->protocol == PROTO_FTP) { if (ftpReplyGet (ctrlSock, TRUE) != FTP_COMPLETE) status = ERROR; } else { /* check control socket for error */ if ((nBytes = fioRead (ctrlSock, buf, sizeof (buf) - 1)) > 0) { /* print error message on standard error fd */ buf [nBytes] = EOS; /* insure string termination */ printErr ("%s:%s", pNetFd->pNetDev->host, buf); /* set the task's status according to the UNIX error */ getNetStatus (buf); status = ERROR; } } if (pNetFd->pNetDev->protocol == PROTO_FTP && ftpCommand (ctrlSock, "QUIT",0,0,0,0,0,0) != FTP_COMPLETE) { status = ERROR; } close (ctrlSock); return (status); }/******************************************************************************** netLsByName - list a remote directory by name** RETURNS: OK if successful, otherwise ERROR. If the device is not a netDrv* device, errno is set to S_netDrv_UNKNOWN_REQUEST.** ERRNO* S_netDrv_UNKNOWN_REQUEST** NOMANUAL*/STATUS netLsByName ( char * dirName /* name of the directory */ ) { DEV_HDR * pDevHdr; /* device header */ char fullFileName [MAX_FILENAME_LENGTH]; NET_FD * pNetFd; STATUS netLsReturn; if (ioFullFileNameGet (dirName, &pDevHdr, fullFileName) == ERROR) return (ERROR); /* make sure the device is a netDrv device */ if (drvTable [pDevHdr->drvNum].de_open != netOpen) { errno = S_netDrv_UNKNOWN_REQUEST; return (ERROR); } /* create a NET_FD to pass to netLs */ pNetFd = (NET_FD *) netCreate ((NET_DEV *) pDevHdr, fullFileName, 0); netLsReturn = netLs (pNetFd); releaseNetFd (pNetFd); return (netLsReturn); }/********************************************************************************* netFileExists - check for the existence of a file.** RETURNS: OK if the file exists, or ERROR.*/LOCAL STATUS netFileExists ( NET_DEV *pNetDev, char *name /* remote file name */ ) { int dataSock; int ctrlSock; char buf [DATASIZE]; /* make buf the same size as NET_FD's databuf */ char command[100]; STATUS status = OK; char usr [MAX_IDENTITY_LEN]; char passwd [MAX_IDENTITY_LEN]; char *lsErrMsg = "not found"; int lsErrMsgLen = strlen (lsErrMsg);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -