int ftpcmd(const char *s1, const char *s2, FILE *stream, char *buf) { unsigned n; if (verbose_flag) { lib_error("cmd %s %s", s1, s2); } if (s1) { if (s2) { fprintf(stream, "%s %s\r\n", s1, s2); } else { fprintf(stream, "%s\r\n", s1); } } do { char *buf_ptr; if (fgets(buf, 510, stream) == NULL) { lib_error("fgets"); } printf("%s", buf); buf_ptr = strstr(buf, "\r\n"); if (buf_ptr) { *buf_ptr = '\0'; } } while (!isdigit(buf[0]) || buf[3] != ' '); buf[3] = '\0'; //n = xatou(buf); n = atoi(buf); buf[3] = ' '; return n; }
int lib_create_tcp(const char* func, unsigned short port, int use_ndelay) { struct sockaddr_in sa; int fd; int i; if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { lib_error("%s, socket err(%d)", func, errno); return -1; } i = 1; if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&i, sizeof(i)) < 0) { lib_error("%s, SO_REUSEADDR err(%d)", func, errno); close(fd); return -1; } if(port != 0){ memset(&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_port = htons((short)port); if (bind(fd, (struct sockaddr*)&sa, sizeof(sa)) < 0) { lib_error("%s, bind err(%d)", func, errno); close(fd); return -1; } } if (use_ndelay) { fcntl(fd, F_SETFL, O_NONBLOCK | O_NDELAY); } return fd; }
FILE *ftp_login(ftp_host_info_t *server) { FILE *control_stream; char buf[512]; int conn_ret = -1; ftp_fd = lib_create_tcp(__FUNCTION__, 0, 0); if(ftp_fd < 0){ lib_error("[%s] lib_create_tcp err!!", __FUNCTION__); return NULL; } conn_ret = lib_connect_tcp(__FUNCTION__, ftp_fd, server->ip, server->port); if(conn_ret < 0){ lib_error("[%s] lib_connect_tcp err!!", __FUNCTION__); return NULL; } /* Connect to the command socket */ control_stream = fdopen(ftp_fd, "r+"); if (control_stream == NULL) { lib_error("[%s] fdopen err!!", __FUNCTION__); return NULL; } if (ftpcmd(NULL, NULL, control_stream, buf) != 220) { ftp_die(NULL, buf); } //printf("[%s] debug\n", __FUNCTION__); /* Login to the server */ switch (ftpcmd("USER", server->user, control_stream, buf)) { case 230: break; case 331: if (ftpcmd("PASS", server->password, control_stream, buf) != 230) { ftp_die("PASS", buf); lib_trace("FTP Login Fail."); return NULL; } else lib_trace("FTP Login OK."); break; default: ftp_die("USER", buf); lib_trace("FTP Login Fail."); return NULL; } ftpcmd("TYPE I", NULL, control_stream, buf); if(ftpcmd("CWD", server->dir, control_stream, buf) != 250){ ftp_die("CWD", buf); return NULL; } return control_stream; }
/* * Function takes an array of values and prints them to a file. * Each integer on a separate line. */ void lib_write_file(const char *filename, const int *vals, const int size) { FILE *f; if ((f = fopen(filename, "w")) == NULL) lib_error("WRITE: Failed to open file."); for (int i = 0; i < size; ++i) fprintf(f, "%d,\n", vals[i]); if (fclose(f) != 0) lib_error("WRITE: Failed to close properly."); }
int lib_recv_tcp(const char* func, int fd, uchar* data, int len) { int read = -1; read = recv(fd, data, len, 0); if (read < 0) { lib_error("%s, recvfrom err(%d)", func, errno); return -1; } else if (read == 0) { lib_error("%s, recvfrom return 0", func); return -1; } return read; }
/* * Opens the filename passed in and reads size numbers into the vals array. */ void lib_read_file(const char *filename, int *vals, const int size) { // Note on size, I start it at -1 to compensate for the below while loop going one extra time. FILE *f; if ((f = fopen(filename, "r")) == NULL) lib_error("READ: Failed to open file."); for (int i = 0; i < size; ++i) fscanf(f, "%d,", vals+i); if (fclose(f) != 0) lib_error("READ: Failed to close properly."); }
/* * Counts the number of integers in a given file. File is formatted as a csv with a comma after every integer. */ int lib_count_integers(const char *filename) { int count = 0, temp = 0; FILE *f; if ((f = fopen(filename, "r")) == NULL) lib_error("COUNT: Failed to open file."); while (fscanf(f, "%d,", &temp) && ferror(f) == 0 && feof(f) == 0) count++; if (fclose(f) != 0) lib_error("READ: Failed to close properly."); return count; }
int main(int argc, char **argv) { int i,disk; struct DEVICEPARAMS dp; if (argc == 2) disk = atoi(argv[1]); else disk = get_drive(); printf("\nDrive %c:\n",disk+'A'); if ((i = disk_getparams(disk,&dp)) != DISK_OK) { lib_error("get",i); } else { #ifdef _WIN32 #if defined __WATCOMC__ && __WATCOMC__ >= 1100 if (dp.total_sectors > MAX_FAT16_SECS) printf("drive size %Lu\n",disk_size32(&dp)); /* Microsoft %? */ else #endif #endif printf("drive size %lu\n",disk_size(&dp)); display(&dp); } return 0; }
/* * Main execution body. */ int main(int argc, char **argv) { int rank, size, *vals = NULL, num_vals; double start; /* Standard init for MPI, start timer after init. */ MPI_Init(&argc, &argv); start = MPI_Wtime(); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); if (rank == ROOT) { if (argc < 3) lib_error("MAIN: Error in usage, see notes in c file."); /* Get the work amount from command. */ num_vals = atoi(*++argv); /* Allocate it on the heap, large amount of memory likely wouldn't fit on stack. */ vals = (int *)malloc(num_vals * sizeof(int)); if (vals == NULL) lib_error("MAIN: Can't allocate vals array on heap."); /* If requested, generate new input file. */ if (strcmp(*++argv, GENERATE_FLAG) == 0) { lib_generate_numbers(vals, num_vals); lib_write_file(INPUT, vals, num_vals); } /* Read back input from file into array on heap. */ lib_read_file(INPUT, vals, num_vals); /* Sort and output to file. */ qsort(vals, num_vals, sizeof(int), lib_compare); lib_write_file(OUTPUT, vals, num_vals); free(vals); printf("Time elapsed from MPI_Init to MPI_Finalize is %.10f seconds.\n", MPI_Wtime() - start); } MPI_Finalize(); return 0; }
int lib_send_tcp(const char* func, int fd, uchar* data, int len) { int ret = -1; ret = send(fd, data, len, 0); if(ret < 0) { lib_error("%s, sendto_udp err(%d)", func, errno); return -1; } return ret; }
static int connect_ftpdata(ftp_host_info_t *server, char *buf) { char *buf_ptr; unsigned short port_num; int fd = -1; int conn_ret = -1; /* Response is "NNN garbageN1,N2,N3,N4,P1,P2[)garbage] * Server's IP is N1.N2.N3.N4 (we ignore it) * Server's port for data connection is P1*256+P2 */ buf_ptr = strrchr(buf, ')'); if (buf_ptr) *buf_ptr = '\0'; buf_ptr = strrchr(buf, ','); *buf_ptr = '\0'; port_num = atoi(buf_ptr+1); buf_ptr = strrchr(buf, ','); *buf_ptr = '\0'; port_num += atoi(buf_ptr+1) * 256; //server->port = port_num; //printf("port : %d\n", port_num); fd = lib_create_tcp(__FUNCTION__, 0, 0); if(fd < 0){ lib_error("[%s] lib_create_tcp err!!", __FUNCTION__); return -1; } conn_ret = lib_connect_tcp(__FUNCTION__, fd, server->ip, port_num); if(conn_ret < 0){ lib_error("[%s] lib_connect_tcp err!!", __FUNCTION__); return -1; } return fd; }
int lib_connect_tcp(const char* func, int fd, uint ip, unsigned short port) { struct sockaddr_in sa; int ret = -1; sa.sin_family = AF_INET; sa.sin_addr.s_addr = ip; sa.sin_port = htons(port); ret = connect(fd, (struct sockaddr *)&sa, sizeof(sa)); if(ret < 0){ lib_error("%s, connect err(%d)", func, errno); close(fd); return -1; } return 0; }
void setlast(int disk, int *track, int *head, int sysonly) { int i; struct DEVICEPARAMS dp; long fatsector,lastsec; int secsfat,datasec; unsigned int nclusters; unsigned short maxcluster; if ((i = disk_getparams(disk,&dp)) != DISK_OK) { /* LIB TODO: make a strliberror() function (like strerror()) */ lib_error("getlast()",i); exit(1); } if (sysonly) { datasec = data_sector(&dp); physical(track,NULL,head,datasec,dp.hidden_sectors,dp.secs_track, dp.num_heads); printf("System extends to track %d, side %d (logical sector %d).\n", MaxTrack,MaxHead,datasec); return; } nclusters = num_clusters(&dp); fatsector = dp.reserved_secs; secsfat = dp.secs_fat; maxcluster = searchfat12(disk,(unsigned short)nclusters, fatsector,secsfat,0); if (maxcluster == 0) die("There seems to be no data on the disk in ","%c:.",disk+'A'); datasec = data_sector(&dp); lastsec = cluster_to_sector(maxcluster,datasec,dp.secs_cluster); lastsec += (dp.secs_cluster-1); physical(track,NULL,head,lastsec,dp.hidden_sectors,dp.secs_track, dp.num_heads); printf("Last allocated cluster, %u, is on ",maxcluster); printf("track %d, side %d.\n",MaxTrack,MaxHead); }
/* * Main execution body. */ int main(int argc, char **argv) { /* Rank is my id in comm_world, world is num procs total, root_world is num of rows/cols required. */ int rank = 0, world = 0, root_world, nodes = 0, ele_per_block = 0, row_id = 0, col_id = 0; int *store_c = NULL, *store_p = NULL, **c = NULL, **p = NULL, *send_buf = NULL; double start = 0.0; FILE *log; MPI_Comm comm_row, comm_col; /* Communicators to bcast column or row. */ /* Standard init for MPI, start timer after init. */ MPI_Init(&argc, &argv); start = MPI_Wtime(); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &world); /* Init rand, open output log and memset buffer for path. */ srand(time(NULL)); log = fopen(OUTPUT, "w"); if (rank == ROOT) { if (argc < 3) lib_error("MAIN: Error in usage, see notes in c file."); } /* Get the number of nodes, ints per_node and root_world which is the num of rows and cols needed in mesh. */ nodes = atoi(*++argv); ele_per_block = (nodes*nodes)/world; root_world = lib_sqrt(world); /* Due to 2D mesh division, check requirements for even operation. */ if (rank == ROOT) { /* Ensure we have even split amongst processors. */ if ((nodes % world) != 0) { lib_error("MAIN: Choose a number of nodes that is a multiple of the processors."); return 1; } /* Ensure we have an even sqrt(p) value. */ if (root_world == 0) { lib_error("The number of processors must have even square root values.\n" "For example, p = 16, root = 4.\n"); return 1; } } /* Row and col id calculated by div and mod easily. */ row_id = rank/root_world; col_id = rank%root_world; /* Create the row and column communicators needed. */ MPI_Comm_split(MPI_COMM_WORLD, row_id, rank, &comm_row); MPI_Comm_split(MPI_COMM_WORLD, col_id, rank, &comm_col); /* Allocate cost matrices on heap, they are nodes*nodes large. */ store_c = (int *)malloc(nodes * nodes * sizeof(int)); if (store_c == NULL) lib_error("MAIN: Can't allocate storage for cost on heap."); /* Take contiguous 1D array and make c be a 2d pointer into it. */ c = (int **)malloc(nodes * sizeof(int*)); if (c == NULL) lib_error("MAIN: Can't allocate cost pointers array on heap."); for (int i = 0; i < nodes; ++i) c[i] = store_c+(i*nodes); /* Allocate path same as cost above. */ store_p = (int *)malloc(nodes * nodes * sizeof(int)); if (store_p == NULL) lib_error("MAIN: Can't allocate storage for path on heap."); /* Take contiguous 1D array and make p be a 2d pointer into it. */ p = (int **)malloc(nodes * sizeof(int*)); if (p == NULL) lib_error("MAIN: Can't allocate path pointers array on heap."); for (int i = 0; i < nodes; ++i) p[i] = store_p+(i*nodes); /* Allocate send buffer for bcast. */ send_buf = (int *)malloc((ele_per_block+2) * sizeof(int)); if (send_buf == NULL) lib_error("MAIN: Can't allocate send buffer for bcast."); /* At this point, c and p are nxn matrices put on heap and freed later. Now root can initialise values. */ if (rank == ROOT) { lib_init_cost(c, nodes); lib_init_path(p, nodes); /* If requested, generate new input file. */ if (strcmp(*++argv, GENERATE_FLAG) == 0) { lib_generate_graph(c, nodes); lib_write_cost_matrix(INPUT, c, nodes); } /* Read back input from file into array on heap. */ lib_read_cost_matrix(INPUT, c, nodes); fprintf(log, "Initial arrays cost and path.\nCost:\n"); lib_trace_matrix(log, c, nodes); fprintf(log, "Path:\n"); lib_trace_matrix(log, p, nodes); } /* Broadcast the values to all and start parallel execution. */ MPI_Bcast(c, nodes*nodes, MPI_INT, ROOT, MPI_COMM_WORLD); int nodes_per_block = nodes/root_world; int send_row_id = 0, send_col_id = 0, cnt = 0, b_root = 0; /* Start parallel algorithm. */ for (int k = 0; k < nodes; ++k) { const int i_begin = row_id*nodes_per_block, j_begin = col_id*nodes_per_block; const int i_end = i_begin+nodes_per_block, j_end = j_begin+nodes_per_block; for (int i = i_begin; i < i_end; ++i) { for (int j = j_begin; j < j_end; ++j) { int new_dist = c[i][k] + c[k][j]; if (new_dist < c[i][j]) { c[i][j] = new_dist; p[i][j] = k; } } } /* This is the root node of the broadcast. */ b_root = k/nodes_per_block; /* If I am row root, copy elements into array and bcast. Include source row,col id at begin. */ if (row_id == b_root) { cnt = 0; send_buf[cnt++] = row_id; send_buf[cnt++] = col_id; for (int i = i_begin; i < i_end; ++i) { for (int j = j_begin; j < j_end; ++j) { send_buf[cnt++] = c[i][j]; } } } MPI_Bcast(send_buf, ele_per_block+2, MPI_INT, b_root, comm_row); /* I have new values from some source, get id, make new i_begin and overwrite. */ cnt = 0; send_row_id = send_buf[cnt++]; send_col_id = send_buf[cnt++]; int si_begin = send_row_id*nodes_per_block, sj_begin = send_col_id*nodes_per_block; int si_end = si_begin+nodes_per_block, sj_end = sj_begin+nodes_per_block; for (int i = si_begin; i < si_end; ++i) { for (int j = sj_begin; j < sj_end; ++j) { c[i][j] = send_buf[cnt++]; } } /* If I am col root, repeat above steps. */ if (col_id == b_root) { printf("Send row, send col, row, col. %d %d %d %d.", send_buf[0], send_buf[1], row_id, col_id); cnt = 0; send_buf[cnt++] = row_id; send_buf[cnt++] = col_id; for (int i = i_begin; i < i_end; ++i) { for (int j = j_begin; j < j_end; ++j) { send_buf[cnt++] = c[i][j]; } } } MPI_Bcast(send_buf, ele_per_block+2, MPI_INT, b_root, comm_col); cnt = 0; send_row_id = send_buf[cnt++]; send_col_id = send_buf[cnt++]; si_begin = send_row_id*nodes_per_block, sj_begin = send_col_id*nodes_per_block; si_end = si_begin+nodes_per_block, sj_end = sj_begin+nodes_per_block; for (int i = si_begin; i < si_end; ++i) { for (int j = sj_begin; j < sj_end; ++j) { c[i][j] = send_buf[cnt++]; } } MPI_Barrier(MPI_COMM_WORLD); } /* End algorithm. */ if (rank == ROOT) { /* Log final. */ fprintf(log, "After determining the shortest path.\nCost:\n"); lib_trace_matrix(log, c, nodes); fprintf(log, "Path:\n"); lib_trace_matrix(log, p, nodes); /* Dump final cost and path matrix to anaylze later. */ lib_write_cost_matrix(COST_FILE, c, nodes); lib_write_cost_matrix(PATH_FILE, p, nodes); fprintf(stdout, "Time elapsed from MPI_Init to MPI_Finalize is %.10f seconds.\n", MPI_Wtime() - start); } /* Clean up the heap allocation. */ MPI_Comm_free(&comm_row); MPI_Comm_free(&comm_col); free(c); free(p); free(store_c); free(store_p); fclose(log); MPI_Finalize(); return 0; }
/* * Main execution body. */ int main(int argc, char **argv) { int id = 0, world = 0, num_per_proc = 0, root_size = 0, recv_size = 0, local_size = 0, dimension = 0; int *root = NULL, *recv = NULL, *local = NULL; char file[FILE_SIZE]; double start = 0.0; /* Standard init for MPI, start timer after init. Get rank and size too. */ MPI_Init(&argc, &argv); start = MPI_Wtime(); MPI_Comm_rank(MPI_COMM_WORLD, &id); MPI_Comm_size(MPI_COMM_WORLD, &world); #ifdef QDEBUG /* Open log file, overwrite on each open. */ snprintf(file, FILE_SIZE, LOG_FORMAT, id); if ((log = fopen(file, "w")) == NULL) lib_error("MAIN: Could not open log file."); #endif /* Determine the dimension of the cube. */ dimension = determine_dimension(world); if (dimension == 0) lib_error("MAIN: This hypercube program only supports running with 2, 4 or 8 processors."); /* Get the work amount from command for each process. */ num_per_proc = atoi(*++argv); root_size = num_per_proc * world; /* Root only work, ensure good usage and proper input. */ if (id == ROOT) { /* Allocate the whole array on the heap, large amount of memory likely wouldn't fit on stack. */ root = (int *)malloc(root_size * sizeof(int)); if (root == NULL) lib_error("MAIN: Can't allocate root_vals array on heap."); /* If requested, generate new input file. */ if (argc == 3 && strcmp(*++argv, GENERATE_FLAG) == 0) { lib_generate_numbers(root, root_size); lib_write_file(INPUT, root, root_size); } /* Read back input from file into array on heap. */ lib_read_file(INPUT, root, root_size); } /* * Allocate a recv buffer with a bit of extra padding, accounts for small deviations in distribution. * Local will be reallocated based on need, start as num_per_proc. */ recv_size = num_per_proc * GATHER_SCALE; local_size = num_per_proc; recv = (int *)malloc(recv_size * sizeof(int)); if (recv == NULL) lib_error("MAIN: Can't allocate recv array on heap."); local = (int *)malloc(local_size * sizeof(int)); if (local == NULL) lib_error("MAIN: Can't allocate local array on heap."); /* Scatter across the processes and then do hyper quicksort algorithm. Also, bcast the pivots. */ MPI_Scatter(root, num_per_proc, MPI_INT, local, local_size, MPI_INT, ROOT, MPI_COMM_WORLD); #ifdef QDEBUG lib_trace_array(log, "SCATTER", local, local_size); #endif /* Rearrange the cube so that each processor has data strictly less than one with higher number.*/ hyper_quicksort(dimension, id, &local, &local_size, recv, recv_size); #ifdef QDEBUG lib_trace_array(log, "HYPER", local, local_size); #endif /* * Reallocated root to be rescaled, mpi_gather doesn't know how many per process anymore. * Set values to -1 and assume it won't be worse than the scaling factor of about 20%. */ if (id == ROOT) { free(root); root_size *= GATHER_SCALE; root = (int *)malloc(root_size * sizeof(int)); if (root == NULL) lib_error("MAIN: Can't allocate root array on heap."); memset(root, -1, root_size * sizeof(int)); } /* Quicksort local array and then send back to root. */ qsort(local, local_size, sizeof(int), lib_compare); MPI_Gather(local, local_size, MPI_INT, root, GATHER_SCALE*num_per_proc, MPI_INT, ROOT, MPI_COMM_WORLD); /* Last step, root has to compress array due to uneven nature after gather. Then write to file. */ if (id == ROOT) { lib_compress_array(world, root, root_size); root_size /= GATHER_SCALE; #ifdef QDEBUG lib_trace_array(log, "GATHER", root, root_size); #endif lib_write_file(OUTPUT, root, root_size); printf("Time elapsed from MPI_Init to MPI_Finalize is %.10f seconds.\n", MPI_Wtime() - start); free(root); } free(recv); /* May have been entirely deallocated if has no more at process. */ if (local != NULL) free(local); #ifdef QDEBUG fclose(log); #endif MPI_Finalize(); return 0; }
/* * Implementation of the hyper quicksort for any given dimension. Topology is assumed to be entirely * in MPI_COMM_WORLD. Details follow traditional hypercube algorithm seen on page 422 of Parallel Computing (Gupta). * At the end, each processor with local_size elements in local will be ready to locally sort. */ void hyper_quicksort(const int dimension, const int id, int *local[], int *local_size, int recv[], const int recv_size) { MPI_Status mpi_status; MPI_Request mpi_request; subgroup_info_t info = {0, 0, 0, 0, id}; /* Init struct to zero, except for id of caller. */ int pivot = 0, lt_size = 0, gt_size = 0, received = 0; if (dimension < 1) lib_error("HYPER: Dimension can't be less than 1."); /* Iterate for all dimensions of cube. */ for (int d = dimension-1; d >= 0; --d) { /* Determine the group and member number of id, and its partner. */ lib_subgroup_info(d+1, &info); #ifdef QDEBUG snprintf(log_buf, LOG_SIZE, "INFO: World_id, Group, mem, partner. %d %d %d %d.\n", info.world_id, info.group_num, info.member_num, info.partner); lib_log(log, "INFO", log_buf); #endif /* Select and broadcast pivot only to subgroup. */ if (info.member_num == 0) { int pivot_index = lib_median_of_medians(*local, 0, (*local_size) - 1); pivot = (*local)[pivot_index]; #ifdef QDEBUG snprintf(log_buf, LOG_SIZE, "ROUND: %d, GROUP: %d, pivot is: %d.\n", dimension-d, info.group_num, pivot); lib_log(log, "PIVOT", log_buf); #endif send_pivot(pivot, &info); } else { MPI_Recv(&pivot, 1, MPI_INT, MPI_ANY_SOURCE, PIVOT_TAG, MPI_COMM_WORLD, &mpi_status); } /* Partition the array. */ lib_partition_by_pivot_val(pivot, *local, *local_size, <_size, >_size); #ifdef QDEBUG lib_trace_array(log, "PARTITIONED", *local, *local_size); #endif /* Determine position in the cube. If below is true, I am in upper part of this dimension. */ if (id & (1<<d)) { MPI_Isend(*local, lt_size, MPI_INT, info.partner, EXCHANGE_TAG, MPI_COMM_WORLD, &mpi_request); MPI_Recv(recv, recv_size, MPI_INT, info.partner, EXCHANGE_TAG, MPI_COMM_WORLD, &mpi_status); /* We have sent lower portion, move elements greater down. Update local_size.*/ memmove(*local, *local+lt_size, gt_size*sizeof(int)); *local_size = gt_size; } else { MPI_Isend(*local+lt_size, gt_size, MPI_INT, info.partner, EXCHANGE_TAG, MPI_COMM_WORLD, &mpi_request); MPI_Recv(recv, recv_size, MPI_INT, info.partner, EXCHANGE_TAG, MPI_COMM_WORLD, &mpi_status); /* We have sent upper portion of array, merely update size and ignore older elements. */ *local_size = lt_size; } /* Get the received count and call array union function to merge into local. */ MPI_Get_count(&mpi_status, MPI_INT, &received); lib_array_union(local, local_size, recv, received); /* Ensure all partner exchanges complete before proceeding to the next round. */ #ifdef QDEBUG lib_trace_array(log, "RECV", recv, received); lib_trace_array(log, "UNION", *local, *local_size); #endif } }
int ftp_send(ftp_host_info_t *server, FILE *control_stream, const char *server_path, char *local_path) { struct stat sbuf; char buf[512]; int fd_data; int fd_local; int response; /* Connect to the data socket */ if (ftpcmd("PASV", NULL, control_stream, buf) != 227) { ftp_die("PASV", buf); } fd_data = connect_ftpdata(server, buf); if(fd_data < 0){ lib_error("[%s] connect_ftpdata err!!", __FUNCTION__); return -1; } /* get the local file */ fd_local = STDIN_FILENO; if (NOT_LONE_DASH(local_path)) { fd_local = open(local_path, O_RDONLY, 0666); if(fd_local < 0){ lib_error("[%s] open err!!", __FUNCTION__); close(fd_data); return -1; } fstat(fd_local, &sbuf); sprintf(buf, "ALLO %"OFF_FMT"u", sbuf.st_size); response = ftpcmd(buf, NULL, control_stream, buf); switch (response) { case 200: case 202: break; default: ftp_die("ALLO", buf); break; } } response = ftpcmd("STOR", server_path, control_stream, buf); switch (response) { case 125: case 150: break; default: ftp_die("STOR", buf); close(fd_local); close(fd_data); return -1; } /* transfer the file */ if (copyfd_eof(fd_local, fd_data, 0) == -1) { close(fd_data); close(fd_local); return -1; } /* close it all down */ close(fd_local); close(fd_data); if (ftpcmd(NULL, NULL, control_stream, buf) != 226) { ftp_die("close", buf); } //ftpcmd("NOOP", NULL, control_stream, buf); ftpcmd("QUIT", NULL, control_stream, buf); return 0; }
int ftp_msend2(ftp_host_info_t *server, FILE *control_stream, file_path_t *file_path, int file_cnt) { struct stat sbuf; char buf[512]; int fd_data; int* fd_local = NULL; int response; int i = 0; if(file_cnt == 0) return -1; fd_local = (int*)malloc(sizeof(int)*file_cnt); if(fd_local == NULL){ lib_error("[%s] malloc err!!", __FUNCTION__); return -1; } for(i=0;i<file_cnt;i++){ memset(buf, 0, sizeof(buf)); /* Connect to the data socket */ if (ftpcmd("PASV", NULL, control_stream, buf) != 227) { ftp_die("PASV", buf); } fd_data = connect_ftpdata(server, buf); if(fd_data < 0){ lib_error("[%s] connect_ftpdata err!!", __FUNCTION__); return -1; } /* get the local file */ fd_local[i] = STDIN_FILENO; if (NOT_LONE_DASH(file_path[i].local_path)) { //printf("%d: lc_path : %s, rt_path:%s\n",i, file_path[i].local_path, file_path[i].server_path); fd_local[i] = open(file_path[i].local_path, O_RDONLY, 0666); if(fd_local[i] < 0){ lib_error("[%s] open err!!", __FUNCTION__); close(fd_data); return -1; } fstat(fd_local[i], &sbuf); sprintf(buf, "ALLO %"OFF_FMT"u", sbuf.st_size); response = ftpcmd(buf, NULL, control_stream, buf); switch (response) { case 200: case 202: break; default: ftp_die("ALLO", buf); break; } } response = ftpcmd("STOR", file_path[i].server_path, control_stream, buf); switch (response) { case 125: case 150: break; default: ftp_die("STOR", buf); close(fd_local[i]); close(fd_data); goto ftp_msend_quit_error; } /* transfer the file */ if (copyfd_eof(fd_local[i], fd_data, 0) == -1) { close(fd_data); close(fd_local[i]); goto ftp_msend_quit_error; } /* close it all down */ close(fd_local[i]); close(fd_data); if (ftpcmd(NULL, NULL, control_stream, buf) != 226) { ftp_die("close", buf); } } ftpcmd("QUIT", NULL, control_stream, buf); return 0; ftp_msend_quit_error: ftpcmd("QUIT", NULL, control_stream, buf); return -1; }
const char* CarlaBridgeUI::libError() const noexcept { CARLA_SAFE_ASSERT_RETURN(fLibFilename.isNotEmpty(), nullptr); return lib_error(fLibFilename); }