示例#1
0
/**
 * @brief xor hash specified block
 *
 * @see
 * @note
 * @author auxten  <*****@*****.**>
 * @date 2011-8-1
 **/
unsigned xor_hash_block(s_job_t * jo, GKO_INT64 block_id, u_char * buf)
{
    s_file_t * files = jo->files;
    s_block_t * blocks = jo->blocks;
    GKO_INT64 read_counter = 0;
    GKO_INT64 file_i = (blocks + block_id)->start_f;
    GKO_INT64 offset = 0;
    int fd;
    unsigned tmp_hash = 0;

    if (FAIL_CHECK(-1 == (fd = open((files + ((blocks + block_id)->start_f))->name,
                            O_RDONLY | O_NOFOLLOW))))
    {
        GKOLOG(WARNING, "file open() error!");
    }
    memset(buf, 0, BLOCK_SIZE);
    offset = (blocks + block_id)->start_off;
    while (read_counter < (blocks + block_id)->size)
    {
        GKO_INT64 tmp = pread(fd, buf + read_counter,
                (blocks + block_id)->size - read_counter, offset);
        if (FAIL_CHECK(tmp < 0))
        {
            GKOLOG(WARNING, "pread failed");
        }
        if (LIKELY(tmp))
        {
            ///printf("read: %ld\n", tmp);
            tmp_hash = xor_hash(buf + read_counter, (int) tmp, tmp_hash);
            read_counter += tmp;
            offset += tmp;
        }
        else
        {
            close(fd);
            ///if the next if a nonfile then next
            file_i = next_f(jo, file_i);
            if (FAIL_CHECK(-1
                    == (fd = open(
                                    (files + ((blocks + block_id)->start_f)
                                            + file_i)->name, O_RDONLY | O_NOFOLLOW))))
            {
                fprintf(stderr, "filename: %s\n",
                        (files + ((blocks + block_id)->start_f) + file_i)->name);
                GKOLOG(WARNING, "filename: %s",
                        (files + ((blocks + block_id)->start_f) + file_i)->name);
            }
            offset = 0;

        }
    }
    (blocks + block_id)->digest = tmp_hash;
    ///    printf("buf: %d\n", sizeof(buf));
    ///    memset(buf, 0, sizeof(buf));
    ///    printf("buf: %d\n", sizeof(buf));
    close(fd);
    return tmp_hash;
}
示例#2
0
/**
 * @brief xor hash the file given
 *
 * @see
 * @note
 * @author auxten  <*****@*****.**>
 * @date 2011-8-1
 **/
unsigned xor_hash_file(unsigned value, FILE * fd, off_t * off, size_t * count,
        u_char * buf)
{
    fseeko(fd, *off, SEEK_SET);
    if (FAIL_CHECK(*count != fread(buf, sizeof(char), *count, fd)))
    {
        GKOLOG(FATAL, "fread error");
    }
    ///fprintf(stderr, "#######################buf: %s\n", buf);
    return xor_hash(buf, *count, value);
}
示例#3
0
/**
 * @brief gracefully close a socket, for client side
 *
 * @see
 * @note
 * @author auxten <*****@*****.**> <*****@*****.**>
 * @date 2011-8-1
 **/
int close_socket(int sock)
{
    ///  if (shutdown(sock, 2)) {
    ///      gko_log(WARNING, "shutdown sock error");
    ///      return -1;
    ///  }
//    struct linger so_linger;
//    so_linger.l_onoff = 1; /// close right now, no time_wait at serv
//    so_linger.l_linger = 0; /// at most wait for 1s
//    if (FAIL_CHECK(setsockopt(sock, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(so_linger))))
//    {
//        gko_log(WARNING, "set so_linger failed");
//    }
    if (FAIL_CHECK(close(sock)))
    {
        gko_log(WARNING, "close sock error");
        return -1;
    }
    return 0;
}
示例#4
0
/**
 * @brief connect to a host
 *
 * @see
 * @note
 *     h: pointer to s_host_t
 *     recv_sec: receive timeout seconds, 0 for never timeout
 *     return the socket when succ
 *     return < 0 when error, specially HOST_DOWN_FAIL indicate host dead
 * @author auxten <*****@*****.**> <*****@*****.**>
 * @date 2011-8-1
 **/
