Esempio n. 1
0
int cmd_havespace(struct protstream *conn, mystring_t *sieve_name, unsigned long num)
{
    int result;
    int maxscripts;
    unsigned long maxscriptsize;

    result = scriptname_valid(sieve_name);
    if (result!=TIMSIEVE_OK)
    {
	prot_printf(conn,"NO \"Invalid script name\"\r\n");
	return result;
    }

    /* see if the size of the script is too big */
    maxscriptsize = config_getint(IMAPOPT_SIEVE_MAXSCRIPTSIZE);
    maxscriptsize *= 1024;

    if (num > maxscriptsize)
    {
	prot_printf(conn,
		    "NO (\"QUOTA\") \"Script size is too large. "
		    "Max script size is %ld bytes\"\r\n",
		    maxscriptsize);
	return TIMSIEVE_FAIL;
    }

    /* see if this would put the user over quota */
    maxscripts = config_getint(IMAPOPT_SIEVE_MAXSCRIPTS);

    if (countscripts(string_DATAPTR(sieve_name))+1 > maxscripts)
    {
	prot_printf(conn,
		    "NO (\"QUOTA\") \"You are only allowed %d scripts on this server\"\r\n",
		    maxscripts);
	return TIMSIEVE_FAIL;
    }


    prot_printf(conn,"OK\r\n");
    return TIMSIEVE_OK;
}
Esempio n. 2
0
/* save name as a sieve script */
int putscript(struct protstream *conn, mystring_t *name, mystring_t *data,
	      int verify_only)
{
  FILE *stream;
  char *dataptr;
  char *errstr;
  int lup;
  int result;
  char path[1024], p2[1024];
  char bc_path[1024], bc_p2[1024];
  int maxscripts;
  sieve_script_t *s;

  result = scriptname_valid(name);
  if (result!=TIMSIEVE_OK)
  {
      prot_printf(conn,"NO \"Invalid script name\"\r\n");
      return result;
  }

  if (verify_only)
      stream = tmpfile();

  else {
      /* see if this would put the user over quota */
      maxscripts = config_getint(IMAPOPT_SIEVE_MAXSCRIPTS);

      if (countscripts(string_DATAPTR(name))+1 > maxscripts)
      {
	  prot_printf(conn,
		      "NO (\"QUOTA\") \"You are only allowed %d scripts on this server\"\r\n",
		      maxscripts);
	  return TIMSIEVE_FAIL;
      }

      snprintf(path, 1023, "%s.script.NEW", string_DATAPTR(name));

      stream = fopen(path, "w+");
  }


  if (stream == NULL) {
      prot_printf(conn, "NO \"Unable to open script for writing (%s)\"\r\n",
		  path);
      return TIMSIEVE_NOEXIST;
  }

  dataptr = string_DATAPTR(data);

  for (lup=0;lup<= data->len / BLOCKSIZE; lup++) {
      int amount = BLOCKSIZE;

      if (lup*BLOCKSIZE+BLOCKSIZE > data->len)
	  amount=data->len % BLOCKSIZE;

      fwrite(dataptr, 1, amount, stream);
      
      dataptr += amount;
  }

  /* let's make sure this is a valid script
     (no parse errors)
  */
  result = is_script_parsable(stream, &errstr, &s);

  if (result != TIMSIEVE_OK) {
      if (errstr && *errstr) { 
	  prot_printf(conn, "NO {" SIZE_T_FMT "}\r\n%s\r\n",
		      strlen(errstr), errstr);
	  free(errstr);
      } else {
	  if (errstr) free(errstr);
	  prot_printf(conn, "NO \"parse failed\"\r\n");
      }
      fclose(stream);
      unlink(path);
      return result;
  }

  fflush(stream);
  fclose(stream);
  
  if (!verify_only) {
      int fd;
      bytecode_info_t *bc;
      
      /* Now, generate the bytecode */
      if(sieve_generate_bytecode(&bc, s) == -1) {
	  unlink(path);
	  sieve_script_free(&s);
	  prot_printf(conn, "NO \"bytecode generate failed\"\r\n");
	  return TIMSIEVE_FAIL;
      }

      /* Now, open the new file */
      snprintf(bc_path, 1023, "%s.bc.NEW", string_DATAPTR(name));
      fd = open(bc_path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
      if(fd < 0) {
	  unlink(path);
	  sieve_free_bytecode(&bc);
	  sieve_script_free(&s);
	  prot_printf(conn, "NO \"couldn't open bytecode file\"\r\n");
	  return TIMSIEVE_FAIL;
      }
	  
      /* Now, emit the bytecode */
      if(sieve_emit_bytecode(fd, bc) == -1) {
	  close(fd);
	  unlink(path);
	  unlink(bc_path);
	  sieve_free_bytecode(&bc);
	  sieve_script_free(&s);
	  prot_printf(conn, "NO \"bytecode emit failed\"\r\n");
	  return TIMSIEVE_FAIL;
      }

      sieve_free_bytecode(&bc);
      sieve_script_free(&s);

      close(fd);

      /* Now, rename! */
      snprintf(p2, 1023, "%s.script", string_DATAPTR(name));
      snprintf(bc_p2, 1023, "%s.bc", string_DATAPTR(name));
      rename(path, p2);
      rename(bc_path, bc_p2);

  }

  prot_printf(conn, "OK\r\n");
  sync_log_sieve(sieved_userid);

  return TIMSIEVE_OK;
}
Esempio n. 3
0
/* save name as a sieve script */
int putscript(struct protstream *conn, const struct buf *name,
              const struct buf *data, int verify_only)
{
  FILE *stream;
  const char *dataptr;
  char *errstr;
  unsigned int i;
  int last_was_r = 0;
  int result;
  char path[1024], p2[1024];
  char bc_path[1024], bc_p2[1024];
  int maxscripts;
  sieve_script_t *s;

  result = scriptname_valid(name);
  if (result!=TIMSIEVE_OK)
  {
      prot_printf(conn,"NO \"Invalid script name\"\r\n");
      return result;
  }

  if (verify_only)
      stream = tmpfile();

  else {
      /* see if this would put the user over quota */
      maxscripts = config_getint(IMAPOPT_SIEVE_MAXSCRIPTS);

      if (countscripts(name->s)+1 > maxscripts)
      {
          prot_printf(conn,
                      "NO (QUOTA/MAXSCRIPTS) \"You are only allowed %d scripts on this server\"\r\n",
                      maxscripts);
          return TIMSIEVE_FAIL;
      }

      snprintf(path, 1023, "%s.script.NEW", name->s);

      stream = fopen(path, "w+");
  }


  if (stream == NULL) {
      prot_printf(conn, "NO \"Unable to open script for writing (%s)\"\r\n",
                  path);
      return TIMSIEVE_NOEXIST;
  }

  dataptr = data->s;

  /* copy data to file - replacing any lone \r or \n with the
   * \r\n pair so notify messages are SMTP compatible */
  for (i = 0; i < data->len; i++) {
      if (last_was_r) {
          if (dataptr[i] != '\n')
              putc('\n', stream);
      }
      else {
          if (dataptr[i] == '\n')
              putc('\r', stream);
      }
      putc(dataptr[i], stream);
      last_was_r = (dataptr[i] == '\r');
  }
  if (last_was_r)
      putc('\n', stream);


  /* let's make sure this is a valid script
     (no parse errors)
  */
  result = is_script_parsable(stream, &errstr, &s);

  if (result != TIMSIEVE_OK) {
      if (errstr && *errstr) {
          prot_printf(conn, "NO ");
          prot_printstring(conn, errstr);
          prot_printf(conn, "\r\n");
      } else {
          prot_printf(conn, "NO \"parse failed\"\r\n");
      }
      free(errstr);
      fclose(stream);
      unlink(path);
      return result;
  }

  fflush(stream);
  fclose(stream);

  if (!verify_only) {
      int fd;
      bytecode_info_t *bc;

      /* Now, generate the bytecode */
      if(sieve_generate_bytecode(&bc, s) == -1) {
          unlink(path);
          sieve_script_free(&s);
          prot_printf(conn, "NO \"bytecode generate failed\"\r\n");
          return TIMSIEVE_FAIL;
      }

      /* Now, open the new file */
      snprintf(bc_path, 1023, "%s.bc.NEW", name->s);
      fd = open(bc_path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
      if(fd < 0) {
          unlink(path);
          sieve_free_bytecode(&bc);
          sieve_script_free(&s);
          prot_printf(conn, "NO \"couldn't open bytecode file\"\r\n");
          return TIMSIEVE_FAIL;
      }

      /* Now, emit the bytecode */
      if(sieve_emit_bytecode(fd, bc) == -1) {
          close(fd);
          unlink(path);
          unlink(bc_path);
          sieve_free_bytecode(&bc);
          sieve_script_free(&s);
          prot_printf(conn, "NO \"bytecode emit failed\"\r\n");
          return TIMSIEVE_FAIL;
      }

      sieve_free_bytecode(&bc);
      sieve_script_free(&s);

      close(fd);

      /* Now, rename! */
      snprintf(p2, 1023, "%s.script", name->s);
      snprintf(bc_p2, 1023, "%s.bc", name->s);
      rename(path, p2);
      rename(bc_path, bc_p2);

  }

  prot_printf(conn, "OK\r\n");
  sync_log_sieve(sieved_userid);

  return TIMSIEVE_OK;
}