📄 ftpdlib.c
字号:
{ return FALSE ; } else { pPat ++ ; } } /* loop is done, let's see if there is anything left */ if( (*pPat == EOS) || (pPat[0] == anyMany && pPat[1] == EOS)) return TRUE ; else return FALSE ; }#ifdef __unitest__int ftpPatternTest(void) { int i, err = 0 ; const struct { char * pat; char * name; BOOL result; } testData[] = { { "*", "abcd.e_f-j", 1}, { "*", "1", 1}, { "*", "", 1}, { "*abcde.f", "abcde.f", 1}, { "*abcde.f", "0abcde.f", 1}, { "*ab.f", "0abcde.f", 0}, { "*de.f", "0abcde.f", 1}, { "*ab?.c", "zabcde.f", 0}, { "*ab??.c", "zabcde.f", 0}, { "*ab???.c", "zabcde.f", 0}, { "*ab???.?", "zabcde.f", 1}, { "*ab???.?", "aBcde.c", 1}, { "*", "a", 1}, { "*", "a.1", 1}, { "*", "a.b.c.$%(", 1}, { "*.*", "a.b", 1}, { "*.*", "1.2.3.4", 1}, { "*.*", ".a.b", 1}, { "?*", ".x", 1}, { "?*", "x.y.t.r.#@%", 1}, { "?*", "x", 1}, { "?*", ".", 1}, { "?a*", "aa", 1}, { "?a*", "xa", 1}, { "?a*", ".a", 1}, { "?a*", ".ab", 1}, { "?a*", "xaq1.&%#@___", 1}, { "?a*", "_a-b.cde", 1}, { "?A?B?C", "AaBbCc", 1}, { "?A?B?C", "aabbcc", 1}, { "?A?B?C", "AABBCC", 1}, { "?A?B?C", ".a.b.c", 1}, { "?A?B?C", "xa-b_c", 1}, { "?*.dat", "p.dat", 1}, { "?*.dat", "README.Dat", 1}, { "?*.dat", "Copy of some.dat", 1}, { "README?*", "readMe.", 1}, { "README?*", "Readme1", 1}, { "README?*", "readmeFile", 1}, { "README?*", "ReAdMe, please", 1}, { "??? ???", "fll .,&", 1}, { "??? ???", "asd ___", 1}, { "??? ???", "123 321", 1}, { "*.*", "a", 0}, { "*.*", "1-2-3-4", 0}, { "?*.*", ".a", 0}, { "?a*", "a", 0}, { "?a*", "ax", 0}, { "?A?B?C", "aBbCc", 0}, { "?A?B?C", "aabcc", 0}, { "?A?B?C", "AABBC", 0}, { "?A?B?C", "a.b.c", 0}, { "?A?B?C", "aab.c", 0}, { "?*.dat", "p.d", 0}, { "?*.dat", ".dat", 0}, { "?*.dat", "README_Dat", 0}, { "?*.dat", "Copy of some dat", 0}, { "README?*", "readMe", 0}, { "README?*", "README", 0}, { "README?*", "1README_DAT", 0}, { "README?*", "_ReAdMe, please", 0}, { "??? ???", "fll_.,&", 0}, { "??? ???", "asd.___", 0}, { "??? ???", "23 321", 0}, { "??? ???", "123 21", 0}, { "", "a", 0} }; for(i=0; i <NELEMENTS(testData); i++ ) { if( ftpDirListPattern( testData[i].pat, testData[i].name ) != testData[i].result ) { printf("Test failed, pattern \"%s\", name \"%s\", expected %d\n", testData[i].pat, testData[i].name, testData[i].result ); err ++ ; } } return (err); }#endif /*__unitest__*//********************************************************************************* ftpdDirListEnt - list one file or directory** INTERNAL* we dont check results of each fdprintf here, just the last one, which* should be enough in case the connection broke.*/LOCAL STATUS ftpdDirListEnt ( int fd, char * fileName, struct stat * fileStat, char * prefix, BOOL doLong ) { time_t now; /* current clock */ struct tm nowDate; /* current date & time */ struct tm fileDate; /* file date/time (long listing) */ const char *monthNames[] = {"???", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; char fType ; if(doLong) { /* Break down file modified time */ time( &now ); localtime_r (&now, &nowDate); localtime_r (&fileStat->st_mtime, &fileDate); if( fileStat->st_attrib & DOS_ATTR_RDONLY ) fileStat->st_mode &= ~(S_IWUSR|S_IWGRP|S_IWOTH); if( S_ISDIR (fileStat->st_mode) ) fType = 'd' ; else if( S_ISREG (fileStat->st_mode) ) fType = '-' ; else fType = '?' ; /* print file mode */ fdprintf(fd, "%c%c%c%c%c%c%c%c%c%c", fType, (fileStat->st_mode & S_IRUSR)? 'r':'-', (fileStat->st_mode & S_IWUSR)? 'w':'-', (fileStat->st_mode & S_IXUSR)? 'x':'-', '-', '-', '-', /* XXX- figure out what to do with last flags */ (fileStat->st_attrib & DOS_ATTR_ARCHIVE)? 'A':'-', (fileStat->st_attrib & DOS_ATTR_SYSTEM)? 'S':'-', (fileStat->st_attrib & DOS_ATTR_HIDDEN)? 'H':'-' ); /* fake links, user and group fields */ fdprintf(fd, " %2d %-7s %-7s ", fileStat->st_nlink, "user", "group" ); /* print file size - XXX: add 64 bit file size support */ fdprintf(fd, " %9lu ", fileStat->st_size ); /* print date */ if( fileDate.tm_year == nowDate.tm_year ) { fdprintf(fd, "%s %2d %02d:%02d ", monthNames [fileDate.tm_mon + 1],/* month */ fileDate.tm_mday, /* day of month */ fileDate.tm_hour, /* hour */ fileDate.tm_min /* minute */ ); } else { fdprintf(fd, "%s %2d %04d ", monthNames [fileDate.tm_mon + 1],/* month */ fileDate.tm_mday, /* day of month */ fileDate.tm_year+1900 /* year */ ); } } /* if doLong */ else { /* short listing */ if( prefix != NULL) fdprintf(fd, prefix); } /* last, print file name */ if( fdprintf(fd, "%s\n", fileName ) == ERROR ) return ERROR; return OK ; }/******************************************************************************** INTERNAL* Borrowed from ls() in usrLib.c.** RETURNS: OK or ERROR.** SEE ALSO: ls(), stat()*/LOCAL STATUS ftpdDirListGet ( int sd, char *dirName, BOOL doLong ) { FAST STATUS status; FAST DIR *pDir; FAST struct dirent *pDirEnt; struct stat fileStat; BOOL firstFile; char *pPattern; char fileName [MAX_FILENAME_LENGTH]; if (dirName == NULL) dirName = "."; pDir = NULL ; pPattern = NULL ; /* Open dir */ pDir = opendir (dirName) ; if( pDir == NULL && (pPattern = rindex(dirName, '/')) != NULL ) { *pPattern++ = EOS ; pDir = opendir (dirName) ; } if( pDir == NULL ) goto _nodir ; /* List files */ ftpdDebugMsg ("listing dir %s pattern %s\n", (int)dirName,(int) pPattern, 0,0); status = OK; firstFile = TRUE; do { errno = OK; pDirEnt = readdir (pDir); if (pDirEnt != NULL) { if (pPattern != NULL && ftpDirListPattern( pPattern, pDirEnt->d_name) == FALSE ) continue ; if (doLong) /* if doing long listing */ { strncpy( fileName, dirName, MAX_FILENAME_LENGTH ); if( fileName [ strlen(fileName) -1 ] != '/'); strcat(fileName, "/"); strncat( fileName, pDirEnt->d_name, MAX_FILENAME_LENGTH - strlen(dirName) ); if (stat (fileName, &fileStat) != OK) { bzero( (caddr_t) &fileStat, sizeof(fileStat)); } } if( ftpdDirListEnt(sd, pDirEnt->d_name, &fileStat, NULL, doLong ) == ERROR ) return ( ERROR | closedir (pDir) ); } else { if (errno != OK) { if (fdprintf (sd, "error reading entry: %x\n", errno) == ERROR) return ( ERROR | closedir (pDir)); status = ERROR; } } } while (pDirEnt != NULL); /* until end of dir */ /* fdprintf (sd, "\n"); XXX*/ /* Close dir */ status |= closedir (pDir); return (status);_nodir: fdprintf (sd, "Can't open \"%s\".\n", dirName); return (ERROR); }/********************************************************************************* unImplementedType - send FTP invalid representation type error reply*/LOCAL void unImplementedType ( FTPD_SESSION_DATA *pSlot ) { ftpdCmdSend (pSlot, pSlot->cmdSock, 550, messages [MSG_TYPE_ERROR], FTPD_REPRESENTATION (pSlot), 0, 0, 0, 0, 0); ftpdSockFree (&pSlot->dataSock); }/********************************************************************************* dataError - send FTP data connection error reply** Send the final error message about connection error and delete the session.*/LOCAL void dataError ( FTPD_SESSION_DATA *pSlot ) { ftpdCmdSend (pSlot, pSlot->cmdSock, 426, messages [MSG_DATA_CONN_ERROR], 0, 0, 0, 0, 0, 0); ftpdSockFree (&pSlot->dataSock); }/********************************************************************************* fileError - send FTP file I/O error reply** Send the final error message about file error and delete the session.*/LOCAL void fileError ( FTPD_SESSION_DATA *pSlot ) { ftpdCmdSend (pSlot, pSlot->cmdSock, 551, messages [MSG_INPUT_FILE_ERROR], 0, 0, 0, 0, 0, 0); ftpdSockFree (&pSlot->dataSock); }/********************************************************************************* transferOkay - send FTP file transfer completion reply*/LOCAL void transferOkay ( FTPD_SESSION_DATA *pSlot ) { ftpdSockFree (&pSlot->dataSock); ftpdCmdSend (pSlot, pSlot->cmdSock, 226, messages [MSG_TRANS_COMPLETE], 0, 0, 0, 0, 0, 0); }/********************************************************************************* ftpdCmdSend - send a FTP command reply** In response to a request, we send a reply containing completion* status, error status, and other information over a command connection.*/LOCAL STATUS ftpdCmdSend ( FTPD_SESSION_DATA *pSlot, /* pointer to the session slot */ int controlSock, /* control socket for reply */ int code, /* FTP status code */ const char *format, /* printf style format string */ int arg1, int arg2, int arg3, int arg4, int arg5, int arg6 ) { int buflen; char buf [BUFSIZE]; /* local buffer */ FAST char *pBuf = &buf [0]; /* pointer to buffer */ BOOL lineContinue = (code & FTPD_MULTI_LINE) == FTPD_MULTI_LINE; /* * If this routine is called before a session is established, the * pointer to session-specific data is NULL. Otherwise, exit with * an error if an earlier attempt to send a control message failed. */ if ( (pSlot != NULL) && (pSlot->cmdSockError == ERROR)) return (ERROR); code &= ~FTPD_MULTI_LINE; /* strip multi-line bit from reply code */ /* embed the code first */ (void) sprintf (pBuf, "%d%c", code, lineContinue ? '-' : ' '); pBuf += strlen (pBuf); (void) sprintf (pBuf, format, arg1, arg2, arg3, arg4, arg5, arg6); pBuf += strlen (pBuf); /* telnet style command terminator */ (void) sprintf (pBuf, "\r\n"); /* send it over to our client */ buflen = strlen (buf); if ( write (controlSock, buf, buflen) != buflen ) { if (pSlot != NULL) pSlot->cmdSockError = ERROR; ftpdDebugMsg ("sent %s Failed on write\n", (int)buf,0,0,0); return (ERROR); /* Write Error */ } ftpdDebugMsg ("sent %s\n", (int)buf,0,0,0); return (OK); /* Command Sent Successfully */ }/********************************************************************************* ftpdDebugMsg - print out FTP command request and replies for debugging.*/LOCAL void ftpdDebugMsg ( char *format, int arg1, int arg2, int arg3, int arg4 ) { if (ftpdDebug == TRUE) logMsg (format, arg1, arg2, arg3, arg4, 0, 0); }STATUS ftpLoginUserVerify(char *name, char *passwd ) { if ( (strcmp(name, "hualong") == 0) && (strcmp(passwd, "hualong") == 0) ) { return (OK); } else { return (ERROR); } }/******************************************************************************** RETURNS: N/A** SEE ALSO: loginLib*/void ftpdLoginInstall ( FUNCPTR pLoginFunc ) { pLoginVrfyFunc = pLoginFunc; }/******************************************************************************** RETURNS: OK, or ERROR*/STATUS ftpdAnonymousAllow ( const char * rootDir, /* path for guest root directory */ const char * uploadDir /* path for guest uploads */ ) { if( rootDir == NULL ) return ERROR; strncpy( guestHomeDir, rootDir, MAX_FILENAME_LENGTH ); if( uploadDir != NULL ) { strcpy( writeDirName, guestHomeDir ); strcat( writeDirName, "/" ); strncat( writeDirName, uploadDir, MAX_FILENAME_LENGTH ); pathCondense( writeDirName ); } else { writeDirName[0] = EOS ; /* clear */ } return OK ; }/********************************************************************************* RETURNS: OK*/STATUS ftpdHomeDirSet( const char * homeDir ) { if( homeDir == NULL ) return ERROR; strncpy( defaultHomeDir, homeDir, MAX_FILENAME_LENGTH ); return( OK); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -