Advertisement
Guest User

FTP by Basshunter

a guest
Nov 1st, 2016
30
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pawn 5.74 KB | None | 0 0
  1. // Very very basic FTP by Basshunter
  2.  
  3. #if defined ftp_included
  4.     #endinput
  5. #endif
  6. #define ftp_included
  7. #pragma library ftp
  8.  
  9. #include <a_samp>
  10. #include <socket>
  11.  
  12. #undef INVALID_SOCKET
  13. #define INVALID_SOCKET Socket:(-1) // warning miatt
  14.  
  15. #define INVALID_FTP_ID -1
  16. #define MAX_FTP 255
  17. #define MAX_FILE_PATH_LEN 255
  18. #define MAX_USER_LEN 32
  19. #define MAX_PASS_LEN 32
  20.  
  21. forward OnFTPConnected(ftpId);
  22. forward OnFTPDisconnected(ftpId);
  23. forward OnFileDownloaded(ftpId, file[], savedAs[]);
  24.  
  25. enum ftpEnum {
  26.     bool:Active,
  27.     bool:Connected,
  28.     Host[32],
  29.     Socket:SocketId,
  30.     Socket:DataSocketId,
  31.     File[MAX_FILE_PATH_LEN],
  32.     SaveAs[MAX_FILE_PATH_LEN]
  33. }
  34.  
  35. new ftpData[MAX_FTP][ftpEnum];
  36.  
  37. stock CreateFTP(host[], port, user[] = "", pass[] = "") {
  38.     new ftpId = 0;
  39.     for (; ftpId < MAX_FTP; ftpId++) if (!ftpData[ftpId][Active]) break;
  40.     if (ftpId == MAX_FTP) return INVALID_FTP_ID;
  41.     ftpData[ftpId][SocketId] = socket_create(TCP);
  42.     if (is_socket_valid(ftpData[ftpId][SocketId])) {
  43.         socket_connect(ftpData[ftpId][SocketId], host, port);
  44.         format(ftpData[ftpId][Host], 32, host);
  45.         new formatstring[256] = "";
  46.         if (strlen(user) > 0) {
  47.             format(formatstring, sizeof(formatstring), "USER %s\r\n", user);
  48.         }
  49.         if (strlen(pass) > 0) {
  50.             format(formatstring, sizeof(formatstring), "%sPASS %s\r\n", formatstring, pass);
  51.         }
  52.         format(formatstring, sizeof(formatstring), "%sPWD\r\nTYPE I\r\nPASV\r\nMLSD\r\n", formatstring);
  53.         socket_send(ftpData[ftpId][SocketId], formatstring, strlen(formatstring));
  54.         ftpData[ftpId][Active] = true;
  55.         ftpData[ftpId][Connected] = false;
  56.         ftpData[ftpId][File][0] = '\0';
  57.         ftpData[ftpId][SaveAs][0] = '\0';
  58.         return ftpId;
  59.     }
  60.     return INVALID_FTP_ID;
  61. }
  62.  
  63. stock DestroyFTP(ftpId) {
  64.     if (!ftpData[ftpId][Active]) return 1;
  65.     if (is_socket_valid(ftpData[ftpId][SocketId])) {
  66.         socket_send(ftpData[ftpId][SocketId], "QUIT\r\n", strlen("QUIT\r\n"));
  67.         socket_destroy(ftpData[ftpId][SocketId]);
  68.     }
  69.     if (is_socket_valid(ftpData[ftpId][DataSocketId])) {
  70.         socket_send(ftpData[ftpId][DataSocketId], "QUIT\r\n", strlen("QUIT\r\n"));
  71.         socket_destroy(ftpData[ftpId][DataSocketId]);
  72.     }
  73.     ftpData[ftpId][Connected] = false;
  74.     ftpData[ftpId][File][0] = '\0';
  75.     ftpData[ftpId][SaveAs][0] = '\0';
  76.     ftpData[ftpId][Active] = false;
  77.     CallRemoteFunction("OnFTPDisconnected", "i", ftpId);
  78.     return 0;
  79. }
  80.  
  81. stock DownloadFTP(ftpId, file[], saveAs[]) {
  82.     if (!ftpData[ftpId][Active]) return 1;
  83.     memcpy(ftpData[ftpId][File], file, 0, MAX_FILE_PATH_LEN * 4, MAX_FILE_PATH_LEN);
  84.     memcpy(ftpData[ftpId][SaveAs], saveAs, 0, MAX_FILE_PATH_LEN * 4, MAX_FILE_PATH_LEN);
  85.     new formatstring[128];
  86.     format(formatstring, sizeof(formatstring), "RETR %s\r\n", file);
  87.     socket_send(ftpData[ftpId][SocketId], formatstring, strlen(formatstring));
  88.     return 0;
  89. }
  90.  
  91. public onSocketAnswer(Socket:id, data[], data_len) {
  92.     // FTP id behatárolása
  93.     new
  94.         bool:dataSocket = false,
  95.         ftpId = 0;
  96.     for (; ftpId < MAX_FTP; ftpId++) {
  97.         if (ftpData[ftpId][SocketId] == id) break;
  98.         if (ftpData[ftpId][DataSocketId] == id) {
  99.             dataSocket = true;
  100.             break;
  101.         }
  102.     }
  103.     if (ftpId == INVALID_FTP_ID) return 1;
  104.     if (!ftpData[ftpId][Connected]) {
  105.         CallRemoteFunction("OnFTPConnected", "i", ftpId);
  106.         ftpData[ftpId][Connected] = true;
  107.     }
  108.     if (dataSocket) {
  109.         if (ftpData[ftpId][File][0] != '\0') {
  110.             new File:downloaded = fopen(ftpData[ftpId][SaveAs], io_write);
  111.             //fwrite(downloaded, data);
  112.             //for (new i = 0; i < data_len; i++) printf("%c", getarg(1,i));
  113.             for (new i = 0; i < data_len; i++) fputchar(downloaded, data[i] & 255, false);
  114.             fclose(downloaded);
  115.             CallRemoteFunction("OnFileDownloaded", "iss", ftpId, ftpData[ftpId][File], ftpData[ftpId][SaveAs]);
  116.             ftpData[ftpId][File][0] = '\0';
  117.             ftpData[ftpId][SaveAs][0] = '\0';
  118.         }
  119.     }
  120.     else {
  121.         new File:temp = ftemp();
  122.         fwrite(temp, data);
  123.         fseek(temp, 0, seek_start); // fájl elejére ugrás
  124.         new line[256];
  125.         // Soronként olvasás...
  126.         while (fread(temp, line, sizeof(line))) {
  127.             //printf("[FTP #%i] %s", ftpId, line);
  128.             switch (GetFTPCode(line)) {
  129.                 // https://en.wikipedia.org/wiki/List_of_FTP_server_return_codes
  130.                 // Alkalmazva a teljesség igénye nélkül... :D
  131.                 case 227: {
  132.                     new port = GetPort(line);
  133.                     if (port != (-1)) {
  134.                         ftpData[ftpId][DataSocketId] = socket_create(TCP);
  135.                         if (is_socket_valid(ftpData[ftpId][DataSocketId])) {
  136.                             socket_connect(ftpData[ftpId][DataSocketId], ftpData[ftpId][Host], port);
  137.                         }
  138.                         printf("[FTP #%i] Szerver altal felkinalt port: %i", ftpId, port);
  139.                     }
  140.                 }
  141.                 // 332 Need account for login.
  142.                 // 430 Invalid username or password
  143.                 // 421 Connection timed out
  144.                 case 332, 430, 421: {
  145.                     DestroyFTP(ftpId);
  146.                 }
  147.                 // 550 File not found
  148.                 case 550: {
  149.                     printf("[FTP #%i] Fájl nem található: %s", ftpId, ftpData[ftpId][File]);
  150.                     ftpData[ftpId][File][0] = '\0';
  151.                     ftpData[ftpId][SaveAs][0] = '\0';
  152.                 }
  153.             }
  154.         }
  155.         fclose(temp);
  156.     }
  157.     return 1;
  158. }
  159.  
  160. // Segédfüggvények...
  161.  
  162. // Megmondja, milyen szám van a sztring elején
  163. stock GetFTPCode(string[]) {
  164.     new code;
  165.     for (new i = 0; '0' <= string[i] <= '9'; i++) {
  166.         code = (code * 10) + string[i] - '0';
  167.     }
  168.     return code;
  169. }
  170.  
  171. // A passzív mód üzenetéből kiolvassa a portot
  172. // www.serv-u.com/respcode.asp?resp=227
  173. stock GetPort(string[]) {
  174.     new p1, p2, delims = 0;
  175.     for (new i = 0; string[i]; i++) {
  176.         if ('0' <= string[i] <= '9') {
  177.             if (delims == 4) p1 = p1 * 10 + string[i] - '0';
  178.             if (delims == 5) p2 = p2 * 10 + string[i] - '0';
  179.         }
  180.         else if (delims >= 5) return (p1 * 256) + p2;
  181.         if (string[i] == ',') delims++;
  182.     }
  183.     return -1;
  184. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement