Esempio n. 1
0
int
main (int argc, char *argv[])
{
  mu_locker_t locker = 0;
  int err = 0;
  pid_t usergid = getgid ();
  pid_t mailgid = getegid ();

  /* Native Language Support */
  MU_APP_INIT_NLS ();

  /* Drop permissions during argument parsing. */

  if (setegid (usergid) < 0)
    return MU_DL_EX_ERROR;

  argp_err_exit_status = MU_DL_EX_ERROR;
  
  mu_argp_init (NULL, NULL);
  if (mu_app_init (&argp, dotlock_capa, dotlock_cfg_param, 
		   argc, argv, 0, NULL, NULL))
    exit (1);

  if (force)
    {
      force *= 60;
      flags |= MU_LOCKER_TIME;
    }

  if (retries != 0)
    flags |= MU_LOCKER_RETRY;
  
  if ((err = mu_locker_create (&locker, file, flags)))
    {
      if (debug)
	mu_diag_funcall (MU_DIAG_ERROR, "mu_locker_create", NULL, err);
      return MU_DL_EX_ERROR;
    }

  if (force != 0)
    mu_locker_set_expire_time (locker, force);

  if (retries != 0)
    mu_locker_set_retries (locker, retries);

  if (setegid (mailgid) < 0)
    return MU_DL_EX_ERROR;

  if (unlock)
    err = mu_locker_remove_lock (locker);
  else
    err = mu_locker_lock (locker);

  setegid(usergid);

  mu_locker_destroy (&locker);

  if (debug && err)
    mu_error (unlock ? _("unlocking the file %s failed: %s") :
	      _("locking the file %s failed: %s"),
	      file, mu_strerror (err));

  switch (err)
    {
    case 0:
      err = MU_DL_EX_OK;
      break;
    case EPERM:
      err = MU_DL_EX_PERM;
      break;
    case MU_ERR_LOCK_NOT_HELD:
      err = MU_DL_EX_NEXIST;
      break;
    case MU_ERR_LOCK_CONFLICT:
      err = MU_DL_EX_EXIST;
      break;
    default:
      err = MU_DL_EX_ERROR;
      break;
    }

  return err;
}
Esempio n. 2
0
/* Check and update the vacation database. Return 0 if the mail should
   be answered, 0 if it should not, and throw exception if an error
   occurs. */
static int
check_db (mu_sieve_machine_t mach, mu_list_t tags, char *from)
{
  mu_property_t prop;
  char *file;
  mu_sieve_value_t *arg;
  unsigned int days;
  int rc;
  mu_stream_t str;
  mu_locker_t locker;
  
  if (mu_sieve_tag_lookup (tags, "days", &arg))
    {
      days = arg->v.number;
      if (days > DAYS_MAX)
	days = DAYS_MAX;
    }
  else
    days = DAYS_DEFAULT;

  file = mu_tilde_expansion ("~/.vacation", MU_HIERARCHY_DELIMITER, NULL);
  if (!file)
    {
      mu_sieve_error (mach, _("%lu: cannot build db file name"),
		      (unsigned long) mu_sieve_get_message_num (mach));
      mu_sieve_abort (mach);
    }

  rc = mu_locker_create (&locker, file, 0);
  if (rc)
    {
      mu_sieve_error (mach, _("%lu: cannot lock %s: %s"),
		      (unsigned long) mu_sieve_get_message_num (mach),
		      file,
		      mu_strerror (rc));
      free (file);
      mu_sieve_abort (mach);
    }

  rc = mu_file_stream_create (&str, file, MU_STREAM_RDWR|MU_STREAM_CREAT);
  if (rc)
    {
      mu_sieve_error (mach, "%lu: mu_file_stream_create(%s): %s",
		      (unsigned long) mu_sieve_get_message_num (mach),
		      file,
		      mu_strerror (rc));
      mu_locker_destroy (&locker);
      free (file);
      mu_sieve_abort (mach);
    }
  
  free (file);

  rc = mu_property_create_init (&prop, mu_assoc_property_init, str);
  if (rc)
    {
      mu_sieve_error (mach, "%lu: mu_property_create_init: %s",
		      (unsigned long) mu_sieve_get_message_num (mach),
		      mu_strerror (rc));
      mu_locker_destroy (&locker);
      mu_sieve_abort (mach);
    }

  rc = mu_locker_lock (locker);
  if (rc)
    {
      mu_sieve_error (mach, "%lu: cannot lock vacation database: %s",
		      (unsigned long) mu_sieve_get_message_num (mach),
		      mu_strerror (rc));
      mu_property_destroy (&prop);
      mu_sieve_abort (mach);
    }

  rc = test_and_update_prop (prop, from, time (NULL), days, mach);
  mu_property_destroy (&prop);
  mu_locker_unlock (locker);
  mu_locker_destroy (&locker);
  if (rc == -1)
    mu_sieve_abort (mach);

  return rc;
}
Esempio n. 3
0
int
mu_locker_create (mu_locker_t *plocker, const char *fname, int flags)
{
  unsigned type;
  mu_locker_t l;
  char *filename;
  int err = 0;

  if (plocker == NULL)
    return MU_ERR_OUT_PTR_NULL;

  if (fname == NULL)
    return EINVAL;

  if ((err = mu_unroll_symlink (fname, &filename)))
    {
      if (err == ENOENT)
	{
	  /* Try the directory part.  If it unrolls successfully (i.e.
	     all its components exist), tuck the filename part back in
	     the resulting path and use it as the lock filename. */
	  char *p, *new_name, *tmp = strdup (fname);
	  if (!tmp)
	    return ENOMEM;
	  p = strrchr (tmp, '/');
	  if (!p)
	    filename = tmp;
	  else
	    {
	      *p = 0;
	      err = mu_unroll_symlink (tmp, &filename);
	      if (err)
		{
		  free (tmp);
		  return err;
		}

	      new_name = mu_make_file_name_suf (filename, p + 1, NULL);
	      free (tmp);
	      free (filename);
	      if (!new_name)
		return ENOMEM;
	      filename = new_name;
	    }
	}
      else
	return err;
    }

  l = calloc (1, sizeof (*l));

  if (l == NULL)
    {
      free (filename);
      return ENOMEM;
    }
  
  l->file = filename;
  
  if (l->file == NULL)
    {
      free (l);
      return ENOMEM;
    }

  if (strcmp (filename, "/dev/null") == 0)
    l->flags = MU_LOCKER_NULL;
  else if (flags)
    l->flags = flags;
  else
    l->flags = mu_locker_default_flags;

  l->expire_time = mu_locker_expire_timeout;
  l->retries = mu_locker_retry_count;
  l->retry_sleep = mu_locker_retry_timeout;

  type = MU_LOCKER_TYPE (l);

  if (type >= MU_LOCKER_NTYPES)
    {
      free (l->file);
      return EINVAL;
    }

  /* Initialize locker-type-specific data */
  err = locker_tab[type].init ? locker_tab[type].init (l) : 0;
  if (err)
    {
      mu_locker_destroy (&l);
      return err;
    }

  *plocker = l;

  return 0;
}