Example #1
0
/* XXX - these two functions should be out in append.c or reserve.c
 * or something more general */
EXPORTED const char *dlist_reserve_path(const char *part, int isarchive,
                                        const struct message_guid *guid)
{
    static char buf[MAX_MAILBOX_PATH];
    const char *base;

    /* part can be either a configured partition name, or a path */
    if (strchr(part, '/')) {
        base = part;
    }
    else {
        base = isarchive ? config_archivepartitiondir(part)
                         : config_partitiondir(part);
    }

    /* we expect to have a base at this point, so let's assert that */
    assert(base != NULL);

    snprintf(buf, MAX_MAILBOX_PATH, "%s/sync./%lu/%s",
                  base, (unsigned long)getpid(),
                  message_guid_encode(guid));

    /* gotta make sure we can create files */
    if (cyrus_mkdir(buf, 0755)) {
        /* it's going to fail later, but at least this will help */
        syslog(LOG_ERR, "IOERROR: failed to create %s/sync./%lu/ for reserve: %m",
                        base, (unsigned long)getpid());
    }
    return buf;
}
Example #2
0
static int myopen(const char *fname, int flags, struct dbengine **ret, struct txn **mytid)
{
    struct dbengine *db;
    struct stat sbuf;

    assert(fname && ret);

    db = find_db(fname);
    if (db)
        goto out;   /* new reference to existing db */

    db = (struct dbengine *) xzmalloc(sizeof(struct dbengine));

    db->fd = open(fname, O_RDWR, 0644);
    if (db->fd == -1 && errno == ENOENT) {
        if (!(flags & CYRUSDB_CREATE)) {
            free_db(db);
            return CYRUSDB_NOTFOUND;
        }
        if (cyrus_mkdir(fname, 0755) == -1) {
            free_db(db);
            return CYRUSDB_IOERROR;
        }
        db->fd = open(fname, O_RDWR | O_CREAT, 0644);
    }

    if (db->fd == -1) {
        syslog(LOG_ERR, "IOERROR: opening %s: %m", fname);
        free_db(db);
        return CYRUSDB_IOERROR;
    }

    if (fstat(db->fd, &sbuf) == -1) {
        syslog(LOG_ERR, "IOERROR: fstat on %s: %m", fname);
        close(db->fd);
        free_db(db);
        return CYRUSDB_IOERROR;
    }
    db->ino = sbuf.st_ino;

    map_refresh(db->fd, 0, &db->base, &db->len, sbuf.st_size,
                fname, 0);
    db->size = sbuf.st_size;

    db->fname = xstrdup(fname);
    db->refcount = 1;

    /* prepend to the list */
    db->next = alldbs;
    alldbs = db;

    if (mytid) {
        int r = starttxn_or_refetch(db, mytid);
        if (r) return r;
    }

out:
    *ret = db;
    return 0;
}
Example #3
0
static void sync_log_base(const char *channel, const char *string)
{
    int fd;
    struct stat sbuffile, sbuffd;
    int retries = 0;
    const char *fname;

    /* are we being supressed? */
    if (!sync_log_enabled(channel)) return;

    fname = sync_log_fname(channel);

    while (retries++ < SYNC_LOG_RETRIES) {
	fd = open(fname, O_WRONLY|O_APPEND|O_CREAT, 0640);
	if (fd < 0 && errno == ENOENT) {
	    if (!cyrus_mkdir(fname, 0755)) {
		fd = open(fname, O_WRONLY|O_APPEND|O_CREAT, 0640);
	    }
	}
	if (fd < 0) {
	    syslog(LOG_ERR, "sync_log(): Unable to write to log file %s: %s",
		   fname, strerror(errno));
	    return;
	}

	if (lock_blocking(fd, fname) == -1) {
	    syslog(LOG_ERR, "sync_log(): Failed to lock %s for %s: %m",
		   fname, string);
	    xclose(fd);
	    return;
	}

	/* Check that the file wasn't renamed after it was opened above */
	if ((fstat(fd, &sbuffd) == 0) &&
	    (stat(fname, &sbuffile) == 0) &&
	    (sbuffd.st_ino == sbuffile.st_ino))
	    break;

	lock_unlock(fd, fname);
	xclose(fd);
    }
    if (retries >= SYNC_LOG_RETRIES) {
	xclose(fd);
	syslog(LOG_ERR,
	       "sync_log(): Failed to lock %s for %s after %d attempts",
	       fname, string, retries);
	return;
    }

    if (retry_write(fd, string, strlen(string)) < 0)
	syslog(LOG_ERR, "write() to %s failed: %s",
	       fname, strerror(errno));

    (void)fsync(fd); /* paranoia */
    lock_unlock(fd, fname);
    xclose(fd);
}
Example #4
0
/* NOTE - we don't provide any guarantees that the file isn't open multiple
 * times.  So don't do that.  It will mess with your locking no end */
