// main client handler procedure, runs in its own thread void * thread_proc(void * param) { CLIENT_INFO client_info; memset(&client_info, 0, sizeof(client_info)); client_info.fd = (int)param; strcpy(client_info.dir, "/"); send_code(client_info.fd, 220); while (1) { int result = client_read(client_info.fd, client_info.buf, &client_info.buffer_pos); if (result == -1) break; while (client_info.buffer_pos >= 4) { char line[BUFFER_SIZE] = { 0 }; if (compare_command(client_info.buf, "USER")) command_user(&client_info); else if (compare_command(client_info.buf, "PASS")) command_pass(&client_info); else if (compare_command(client_info.buf, "PWD")) command_pwd(&client_info); else if (compare_command(client_info.buf, "PORT")) command_port(&client_info); else if (compare_command(client_info.buf, "PASV")) command_pasv(&client_info); else if (compare_command(client_info.buf, "LIST")) command_list(&client_info); else if (compare_command(client_info.buf, "CWD")) command_cwd(&client_info); else if (compare_command(client_info.buf, "RETR")) command_retr(&client_info); else if (compare_command(client_info.buf, "NOOP")) command_noop(&client_info); else if (compare_command(client_info.buf, "SYST")) command_syst(&client_info); else if (compare_command(client_info.buf, "TYPE")) command_type(&client_info); else if (compare_command(client_info.buf, "QUIT")) { get_line(client_info.fd, line, client_info.buf, &client_info.buffer_pos); send_code(client_info.fd, 221); close(client_info.fd); client_info.fd = 0; return NULL; } else { get_line(client_info.fd, line, client_info.buf, &client_info.buffer_pos); send_code(client_info.fd, 500); } } } if (client_info.fd != 0) { close(client_info.fd); client_info.fd = 0; } return NULL; }
//Le a primeira coluna de dados, e processa o comando correspondente //retorna a flag para finalizacao do shiii int process(char com_matrix[10][64][1024], //Matriz que guarda os comandos de forma legivel int* n_command, //numero de comandos int* pipe, //Localizacao do pipe int* bkgnd, //Flag de execucao em background char* diretorio) //Diretorio corrente { int conta_comando = 0; while (conta_comando <= *n_command) { //Comando do bash CD if (!strcmp(com_matrix[conta_comando][0],"cd")) { command_cd(com_matrix[conta_comando][1],diretorio); } else if (!strcmp(com_matrix[conta_comando][0],"pwd")) { command_pwd(); } else if (!strcmp(com_matrix[conta_comando][0],"wait")) { command_wait(); } else if (!strcmp(com_matrix[conta_comando][0],"exit")) { printf("Adeus!\n"); return 1; //Finaliza o processamento prematuramente } else if (!strcmp(com_matrix[conta_comando][0],"history")) { hist_show(); } else if (com_matrix[conta_comando][0][0]=='!')//Hist_recall { //Deve conter apenas ! e um inteiro if (com_matrix[conta_comando][0][2]!='\0') { printf("Erro: Evento desconhecido!\n"); } else { hist_recall(((int)com_matrix[conta_comando][0][1])-48,diretorio); } } else { executa_aplicativo(com_matrix,&conta_comando,bkgnd,pipe); } conta_comando++; }//Fim while return 0; //retorna ok para continuar a shii }
static int do_run(t_env *env, char **splitted) { if (!ft_strcmp(splitted[0], "ls")) command_ls(env, splitted); else if (!ft_strcmp(splitted[0], "cd")) command_cd(env, splitted); else if (!ft_strcmp(splitted[0], "get")) command_get(env, splitted); else if (!ft_strcmp(splitted[0], "put")) command_put(env, splitted); else if (!ft_strcmp(splitted[0], "pwd")) command_pwd(env, splitted); else if (!ft_strcmp(splitted[0], "quit") || !ft_strcmp(splitted[0], "exit")) command_quit(env, splitted); else if (!ft_strcmp(splitted[0], "touch")) command_touch(env, splitted); else if (!ft_strcmp(splitted[0], "unlink")) command_unlink(env, splitted); else return (0); return (1); }
int main(int argc, char* argv[]) { //BEGIN: initialization struct sockaddr_in sin_server; int sfd_client, x; size_t size_sockaddr = sizeof(struct sockaddr), size_packet = sizeof(struct packet); short int connection_id; struct packet* chp = (struct packet*) malloc(size_packet); // client host packet set0(chp); struct packet* data; // network packet if((x = sfd_client = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) er("socket()", x); memset((char*) &sin_server, 0, sizeof(struct sockaddr_in)); sin_server.sin_family = AF_INET; sin_server.sin_addr.s_addr = inet_addr(IPSERVER); sin_server.sin_port = htons(PORTSERVER); if((x = connect(sfd_client, (struct sockaddr*) &sin_server, size_sockaddr)) < 0) er("connect()", x); printf(ID "FTP Client started up. Attempting communication with server @ %s:%d...\n\n", IPSERVER, PORTSERVER); //END: initialization struct command* cmd; char lpwd[LENBUFFER], pwd[LENBUFFER]; //用作本地和FTP server端的当前工作区间名的缓冲区 char userinput[LENUSERINPUT]; while(1) { printf("\t> "); fgets(userinput, LENUSERINPUT, stdin); /* in order to give a filename with spaces, put ':' instead of ' '. If a command needs x paths, and y (y > x) paths are provided, y - x paths will be ignored. */ cmd = userinputtocommand(userinput); if(!cmd) continue; //printcommand(cmd); switch(cmd->id) { case GET: if(cmd->npaths) command_get(chp, data, sfd_client, *cmd->paths); else fprintf(stderr, "No path to file given.\n"); break; case PUT: if(cmd->npaths) command_put(chp, data, sfd_client, *cmd->paths); else fprintf(stderr, "No path to file given.\n"); break; case MGET: if(cmd->npaths) command_mget(chp, data, sfd_client, cmd->npaths, cmd->paths); else fprintf(stderr, "No path to file given.\n"); break; case MPUT: if(cmd->npaths) command_mput(chp, data, sfd_client, cmd->npaths, cmd->paths); else fprintf(stderr, "No path to file given.\n"); break; case MGETWILD: command_mgetwild(chp, data, sfd_client); break; case MPUTWILD: if(!getcwd(lpwd, sizeof lpwd)) er("getcwd()", 0); command_mputwild(chp, data, sfd_client, lpwd); break; case CD: if(cmd->npaths) command_cd(chp, data, sfd_client, *cmd->paths); else fprintf(stderr, "No path given.\n"); break; case LCD: // 改变local 工作区间 if(cmd->npaths) command_lcd(*cmd->paths); else fprintf(stderr, "No path given.\n"); break; case PWD: command_pwd(chp, data, sfd_client); break; case LPWD: // local pwd if(!getcwd(lpwd, sizeof lpwd)) er("getcwd()", 0); printf("\t%s\n", lpwd); break; case DIR_: case LS: command_ls(chp, data, sfd_client); break; case LDIR: case LLS: if(!getcwd(lpwd, sizeof lpwd)) er("getcwd()", 0); command_lls(lpwd); break; case MKDIR: if(cmd->npaths) command_mkdir(chp, data, sfd_client, *cmd->paths); else fprintf(stderr, "No path to directory given.\n"); break; case LMKDIR: if(cmd->npaths) command_lmkdir(*cmd->paths); else fprintf(stderr, "No path to directory given.\n"); break; case RGET: if(!getcwd(lpwd, sizeof lpwd)) er("getcwd()", 0); command_rget(chp, data, sfd_client); if((x = chdir(lpwd)) == -1) fprintf(stderr, "Wrong path.\n"); break; case RPUT: if(!getcwd(lpwd, sizeof lpwd)) er("getcwd()", 0); command_rput(chp, data, sfd_client); if((x = chdir(lpwd)) == -1) fprintf(stderr, "Wrong path.\n"); break; case EXIT: goto outside_client_command_loop; default: // display error break; } } outside_client_command_loop: /* chp->type = REQU; chp->conid = -1; strcpy(path, argv[1]); strcpy(chp->buffer, argv[1]); //printpacket(chp, HP); data = htonp(chp); if((x = send(sfd_client, data, size_packet, 0)) != size_packet) er("send()", x); set0(data); do { if((x = recv(sfd_client, data, size_packet, 0)) <= 0) er("recv()", x); chp = htonp(data); if(chp->type == INFO) printf(ID "Server says: %s\n", chp->buffer); else if(chp->type == DATA) { //printpacket(chp, HP); receive_file(extract_filename(path), sfd_client, chp); } } while(chp->type != TERM); fprintf(stderr, "TERM received; exiting...\n"); */ close(sfd_client); printf(ID "Done.\n"); fflush(stdout); return 0; }
/*PAGE * * exec_command * * Parse and execute FTP command. * * FIXME: This section is somewhat of a hack. We should have a better * way to parse commands. * * Input parameters: * info - corresponding SessionInfo structure * cmd - command to be executed (upper-case) * args - arguments of the command * * Output parameters: * NONE */ static void exec_command(FTPD_SessionInfo_t *info, char* cmd, char* args) { char fname[FTPD_BUFSIZE]; int wrong_command = 0; fname[0] = '\0'; if (!strcmp("PORT", cmd)) { command_port(info, args); } else if (!strcmp("PASV", cmd)) { command_pasv(info); } else if (!strcmp("RETR", cmd)) { strncpy(fname, args, 254); command_retrieve(info, fname); } else if (!strcmp("STOR", cmd)) { strncpy(fname, args, 254); command_store(info, fname); } else if (!strcmp("LIST", cmd)) { strncpy(fname, args, 254); command_list(info, fname, 1); } else if (!strcmp("NLST", cmd)) { strncpy(fname, args, 254); command_list(info, fname, 0); } else if (!strcmp("MDTM", cmd)) { strncpy(fname, args, 254); command_mdtm(info, fname); } else if (!strcmp("SYST", cmd)) { send_reply(info, 215, FTPD_SYSTYPE); } else if (!strcmp("TYPE", cmd)) { if (args[0] == 'I') { info->xfer_mode = TYPE_I; send_reply(info, 200, "Type set to I."); } else if (args[0] == 'A') { info->xfer_mode = TYPE_A; send_reply(info, 200, "Type set to A."); } else { info->xfer_mode = TYPE_I; send_reply(info, 504, "Type not implemented. Set to I."); } } else if (!strcmp("USER", cmd) || !strcmp("PASS", cmd)) { send_reply(info, 230, "User logged in."); } else if (!strcmp("DELE", cmd)) { if(!can_write()) { send_reply(info, 550, "Access denied."); } else if ( strncpy(fname, args, 254) && unlink(fname) == 0) { send_reply(info, 257, "DELE successful."); } else { send_reply(info, 550, "DELE failed."); } } else if (!strcmp("SITE", cmd)) { char* opts; split_command(args, &cmd, &opts, &args); if(!strcmp("CHMOD", cmd)) { int mask; if(!can_write()) { send_reply(info, 550, "Access denied."); } else { char *c; c = strchr(args, ' '); if((c != NULL) && (sscanf(args, "%o", &mask) == 1) && strncpy(fname, c+1, 254) && (chmod(fname, (mode_t)mask) == 0)) send_reply(info, 257, "CHMOD successful."); else send_reply(info, 550, "CHMOD failed."); } } else wrong_command = 1; } else if (!strcmp("RMD", cmd)) { if(!can_write()) { send_reply(info, 550, "Access denied."); } else if ( strncpy(fname, args, 254) && rmdir(fname) == 0) { send_reply(info, 257, "RMD successful."); } else { send_reply(info, 550, "RMD failed."); } } else if (!strcmp("MKD", cmd)) { if(!can_write()) { send_reply(info, 550, "Access denied."); } else if ( strncpy(fname, args, 254) && mkdir(fname, S_IRWXU | S_IRWXG | S_IRWXO) == 0) { send_reply(info, 257, "MKD successful."); } else { send_reply(info, 550, "MKD failed."); } } else if (!strcmp("CWD", cmd)) { strncpy(fname, args, 254); command_cwd(info, fname); } else if (!strcmp("CDUP", cmd)) { command_cwd(info, ".."); } else if (!strcmp("PWD", cmd)) { command_pwd(info); } else wrong_command = 1; if(wrong_command) send_reply(info, 500, "Command not understood."); }
void* serve_client(void* info) { int sfd_client, connection_id, x; struct packet* data = (struct packet*) malloc(size_packet); struct packet* shp; char lpwd[LENBUFFER]; struct client_info* ci = (struct client_info*) info; sfd_client = ci->sfd; connection_id = ci->cid; while(1) { if((x = recv(sfd_client, data, size_packet, 0)) == 0) { fprintf(stderr, "client closed/terminated. closing connection.\n"); break; } shp = ntohp(data); if(shp->type == TERM) break; if(shp->conid == -1) shp->conid = connection_id; if(shp->type == REQU) { switch(shp->comid) { case PWD: if(!getcwd(lpwd, sizeof lpwd)) er("getcwd()", 0); command_pwd(shp, data, sfd_client, lpwd); break; case CD: if((x = chdir(shp->buffer)) == -1) fprintf(stderr, "Wrong path.\n"); command_cd(shp, data, sfd_client, x == -1 ? "fail" : "success"); break; case MKDIR: command_mkdir(shp, data, sfd_client); break; case LS: if(!getcwd(lpwd, sizeof lpwd)) er("getcwd()", 0); command_ls(shp, data, sfd_client, lpwd); break; case GET: command_get(shp, data, sfd_client); break; case PUT: command_put(shp, data, sfd_client); break; case RGET: if(!getcwd(lpwd, sizeof lpwd)) er("getcwd()", 0); command_rget(shp, data, sfd_client); send_EOT(shp, data, sfd_client); if((x = chdir(lpwd)) == -1) fprintf(stderr, "Wrong path.\n"); default: // print error break; } /* //send info and then proceed to complete the request shp->type = INFO; strcpy(path, shp->buffer); sprintf(shp->buffer, "File found. Processing..."); data = htonp(shp); if((x = send(sfd_client, data, size_packet, 0)) != size_packet) er("send()", x); send_file(path, sfd_client, shp); send_TERM(sfd_client, shp); */ } else { //show error, send TERM and break fprintf(stderr, "packet incomprihensible. closing connection.\n"); send_TERM(shp, data, sfd_client); break; } } close(sfd_client); fflush(stdout); }
void* serve_client(void* info) { int sfd_client, connection_id, x; struct packet shp; char lpwd[LENBUFFER]; struct client_info* ci = (struct client_info*) info; sfd_client = ci->sfd; connection_id = ci->cid; while(1) { if(recv_packet_ret(sfd_client, &shp) < 0) { fprintf(stderr, "client ID(%d) closed/terminated. closing connection.\n", connection_id); break; } if(shp.type == TERM) break; if(shp.conid == -1) shp.conid = connection_id; if(shp.type == REQU) { switch(shp.comid) { case PWD: if(!getcwd(lpwd, sizeof lpwd)) er("getcwd()", 0); command_pwd(sfd_client, &shp, lpwd); break; case CD: if((x = chdir(shp.buffer)) == -1) fprintf(stderr, "Wrong path.\n"); command_cd(sfd_client, &shp, x == -1 ? "fail" : "success"); break; case MKDIR: command_mkdir(sfd_client, &shp); break; case LS: if(!getcwd(lpwd, sizeof lpwd)) er("getcwd()", 0); command_ls(sfd_client, &shp, lpwd); break; case GET: command_get(sfd_client, &shp); break; case PUT: command_put(sfd_client, &shp); break; case RGET: if(!getcwd(lpwd, sizeof lpwd)) er("getcwd()", 0); command_rget(sfd_client, &shp); send_EOT(sfd_client, &shp); if((x = chdir(lpwd)) == -1) fprintf(stderr, "Wrong path.\n"); break; default: // print error break; } } else { //show error, send TERM and break fprintf(stderr, "packet incomprihensible. closing connection.\n"); send_TERM(sfd_client, &shp); break; } } close(sfd_client); fflush(stdout); return NULL; }