int connect_host(s_host_t * h, int recv_sec, int send_sec)
{
    int sock = -1;
    int ret;
    int select_ret;
    int res;
    socklen_t res_size = sizeof res;
    struct sockaddr_in channel;
    in_addr_t host;
    int addr_len;
    struct timeval recv_timeout;
    struct timeval send_timeout;
#if HAVE_POLL
#else
    fd_set wset;
#endif /* HAVE_POLL */

    addr_len = getaddr_my(h->addr, &host);
    if (FAIL_CHECK(!addr_len))
    {
        gko_log(WARNING, "gethostbyname %s error", h->addr);
        ret = -1;
        goto CONNECT_END;
    }
    sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (FAIL_CHECK(sock < 0))
    {
        gko_log(WARNING, "get socket error");
        ret = -1;
        goto CONNECT_END;
    }

    recv_timeout.tv_usec = 0;
    recv_timeout.tv_sec = recv_sec ? recv_sec : RCV_TIMEOUT;
    send_timeout.tv_usec = 0;
    send_timeout.tv_sec = send_sec ? send_sec : SND_TIMEOUT;

    memset(&channel, 0, sizeof(channel));
    channel.sin_family = AF_INET;
    memcpy(&channel.sin_addr.s_addr, &host, addr_len);
    channel.sin_port = htons(h->port);

    /** set the connect non-blocking then blocking for add timeout on connect **/
    if (FAIL_CHECK(setnonblock(sock) < 0))
    {
        gko_log(WARNING, "set socket non-blocking error");
        ret = -1;
        goto CONNECT_END;
    }

    /** connect and send the msg **/
    if (FAIL_CHECK(connect(sock, (struct sockaddr *) &channel, sizeof(channel)) &&
            errno != EINPROGRESS))
    {
        gko_log(WARNING, "connect error");
        ret = HOST_DOWN_FAIL;
        goto CONNECT_END;
    }

    /** Wait for write bit to be set **/
#if HAVE_POLL
    {
        struct pollfd pollfd;

        pollfd.fd = sock;
        pollfd.events = POLLOUT;

        /* send_sec is in seconds, timeout in ms */
        select_ret = poll(&pollfd, 1, (int)(send_sec * 1000 + 1));
    }
#else
    {
        FD_ZERO(&wset);
        FD_SET(sock, &wset);
        select_ret = select(sock + 1, 0, &wset, 0, &send_timeout);
    }
#endif /* HAVE_POLL */
    if (select_ret < 0)
    {
        gko_log(WARNING, "select/poll error on connect");
        ret = HOST_DOWN_FAIL;
        goto CONNECT_END;
    }
    if (!select_ret)
    {
        gko_log(WARNING, "connect timeout on connect");
        ret = HOST_DOWN_FAIL;
        goto CONNECT_END;
    }

    /**
     * check if connection is RESETed, maybe this is the
     * best way to do that
     * SEE: http://cr.yp.to/docs/connect.html
     **/
    (void) getsockopt(sock, SOL_SOCKET, SO_ERROR, &res, &res_size);
    if (CONNECT_DEST_DOWN(res))
    {
//        gko_log(NOTICE, "connect dest is down errno: %d", res);
        ret = HOST_DOWN_FAIL;
        goto CONNECT_END;
    }

    ///gko_log(WARNING, "selected %d ret %d, time %d", sock, select_ret, send_timeout.tv_sec);
    /** set back blocking **/
    if (FAIL_CHECK(setblock(sock) < 0))
    {
        gko_log(WARNING, "set socket non-blocking error");
        ret = -1;
        goto CONNECT_END;
    }

    /** set recv & send timeout **/
    if (FAIL_CHECK(setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *) &recv_timeout,
                    sizeof(struct timeval))))
    {
        gko_log(WARNING, "setsockopt SO_RCVTIMEO error");
        ret = -1;
        goto CONNECT_END;
    }
    if (FAIL_CHECK(setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *) &send_timeout,
                    sizeof(struct timeval))))
    {
        gko_log(WARNING, "setsockopt SO_SNDTIMEO error");
        ret = -1;
        goto CONNECT_END;
    }

    ret = sock;

    CONNECT_END:
    ///
    if (ret < 0 && sock >= 0)
    {
        close_socket(sock);
    }
    return ret;
}
示例#5
0
/**
 * @brief convert the remote path recv from JOIN to local path
 *
 * @see
 * @note
 * @author auxten  <*****@*****.**>
 * @date 2011-8-1
 **/
