FtpMethod.cc

Go to the documentation of this file.
00001 //
00002 // Copyright 2002,2003 Sony Corporation 
00003 //
00004 // Permission to use, copy, modify, and redistribute this software for
00005 // non-commercial use is hereby granted.
00006 //
00007 // This software is provided "as is" without warranty of any kind,
00008 // either expressed or implied, including but not limited to the
00009 // implied warranties of fitness for a particular purpose.
00010 //
00011 
00012 #include <sys/stat.h>
00013 #include <sys/unistd.h>
00014 #include <OPENR/OSyslog.h>
00015 #include <OPENR/ODebug.h>
00016 #include <OPENR/OCalendarTime.h>
00017 #include <stdlib.h>
00018 #include "FtpDTP.h"
00019 #include <stdio.h>
00020 
00021 Port 
00022 FtpDTP::SetIP(IPAddress ip)
00023 {
00024     connectIP = ip;
00025     connectPort = FTP_PASV_DATA_PORT + (int)continuation;
00026     passive = true;
00027     Listen();
00028     return connectPort;
00029 }
00030 
00031 bool
00032 FtpDTP::SetPort(char* ipport)
00033 {
00034     longword buf;
00035     uint32 ip = 0;
00036     uint16 port = 0;
00037 
00038     buf = atoi(ipport);
00039     ip |= (buf << 24);
00040     while (*ipport++ != ',') {
00041         ;
00042     }
00043     buf = atoi(ipport);
00044     ip |= (buf << 16);
00045     while (*ipport++ != ',') {
00046         ;
00047     }
00048     buf = atoi(ipport);
00049     ip |= (buf << 8);
00050     while (*ipport++ != ',') {
00051         ;
00052     }
00053     buf = atoi(ipport);
00054     ip |= buf;
00055     while (*ipport++ != ',') {
00056         ;
00057     }
00058 
00059     buf = atoi(ipport);
00060     port |= (buf << 8);
00061     while (*ipport++ != ',') {
00062         ;
00063     }
00064     buf = atoi(ipport);
00065     port |= buf;
00066 
00067     OSYSDEBUG(("FtpDTP::Port():Set IP:%x Port:%d\n", ip, port));
00068     connectIP   = (IPAddress)ip;
00069     connectPort = (Port)port;
00070     passive = false;
00071     return true;
00072 }
00073 
00074 bool
00075 FtpDTP::Store(char* filename)
00076 {
00077     char file[MAX_STRING_LENGTH * 2];
00078     method = FTP_METHOD_STOR;
00079 
00080     if (filename[0] == '/') {
00081         sprintf(file, "%s", filename);
00082     } else {
00083         sprintf(file, "%s%s", ftpDir, filename);
00084     }
00085 
00086     DirNorm(file);
00087 
00088     if (!strncmp(file, ftpHome, strlen(ftpHome))) {
00089         if((fp = fopen(file, "wb")) == NULL) {
00090             OSYSLOG1((osyslogERROR, "Ftpd::File Open Failed %s.", file));
00091             return false;
00092         }
00093     } else {
00094         return false;
00095     }
00096 
00097     strncpy(ftpFile, filename, MAX_STRING_LENGTH);
00098 
00099     if (passive) {
00100         if (connection.state == CONNECTION_CONNECTED) {
00101             connection.recvSize = 0;
00102             Receive();
00103         }
00104     } else {
00105         Connect();
00106     }
00107     return true;
00108 }
00109 
00110 bool
00111 FtpDTP::Retrieve(char* filename)
00112 {
00113     char file[MAX_STRING_LENGTH * 2];
00114     method = FTP_METHOD_RETR;
00115 
00116     if (filename[0] == '/') {
00117         sprintf(file, "%s", filename);
00118     } else {
00119         sprintf(file, "%s%s", ftpDir, filename);
00120     }
00121 
00122     DirNorm(file);
00123 
00124     if (!strncmp(file, ftpHome, strlen(ftpHome))) {
00125         if((fp = fopen(file, "rb")) == NULL) {
00126             OSYSLOG1((osyslogERROR, "FtpDTP::File Open Failed %s.", file));
00127             return false;
00128         }
00129     } else {
00130         return false;
00131     }
00132 
00133     strncpy(ftpFile, filename, MAX_STRING_LENGTH);
00134 
00135     if (passive) {
00136         if (connection.state == CONNECTION_CONNECTED) {
00137             RetrieveSend();
00138         }
00139     } else {
00140         Connect();
00141     }
00142     return true;
00143 }
00144 
00145 bool
00146 FtpDTP::RetrieveSend()
00147 {
00148     if (dataType == FTP_DATA_A) {
00149        connection.recvSize
00150            = fread(connection.recvData, 1, FTP_BUFFER_SIZE / 2, fp);
00151        if (FTP_BUFFER_SIZE / 2 > connection.recvSize) {
00152             byte *cur_r = connection.recvData;
00153             byte *cur_s = connection.sendData;
00154             connection.sendSize = connection.recvSize;
00155             for (int i = 0; i < connection.recvSize; i++, cur_r++) {
00156                 if (*cur_r == LF) {
00157                     if ((cur_r != connection.recvData)
00158                         && (*(cur_r - 1) != CR)) {
00159                         *cur_s++ = CR;
00160                         connection.sendSize++;
00161                     }
00162                     *cur_s++ = *cur_r;
00163                 } else {
00164                     *cur_s++ = *cur_r;
00165                 }
00166             }
00167             fclose(fp);
00168             method = FTP_METHOD_NOOP;
00169             Send();
00170         } else {
00171             byte *cur_r = connection.recvData;
00172             byte *cur_s = connection.sendData;
00173             connection.sendSize = connection.recvSize;
00174             for (int i = 0; i < connection.recvSize; i++, cur_r++) {
00175                 if (*cur_r == LF) {
00176                     if ((cur_r != connection.recvData)
00177                         && (*(cur_r - 1) != CR)) {
00178                         *cur_s++ = CR;
00179                         connection.sendSize++;
00180                     }
00181                     *cur_s++ = *cur_r;
00182                 } else {
00183                     *cur_s++ = *cur_r;
00184                 }
00185             }
00186             Send();
00187         }
00188     } else {
00189         connection.sendSize
00190             = fread(connection.sendData, 1, FTP_BUFFER_SIZE, fp);
00191         if (FTP_BUFFER_SIZE > connection.sendSize) {
00192             fclose(fp);
00193             method = FTP_METHOD_NOOP;
00194             Send();
00195         } else {
00196             Send();
00197         }
00198     }
00199     return true;
00200 }
00201 
00202 bool
00203 FtpDTP::RenameFrom(char *file)
00204 {
00205     char tmp[MAX_STRING_LENGTH * 2];
00206 
00207     if (file[0] == '/') {
00208         sprintf(tmp, "%s", file);
00209     } else {
00210         sprintf(tmp, "%s%s", ftpDir, file);
00211     }
00212 
00213     DirNorm(tmp);
00214 
00215     if (!strncmp(tmp, ftpHome, strlen(ftpHome))) {
00216         FILE *fp = fopen(tmp, "r");
00217         if (fp != NULL) {
00218             strncpy(ftpFile, tmp, MAX_STRING_LENGTH);
00219             fclose(fp);
00220             return true;
00221         }
00222     }
00223 
00224     return false;
00225 }
00226 
00227 bool
00228 FtpDTP::RenameTo(char *file)
00229 {
00230     char tmp[MAX_STRING_LENGTH * 2];
00231 
00232     if (file[0] == '/') {
00233         sprintf(tmp, "%s", file);
00234     } else {
00235         sprintf(tmp, "%s%s", ftpDir, file);
00236     }
00237 
00238     DirNorm(tmp);
00239 
00240     if (!strncmp(tmp, ftpHome, strlen(ftpHome))) {
00241         int ret = rename(ftpFile, tmp);
00242         if (ret == 0) {
00243             strcpy(ftpFile, "");
00244             return true;
00245         }
00246     }
00247 
00248     strcpy(ftpFile, "");
00249     return false;
00250 }
00251 
00252 bool
00253 FtpDTP::List(char* dir)
00254 {
00255     char tmp[MAX_STRING_LENGTH * 2];
00256     total = true;
00257 
00258     if ((dir[0] != '\0') && (dir[0] == '/')) {
00259         sprintf(tmp, "%s/", dir);
00260         listLong = false;
00261     } else if ((dir[0] != '\0') && (dir[0] == '-')) {
00262         sprintf(tmp, "%s", ftpDir);
00263         listLong = true;
00264     } else {
00265         sprintf(tmp, "%s%s", ftpDir, dir);
00266         listLong = false;
00267     }
00268 
00269     listLong = true;
00270 
00271     DirNorm(tmp);
00272 
00273     if (!strncmp(tmp, ftpHome, strlen(ftpHome))) {
00274         if (dirp = opendir(tmp)) {
00275             method = FTP_METHOD_LIST;
00276             strcpy(ftpFile, tmp);
00277             if (passive) {
00278                 if (connection.state == CONNECTION_CONNECTED) {
00279                     if (!ListSend()) {
00280                         Close();
00281                     }
00282                 }
00283             } else {
00284                 Connect();
00285             }
00286             return true;
00287         }
00288     }
00289     return false;
00290 }
00291 
00292 bool
00293 FtpDTP::ListSend()
00294 {
00295     dirent *entry;
00296     char tmp[MAX_STRING_LENGTH];
00297 
00298     if (total) {
00299         sprintf((char *)connection.sendData,
00300                 "total %d\r\n", 0);
00301         connection.sendSize = strlen((char *)connection.sendData);
00302         Send();
00303         total = false;
00304         return true;
00305     }
00306 
00307     entry = readdir(dirp);
00308     if (entry) {
00309         struct stat statbuf;
00310         sprintf(tmp, "%s/%s", ftpFile, entry->d_name);
00311         DirNorm(tmp);
00312         
00313         int ret = stat(tmp, &statbuf);
00314         if (listLong) {
00315             sprintf((char *)connection.sendData,
00316                     "%c%c%c%c%c%c%c%c%c%c %x %s %s %-d %s %d %d %s\r\n",
00317                     (statbuf.st_mode & S_IFMT) == S_IFDIR ? 'd' : '-',
00318                     (statbuf.st_mode & S_IRUSR) ? 'r' : '-',
00319                     (statbuf.st_mode & S_IWUSR) ? 'w' : '-',
00320                     (statbuf.st_mode & S_IFMT) == S_IFDIR ? 'x' : '-',
00321                     (statbuf.st_mode & S_IRUSR) ? 'r' : '-',
00322                     (statbuf.st_mode & S_IWUSR) ? 'w' : '-',
00323                     (statbuf.st_mode & S_IFMT) == S_IFDIR ? 'x' : '-',
00324                     (statbuf.st_mode & S_IRUSR) ? 'r' : '-',
00325                     (statbuf.st_mode & S_IWUSR) ? 'w' : '-',
00326                     (statbuf.st_mode & S_IFMT) == S_IFDIR ? 'x' : '-',
00327                     0,
00328                     "AIBO",
00329                     "AIBO",
00330                     statbuf.st_size,
00331                     "May",
00332                     11,
00333                     1999,
00334                     entry->d_name
00335                 );
00336         } else {
00337             if ((statbuf.st_mode & S_IFMT) == S_IFDIR) {
00338                 sprintf((char *)connection.sendData,
00339                         "%s/\r\n",
00340                         entry->d_name);
00341             } else {
00342                 sprintf((char *)connection.sendData,
00343                         "%s\r\n",
00344                         entry->d_name);
00345             }
00346         }
00347         connection.sendSize = strlen((char *)connection.sendData);
00348         Send();
00349     } else {
00350         method = FTP_METHOD_NOOP;
00351         closedir(dirp);
00352         return false;
00353     }
00354 
00355     return true;
00356 }
00357 
00358 bool
00359 FtpDTP::ChangeDir(char* dir)
00360 {
00361     char tmp[MAX_STRING_LENGTH * 2];
00362 
00363     if (dir[0] == '/') {
00364         sprintf(tmp, "%s/", dir);
00365     } else {
00366         sprintf(tmp, "%s%s/", ftpDir, dir);
00367     }
00368 
00369     DirNorm(tmp);
00370 
00371     if (!strncmp(tmp, ftpHome, strlen(ftpHome))) {
00372         DIR* tmpdirp;
00373         if (tmpdirp = opendir(tmp)) {
00374             closedir(tmpdirp);
00375             strcpy(ftpDir, tmp);
00376             return true;
00377         }
00378     }
00379 
00380     return false;
00381 }
00382 
00383 bool
00384 FtpDTP::MakeDir(char* dir)
00385 {
00386     char tmp[MAX_STRING_LENGTH * 2];
00387 
00388     if (dir[0] == '/') {
00389         sprintf(tmp, "%s", dir);
00390     } else {
00391         sprintf(tmp, "%s%s", ftpDir, dir);
00392     }
00393 
00394     DirNorm(tmp);
00395 
00396     if (!strncmp(tmp, ftpHome, strlen(ftpHome))) {
00397         if (!mkdir(tmp, 0777)) {
00398             return true;
00399         }
00400     }
00401 
00402     return false;
00403 }
00404 
00405 bool
00406 FtpDTP::RemoveDir(char* dir)
00407 {
00408     char tmp[MAX_STRING_LENGTH * 2];
00409 
00410     if (dir[0] == '/') {
00411         sprintf(tmp, "%s", dir);
00412     } else {
00413         sprintf(tmp, "%s%s", ftpDir, dir);
00414     }
00415 
00416     DirNorm(tmp);
00417 
00418     if (!strncmp(tmp, ftpHome, strlen(ftpHome))) {
00419         if (!rmdir(tmp)) {
00420             return true;
00421         }
00422     }
00423 
00424     return false;
00425 }
00426 
00427 bool
00428 FtpDTP::Delete(char* filename)
00429 {
00430     char tmp[MAX_STRING_LENGTH * 2];
00431 
00432     if (filename[0] == '/') {
00433         sprintf(tmp, "%s", filename);
00434     } else {
00435         sprintf(tmp, "%s%s", ftpDir, filename);
00436     }
00437 
00438     DirNorm(tmp);
00439 
00440     if (!strncmp(tmp, ftpHome, strlen(ftpHome))) {
00441         if (!remove(tmp)) {
00442             return true;
00443         }
00444     }
00445 
00446     return false;
00447 }
00448 
00449 void
00450 FtpDTP::Save(byte *data, int length, bool end)
00451 {
00452     OSYSDEBUG(("FtpDTP::Save %d %d\n", length, end));
00453     if (length) fwrite(data, length, 1, fp);
00454     if (end) {
00455         fclose(fp);
00456         strcpy(ftpFile, "");
00457     }
00458 }
00459 
00460 size_t
00461 FtpDTP::GetFileSize(char *name)
00462 {
00463     struct stat statbuf;
00464     int ret = stat(name, &statbuf);
00465     if (ret == 0) {
00466         return statbuf.st_size;
00467     } else {
00468         return 0;
00469     }
00470 }
00471 
00472 void
00473 FtpDTP::ResetFilename()
00474 {
00475     strcpy(ftpFile, "");
00476 }
00477 
00478 void
00479 FtpDTP::SetUser(char *user)
00480 {
00481     strncpy(ftpUser, user, MAX_STRING_LENGTH);
00482 }
00483 
00484 void
00485 FtpDTP::SetHome(char *home)
00486 {
00487     sprintf(ftpHome, "%s/", home);
00488 
00489     DirNorm(ftpHome);
00490     strcpy(ftpDir, ftpHome);
00491 }
00492 
00493 void
00494 FtpDTP::DirNorm(char *dir)
00495 {
00496     char tmp[MAX_STRING_LENGTH * 2];
00497     int length = strlen(dir);
00498     int cur = 0;
00499 
00500     for (int i = 0; i < length + 1; i++) {
00501         OSYSDEBUG(("DirNorm %c\n", dir[i]));
00502         if (dir[i] == '.') {
00503             if ((dir[i + 1] == '.') && (dir[i + 2] == '/')) {
00504                 cur -= 2;
00505                 while(tmp[cur] != '/') {
00506                     cur--;
00507                 }
00508                 cur++;
00509             } else if (dir[i + 1] == '/') {
00510                 i++;
00511             } else {
00512                 tmp[cur++] = toupper(dir[i]);
00513             }
00514         } else if (dir[i] == '/') {
00515             if ((cur == 0) || ((cur != 0) && (tmp[cur - 1] != '/'))) {
00516                 tmp[cur++] = toupper(dir[i]);
00517             }
00518         } else {
00519             tmp[cur++] = toupper(dir[i]);
00520         }
00521     }
00522         
00523     strncpy(dir, tmp, MAX_STRING_LENGTH);
00524     dir[MAX_STRING_LENGTH] = '0';
00525 }

Generated on Sun Dec 2 23:04:28 2007 for openSDK by  doxygen 1.3.9.1