EXPORTED int mappedfile_open(struct mappedfile **mfp,
                             const char *fname, int flags)
{
    struct mappedfile *mf;
    struct stat sbuf;
    int openmode = (flags & MAPPEDFILE_RW) ? O_RDWR : O_RDONLY;
    int create = (flags & MAPPEDFILE_CREATE) ? 1 : 0;
    int r;

    assert(fname);
    assert(!*mfp);

    mf = xzmalloc(sizeof(struct mappedfile));
    mf->fname = xstrdup(fname);
    mf->is_rw = (flags & MAPPEDFILE_RW) ? 1 : 0;

    mf->fd = open(mf->fname, openmode, 0644);
    if (mf->fd < 0 && errno == ENOENT) {
        if (!create || !mf->is_rw) {
            r = -errno;
            goto err;
        }
        r = cyrus_mkdir(mf->fname, 0755);
        if (r < 0) {
            syslog(LOG_ERR, "IOERROR: cyrus_mkdir %s: %m", mf->fname);
            goto err;
        }
        mf->fd = open(mf->fname, O_RDWR | O_CREAT, 0644);
    }

    if (mf->fd == -1) {
        syslog(LOG_ERR, "IOERROR: open %s: %m", mf->fname);
        r = -errno;
        goto err;
    }

    /* it's zero, but set it anyway */
    mf->lock_status = MF_UNLOCKED;
    mf->dirty = 0;

    r = fstat(mf->fd, &sbuf);
    if (r < 0) {
        syslog(LOG_ERR, "IOERROR: fstat %s: %m", mf->fname);
        goto err;
    }

    _ensure_mapped(mf, sbuf.st_size, /*update*/0);

    *mfp = mf;

    return 0;

err:
    mappedfile_close(&mf);
    return r;
}
Example #5
0
static int my_mkparentdir(const char *fname)
{
    struct buf buf = BUF_INITIALIZER;
    int r;

    buf_setcstr(&buf, fname);
    r = cyrus_mkdir(buf_cstring(&buf), 0755);
    buf_free(&buf);
    return r;
}
Example #6
0
EXPORTED int proc_register(const char *servicename, const char *clienthost,
		  const char *userid, const char *mailbox)
{
    pid_t pid = getpid();
    FILE *procfile = NULL;
    char *newfname = NULL;

    if (!procfname)
	procfname = proc_getpath(pid, /*isnew*/0);

    newfname = proc_getpath(pid, /*isnew*/1);

    procfile = fopen(newfname, "w+");
    if (!procfile) {
	if (cyrus_mkdir(newfname, 0755) == -1) {
	    fatal("couldn't create proc directory", EC_IOERR);
	}
	else {
	    syslog(LOG_NOTICE, "created proc directory");
	    procfile = fopen(newfname, "w+");
	    if (!procfile) {
		syslog(LOG_ERR, "IOERROR: creating %s: %m", newfname);
		fatal("can't write proc file", EC_IOERR);
	    }
	}
    }

    fprintf(procfile, "%s\t%s", servicename, clienthost);
    if (userid) {
	fprintf(procfile, "\t%s", userid);
	if (mailbox) {
	    fprintf(procfile, "\t%s", mailbox);
	}
    }
    putc('\n', procfile);
    fclose(procfile);

    if (rename(newfname, procfname)) {
	syslog(LOG_ERR, "IOERROR: renaming %s to %s: %m", newfname, procfname);
	unlink(newfname);
	fatal("can't write proc file", EC_IOERR);
    }

    setproctitle("%s: %s %s %s", servicename, clienthost,
		 userid ? userid : "",
		 mailbox ? mailbox : "");

    free(newfname);
    return 0;
}
Example #7
0
int actions_setuser(const char *userid)
{
  char userbuf[1024], *user, *domain = NULL;
  size_t size = 1024, len;
  int result;

  char *sieve_dir = (char *) xzmalloc(size+1);

  sieved_userid = xstrdup(userid);
  user = (char *) userid;
  if (config_virtdomains && strchr(user, '@')) {
      /* split the user and domain */
      strlcpy(userbuf, userid, sizeof(userbuf));
      user = userbuf;
      if ((domain = strrchr(user, '@'))) *domain++ = '\0';
  }

  len = strlcpy(sieve_dir, sieve_dir_config, size);

  if (domain) {
      char dhash = (char) dir_hash_c(domain, config_fulldirhash);
      len += snprintf(sieve_dir+len, size-len, "%s%c/%s",
                      FNAME_DOMAINDIR, dhash, domain);
  }

  if (sieved_userisadmin) {
      strlcat(sieve_dir, "/global", size);
  }
  else {
      char hash = (char) dir_hash_c(user, config_fulldirhash);
      snprintf(sieve_dir+len, size-len, "/%c/%s", hash, user);
  }

  result = chdir(sieve_dir);
  if (result != 0) {
      result = cyrus_mkdir(sieve_dir, 0755);
      if (!result) result = mkdir(sieve_dir, 0755);
      if (!result) result = chdir(sieve_dir);
      if (result) {
          syslog(LOG_ERR, "mkdir %s: %m", sieve_dir);
          free(sieve_dir);
          return TIMSIEVE_FAIL;
      }
  }

  free(sieve_dir);
  return TIMSIEVE_OK;
}
Example #8
0
int seen_open(const char *user, 
	      int flags,
	      struct seen **seendbptr)
{
    struct seen *seendb = NULL;
    char *fname = NULL;
    int dbflags = (flags & SEEN_CREATE) ? CYRUSDB_CREATE : 0;
    int r;

