/A6/protocol.c

https://bitbucket.org/JuantAldea/lut-2012-network-programming · C · 263 lines · 215 code · 29 blank · 19 comment · 23 complexity · 3fe9a720070ea600832c93dbda91386e MD5 · raw file

  1. /*
  2. ###############################################
  3. # CT30A5001 - Network Programming #
  4. # Assignment 6: FTP Client #
  5. # Juan Antonio Aldea Armenteros (0404450) #
  6. # juan.aldea.armenteros@lut.fi #
  7. # protocol.c #
  8. ###############################################
  9. */
  10. #include "protocol.h"
  11. //wrap and send the msg by the socket
  12. int send_msg(int socket, uchar *msg, int msg_size)
  13. {
  14. //allocate the needed buffer
  15. msg_size--;//remove the \0;
  16. uint32_t wrapped_size = msg_size + 2; // + \r\n
  17. uchar * wrapped_msg = (uchar *) malloc(sizeof(uchar) * wrapped_size);
  18. memcpy(wrapped_msg, msg, sizeof(uchar) * msg_size);
  19. wrapped_msg[msg_size ] = '\r';
  20. wrapped_msg[msg_size + 1] = '\n';
  21. //dump_msg(wrapped_msg, wrapped_size);
  22. //send the whole msg
  23. int bytes_to_send = sizeof(uchar) * wrapped_size;
  24. int total_sent_bytes = 0;
  25. while (total_sent_bytes < bytes_to_send){
  26. total_sent_bytes += send(socket, &(wrapped_msg[total_sent_bytes]), bytes_to_send - total_sent_bytes, 0);
  27. }
  28. free(wrapped_msg);
  29. return total_sent_bytes;
  30. }
  31. // returns in full_message by reference if the whole message has been received
  32. int recv_msg(int socket, char *buffer)
  33. {
  34. int recv_bytes;
  35. while ((recv_bytes = recv(socket, buffer, MAX_MSG_SIZE, MSG_PEEK)) > 0){
  36. if (strchr(buffer, '\r') != NULL && strchr(buffer, '\n') != NULL){
  37. int size = strchr(buffer, '\n') - buffer + 1;
  38. int a = recv(socket, buffer, size, 0);
  39. buffer[a] = 0;
  40. return a;
  41. }
  42. }
  43. return recv_bytes;
  44. }
  45. int send_username(int socket, char *username)
  46. {
  47. int message_length = strlen(username) + 4 + 1 + 1; //USER username\0
  48. char *buffer = (char*) malloc(sizeof(char) * message_length);
  49. memset(buffer, '\0', message_length);
  50. sprintf(buffer, "USER %s", username);
  51. int bytes_sent = send_msg(socket, (uchar *)buffer, message_length);
  52. free(buffer);
  53. return bytes_sent;
  54. }
  55. int send_password(int socket, char *password)
  56. {
  57. int message_length = strlen(password) + 4 + 1 + 1; //PASS password\0
  58. char *buffer = (char*) malloc(sizeof(char) * message_length);
  59. memset(buffer, '\0', message_length);
  60. sprintf(buffer, "PASS %s", password);
  61. int bytes_sent = send_msg(socket, (uchar *)buffer, message_length);
  62. free(buffer);
  63. return bytes_sent;
  64. }
  65. int send_quit(int socket)
  66. {
  67. char msg[] = "QUIT";
  68. return send_msg(socket, (uchar *)msg, strlen(msg) + 1);
  69. }
  70. int enter_passive_mode(int socket)
  71. {
  72. char msg[] = "PASV";
  73. return send_msg(socket, (uchar *)msg, strlen(msg) + 1);
  74. }
  75. int enter_active_mode(int socket, int ip[4], int port[2])
  76. {
  77. char msg[100];
  78. sprintf(msg, "PORT %d,%d,%d,%d,%d,%d", ip[0], ip[1], ip[2], ip[3], port[0], port[1]);
  79. return send_msg(socket, (uchar *)msg, strlen(msg) + 1);
  80. }
  81. int send_list(int socket)
  82. {
  83. char msg[] = "LIST";
  84. return send_msg(socket, (uchar *)msg, strlen(msg) + 1);
  85. }
  86. int send_cwd(int socket)
  87. {
  88. char msg[] = "PWD";
  89. return send_msg(socket, (uchar *)msg, strlen(msg) + 1);
  90. }
  91. int send_binary(int socket)
  92. {
  93. char msg[] = "TYPE I";
  94. return send_msg(socket, (uchar *)msg, strlen(msg) + 1);
  95. }
  96. int send_put(int socket, char *path)
  97. {
  98. char msg[] = "STOR\0";
  99. char *buffer = malloc(sizeof(char) * (strlen(msg) + 1 + strlen(path) + 1));
  100. sprintf(buffer, "%s %s", msg, path);
  101. int sent_bytes = send_msg(socket, (uchar *)buffer, strlen(buffer) + 1);
  102. free(buffer);
  103. return sent_bytes;
  104. }
  105. int send_get(int socket, char *path)
  106. {
  107. char msg[] = "RETR\0";
  108. char *buffer = malloc(sizeof(char) * (strlen(msg) + 1 + strlen(path) + 1));
  109. sprintf(buffer, "%s %s", msg, path);
  110. int sent_bytes = send_msg(socket, (uchar *)buffer, strlen(buffer) + 1);
  111. free(buffer);
  112. return sent_bytes;
  113. }
  114. int send_cd(int socket, char *path)
  115. {
  116. char msg[] = "CWD\0";
  117. char *buffer = malloc(sizeof(char) * (strlen(msg) + 1 + strlen(path) + 1));
  118. sprintf(buffer, "%s %s", msg, path);
  119. int sent_bytes = send_msg(socket, (uchar *)buffer, strlen(buffer) + 1);
  120. free(buffer);
  121. return sent_bytes;
  122. }
  123. void dump_msg(uchar *msg, int length)
  124. {
  125. printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
  126. for (int i = 0; i < length; i++){
  127. if(msg[i] == '\r'){
  128. printf("\\r");
  129. }else if(msg[i] == '\n'){
  130. printf("\\n\n");
  131. }else if(msg[i] == '\0'){
  132. printf("\\0");
  133. }else{
  134. printf("%c", msg[i]);
  135. }
  136. }
  137. printf("\n");
  138. printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
  139. printf("\n");
  140. }
  141. int send_file(int socket, char *path)
  142. {
  143. uchar buffer[MAX_MSG_SIZE];
  144. FILE *source = fopen(path, "rb");
  145. if (source == NULL){
  146. printf("ERROR opening the file %s\n", strerror(errno));
  147. return -1;
  148. }
  149. struct timeval before, after;
  150. gettimeofday(&before, NULL);
  151. int readed_bytes = 0;
  152. int total_sent_bytes = 0;
  153. while((readed_bytes = fread(buffer, sizeof(char), MAX_MSG_SIZE, source)) > 0){
  154. int sent_bytes = 0;
  155. while (sent_bytes < readed_bytes){
  156. sent_bytes += send(socket, &(buffer[sent_bytes]), readed_bytes - sent_bytes, 0);
  157. total_sent_bytes += sent_bytes;
  158. }
  159. }
  160. gettimeofday(&after, NULL);
  161. if(total_sent_bytes){
  162. printf("Total bytes sent: %d, transfer rate: %f Kilobytes/second\n", total_sent_bytes,
  163. transfer_rate(total_sent_bytes, &after, &before));
  164. }
  165. fclose(source);
  166. return total_sent_bytes;
  167. }
  168. int recv_file(int socket, char *path)
  169. {
  170. uchar buffer[MAX_MSG_SIZE];
  171. int destination = open(path, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR);
  172. //FILE *destination = fopen(path, "wb");
  173. if (destination < 0){
  174. //if (destination == NULL){
  175. printf("ERROR opening the file %s\n", strerror(errno));
  176. return 0;
  177. }
  178. struct timeval before, after;
  179. gettimeofday(&before, NULL);
  180. int total_bytes_received = 0;
  181. int received_bytes = 0;
  182. while((received_bytes = recv(socket, buffer, MAX_MSG_SIZE, 0)) > 0){
  183. total_bytes_received += received_bytes;
  184. if (write(destination, buffer, received_bytes) <= 0){
  185. //if (fwrite(buffer, sizeof(char), received_bytes, destination) <= 0){
  186. printf("ERROR writing the file %s\n", strerror(errno));
  187. return -1;
  188. }
  189. }
  190. gettimeofday(&after, NULL);
  191. if(total_bytes_received){
  192. printf("Total bytes received: %d transfer rate: %f Kilobytes/second\n", total_bytes_received,
  193. transfer_rate(total_bytes_received, &after, &before));
  194. }
  195. close(destination);
  196. //fclose(destination);
  197. return total_bytes_received;
  198. }
  199. int recv_ls(int socket)
  200. {
  201. char buffer[MAX_MSG_SIZE];
  202. memset(buffer, 0, MAX_MSG_SIZE);
  203. int recv_bytes = recv_msg(socket, buffer);
  204. if (recv_bytes > 0){
  205. printf("%s", buffer);
  206. }
  207. return recv_bytes;
  208. }
  209. /* extras*/
  210. int send_help(int socket)
  211. {
  212. char msg[] = "HELP";
  213. return send_msg(socket, (uchar *)msg, strlen(msg) + 1);
  214. }
  215. int send_syst(int socket)
  216. {
  217. char msg[] = "SYST";
  218. return send_msg(socket, (uchar *)msg, strlen(msg) + 1);
  219. }
  220. int send_stat(int socket)
  221. {
  222. char msg[] = "STAT";
  223. return send_msg(socket, (uchar *)msg, strlen(msg) + 1);
  224. }
  225. int send_raw(int socket, char *msg)
  226. {
  227. return send_msg(socket, (uchar *)msg, strlen(msg) + 1);
  228. }
  229. float transfer_rate(int size, struct timeval *after, struct timeval *before)
  230. {
  231. long int delta = after->tv_usec + 1000000 * after->tv_sec - (before->tv_usec + 1000000 * before->tv_sec);
  232. double seconds = delta /(double)1000000;
  233. return (size/(double)1024)/seconds;
  234. }