예제 #1
0
파일: ad_conv.c 프로젝트: NTmatter/Netatalk
static int ad_conv_v22ea_rf(const char *path, const struct stat *sp, const struct vol *vol)
{
    EC_INIT;
    struct adouble adv2;
    struct adouble adea;

    LOG(log_debug, logtype_default,"ad_conv_v22ea_rf(\"%s\"): BEGIN", fullpathname(path));

    if (S_ISDIR(sp->st_mode))
        return 0;

    ad_init(&adea, vol);
    ad_init_old(&adv2, AD_VERSION2, adea.ad_options);

    /* Open and lock adouble:v2 file */
    EC_ZERO( ad_open(&adv2, path, ADFLAGS_HF | ADFLAGS_RF | ADFLAGS_RDWR) );

    if (adv2.ad_rlen > 0) {
        EC_NEG1_LOG( ad_tmplock(&adv2, ADEID_RFORK, ADLOCK_WR | ADLOCK_FILELOCK, 0, 0, 0) );

        /* Create a adouble:ea resource fork */
        EC_ZERO_LOG( ad_open(&adea, path, ADFLAGS_HF | ADFLAGS_RF | ADFLAGS_RDWR | ADFLAGS_CREATE, 0666) );

        EC_ZERO_LOG( copy_fork(ADEID_RFORK, &adea, &adv2) );
        adea.ad_rlen = adv2.ad_rlen;
        ad_flush(&adea);
    }

EC_CLEANUP:
    EC_ZERO_LOG( ad_close(&adv2, ADFLAGS_HF | ADFLAGS_RF) );
    EC_ZERO_LOG( ad_close(&adea, ADFLAGS_HF | ADFLAGS_RF) );
    LOG(log_debug, logtype_default,"ad_conv_v22ea_rf(\"%s\"): END: %d", fullpathname(path), ret);
    EC_EXIT;
}
예제 #2
0
파일: ad_conv.c 프로젝트: NTmatter/Netatalk
/*!
 * Remove hexencoded dots and slashes (":2e" and ":2f")
 */