int process_path(s_job_t * jo)
{
    char out_path[MAX_PATH_LEN] = {'\0'};
    strncpy(out_path, jo->path, MAX_PATH_LEN);
    inplace_strip_tailing_slash(out_path);
    int out_type = path_type(out_path);
    if (out_type & GKO_NONE)
    {/** non-existed dest or dest is symlink to non-existed **/
        if (out_type & GKO_LINK)
        {/** dest is symlink to non-existed **/
            GKOLOG(FATAL, "destination: '%s' is a symlink to non-exist",
                    out_path);
            return -1;
        }
        else if ((jo->file_count == 1 && jo->files->size >= 0) &&
                (jo->path)[strlen(jo->path) - 1] == '/')
        {/** dest is a non existed dir path like './non/' but job is a singal file **/
            GKOLOG(FATAL, "downloading a file to non existed path '%s'",
                    jo->path);
            return -1;
        }
        else
        { /** non-existed dest **/
            /** determine if the base dir is existed **/
            char out_base_path[MAX_PATH_LEN];
            //strncpy(out_base_path, out_path, MAX_PATH_LEN);
            cwd_path_to_abs_path(out_base_path, out_path);

            int base_idx = get_base_name_index(NULL, out_base_path);
            if (base_idx < 0)
            {
                GKOLOG(FATAL, "process_path failed");
                return -1;
            }
            out_base_path[base_idx] = '\0';
            int out_base_type = path_type(out_base_path);
            if (out_base_type & GKO_DIR)
            {/** out base path is a dir or symlink to dir **/
                for (int i = 0; i < jo->file_count; i++)
                {
                    if (FAIL_CHECK(
                            change_to_local_path((jo->files + i)->name, jo->uri, out_path, 0)))
                    {
                        GKOLOG(
                                FATAL,
                                "change to local path error, name: '%s', uri: '%s', path: '%s'",
                                (jo->files + i)->name, jo->uri, out_path);
                        return -1;
                    }
                    //GKOLOG(NOTICE, "path: '%s'", (jo->files + i)->name);
                }
                return 0;
            }
            else
            {/** out base path is not dir, nor symlink to dir **/
                GKOLOG(FATAL, "base path: '%s' is non-dir", out_base_path);
                return -1;
            }
        }
    }
    else
    {/** dest path existed **/
        if (out_type & GKO_FILE)
        {/** dest path is file or symlink to file **/
            if (jo->file_count == 1)
            {
                if ((jo->files)->size == -1)
                {/** dest path is dir **/
                    GKOLOG(FATAL, "can't overwrite dir: '%s' on file: '%s'",
                            (jo->files)->name, out_path);
                    return -1;
                }
                else if ((jo->files)->size == -2)
                {/** dest path is symlink **/
                    GKOLOG(FATAL, "can't overwrite symlink: '%s' on file: '%s'",
                            (jo->files)->name, out_path);
                    return -1;
                }
                else
                {/** dest path is file **/
                    strncpy((jo->files)->name, out_path, MAX_PATH_LEN);
                    return 0;
                }
            }
            else
            { /** file count != 1,
                indicating that job is a dir, dest is a existed file **/
                GKOLOG(FATAL, "can't overwrite dir: '%s' on file: '%s'",
                        (jo->files)->name, out_path);
                return -1;
            }
        }
        else if (out_type & GKO_DIR)
        {/** dest is a existed dir **/
            for (int i = 0; i < jo->file_count; i++)
            {
                if (FAIL_CHECK(change_to_local_path((jo->files + i)->name, jo->uri, out_path, 1)))
                {
                    GKOLOG(
                            FATAL,
                            "change to local path error, name: '%s', uri: '%s', path: '%s'",
                            (jo->files + i)->name, jo->uri, out_path);
                    return -1;
                }
            }
            return 0;
        }
        else
        {/** dest is non-regular file or dir **/
            GKOLOG(FATAL, "the dest: '%s' is non-regular file or dir", out_path);
            return -1;
        }
    }
    return 0;
}