コード例 #1
0
ファイル: server_send.c プロジェクト: shoki/uftp
/**
 * The main sending function.  Goes through all files/diectories specified on
 * the command line and initializes the group for multiple files.
 */
int send_files()
{
    int i, rval, len;
    struct finfo_t group_info;
    char *dir, *base;
    time_t t;
    char path[MAXPATHNAME];

    t = time(NULL);
    if (!showtime) fprintf(applog, "\n");
    log(0, 0, "%s", VERSIONSTR);
    if (!showtime) clog(0, 0, "Starting at %s", ctime(&t));
    if (privkey) {
        log(0, 0, "Loaded %d bit key with fingerprint %s",
                  RSA_keylen(privkey) * 8, print_key_fingerprint(privkey));
    }
    if (rate == -1) {
        log(0, 0, "Transfer rate: full interface speed");
    } else {
        log(0, 0, "Transfer rate: %d Kbps (%d KB/s)", rate, rate / 8);
        log(0, 0, "Wait between packets: %d us", packet_wait);
    }

    memset(&group_info, 0, sizeof(struct finfo_t));
    if (restart_groupid) {
        group_info.group_id = restart_groupid;
    } else {
        group_info.group_id = rand() & 0xFFFF;
        group_info.group_id |= (rand() & 0xFFFF) << 16;
    }
    group_info.deststate = calloc(destcount ? destcount : MAXDEST,
                                  sizeof(struct deststate_t));
    if (group_info.deststate == NULL) {
        syserror(0, 0, "calloc failed!");
        exit(1);
    }
    log(0, 0, "Using private multicast address %s  Group ID: %08X",
               inet_ntoa(receive_dest.sin_addr), group_info.group_id);
    rval = announce_phase(&group_info);
    if (rval) {
        rval = 0;
        for (i = 0; i < filecount; i++) {
            split_path(filelist[i], &dir, &base);
            if (strcmp(destfname, "")) {
                if (filecount > 1) {
                    len = snprintf(path, sizeof(path), "%s/%s", destfname,base);
                    if ((len >= sizeof(path)) || (len == -1)) {
                        log(0, 0, "Max pathname length exceeded: %s/%s",
                                   destfname, base);
                        free(dir);
                        free(base);
                        continue;
                    }
                    rval = send_file(dir, base, path, group_info.group_id);
                } else {
                    rval = send_file(dir, base, destfname, group_info.group_id);
                }
            } else {
                rval = send_file(dir, base, base, group_info.group_id);
            }
            free(dir);
            free(base);
            if (!rval) {
                break;
            }
        }
        if (rval) {
            log(0, 0, "-----------------------------");
            transfer_phase(&group_info);
        }
    }
    if (save_fail) {
        write_restart_file(group_info.group_id);
    }
    free(group_info.deststate);

    t = time(NULL);
    if (!showtime) clog(0, 0, "uftp: Finishing at %s", ctime(&t));
    return rval;
}
コード例 #2
0
ファイル: client_common.c プロジェクト: b-cuts/uftp
/**
 * Clean up a group list entry.  Close the file if open,
 * free malloc'ed structures, drop the multicast group
 * (if no one else is using it) and free the slot.
 */
void file_cleanup(int listidx, int abort)
{
    if (group_list[listidx].fileinfo.fd >= 0) {
        close(group_list[listidx].fileinfo.fd);
        group_list[listidx].fileinfo.fd = -1;
        if (tempfile) {
            move_to_backup(listidx);
            if (rename(group_list[listidx].fileinfo.temppath,
                       group_list[listidx].fileinfo.filepath) == -1) {
                syserror(group_list[listidx].group_id,
                         group_list[listidx].file_id,
                         "Couldn't rename from %s to %s",
                         group_list[listidx].fileinfo.temppath,
                         group_list[listidx].fileinfo.filepath);
            }
        }
        if (group_list[listidx].fileinfo.tstamp) {
            utim_buf utbuf;
            utbuf.actime = group_list[listidx].fileinfo.tstamp;
            utbuf.modtime = group_list[listidx].fileinfo.tstamp;
            if (utime(group_list[listidx].fileinfo.filepath, &utbuf) == -1) {
                syserror(group_list[listidx].group_id,
                         group_list[listidx].file_id, "utime failed");
            }
        }
    }

    if ((group_list[listidx].version == UFTP_V2_VER) ||
            abort || (group_list[listidx].file_id == 0)) {
        if ((group_list[listidx].multi.s_addr != 0) &&
                !other_mcast_users(listidx) && group_list[listidx].multi_join) {
            if (server_count > 0) {
                multicast_leave(listener, group_list[listidx].group_id,
                        &group_list[listidx].multi, m_interface,
                        interface_count, server_keys, server_count);
                if (has_proxy) {
                    multicast_leave(listener, group_list[listidx].group_id,
                            &group_list[listidx].multi, m_interface,
                            interface_count, &proxy_info, 1);
                }
            } else {
                multicast_leave(listener, group_list[listidx].group_id,
                        &group_list[listidx].multi,
                        m_interface, interface_count, NULL, 0);
            }
        }
        if (group_list[listidx].serverkey) {
            free_RSA_key(group_list[listidx].serverkey);
        }
        if (group_list[listidx].restartinfo &&
                (strcmp(group_list[listidx].restartinfo->name, ""))) {
            // We have unused restart info from the last run.
            // Chalk this up as a loss and delete the data file
            char filepath[MAXPATHNAME];
            snprintf(filepath, sizeof(filepath), "%s%c_group_%08X%c%s", tempdir,
                     PATH_SEP, group_list[listidx].group_id, PATH_SEP,
                     group_list[listidx].restartinfo->name);
            unlink(filepath);
        }
        if (abort) {
            write_restart_file(listidx);
        }

        free(group_list[listidx].fileinfo.naklist);
        free(group_list[listidx].fileinfo.section_done);
        if (group_list[listidx].restartinfo) {
            free(group_list[listidx].restartinfo->naklist);
            free(group_list[listidx].restartinfo->section_done);
            free(group_list[listidx].restartinfo);
        }
        memset(&group_list[listidx], 0, sizeof(group_list[listidx]));
    } else {
        // Don't clear the file_id in case we need to respond to late DONEs
        group_list[listidx].phase = PHASE_MIDGROUP;
        set_timeout(listidx);
        free(group_list[listidx].fileinfo.naklist);
        free(group_list[listidx].fileinfo.section_done);
        group_list[listidx].fileinfo.naklist = NULL;
        group_list[listidx].fileinfo.section_done = NULL;
    }
}
コード例 #3
0
ファイル: client_common.c プロジェクト: No9/uftp
/**
 * Clean up a group list entry.  Close the file if open,
 * free malloc'ed structures, drop the multicast group
 * (if no one else is using it) and free the slot.
 */