static int ad_conv_dehex(const char *path, const struct stat *sp, const struct vol *vol, const char **newpathp)
{
    EC_INIT;
    static char buf[MAXPATHLEN];
    const char *adpath, *p;
    int adflags = S_ISDIR(sp->st_mode) ? ADFLAGS_DIR : 0;
    bstring newpath = NULL;

    LOG(log_debug, logtype_default,"ad_conv_dehex(\"%s\"): BEGIN", fullpathname(path));

    *newpathp = NULL;

    if ((p = strchr(path, ':')) == NULL)
        goto EC_CLEANUP;

    EC_NULL( newpath = bfromcstr(path) );

    EC_ZERO( bfindreplace(newpath, bfromcstr(":2e"), bfromcstr("."), 0) );
    EC_ZERO( bfindreplace(newpath, bfromcstr(":2f"), bfromcstr(":"), 0) );
    
    become_root();
    if (adflags != ADFLAGS_DIR)
        rename(vol->ad_path(path, 0), vol->ad_path(bdata(newpath), 0));
    rename(path, bdata(newpath));
    unbecome_root();

    strlcpy(buf, bdata(newpath), sizeof(buf));
    *newpathp = buf;

EC_CLEANUP:
    if (newpath)
        bdestroy(newpath);
    EC_EXIT;
}
예제 #3
0
파일: ad_conv.c 프로젝트: NTmatter/Netatalk
static int ad_conv_v22ea(const char *path, const struct stat *sp, const struct vol *vol)
{
    EC_INIT;
    const char *adpath;
    int adflags = S_ISDIR(sp->st_mode) ? ADFLAGS_DIR : 0;

    become_root();

    EC_ZERO( ad_conv_v22ea_hf(path, sp, vol) );
    EC_ZERO( ad_conv_v22ea_rf(path, sp, vol) );

    EC_NULL( adpath = ad_path(path, adflags) );
    LOG(log_debug, logtype_default,"ad_conv_v22ea_hf(\"%s\"): deleting adouble:v2 file: \"%s\"",
        path, fullpathname(adpath));

    unlink(adpath);

EC_CLEANUP:
    if (errno == ENOENT)
        EC_STATUS(0);

    unbecome_root();

    EC_EXIT;
}
예제 #4
0
파일: extattr.c 프로젝트: NTmatter/Netatalk
static int solaris_attropen(const char *path, const char *attrpath, int oflag, mode_t mode)
{
    EC_INIT;
	int filedes = -1, eafd = -1;

    if ((filedes = open(path, O_RDONLY | (oflag & O_NOFOLLOW), mode)) == -1) {
        switch (errno) {
        case ENOENT:
        case EEXIST:
        case OPEN_NOFOLLOW_ERRNO:
            EC_FAIL;
        default:
            LOG(log_debug, logtype_default, "open(\"%s\"): %s", fullpathname(path), strerror(errno));
            errno = ENOATTR;
            EC_FAIL;
        }
	}

	if ((eafd = openat(filedes, attrpath, oflag | O_XATTR, mode)) == -1) {
        switch (errno) {
        case ENOENT:
        case EEXIST:
            EC_FAIL;
        default:
            LOG(log_debug, logtype_default, "openat(\"%s\"): %s", fullpathname(path), strerror(errno));
            errno = ENOATTR;
            EC_FAIL;
        }
	}
    
EC_CLEANUP:
    if (filedes != -1)
        close(filedes);
    if (ret != 0) {
        if (eafd != -1)
            close(eafd);
        eafd = -1;
    }
    return eafd;
}
예제 #5
0
파일: unix.c 프로젝트: hajuuk/R7000
/* -----------------------------
   a dropbox is a folder where w is set but not r eg:
   rwx-wx-wx or rwx-wx--
   rwx----wx (is not asked by a Mac with OS >= 8.0 ?)
*/
int stickydirmode(const char *name, const mode_t mode, const int dropbox, const mode_t v_umask)
{
    int retval = 0;

#ifdef DROPKLUDGE
    /* Turn on the sticky bit if this is a drop box, also turn off the setgid bit */
    if ((dropbox & AFPVOL_DROPBOX)) {
        int uid;

        if ( ( (mode & S_IWOTH) && !(mode & S_IROTH)) ||
             ( (mode & S_IWGRP) && !(mode & S_IRGRP)) )
        {
            uid=geteuid();
            if ( seteuid(0) < 0) {
                LOG(log_error, logtype_afpd, "stickydirmode: unable to seteuid root: %s", strerror(errno));
            }
            if ( (retval=chmod( name, ( (DIRBITS | mode | S_ISVTX) & ~v_umask) )) < 0) {
                LOG(log_error, logtype_afpd, "stickydirmode: chmod \"%s\": %s", fullpathname(name), strerror(errno) );
            } else {
                LOG(log_debug, logtype_afpd, "stickydirmode: chmod \"%s\": %s", fullpathname(name), strerror(retval) );
            }
            seteuid(uid);
            return retval;
        }
    }
#endif /* DROPKLUDGE */

    /*
     *  Ignore EPERM errors:  We may be dealing with a directory that is
     *  group writable, in which case chmod will fail.
     */
    if ( (chmod( name, (DIRBITS | mode) & ~v_umask ) < 0) && errno != EPERM &&
         !(errno == ENOENT && (dropbox & AFPVOL_NOADOUBLE)) )
    {
        LOG(log_error, logtype_afpd, "stickydirmode: chmod \"%s\": %s", fullpathname(name), strerror(errno) );
        retval = -1;
    }

    return retval;
}
예제 #6
0
파일: ad_conv.c 프로젝트: NTmatter/Netatalk
/*!
 * AppleDouble and encoding conversion on the fly
 *
 * @param path      (r) path to file or directory
 * @param sp        (r) stat(path)
 * @param vol       (r) volume handle
 * @param newpath   (w) if encoding changed, new name. Can be NULL.
 *
 * @returns         -1 on internal error, otherwise 0. newpath is NULL if no character conversion was done,
 *                  otherwise newpath points to a static string with the converted name
 */
