void MapCollection::loadDirectory(String directory, MapDirectory& mapStructure) { DIR* dir = opendir(directory.c_str()); if (dir != 0) { dirent* dirent = 0; while ((dirent = readdir(dir)) != NULL) { String name = String(dirent->d_name); if (dirent->d_type == DT_DIR && name != "." && name != "..") { MapDirectory newDirectory; loadDirectory(directory + "/" + name, newDirectory); if (validDir(newDirectory)) { mapStructure.childDirectories.push_back(newDirectory); } } else if (dirent->d_type == DT_REG) { String extension = String(strrchr(dirent->d_name, '.')); if (dirent->d_name && extension == ".map" && (MapFormat::validMap(directory + "/" + String(dirent->d_name))))// && WorldGenerator::validJson( { mapStructure.childMaps.push_back(directory + "/" + dirent->d_name); } } } } }
void Server::getFile(string filename, int fd){ char buffer[DATA_SIZE]; FILE *fp; size_t bytesRead=0; string errorMsg; if( fd < 0){ cout << BADF << endl; return; } if(filename[0] == '/'){ filename.replace(0,1, rootDir); } fp = fopen(filename.c_str() , "rb"); if( fp == NULL ){ errorMsg = getError(); errorMsg = filename + ": " + errorMsg; cout << errorMsg << endl; sendMessage(errorMsg.c_str(), errorMsg.length(), ERROR, NF, fd); return; } if(validDir(filename.c_str())){ errorMsg = ISDIR; cout << errorMsg << endl; sendMessage(errorMsg.c_str(), errorMsg.length(), ERROR, NF, fd); fclose(fp); return ; } sendMessage("OK\n", 3, DATA, NF, fd); do { bytesRead = fread( buffer, 1, DATA_SIZE, fp ); if(ferror(fp) != 0){ errorMsg = getError(); cout << errorMsg << endl; sendMessage(errorMsg.c_str(), errorMsg.length(), ERROR, NF, fd); fclose(fp); return; } if(bytesRead < DATA_SIZE) sendMessage(buffer, bytesRead, DATA, NF, fd); else sendMessage(buffer, bytesRead, DATA, MF, fd); }while(bytesRead == DATA_SIZE); fclose(fp); cout << "File Sent" << endl; }
bool MapCollection::validDir(MapCollection::MapDirectory& dir) { if (dir.childMaps.size() > 0) { return true; } if (dir.childDirectories.size() != 0) { for (int i = 0; i < dir.childDirectories.size(); i++) { bool valid = validDir(dir.childDirectories[i]); if (valid) { return true; } } } return false; }
//Starts the server and listens for connections void Server::start(){ //check if directory exists //If it doesn't , try to create the directory char temp[1024]; //Get address info purposes struct sockaddr_storage otherAddr, otherAddr2; //Connectors address information socklen_t otherAddrLen, otherAddrLen2; int rv; int i; //Socket purposes int newfd; int newfd2; //port numbers unsigned short dataPort; //Handling child processes struct sigaction sa; //Char buffers char buffer[DATA_SIZE]; //String vector vector<string> tokens; //extra string(s) string errMsg = INVCOM; //Copy the string into character array //since chdir() takes char * as argument strncpy( temp, rootDir.c_str() , sizeof(temp) ); temp[ sizeof(temp) - 1 ] = 0; //Check if directory is valid //If no directory create one if( !validDir(temp) ){ if( mkdir(temp, 0777) != 0 ){ perror("mkdir"); exit(1); } } //change directory //call chdir() if(chdir(temp) != 0){ //If chdir fails perror("chdir"); exit(1); } if ( !getPWD() ){ cout << "Unable to get cwd" << endl; exit(1); } //We have now changed the program's pwd to root directory //Now create a socket and bind to the control port and start listening //for connections cs = controlSock = createSocket( controlPort); if(verbose) cout << "Control socket created" << endl; ds = dataSock = createSocket("0"); if(verbose) cout << "Data socket created" << endl; dataPort = getPort(dataSock); //Now we have successfully created the socket //and bound it to the control port //Start listening for connections //Entering the listening loop if ( listen (controlSock , BACKLOG) != 0 ) { perror("listen"); close(controlSock); exit(1); } if( listen(dataSock , BACKLOG) != 0 ){ perror("listen"); close(dataSock); exit(1); } //handle dead processes sa.sa_handler = sigchldHandler; //read all dead processes sigemptyset( &sa.sa_mask ); sa.sa_flags = SA_RESTART; if( sigaction( SIGCHLD, &sa , NULL ) == -1 ){ perror("sigaction"); exit(1); } //Handle user interrupts signal(SIGINT, userIntHandler); cout << "Waiting for connections ... " << endl; while(1){ otherAddrLen = sizeof ( otherAddr) ; newfd = accept ( controlSock , (struct sockaddr *) &otherAddr , &otherAddrLen ); cout << "Connection from " << getIPFromAddr(&otherAddr) << ":" << getPortFromAddr(&otherAddr) << endl; commsock = newfd; send(newfd, (unsigned short *)&dataPort, 2, 0); otherAddrLen2 = sizeof otherAddr2; newfd2 = accept(dataSock, (struct sockaddr *) &otherAddr2, &otherAddrLen2 ); datacommsock = newfd2; cout << "Connection to data socket from client port " << getPortFromAddr(&otherAddr2) << endl; if( fork() == 0 ){ //The code in this block is executed by the child process close(controlSock); //Child doesn't require the control socket close(dataSock); if(verbose){ cout << "Closing listener sockets" << endl; cout << "Child process created for communication with client" << endl; } if (dup2( newfd , 0 ) != 0 ){ perror("dup2"); exit(1); } do{ if(fgets( buffer, DATA_SIZE, stdin ) == NULL){ close(newfd); exit(1); } //Remove carriage return and new line characters for(rv = 0; rv < DATA_SIZE ; rv++){ if(buffer[rv] == '\r'){ buffer[rv] = 0; break; } if(buffer[rv] == '\n'){ buffer[rv] = 0; break; } } //Read buffer and find what command it is //Call the corresponding method string s(buffer); //convert the character array into string if(verbose){ cout << "Received command " + s << endl; } istringstream iss(s); //copy the tokens into the string vector copy( istream_iterator<string>(iss), istream_iterator<string>() , back_inserter<vector<string> >(tokens) ); //Copied the tokens into tokens rv = tokens.size(); if(rv > 0){ //If there is atleast one word if(tokens[0].compare("ls") == 0){ //The client requested a file listing ls(s, newfd2); } else if(tokens[0].compare("quit") == 0){ //The client closed the connection break; } else if(tokens[0].compare("cd") == 0){ //The client requested a directory change if(rv == 2){ cd(tokens[1], newfd2); } else{ sendMessage( errMsg.c_str() , errMsg.length() , ERROR, NF, dataSock ); } } else if( tokens[0].compare("pwd") == 0 ){ //Client requested a pwd PWD(newfd2); } else if(tokens[0].compare("get") == 0){ string temp=""; for(i=1; i < rv;i++){ temp = temp + tokens[i] + " "; } temp = temp.substr(0, temp.length()-1 ); getFile(temp, newfd2); } else if(tokens[0].compare("put") == 0){ string temp=""; for(i=1; i < rv;i++){ temp = temp + tokens[i] + " "; } temp = temp.substr(0, temp.length()-1 ); putFile(temp, newfd2); } else{ sendMessage( errMsg.c_str() , errMsg.length() , ERROR, NF, newfd2 ); } } tokens.clear(); //clear the tokens }while (1); //The client closed the connection //So, close the socket and quit the child process close(newfd); close(newfd2); cout << "Connection closed" << endl; exit(1); } close(newfd); } close(controlSock); }