status_t handle_cwd_command(user_session_t *session, string_t *args, size_t len) { status_t error; if (!session->logged_in) { error = send_530(session); goto exit0; } if (len < 2) { error = send_501(session); goto exit0; } string_t new_dir; string_initialize(&new_dir); char *first_c_str = string_c_str(args + 1); if (first_c_str[0] != '/' && first_c_str[0] != '~') { string_assign_from_char_array(&new_dir, session->directory); char_vector_push_back(&new_dir, '/'); } size_t i; for (i = 1; i < len; i++) { string_concatenate(&new_dir, args + i); } char *resolved_dir = realpath(string_c_str(&new_dir), NULL); if (resolved_dir == NULL || !is_directory(resolved_dir)) { error = send_550(session); goto exit1; } free(session->directory); session->directory = resolved_dir; error = send_250(session); if (error) { goto exit1; } exit1: string_uninitialize(&new_dir); exit0: return error; }
status_t handle_pass_command(user_session_t *session, string_t *args, size_t len) { status_t error; //Make sure that a USER command has already been executed by checking this //pointer value if (session->account == NULL) { error = send_503(session); goto exit0; } if (len < 2) { error = send_501(session); goto exit0; } string_t password; string_initialize(&password); size_t i; for (i = 1; i < len; i++) { string_concatenate(&password, args + i); } if (!bool_strcmp(string_c_str(&password), session->account->password)) { error = send_530(session); } error = send_330(session); if (error) { goto exit1; } session->logged_in = 1; exit1: string_uninitialize(&password); exit0: return error; }
status_t handle_user_command(user_session_t *session, string_t *args, size_t len) { status_t error; if (session->logged_in) { error = send_330(session); goto exit0; } if (len < 2) { error = send_501(session); goto exit0; } string_t username; string_initialize(&username); size_t i; for (i = 1; i < len; i++) { string_concatenate(&username, args + i); } get_account_by_username(session->server->accounts, string_c_str(&username), &session->account); if (session->account == NULL) { error = send_530(session); goto exit1; } error = send_331(session); if (error) { goto exit1; } exit1: string_uninitialize(&username); exit0: return error; }
/* return NULL on memory error */ static char * process_bibtexline( char *p, newstr *tag, newstr *data, uchar stripquotes, fields *bibin ) { int i, status; list tokens; newstr *s; newstr_empty( data ); p = bibtex_tag( p, tag ); if ( p==NULL || tag->len==0 ) return p; list_init( &tokens ); if ( *p=='=' ) { p = bibtex_data( p+1, bibin, &tokens ); if ( p==NULL ) goto out; } replace_strings( &tokens, bibin ); status = string_concatenate( &tokens, bibin ); if ( status!=BIBL_OK ) { p = NULL; goto out; } for ( i=0; i<tokens.n; i++ ) { s = list_get( &tokens, i ); if ( ( stripquotes && s->data[0]=='\"' && s->data[s->len-1]=='\"' ) || ( s->data[0]=='{' && s->data[s->len-1]=='}' ) ) { newstr_trimbegin( s, 1 ); newstr_trimend( s, 1 ); } newstr_newstrcat( data, list_get( &tokens, i ) ); } out: list_free( &tokens ); return p; }
status_t prepend_and_write_to_log(log_t *log, string_t *message, char *prepend, size_t size) { status_t error = SUCCESS; string_t final_message; string_initialize(&final_message); string_assign_from_char_array_with_size(&final_message, prepend, size); string_concatenate(&final_message, message); error = write_log(log, string_c_str(&final_message), string_length(&final_message)); if (error) { goto exit0; } exit0: string_uninitialize(&final_message); return error; }
void hugues_simplify_file_next0(char *pointer, header_t *header) { int fd; hugues_header_initialize(header); header->magic = (int)(COREWAR_EXEC_MAGIC); hugues_detect_header_programname(pointer, header); hugues_detect_header_comment(pointer, header); header->prog_size = string_words_count(pointer); fd = open(string_concatenate(header->prog_name, ".cor"), O_CREAT | O_WRONLY, 0755); write(fd, string_concatenate_length( ((char *)(header)), sizeof(header_t), hugues_code(pointer, header->prog_size), header->prog_size ), header->prog_size + sizeof(*header)); free(pointer); free(header); close(fd); }
status_t handle_list_command(user_session_t *session, string_t *args, size_t len) { /* Possible codes: 125: Data connection already open; transfer starting 150: File status okay; about to open data connection 226: Closing data connection; success 250: File action okay, completed 425: Can't open data connection 426: Connection closed 451: Aborted; local error 450: Requested file action not taken 500: Syntax error; command unrecognized 501: Syntax error in params 502: Not implemented 421: Service connection closing 530: Not logged in */ status_t error; if (!session->logged_in) { error = send_530(session); goto exit0; } if (session->data_sock < 0) { error = send_425(session); goto exit0; } string_t listing; string_initialize(&listing); string_t tmp; string_initialize(&tmp); DIR *directory; if (len < 2) { directory = opendir(session->directory); if (directory == NULL) { error = send_451(session); goto exit1; } struct dirent *entry; while ((entry = readdir(directory))) { string_concatenate_char_array(&listing, entry->d_name); char_vector_push_back(&listing, '\n'); } closedir(directory); } else { string_assign_from_char_array(&tmp, session->directory); char_vector_push_back(&tmp, '/'); string_concatenate(&tmp, args + 1); if (access(string_c_str(&tmp), F_OK) < 0) { error = send_501(session); goto exit1; } directory = opendir(string_c_str(&tmp)); if (directory == NULL) { if (errno != ENOTDIR) { error = send_451(session); goto exit1; } //Already know that the file exists because of the call to access, //so if the file is not a directory, assuming that it's a regular //file, so just list it. This could also be checked using the stat //function. string_concatenate(&listing, args + 1); char_vector_push_back(&listing, '\n'); } else { struct dirent *entry; while ((entry = readdir(directory))) { string_concatenate_char_array(&listing, entry->d_name); char_vector_push_back(&listing, '\n'); } closedir(directory); } } error = send_125(session); if (error) { send_451(session); goto exit1; } error = send_data_string(session->data_sock, &listing, session->server->log); if (error) { send_451(session); } else { error = send_226(session); } exit1: string_uninitialize(&tmp); string_uninitialize(&listing); close(session->data_sock); session->data_sock = -1; exit0: return error; }
status_t handle_retr_command(user_session_t *session, string_t *args, size_t len) { /** * Possible codes: * 125: transfer_starting * 150: about to open data connection * 226: Completed successfully; closing * 250: Requested file action completed * 425: Can't open data connection * 426: Connection closed * 451: Action aborted; local error * 450: File unavailable (busy) * 550: File unavailable (doesn't exit) * 500, 501, 421 */ status_t error; if (!session->logged_in) { error = send_530(session); goto exit0; } if (session->data_sock < 0) { error = send_425(session); goto exit0; } if (len < 2) { error = send_501(session); goto exit1; } string_t path; string_initialize(&path); string_assign_from_char_array(&path, session->directory); char_vector_push_back(&path, '/'); string_concatenate(&path, args + 1); int fd = open(string_c_str(&path), O_RDONLY, 0); if (fd < 0) { error = send_550(session); goto exit2; } string_t file_string; string_initialize(&file_string); ssize_t chars_read; char buff[512]; while ((chars_read = read(fd, buff, sizeof buff)) > 0) { string_concatenate_char_array_with_size(&file_string, buff, sizeof buff); } if (chars_read < 0) { error = send_451(session); goto exit3; } error = send_125(session); if (error) { //let the first error supercede any that might occur here, //so don't save to error send_451(session); goto exit3; } error = send_data_string(session->data_sock, &file_string, session->server->log); if (error) { send_451(session); } else { error = send_226(session); } exit3: string_uninitialize(&file_string); exit2: string_uninitialize(&path); exit1: close(session->data_sock); session->data_sock = -1; exit0: return error; }