int ad_convert(const char *path, const struct stat *sp, const struct vol *vol, const char **newpath)
{
    EC_INIT;
    const char *p;

    LOG(log_debug, logtype_default,"ad_convert(\"%s\"): BEGIN", fullpathname(path));

    if (newpath)
        *newpath = NULL;

    if ((vol->v_adouble == AD_VERSION_EA) && !(vol->v_flags & AFPVOL_NOV2TOEACONV))
        EC_ZERO( ad_conv_v22ea(path, sp, vol) );

    if (vol->v_adouble == AD_VERSION_EA) {
        EC_ZERO( ad_conv_dehex(path, sp, vol, &p) );
        if (p && newpath)
            *newpath = p;
    }

EC_CLEANUP:
    LOG(log_debug, logtype_default,"ad_convert(\"%s\"): END: %d", fullpathname(path), ret);
    EC_EXIT;
}
예제 #7
0
/* ----------------------------- */
static int 
for_each_adouble(const char *from, const char *name, rf_loop fn, void *data, int flag, mode_t v_umask)
{
    char            buf[ MAXPATHLEN + 1];
    char            *m;
    DIR             *dp;
    struct dirent   *de;
    int             ret;
    

    if (NULL == ( dp = opendir( name)) ) {
        if (!flag) {
            LOG(log_error, logtype_afpd, "%s: opendir %s: %s", from, fullpathname(name),strerror(errno) );
            return -1;
        }
        return 0;
    }
    strlcpy( buf, name, sizeof(buf));
    strlcat( buf, "/", sizeof(buf) );
    m = strchr( buf, '\0' );
    ret = 0;
    while ((de = readdir(dp))) {
        if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) {
                continue;
        }
        
        strlcat(buf, de->d_name, sizeof(buf));
        if (fn && (ret = fn(de, buf, data, flag, v_umask))) {
           closedir(dp);
           return ret;
        }
        *m = 0;
    }
    closedir(dp);
    return ret;
}
예제 #8
0
파일: extattr.c 프로젝트: andy-js/Netatalk
static int solaris_attropenat(int filedes, const char *path, const char *attrpath, int oflag, mode_t mode)
{
    EC_INIT;
	int eafd = -1;

	if ((eafd = openat(filedes, attrpath, oflag | O_XATTR, mode)) == -1) {
        switch (errno) {
        case ENOENT:
        case EEXIST:
            EC_FAIL;
        default:
            LOG(log_debug, logtype_default, "openat(\"%s\"): %s", fullpathname(path), strerror(errno));
            EC_FAIL;
        }
	}

EC_CLEANUP:
    if (ret != 0) {
        if (eafd != -1)
            close(eafd);
        eafd = -1;
    }
    return eafd;
}
예제 #9
0
파일: ad_conv.c 프로젝트: NTmatter/Netatalk
static int ad_conv_v22ea_hf(const char *path, const struct stat *sp, const struct vol *vol)
{
    EC_INIT;
    struct adouble adv2;
    struct adouble adea;
    const char *adpath;
    int adflags;
    uint32_t ctime, mtime, afpinfo = 0;
    char *emptyad;

    LOG(log_debug, logtype_default,"ad_conv_v22ea_hf(\"%s\"): BEGIN", fullpathname(path));

    ad_init(&adea, vol);
    ad_init_old(&adv2, AD_VERSION2, adea.ad_options);
    adflags = S_ISDIR(sp->st_mode) ? ADFLAGS_DIR : 0;

    /* Open and lock adouble:v2 file */
    EC_ZERO( ad_open(&adv2, path, adflags | ADFLAGS_HF | ADFLAGS_RDWR) );

    EC_NEG1_LOG( ad_tmplock(&adv2, ADEID_RFORK, ADLOCK_WR | ADLOCK_FILELOCK, 0, 0, 0) );
    EC_NEG1_LOG( adv2.ad_ops->ad_header_read(path, &adv2, sp) );

    /* Check if it's a non-empty header */
    if (S_ISREG(sp->st_mode))
        emptyad = &emptyfilad[0];
    else
        emptyad = &emptydirad[0];

    if (ad_getentrylen(&adv2, ADEID_COMMENT) != 0)
        goto copy;
    if (ad_getentryoff(&adv2, ADEID_FINDERI)
        && (ad_getentrylen(&adv2, ADEID_FINDERI) == ADEDLEN_FINDERI)
        && (memcmp(ad_entry(&adv2, ADEID_FINDERI), emptyad, ADEDLEN_FINDERI) != 0))
        goto copy;
    if (ad_getentryoff(&adv2, ADEID_FILEDATESI)) {
        EC_ZERO_LOG( ad_getdate(&adv2, AD_DATE_CREATE | AD_DATE_UNIX, &ctime) );
        EC_ZERO_LOG( ad_getdate(&adv2, AD_DATE_MODIFY | AD_DATE_UNIX, &mtime) );
        if ((ctime != mtime) || (mtime != sp->st_mtime))
            goto copy;
    }
    if (ad_getentryoff(&adv2, ADEID_AFPFILEI)) {
        if (memcmp(ad_entry(&adv2, ADEID_AFPFILEI), &afpinfo, ADEDLEN_AFPFILEI) != 0)
            goto copy;
    }

    LOG(log_debug, logtype_default,"ad_conv_v22ea_hf(\"%s\"): default adouble", fullpathname(path), ret);
    goto EC_CLEANUP;

copy:
    /* Create a adouble:ea meta EA */
    LOG(log_debug, logtype_default,"ad_conv_v22ea_hf(\"%s\"): copying adouble", fullpathname(path), ret);
    EC_ZERO_LOGSTR( ad_open(&adea, path, adflags | ADFLAGS_HF | ADFLAGS_RDWR | ADFLAGS_CREATE),
                    "ad_conv_v22ea_hf(\"%s\"): error creating metadata EA: %s",
                    fullpathname(path), strerror(errno));
    EC_ZERO_LOG( ad_copy_header(&adea, &adv2) );
    ad_flush(&adea);

EC_CLEANUP:
    EC_ZERO_LOG( ad_close(&adv2, ADFLAGS_HF | ADFLAGS_SETSHRMD) );
    EC_ZERO_LOG( ad_close(&adea, ADFLAGS_HF | ADFLAGS_SETSHRMD) );
    LOG(log_debug, logtype_default,"ad_conv_v22ea_hf(\"%s\"): END: %d", fullpathname(path), ret);
    EC_EXIT;
}
예제 #10
0
파일: diff.cpp 프로젝트: todace/G-CVSNT
int diff (int argc, char **argv)
{
    char tmp[50];
    int c, err = 0;
    int local = 0;
    int which;
    int option_index;

    is_rcs = (strcmp (command_name, "rcsfile") == 0);

    if (argc == -1)
        usage (diff_usage);

    have_rev1_label = have_rev2_label = 0;

    /*
     * Note that we catch all the valid arguments here, so that we can
     * intercept the -r arguments for doing revision diffs; and -l/-R for a
     * non-recursive/recursive diff.
     */

    /* Clean out our global variables (multiroot can call us multiple
       times and the server can too, if the client sends several
       diff commands).  */
    if (opts == NULL)
    {
        opts_allocated = 1;
        opts = (char*)xmalloc (opts_allocated);
    }
    opts[0] = '\0';
    diff_rev1 = NULL;
    diff_rev2 = NULL;
    diff_date1 = NULL;
    diff_date2 = NULL;

    optind = 0;
    while ((c = getopt_long (argc, argv,
                             "+abcdefhilnpstuwy0123456789BHNRTC:D:F:I:L:U:V:W:k:r:",
                             longopts, &option_index)) != -1)
    {
        switch (c)
        {
        case 'a':
        case 'b':
        case 'c':
        case 'd':
        case 'e':
        case 'f':
        case 'h':
        case 'i':
        case 'n':
        case 'p':
        case 's':
        case 't':
        case 'u':
        case 'w':
        case 'y':
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
        case 'B':
        case 'H':
        case 'T':
            (void) sprintf (tmp, " -%c", (char) c);
            allocate_and_strcat (&opts, &opts_allocated, tmp);
            break;
        case 'L':
            if (have_rev1_label++)
                if (have_rev2_label++)
                {
                    error (0, 0, "extra -L arguments ignored");
                    break;
                }

            allocate_and_strcat (&opts, &opts_allocated, " -L");
            allocate_and_strcat (&opts, &opts_allocated, optarg);
            break;
        case 'C':
        case 'F':
        case 'I':
        case 'U':
        case 'V':
        case 'W':
            (void) sprintf (tmp, " -%c", (char) c);
            allocate_and_strcat (&opts, &opts_allocated, tmp);
            allocate_and_strcat (&opts, &opts_allocated, optarg);
            break;
        case 131:
            /* --ifdef.  */
            allocate_and_strcat (&opts, &opts_allocated, " --ifdef=");
            allocate_and_strcat (&opts, &opts_allocated, optarg);
            break;
        case 129:
        case 130:
        case 132:
        case 133:
        case 134:
        case 135:
        case 136:
        case 137:
        case 138:
        case 139:
        case 140:
        case 141:
        case 142:
        case 143:
        case 144:
        case 145:
        case 146:
            allocate_and_strcat (&opts, &opts_allocated, " --");
            allocate_and_strcat (&opts, &opts_allocated,
                                 longopts[option_index].name);
            if (longopts[option_index].has_arg == 1
                    || (longopts[option_index].has_arg == 2
                        && optarg != NULL))
            {
                allocate_and_strcat (&opts, &opts_allocated, "=");
                allocate_and_strcat (&opts, &opts_allocated, optarg);
            }
            break;
        case 'R':
            local = 0;
            break;
        case 'l':
            local = 1;
            break;
        case 'k':
            if (options)
                xfree (options);
            options = RCS_check_kflag (optarg,true,true);
            break;
        case 'r':
            if (diff_rev2 != NULL || diff_date2 != NULL)
                error (1, 0,
                       "no more than two revisions/dates can be specified");
            if (diff_rev1 != NULL || diff_date1 != NULL)
                diff_rev2 = optarg;
            else
                diff_rev1 = optarg;
            break;
        case 'D':
            if (diff_rev2 != NULL || diff_date2 != NULL)
                error (1, 0,
                       "no more than two revisions/dates can be specified");
            if (diff_rev1 != NULL || diff_date1 != NULL)
                diff_date2 = Make_Date (optarg);
            else
                diff_date1 = Make_Date (optarg);
            break;
        case 'N':
            empty_files = 1;
            break;
        case '?':
        default:
            usage (diff_usage);
            break;
        }
    }
    argc -= optind;
    argv += optind;

    /* make sure options is non-null */
    if (!options)
        options = xstrdup ("");

    if (!is_rcs && current_parsed_root->isremote)
    {
        if (local)
            send_arg("-l");
        if (empty_files)
            send_arg("-N");
        send_option_string (opts);
        if (options[0] != '\0')
            option_with_arg ("-k", options);
        if (diff_rev1)
            option_with_arg ("-r", diff_rev1);
        if (diff_date1)
            client_senddate (diff_date1);
        if (diff_rev2)
            option_with_arg ("-r", diff_rev2);
        if (diff_date2)
            client_senddate (diff_date2);

        send_arg("--");
        /* Send the current files unless diffing two revs from the archive */
        if (diff_rev2 == NULL && diff_date2 == NULL)
            send_files (argc, argv, local, 0, 0);
        else
            send_files (argc, argv, local, 0, SEND_NO_CONTENTS);

        send_file_names (argc, argv, SEND_EXPAND_WILD);

        send_to_server ("diff\n", 0);
        err = get_responses_and_close ();
        xfree (options);
        options = NULL;
        return (err);
    }

    if(is_rcs)
    {
        int n;

        if(!argc)
            usage(diff_usage);

        for(n=0; n<argc; n++)
        {
            struct file_info finfo = {0};
            const char *name;
            char *tmp = find_rcs_filename(argv[n]);

            if(!tmp)
                error(1,ENOENT,"%s",argv[n]);

            finfo.fullname=fullpathname(tmp, &name);
            finfo.file = xstrdup(name);
            char *ff = xstrdup(finfo.fullname);
            finfo.update_dir = ff;
            ff[(name-finfo.fullname)-1]='\0';

            finfo.rcs = RCS_fopen(finfo.fullname);
            if(finfo.rcs)
            {
                ff = (char*)finfo.fullname;
                ff[strlen(finfo.fullname)-2]='\0';
                ff = (char*)finfo.file;
                ff[strlen(finfo.file)-2]='\0';
                err+=diff_fileproc(NULL,&finfo);
                freercsnode(&finfo.rcs);
            }
            else
            {
                error(1,ENOENT,"%s",tmp);
                err++;
            }
            xfree(finfo.fullname);
            xfree(finfo.file);
            xfree(finfo.update_dir);
            xfree(tmp);
        }
    }
    else
    {
        if (diff_rev1 != NULL)
            tag_check_valid (diff_rev1, argc, argv, local, 0, "");
        if (diff_rev2 != NULL)
            tag_check_valid (diff_rev2, argc, argv, local, 0, "");

        which = W_LOCAL;
        if (diff_rev1 != NULL || diff_date1 != NULL)
            which |= W_REPOS;

        /* start the recursion processor */
        err = start_recursion (diff_fileproc, diff_filesdoneproc, (PREDIRENTPROC) NULL, diff_dirproc,
                               diff_dirleaveproc, NULL, argc, argv, local,
                               which, 0, 1, (char *) NULL, NULL, 1, verify_read, diff_rev1);
    }

    /* clean up */
    xfree (options);
    options = NULL;

    if (diff_date1 != NULL)
        xfree (diff_date1);
    if (diff_date2 != NULL)
        xfree (diff_date2);

    return (err);
}