#include #include #include #include #include #include #include #include #include #include #include #define MAXDATASIZE 1024 #define DATOTEKA 2147483648 #define MAPA 1073741824 #define KONEC 0 typedef struct Data { uint32_t size; uint32_t type; char name[128]; } Data; int isDir(const char *path) { struct stat path_stat; stat(path, &path_stat); return S_ISDIR(path_stat.st_mode); } void sendFile(int sockfd, const char *fileName) { struct stat st; stat(fileName, &st); Data dataS; dataS.size = st.st_size; dataS.type = DATOTEKA; memset(dataS.name, '\0', sizeof(dataS.name)); strcpy(dataS.name, fileName); if (send(sockfd, &dataS, sizeof(dataS), 0) < 0) { perror("send"); return; } FILE *ptr = fopen(fileName, "rb"); if (ptr == NULL) { perror("File"); return; } uint8_t buffer[MAXDATASIZE]; size_t bytesRead = 0; while (bytesRead < st.st_size) { size_t read = fread(buffer, 1, sizeof(buffer), ptr); if (send(sockfd, buffer, read, 0) < 0) { perror("send"); } bytesRead += read; } fclose(ptr); printf("USPEL\tZBIRKA\t%s\t%d\n", dataS.name, dataS.size); } void sendDir(int sockfd, const char *folderName) { Data dataToSend; dataToSend.size = 0; dataToSend.type = MAPA; strcpy(dataToSend.name, folderName); if (send(sockfd, &dataToSend, sizeof(dataToSend), 0) < 0) { perror("send"); return; } printf("USPEL\tIMENIK\t%s\t%d\n", dataToSend.name, dataToSend.size); } void reciveConferm(int sockfd) { uint8_t ret; if ((recv(sockfd, &ret, sizeof(ret), 0)) == -1) { perror("recv"); } } void sendEnd(int sockfd) { Data dataToSend; dataToSend.size = 0; dataToSend.type = KONEC; strcpy(dataToSend.name, ""); if (send(sockfd, &dataToSend, sizeof(dataToSend), 0) < 0) { perror("send"); return; } } void sendFullFile(int sockfd, char *input) { //nik/nik/nik.txt char *ptr = strtok(input, "/"); char fileName[128]; memset(fileName, '\0', sizeof(fileName)); while (ptr != NULL) { strcat(fileName, ptr); if (isDir(fileName)) { sendDir(sockfd, fileName); strcat(fileName, "/"); } else { sendFile(sockfd, fileName); } reciveConferm(sockfd); ptr = strtok(NULL, "/"); } } void sendFullDir(int sockfd, char *input) { char fileName[128]; memset(fileName, '\0', sizeof(fileName)); //nik/test char *ptr = strtok(input, "/"); while (ptr != NULL) { strcat(fileName, ptr); if (isDir(fileName)) { sendDir(sockfd, fileName); strcat(fileName, "/"); } reciveConferm(sockfd); ptr = strtok(NULL, "/"); } struct dirent *files; DIR *dir = opendir(fileName); if (dir == NULL) { printf("Directory cannot be opened!"); return; } //nik/test/nik.txt char srcName[128]; while ((files = readdir(dir)) != NULL) { if(strncmp( "..", files->d_name, 2) > -1) continue; if(strncmp( ".", files->d_name, 1) > -1) continue; strcpy(srcName, fileName); strcat(srcName, files->d_name); if (!isDir(srcName)) { sendFile(sockfd, srcName); reciveConferm(sockfd); } else { sendFullDir(sockfd, srcName); } } closedir(dir); } int main(int argc, char *argv[]) { if (argc != 4) { //write(0, "Uporaba: TCPtimec ime vrata datoteka\n\0", 29); printf("Uporaba: TCPtimec ime vrata datoteka\n"); exit(1); } int sockfd; // socekt file descriptor, new file descriptor struct hostent *he; // pointer to the structure hostent (returned by gethostbyname) struct sockaddr_in their_addr; // server address // get the server IP address if ((he = gethostbyname(argv[1])) == NULL) { herror("gethostbyname"); // prints string + value of h_error variable [HOST_NOT_FOUND || NO_ADDRESS or NO_DATA || NO_RECOVERY || TRY_AGAIN] exit(1); } // create socket if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } their_addr.sin_family = AF_INET; // family to Address Family InterNET their_addr.sin_port = htons(atoi(argv[2])); // get server's port number - should be checked for input errors (not a number, etc.) their_addr.sin_addr = *((struct in_addr *)he->h_addr); // server's IP address from hostent structure pointed to by he variable... memset(&(their_addr.sin_zero), '\0', 8); // for conversion between structures only, a trick to ensure pointer casting... // connect to the server... (no bind necessary as we are connecting to remote host... Kernel will find a free port for us and will bind it to sockfd) if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1) { perror("connect"); exit(1); } //nik if (isDir(argv[3])) { sendFullDir(sockfd, argv[3]); } else { sendFullFile(sockfd, argv[3]); } sendEnd(sockfd); // close socket close(sockfd); return 0; }