    assert(user);
    assert(*seendbptr == NULL);

    /* create seendb */
    seendb = (struct seen *) xmalloc(sizeof(struct seen));

    if (SEEN_DEBUG) {
	syslog(LOG_DEBUG, "seen_db: seen_open(%s)", user);
    }

    /* open the seendb corresponding to user */
    fname = seen_getpath(user);
    if (flags & SEEN_CREATE) cyrus_mkdir(fname, 0755);
    r = cyrusdb_open(DB, fname, dbflags, &seendb->db);
    if (r) {
	if (!(flags & SEEN_SILENT)) {
	    int level = (flags & SEEN_CREATE) ? LOG_ERR : LOG_DEBUG;
	    syslog(level, "DBERROR: opening %s: %s", fname, 
		   cyrusdb_strerror(r));
	}
	r = IMAP_IOERROR;
	free(seendb);
	free(fname);
	return r;
    }
    syslog(LOG_DEBUG, "seen_db: user %s opened %s", user, fname);
    free(fname);

    seendb->tid = NULL;
    seendb->user = xstrdup(user);

    *seendbptr = seendb;
    return r;
}
Example #9
0
/**
 * \brief Fills partition data.
 *
 * @param inout part_list   items list structure
 * @param in    idx         item index
 */
static void partition_filldata(partlist_t *part_list, int idx)
{
    partitem_t *item = &part_list->items[idx];
    struct statvfs stat;

    item->id = 0;
    item->available = 0;
    item->total = 0;
    item->quota = 0.;

    if (statvfs(item->value, &stat)) {
	/* statvfs error */
    	int error = 1;

	if (errno == ENOENT) {
	    /* try to create path */
	    if ((cyrus_mkdir(item->value, 0755) == -1) || (mkdir(item->value, 0755) == -1)) {
		syslog(LOG_ERR, "IOERROR: creating %s: %m", item->value);
		return;
	    }
	    else {
		error = statvfs(item->value, &stat) ? 1 : 0;
	    }
	}

	if (error) {
	    syslog(LOG_ERR, "IOERROR: statvfs[%s]: %m", item->value);
	    return;
	}
    }

    if (stat.f_blocks <= 0) {
	/* error retrieving statvfs info */
	syslog(LOG_ERR, "IOERROR: statvfs[%s]: non-positive number of blocks", item->value);
	return;
    }

    item->id = stat.f_fsid;
    item->available = (uint64_t)(stat.f_bavail * (stat.f_frsize / 1024.));
    item->total = (uint64_t)(stat.f_blocks * (stat.f_frsize / 1024.));
}
Example #10
0
int seen_rename_user(const char *olduser, const char *newuser)
{
    char *oldfname = seen_getpath(olduser);
    char *newfname = seen_getpath(newuser);
    int r = 0;

    if (SEEN_DEBUG) {
	syslog(LOG_DEBUG, "seen_db: seen_rename_user(%s, %s)", 
	       olduser, newuser);
    }

    cyrus_mkdir(newfname, 0755);
    if (rename(oldfname, newfname) && errno != ENOENT) {
	syslog(LOG_ERR, "error renaming %s to %s: %m", oldfname, newfname);
	r = IMAP_IOERROR;
    }

    free(oldfname);
    free(newfname);
    
    return r;
}
Example #11
0
static int autocreate_sieve(const char *userid, const char *source_script)
{
    /* XXX - this is really ugly, but too much work to tidy up right now -- Bron */
    sieve_script_t *s = NULL;
    bytecode_info_t *bc = NULL;
    char *err = NULL;
    FILE *in_stream, *out_fp;
    int out_fd, in_fd, r, k;
    int do_compile = 0;
    const char *compiled_source_script = NULL;
    const char *sievename = get_script_name(source_script);
    const char *sieve_script_dir = NULL;
    char sieve_script_name[MAX_FILENAME];
    char sieve_bcscript_name[MAX_FILENAME];
    char sieve_default[MAX_FILENAME];
    char sieve_tmpname[MAX_FILENAME];
    char sieve_bctmpname[MAX_FILENAME];
    char sieve_bclink_name[MAX_FILENAME];
    char buf[4096];
    mode_t oldmask;
    struct stat statbuf;

    /* We don't support using the homedirectory, like timsieved */
    if (config_getswitch(IMAPOPT_SIEVEUSEHOMEDIR)) {
        syslog(LOG_WARNING,"autocreate_sieve: autocreate_sieve does not work with sieveusehomedir option in imapd.conf");
        return 1;
    }

    /* Check if sievedir is defined in imapd.conf */
    if(!config_getstring(IMAPOPT_SIEVEDIR)) {
        syslog(LOG_WARNING, "autocreate_sieve: sievedir option is not defined. Check imapd.conf");
        return 1;
    }

    /* Check if autocreate_sieve_compiledscript is defined in imapd.conf */
    if(!(compiled_source_script = config_getstring(IMAPOPT_AUTOCREATE_SIEVE_SCRIPT_COMPILED))) {
        syslog(LOG_WARNING, "autocreate_sieve: autocreate_sieve_compiledscript option is not defined. Compiling it");
        do_compile = 1;
    }

    if (!(sieve_script_dir = user_sieve_path(userid))) {
        syslog(LOG_WARNING, "autocreate_sieve: unable to determine sieve directory for user %s", userid);
        return 1;
    }

    if(snprintf(sieve_tmpname, MAX_FILENAME, "%s/%s.script.NEW",sieve_script_dir, sievename) >= MAX_FILENAME) {
        syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_script_dir, sievename, userid);
        return 1;
    }
    if(snprintf(sieve_bctmpname, MAX_FILENAME, "%s/%s.bc.NEW",sieve_script_dir, sievename) >= MAX_FILENAME) {
        syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_script_dir, sievename, userid);
        return 1;
    }
    if(snprintf(sieve_script_name, MAX_FILENAME, "%s/%s.script",sieve_script_dir, sievename) >= MAX_FILENAME) {
        syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_script_dir, sievename, userid);
        return 1;
    }
    if(snprintf(sieve_bcscript_name, MAX_FILENAME, "%s/%s.bc",sieve_script_dir, sievename) >= MAX_FILENAME) {
        syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_script_dir, sievename, userid);
        return 1;
    }
    if(snprintf(sieve_default, MAX_FILENAME, "%s/%s",sieve_script_dir,"defaultbc") >= MAX_FILENAME) {
        syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_script_dir, sievename, userid);
        return 1;
    }
    /* XXX no directory? umm */
    if(snprintf(sieve_bclink_name, MAX_FILENAME, "%s.bc", sievename) >= MAX_FILENAME) {
        syslog(LOG_WARNING, "autocreate_sieve: Invalid sieve path %s, %s, %s", sieve_script_dir, sievename, userid);
        return 1;
    }

    /* Check if a default sieve filter alrady exists */
    if(!stat(sieve_default,&statbuf)) {
        syslog(LOG_WARNING,"autocreate_sieve: Default sieve script already exists");
        return 1;
    }

    /* Open the source script. if there is a problem with that exit */
    in_stream = fopen(source_script, "r");
    if(!in_stream) {
        syslog(LOG_WARNING,"autocreate_sieve: Unable to open sieve script %s. Check permissions",source_script);
        return 1;
    }

    /*
     * At this point we start the modifications of the filesystem
     */

    /* Create the directory where the sieve scripts will reside */
    r = cyrus_mkdir(sieve_bctmpname, 0755);
    if(r == -1) {
        /* If this fails we just leave */
        fclose(in_stream);
        return 1;
    }

    /*
     * We open the file that will be used as the bc file. If this file exists, overwrite it
     * since something bad has happened. We open the file here so that this error checking is
     * done before we try to open the rest of the files to start copying etc.
     */
    out_fd = open(sieve_bctmpname, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
    if(out_fd < 0) {
        if(errno == EEXIST) {
            syslog(LOG_WARNING,"autocreate_sieve: File %s already exists. Probaly left over. Ignoring",sieve_bctmpname);
        } else if (errno == EACCES) {
            syslog(LOG_WARNING,"autocreate_sieve: No access to create file %s. Check permissions",sieve_bctmpname);
            fclose(in_stream);
            return 1;
        } else {
            syslog(LOG_WARNING,"autocreate_sieve: Unable to create %s: %m",sieve_bctmpname);
            fclose(in_stream);
            return 1;
        }
    }

    if(!do_compile && compiled_source_script && (in_fd = open(compiled_source_script, O_RDONLY)) != -1) {
        while((r = read(in_fd, buf, sizeof(buf))) > 0) {
            if((k=write(out_fd, buf,r)) < 0) {
                syslog(LOG_WARNING, "autocreate_sieve: Error writing to file %s: %m", sieve_bctmpname);
                close(out_fd);
                close(in_fd);
                fclose(in_stream);
                unlink(sieve_bctmpname);
                return 1;
           }
        }

        if(r == 0) { /* EOF */
            xclose(out_fd);
            xclose(in_fd);
        } else if (r < 0) {
            syslog(LOG_WARNING, "autocreate_sieve: Error reading compiled script file %s: %m. Will try to compile it",
                           compiled_source_script);
            xclose(in_fd);
            do_compile = 1;
            if(lseek(out_fd, 0, SEEK_SET)) {
                syslog(LOG_WARNING, "autocreate_sieve: Major IO problem (lseek: %m). Aborting");
                xclose(out_fd);
                return 1;
            }
        }
        xclose(in_fd);
    } else {
        if(compiled_source_script)
              syslog(LOG_WARNING,"autocreate_sieve: Problem opening compiled script file: %s. Compiling it", compiled_source_script);
        do_compile = 1;
    }


    /* Because we failed to open a precompiled bc sieve script, we compile one */
    if(do_compile) {
       if(is_script_parsable(in_stream,&err, &s) == TIMSIEVE_FAIL) {
            if(err && *err) {
               syslog(LOG_WARNING,"autocreate_sieve: Error while parsing script %s.",err);
               free(err);
            } else
                syslog(LOG_WARNING,"autocreate_sieve: Error while parsing script");

            unlink(sieve_bctmpname);
            fclose(in_stream);
            close(out_fd);
            return 1;
        }

        /* generate the bytecode */
        if(sieve_generate_bytecode(&bc, s) == TIMSIEVE_FAIL) {
            syslog(LOG_WARNING,"autocreate_sieve: problem compiling sieve script");
            /* removing the copied script and cleaning up memory */
            unlink(sieve_bctmpname);
            sieve_script_free(&s);
            fclose(in_stream);
            close(out_fd);
            return 1;
        }

        if(sieve_emit_bytecode(out_fd, bc) == TIMSIEVE_FAIL) {
            syslog(LOG_WARNING,"autocreate_sieve: problem emiting sieve script");
            /* removing the copied script and cleaning up memory */
            unlink(sieve_bctmpname);
            sieve_free_bytecode(&bc);
            sieve_script_free(&s);
            fclose(in_stream);
            close(out_fd);
            return 1;
        }

        /* clean up the memory */
        sieve_free_bytecode(&bc);
        sieve_script_free(&s);
    }

    xclose(out_fd);
    rewind(in_stream);

    /* Copy the initial script */
    oldmask = umask(077);
    if((out_fp = fopen(sieve_tmpname, "w")) == NULL) {
        syslog(LOG_WARNING,"autocreate_sieve: Unable to open destination sieve script %s: %m", sieve_tmpname);
        unlink(sieve_bctmpname);
        umask(oldmask);
        fclose(in_stream);
        return 1;
    }
    umask(oldmask);

    while((r = fread(buf,sizeof(char), sizeof(buf), in_stream)) > 0) {
        if( fwrite(buf,sizeof(char), r, out_fp) != (unsigned)r) {
            syslog(LOG_WARNING,"autocreate_sieve: Problem writing to sieve script file %s: %m",sieve_tmpname);
            fclose(out_fp);
            unlink(sieve_tmpname);
            unlink(sieve_bctmpname);
            fclose(in_stream);
            return 1;
        }
    }

    if(feof(in_stream)) {
        fclose(out_fp);
        fclose(in_stream);
    } else { /* ferror */
        fclose(out_fp);
        unlink(sieve_tmpname);
        unlink(sieve_bctmpname);
        fclose(in_stream);
        return 1;
    }

    /* Renaming the necessary stuff */
    if(rename(sieve_tmpname, sieve_script_name)) {
        unlink(sieve_tmpname);
        unlink(sieve_bctmpname);
        return 1;
    }

    if(rename(sieve_bctmpname, sieve_bcscript_name)) {
        unlink(sieve_bctmpname);
        unlink(sieve_bcscript_name);
        return 1;
    }

    /* end now with the symlink */
    if(symlink(sieve_bclink_name, sieve_default)) {
        if(errno != EEXIST) {
            syslog(LOG_WARNING, "autocreate_sieve: problem making the default link (symlink: %m).");
            /* Lets delete the files */
            unlink(sieve_script_name);
            unlink(sieve_bcscript_name);
        }
    }

    /*
     * If everything has succeeded AND we have compiled the script AND we have requested
     * to generate the global script so that it is not compiled each time then we create it.
     */
    if(do_compile &&
          config_getswitch(IMAPOPT_AUTOCREATE_SIEVE_SCRIPT_COMPILE)) {

        if(!compiled_source_script) {
            syslog(LOG_WARNING, "autocreate_sieve: To save a compiled sieve script, autocreate_sieve_compiledscript must have been defined in imapd.conf");
            return 0;
        }

        if(snprintf(sieve_tmpname, MAX_FILENAME, "%s.NEW", compiled_source_script) >= MAX_FILENAME)
            return 0;

        /*
         * Copy everything from the newly created bc sieve sieve script.
         */
        if((in_fd = open(sieve_bcscript_name, O_RDONLY))<0) {
            return 0;
        }

        if((out_fd = open(sieve_tmpname, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) {
            if(errno == EEXIST) {
               /* Someone is already doing this so just bail out. */
               syslog(LOG_WARNING, "autocreate_sieve: %s already exists. Some other instance processing it, or it is left over", sieve_tmpname);
                close(in_fd);
                return 0;
            } else if (errno == EACCES) {
                syslog(LOG_WARNING,"autocreate_sieve: No access to create file %s. Check permissions",sieve_tmpname);
                close(in_fd);
                return 0;
            } else {
                syslog(LOG_WARNING,"autocreate_sieve: Unable to create %s: %m",sieve_tmpname);
                close(in_fd);
                return 0;
            }
        }

        while((r = read(in_fd, buf, sizeof(buf))) > 0) {
            if((k = write(out_fd,buf,r)) < 0) {
                syslog(LOG_WARNING, "autocreate_sieve: Error writing to file: %s: %m", sieve_tmpname);
                close(out_fd);
                close(in_fd);
                unlink(sieve_tmpname);
                return 0;
           }
        }

        if(r == 0 ) { /*EOF */
            xclose(out_fd);
            xclose(in_fd);
        } else if (r < 0) {
                syslog(LOG_WARNING, "autocreate_sieve: Error reading file: %s: %m", sieve_bcscript_name);
                xclose(out_fd);
                xclose(in_fd);
                unlink(sieve_tmpname);
                return 0;
        }

        /* Rename the temporary created sieve script to its final name. */
        if(rename(sieve_tmpname, compiled_source_script)) {
            if(errno != EEXIST) {
               unlink(sieve_tmpname);
               unlink(compiled_source_script);
        }
            return 0;
        }

        syslog(LOG_NOTICE, "autocreate_sieve: Compiled sieve script was successfully saved in %s", compiled_source_script);
    }

    return 0;
}