Esempio n. 1
0
static int create_leading_directories(int base_len,
                                      const char *path, char **new_path,
                                      const char *conflict_suffix,
                                      int *clean)
{
    int len = strlen(path);
    char buf[SEAF_PATH_MAX];
    int offset = base_len, my_offset = base_len;
    SeafStat st;
    int n;

    memcpy (buf, path, base_len);
    *clean = 1;

    /* first create all leading directories. */
    while (offset < len) {
        do {
            buf[my_offset] = path[offset];
            offset++;
            my_offset++;
        } while (offset < len && path[offset] != '/');
        if (offset >= len) {
            buf[my_offset] = 0;
            break;
        }
        buf[my_offset] = 0;

        if (seaf_stat (buf, &st) == 0 && S_ISDIR(st.st_mode)) {
            continue;
        } else if (S_ISREG(st.st_mode)) {
            time_t t = time(NULL);
            char time_buf[64];

            /* It's not a clean merge if conflict path is created. */
            *clean = 0;

            strftime(time_buf, 64, "%Y-%m-%d-%H-%M-%S", localtime(&t));
            n = snprintf (&buf[my_offset], SEAF_PATH_MAX - my_offset,
                          " (%s %s)", conflict_suffix, time_buf);
            my_offset += n;
            if (seaf_stat (buf, &st) == 0 && S_ISDIR(st.st_mode))
                continue;
        }
        
        if (ccnet_mkdir (buf, 0777) < 0) {
            g_warning ("Failed to create directory %s.\n", buf);
            return -1;
        }
    }

    *new_path = g_strdup(buf);

    return 0;
}
Esempio n. 2
0
char *
build_checkout_path (const char *worktree, const char *ce_name, int len)
{
    int base_len = strlen(worktree);
    int full_len;
    char path[SEAF_PATH_MAX];
    int offset;
    SeafStat st;

    if (!len) {
        g_warning ("entry name should not be empty.\n");
        return NULL;
    }

    snprintf (path, SEAF_PATH_MAX, "%s/", worktree);

    /* first create all leading directories. */
    full_len = base_len + len + 1;
    offset = base_len + 1;
    while (offset < full_len) {
        do {
            path[offset] = ce_name[offset-base_len-1];
            offset++;
        } while (offset < full_len && ce_name[offset-base_len-1] != '/');
        if (offset >= full_len)
            break;
        path[offset] = 0;

        if (seaf_stat (path, &st) == 0 && S_ISDIR(st.st_mode))
            continue;
        
        if (ccnet_mkdir (path, 0777) < 0) {
            g_warning ("Failed to create directory %s.\n", path);
            return NULL;
        }
    }
    path[offset] = 0;

    return g_strdup(path);
}
Esempio n. 3
0
static int
checkout_entry (struct cache_entry *ce,
                struct unpack_trees_options *o,
                gboolean recover_merge,
                const char *conflict_suffix)
{
    int base_len = strlen(o->base);
    int len = ce_namelen(ce);
    int full_len;
    char path[PATH_MAX];
    int offset;
    struct stat st;
    char file_id[41];

    if (!len) {
        g_warning ("entry name should not be empty.\n");
        return -1;
    }

    snprintf (path, PATH_MAX, "%s/", o->base);

    /* first create all leading directories. */
    full_len = base_len + len + 1;
    offset = base_len + 1;
    while (offset < full_len) {
        do {
            path[offset] = ce->name[offset-base_len-1];
            offset++;
        } while (offset < full_len && ce->name[offset-base_len-1] != '/');
        if (offset >= full_len)
            break;
        path[offset] = 0;

        if (g_lstat (path, &st) == 0 && S_ISDIR(st.st_mode))
            continue;
        
        if (ccnet_mkdir (path, 0777) < 0) {
            g_warning ("Failed to create directory %s.\n", path);
            return -1;
        }
    }
    path[offset] = 0;

    if (!S_ISDIR(ce->ce_mode)) {
        /* In case that we're replacing an empty dir with a file,
         * we need first to remove the empty dir.
         */
        if (g_lstat (path, &st) == 0 && S_ISDIR(st.st_mode)) {
            if (g_rmdir (path) < 0) {
                g_warning ("Failed to remove dir %s: %s\n", path, strerror(errno));
                /* Don't quit since we can handle conflict later. */
            }
        }
    } else {
        /* For simplicity, we just don't checkout the empty dir if there is
         * already a file with the same name in the worktree.
         * This implies, you can't remove a file then create an empty directory
         * with the same name. But it's a rare requirement.
         */
        if (g_mkdir (path, 0777) < 0) {
            g_warning ("Failed to create empty dir %s.\n", path);
        }
        return 0;
    }

    if (!o->reset && g_lstat (path, &st) == 0 && S_ISREG(st.st_mode) &&
        (ce->ce_ctime.sec != st.st_ctime || ce->ce_mtime.sec != st.st_mtime))
    {
        /* If we're recovering an interrupted merge, we don't know whether
         * the file was changed by checkout or by the user. So we have to
         * calculate the sha1 for that file and compare it with the one in
         * cache entry.
         */
        if (!recover_merge || 
            compare_file_content (path, &st, ce->sha1, o->crypt) != 0) {
            g_warning ("File %s is changed. Skip checking out.\n", path);
            return -1;
        }

        /* Recover merge and file content matches index entry.
         * We were interrupted before updating the index, update index
         * entry timestamp now.
         */
        goto update_cache;
    }

    /* then checkout the file. */
    rawdata_to_hex (ce->sha1, file_id, 20);
    if (seaf_fs_manager_checkout_file (seaf->fs_mgr, file_id,
                                       path, ce->ce_mode,
                                       o->crypt, conflict_suffix) < 0) {
        g_warning ("Failed to checkout file %s.\n", path);
        return -1;
    }

update_cache:
    /* finally fill cache_entry info */
    g_lstat (path, &st);
    fill_stat_cache_info (ce, &st);

    return 0;
}
Esempio n. 4
0
int
main(int argc, char **argv)
{
    char *config_dir;
    char *config_file;
    int c;
    char *name = NULL;

    program_name = argv[0];

    config_dir = DEFAULT_CONFIG_DIR;

    while ((c = getopt_long(argc, argv,
        short_opts, long_opts, NULL)) != EOF) {
        switch (c) {
        case 'h':
            usage (1);
            break;
        case 'c':
            config_dir = strdup(optarg);
            break;
        case 'n':
            name = strdup (optarg);
            break;
        case 'H':
            host_str = strdup (optarg);
            break;
        case 'P':
            port_str = strdup (optarg);
            break;
        default:
            usage(1);
        }
    }

    config_dir = ccnet_expand_path (config_dir);
    /* printf("[conf_dir=%s\n]", config_dir); */
    SSLeay_add_all_algorithms();

    if (RAND_status() != 1) {   /* it should be seeded automatically */
        fprintf(stderr, "PRNG is not seeded\n");
        exit (1);
    }

    if (bits == 0)
        bits = DEFAULT_BITS;

    /* create peer key */
    if (!name) {
        usage(-ERR_NAME_NULL);
    }
    if (strlen(name) < 2 || strlen (name) > 16
        || !is_valid_username(name)) {
        fprintf (stderr, "The user name should be more than 2 bytes and less than 16 bytes, only digits,  alphabetes and '-', '_' are allowed");
        exit(-ERR_NAME_INVALID);
    }
            
    user_name = name;
    peer_name = g_strdup (name);

    create_peerkey ();
    peer_id = id_from_pubkey (peer_pubkey);
    identity_file_peer = g_build_filename (config_dir, PEER_KEYFILE, NULL);

    /* create dir */
    if (ccnet_mkdir(config_dir, 0700) < 0) {
        fprintf (stderr, "Make dir %s error: %s\n", 
                 config_dir, strerror(errno));
        exit(-ERR_PERMISSION);
    }

    /* save key */
    save_privkey (peer_privkey, identity_file_peer);

    /* make configure file */
    config_file = g_build_filename (config_dir, CONFIG_FILE_NAME, NULL);
    make_configure_file (config_file);
    
    printf ("Successly create configuration dir %s.\n", config_dir);
    exit(0);
}