void file_cleanup(struct group_list_t *group, int abort_session)
{
    if (group->fileinfo.fd >= 0) {
        glog2(group, "starting file close");
        close(group->fileinfo.fd);
        glog2(group, "done file close");
        group->fileinfo.fd = -1;
        if (abort_session && !strcmp(tempdir, "")) {
            if (tempfile) {
                unlink(group->fileinfo.temppath);
            } else {
                unlink(group->fileinfo.filepath);
            }
        } else {
            if (tempfile) {
                move_to_backup(group);
                if (rename(group->fileinfo.temppath,
                           group->fileinfo.filepath) == -1) {
                    gsyserror(group, "Couldn't rename from %s to %s",
                             group->fileinfo.temppath,group->fileinfo.filepath);
                }
            }
            if (group->fileinfo.tstamp) {
                utim_buf utbuf;
                utbuf.actime = group->fileinfo.tstamp;
                utbuf.modtime = group->fileinfo.tstamp;
                if (utime(group->fileinfo.filepath, &utbuf) == -1) {
                    gsyserror(group, "utime failed");
                }
            }
        }
    }

    if (abort_session || (group->file_id == 0)) {
        if (!addr_blank(&group->multi) && !other_mcast_users(group) &&
                group->multi_join) {
            if (server_count > 0) {
                multicast_leave(listener, group->group_id, &group->multi,
                        m_interface, interface_count, server_keys,server_count);
                if (has_proxy) {
                    multicast_leave(listener, group->group_id, &group->multi,
                            m_interface, interface_count, &proxy_info, 1);
                }
            } else {
                multicast_leave(listener, group->group_id, &group->multi,
                        m_interface, interface_count, NULL, 0);
            }
        }
        if (group->server_pubkey.key) {
            if (group->keyextype == KEYEX_ECDH_ECDSA) {
                free_EC_key(group->server_pubkey.ec);
            } else {
                free_RSA_key(group->server_pubkey.rsa);
            }
        }
        if (group->server_dhkey.key) {
            free_EC_key(group->server_dhkey.ec);
            free_EC_key(group->client_dhkey.ec);
        }
        if (group->restartinfo &&
                (strcmp(group->restartinfo->name, ""))) {
            // We have unused restart info from the last run.
            // Chalk this up as a loss and delete the data file
            char filepath[MAXPATHNAME];
            snprintf(filepath, sizeof(filepath), "%s%c_group_%08X%c%s", tempdir,
                     PATH_SEP, group->group_id, PATH_SEP,
                     group->restartinfo->name);
            unlink(filepath);
        }
        if (abort_session) {
            write_restart_file(group);
        }

        free(group->loss_history);
        free(group->fileinfo.naklist);
        free(group->fileinfo.section_done);
        free(group->fileinfo.cache);
        free(group->fileinfo.cache_status);
        if (group->restartinfo) {
            free(group->restartinfo->naklist);
            free(group->restartinfo->section_done);
            free(group->restartinfo);
        }
        memset(group, 0, sizeof(struct group_list_t));
    } else {
        // Don't clear the file_id in case we need to respond to late DONEs
        if (!strcmp(tempdir, "")) {
            run_postreceive(group, group->fileinfo.filepath);
        }
        group->phase = PHASE_MIDGROUP;
        set_timeout(group, 0);
        free(group->fileinfo.naklist);
        free(group->fileinfo.section_done);
        free(group->fileinfo.cache);
        free(group->fileinfo.cache_status);
        group->fileinfo.naklist = NULL;
        group->fileinfo.section_done = NULL;
        group->fileinfo.cache = NULL;
        group->fileinfo.cache_status = NULL;
    }
}