Пример #1
0
static int writemmsdata(Octstr *ms, char *df, char subdir[], char *mms_queuedir)
{
     Octstr *dfname;
     int fd, n, res = 0;

     
     dfname = octstr_format("%s/%s%s", mms_queuedir, subdir, df);

     fd = open(octstr_get_cstr(dfname), 
	       O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);	  
     if (fd < 0) {
	  error(0, "mms_queueadd: Failed to open data file %s: error = %s\n",
		octstr_get_cstr(dfname), strerror(errno));
	  res = -1;
	  goto done;
     }

     n = octstr_write_to_socket(fd, ms);
     unlock_and_close(fd);
	  
     if (n != 0) {
	  error(0, "mms_queueadd: Failed to write data file %s: error = %s\n",
		octstr_get_cstr(dfname), strerror(errno));
	  unlink(octstr_get_cstr(dfname));
	  res = -1;
     }

 done:
     octstr_destroy(dfname);
     return res;
}
Пример #2
0
static int free_envelope(MmsEnvelope *e, int removefromqueue)
{
	struct qfile_t *qfs;
	if (e == NULL)
		return 0;
	qfs = e->qfs_data;

	if (removefromqueue) {
		/* Remove qf file */
		char fname[2*QFNAMEMAX];
		snprintf(fname, -1 + sizeof fname, "%s/%s%s", qfs->dir, qfs->subdir,  qfs->name);
		debug("mms_queue.free_envelope",0,"free envelope: %s/%s%s", qfs->dir, qfs->subdir, qfs->name);
		unlink(fname);
		
		/* Remove df file */
		qfs->name[0] = MDF;
		snprintf(fname, -1 + sizeof fname, "%s/%s%s", qfs->dir, qfs->subdir, qfs->name);
		debug("mms_queue.free_envelope",0,"free envelope: %s/%s%s", qfs->dir, qfs->subdir, qfs->name);		
		unlink(fname);
	}
		
	unlock_and_close(qfs->fd); /* close and unlock now that we have deleted it. */
	mms_queue_free_envelope(e);

	return 0;
}
Пример #3
0
int mms_mmbox_count(char *mmbox_root, char *user,  unsigned long *msgcount, unsigned long *byte_count)
{

     int tmpfd = -1;
     FILE *fp = NULL;
     char linbuf[1024];
     int ret = -1;
     Octstr *home = user_mmbox_dir(mmbox_root,user);
     int ifd = -1;

     
     ifd = open_mmbox_index(octstr_get_cstr(home),1);
     
     if (ifd < 0) 
	  goto done;

     if ((tmpfd = dup(ifd)) < 0 || 
	 (fp = fdopen(tmpfd, "r")) == NULL) {
	  error(0, "mmbox.count: %s Failed to dup descriptor for index "
		"file, fp = %p: error = %s\n", octstr_get_cstr(home), 
		fp, strerror(errno));	  
	  goto done;
     }

     *msgcount = 0;
     *byte_count = 0;

     while (fgets(linbuf, sizeof linbuf, fp) != NULL) {
	  int size = 0;	 

	  sscanf(linbuf, "%*s %*s %d", &size);	  
	  ++*msgcount;
	  *byte_count = *byte_count + size;
     }     
     ret = 0;

 done:
     if (fp) 
	  unlock_and_fclose(fp);
     else if (tmpfd)
	  unlock_and_close(tmpfd);
     
     if (ifd > 0)
	  unlock_and_close(ifd);

     return ret;
}
Пример #4
0
int mms_mmbox_delmsg(char *mmbox_root, char *user, Octstr *msgref)
{
 
     Octstr *sdf = octstr_duplicate(msgref);
     Octstr *fname = NULL, *home = user_mmbox_dir(mmbox_root,user);
     Octstr *s = NULL;
     int res = -1;
     int ifd = -1, nifd;
     
     
     octstr_replace(sdf, octstr_imm("-"), octstr_imm("/"));

     if (!home)
	  goto done;

     ifd = open_mmbox_index(octstr_get_cstr(home),1);
     
     if (ifd < 0) 
	  goto done;

     fname = octstr_format("%S/%S", home, sdf);

     if ((nifd = update_mmbox_index(ifd, octstr_get_cstr(home), ITEM_DEL, sdf, NULL, NULL,0)) < 0) {

	  error(0, "mmbox.del: failed to update index file, home is %s!",
		octstr_get_cstr(home));
	  goto done;
     }     
     unlink(octstr_get_cstr(fname));
     ifd = nifd;
     
     res = 0;
 done:
     if (ifd > 0) 
	  unlock_and_close(ifd);

     if (fname)
	  octstr_destroy(fname);

     if (s)
	  octstr_destroy(s);
     if (home) 
	  octstr_destroy(home);

     return 0;
}
Пример #5
0
MmsMsg *mms_mmbox_get(char *mmbox_root, char *user,  Octstr *msgref, unsigned long *msize)
{
     Octstr *sdf = octstr_duplicate(msgref);
     Octstr *fname = NULL, *home = user_mmbox_dir(mmbox_root,user);
     Octstr *s = NULL;
     int ifd = -1;
     MmsMsg *m = NULL;
     
     octstr_replace(sdf, octstr_imm("-"), octstr_imm("/"));

     if (!home)
	  goto done;

     ifd = open_mmbox_index(octstr_get_cstr(home),1); /* Grab a lock on the index file. */
     
     if (ifd < 0) 
	  goto done;

     fname = octstr_format("%S/%S", home, sdf);
     s  = octstr_read_file(octstr_get_cstr(fname));
     
     if (s) {
	  if (msize) 
	       *msize = octstr_len(s);
	  m = mms_frombinary(s, octstr_imm("anon@anon"));     
     } else if (msize) 
	  *msize = 0;
 done:
     if (ifd > 0) 
	  unlock_and_close(ifd);

     if (fname)
	  octstr_destroy(fname);

     if (s)
	  octstr_destroy(s);
     if (home) 
	  octstr_destroy(home);

     return m;
     
}
Пример #6
0
/*
 * To prevent after board packed, and others did not update their list.
 * The ent could be wrong, and the user might update the wrong .DIR entry.
 */
int safely_read_dir(const char *direct, int opened_fd, int ent,
		const FILEHEADER *ofhr, FILEHEADER *nfhr)
{
	int fd, rtval = -1;

	if (opened_fd)
		fd = opened_fd;
	else
		fd = open_and_lock(direct);
	if (fd == -1)
		goto err_out;

	if (get_record_byfd(fd, nfhr, FH_SIZE, ent) == -1)
		goto out;

	if (nfhr->postno == ofhr->postno && !strcmp(nfhr->title, ofhr->title)) {
		/*
		 * The ent position should be correct,
		 * if postno and the title is the same.
		 */
		if (!(ofhr->accessed & FILE_DELE) &&
		    nfhr->accessed & FILE_DELE)
			goto out;
		rtval = 0;
		goto out;
	}

	/*
	 * Search for correct record if still there.
	 * This could spend some CPU/DISK time.
	 */
	/*
	 * FIXME: Just returning error for now.
	 */

out:
	if (!opened_fd)
		unlock_and_close(fd);
err_out:
	return rtval;
}
Пример #7
0
static int open_mmbox_index(char *mmbox_dir, int shouldblock)
{
     char fbuf[256];
     int i, fd;
     
     sprintf(fbuf, "%s/%s", mmbox_dir, IDXFILE);

     i = 0;
     do 	 
	  if ((fd = open(fbuf, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)) < 0) {
	       error(0, "Failed to open mmbox index file [%s], error: %s!",
		     fbuf, strerror(errno));
	       break;
	  }  else if (mm_lockfile(fd, fbuf, shouldblock) != 0) {	  
	       unlock_and_close(fd);
	       fd = -1;
	  }
     while (i++ < MAXTRIES && fd < 0);
     
     return fd;
}
Пример #8
0
/*
 * To prevent after board packed, and others did not update their list.
 * The ent could be wrong, and the user might update the wrong .DIR entry.
 */
int safely_substitute_dir(const char *direct, int opened_fd, int ent,
		const FILEHEADER *ofhr, FILEHEADER *nfhr,
		unsigned char mark_unread)
{
	int fd, rtval = -1;
	FILEHEADER tfhr;

	if (opened_fd)
		fd = opened_fd;
	else
		fd = open_and_lock(direct);
	if (fd == -1)
		goto err_out;

	if (safely_read_dir(NULL, fd, ent, ofhr, &tfhr))
		goto out;

	if (mark_unread) {
		nfhr->mtime = time(NULL);
		get_only_postno(direct, fd, nfhr);
	}
	if (substitute_record_byfd(fd, nfhr, FH_SIZE, ent))
		goto out;
	rtval = 0;

	/*
	 * Search for correct record if still there.
	 * This could spend some CPU/DISK time.
	 */
	/*
	 * FIXME: Just returning error for now.
	 */

out:
	if (!opened_fd)
		unlock_and_close(fd);
err_out:
	return rtval;
}
Пример #9
0
/* Makes a qf file in the queue directory. 
 * Makes several attempts then fails (returns -1) if it can't, fd otherwise
 * puts queue file name in qf (without directory name).
 * It is up to the caller to lock the file descriptor if needed.
 */
static int mkqf(char qf[QFNAMEMAX], char subdir[64], char *mms_queuedir)
{
     Octstr *xqf = NULL;
     char *ctmp;
     int i = 0, fd = -1;
     static int ect;
     
     if (!mms_queuedir)
	  gw_panic(0, "Queue directory passed as null!");
     
     /* First we decide the directory into which it goes... */
     if ((i = random() % 3) == 0) /* toplevel. */
	  subdir[0] = 0; 
     else if (i == 1)  /* one in */
	  sprintf(subdir, "%c/", _TT[random() % _TTSIZE]);
     else { /* two in. */
	  char csubdir[QFNAMEMAX];
	  sprintf(subdir, "%c/%c%c/", 
		  _TT[random() % _TTSIZE],
		  _TT[random() % _TTSIZE],
		  _TT[random() % _TTSIZE]);
	  
	  sprintf(csubdir, "%s/%s", mms_queuedir, subdir);
     	  if (mkdir(csubdir, 
		    S_IRWXU|S_IRWXG) < 0 && 
	      errno != EEXIST) {
	       error(0, "make queue file: Failed to create dir %s - %s!",
		     csubdir, strerror(errno));
	       return -1;
	  }
     }

     do {
	  Octstr *tmp;
	  xqf = octstr_format("%cf%ld.%d.x%d.%ld", 
			       MQF, 
			      (long)time(NULL) % 10000, 
			      (++ect % 10000), getpid()%1000, random() % 100);
	  tmp = octstr_format("%.64s/%s%S", mms_queuedir, subdir, xqf);
	  
	  ctmp = octstr_get_cstr(tmp);
	  fd = open(ctmp, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
	  if (fd >= 0 && 
	      mm_lockfile(fd,ctmp,1) != 0) {
	       unlink(ctmp);
	       unlock_and_close(fd);
	       fd = -1;
	  }
	  octstr_destroy(tmp);
	  if (fd >= 0) 
	       break;
	  

	  octstr_destroy(xqf);
	  xqf = NULL;	  
     } while (i++ < MAXTRIES);

     if (fd >= 0)
	  strncpy(qf, octstr_get_cstr(xqf), QFNAMEMAX); 
     
     if (xqf) octstr_destroy(xqf);


     return fd;
}
Пример #10
0
/* 
 * Attempt to read an envelope from queue file:
 * - opens and locks the file. 
 * - if the lock succeeds, check that file hasn't changed since opening. If it has
 *   return NULL (i.e. file is being processed elsewhere -- race condition), otherwise read it.
 * - If should block is 1, then does a potentially blocking attempt to lock the file.
 */
static MmsEnvelope *mms_queue_readenvelope(char *qf, char *mms_queuedir, int shouldblock)
{
     Octstr *fname;
     int fd;
     Octstr *qdata, *s;
     ParseContext *p;
     MmsEnvelope *e;
     int okfile = 0;
     char subdir[64];
     char realqf[QFNAMEMAX];
     char xqf[QFNAMEMAX+64];
     struct qfile_t *qfs;
     
     get_subdir(qf, subdir, realqf); /* break it down... */

     fname = octstr_format( "%.128s/%s%s", mms_queuedir, subdir, realqf);
     
     strncpy(xqf, octstr_get_cstr(fname), sizeof xqf);
     
#ifdef SunOS
     if ((fd = open(octstr_get_cstr(fname), O_RDWR)) < 0) {
#else
     if ((fd = open(octstr_get_cstr(fname), O_RDONLY)) < 0) {
#endif
		debug("",0,"mms_queue_readenvelope: could not open file %s", octstr_get_cstr(fname));
	  octstr_destroy(fname);
	  return NULL;
     } else if (mm_lockfile(fd, octstr_get_cstr(fname), shouldblock) != 0) {
		debug("",0,"mms_queue_readenvelope: could not lock file %s", octstr_get_cstr(fname));
	  unlock_and_close(fd);
	  octstr_destroy(fname);
	  return NULL;
     }

	debug("",0,"locked and opened file: %s", octstr_get_cstr(fname));
     
     e = mms_queue_create_envelope(NULL, NULL, 
				   NULL, 
				   NULL, NULL, 
				   0, 0, 
				   NULL, 
				   NULL, NULL, 
				   NULL, NULL, 
				   NULL,
				   0, 
				   NULL, 
				   NULL,
				   qf,
				   NULL,
				   sizeof (struct qfile_t), NULL);
     qfs = e->qfs_data;
     
     qfs->fd = fd;
     strncpy(qfs->name, realqf, sizeof qfs->name);
     strncpy(qfs->subdir, subdir, sizeof qfs->subdir);
     strncpy(qfs->dir, mms_queuedir, sizeof qfs->dir);

     qdata = octstr_read_file(octstr_get_cstr(fname));
     octstr_destroy(fname);
     if (qdata == NULL)
	  qdata = octstr_imm("");
     p = parse_context_create(qdata);
     
     for (s = parse_get_line(p); s;  
	  s = parse_get_line(p)) {
	  char *line = octstr_get_cstr(s);
	  int ch = line[0];
	  char *res = line + 1;
	  char *ptmp;

	  switch (ch) {
	       Octstr *t;
	       MmsEnvelopeTo *to;
	  case 'T':
	       t = octstr_create(res);
	       e->msgtype = mms_string_to_message_type(t);
	       octstr_destroy(t);
	       if (e->msgtype < 0) {
		    e->msgtype = 0;
		    error(0, "mms_queueread: Unknown MMS message type (%s) in file %s, skipped!\n",
			  res, xqf);
	       }
	       break;
	  case 'I':
	       e->msgId = octstr_create(res);	       
	       break;
	  case 'i':
	       strncpy(e->src_interface, res, sizeof e->src_interface);
	       break;
	  case 'F':
	       e->from = octstr_create(res);
	       if (mms_validate_address(e->from) != 0) {
		    warning(0, "mms_queueread: Mal-formed address [%s] in file %s! "
			    "Attempting fixup.", res, xqf);
		    _mms_fixup_address(&e->from, NULL, NULL, 1);
	       }
	       break;
	  case 'R':

	       t = octstr_create(res);
	       if (mms_validate_address(t) != 0) {
		    warning(0, "mms_queueread: Mal-formed address [%s] in file %s! " 
			    "Attempting fixup.", res, xqf);
		    _mms_fixup_address(&t, NULL, NULL, 1);
	       }
	       to = gw_malloc(sizeof *to);
	       to->rcpt = t;
	       to->process = 1;	       
	       gwlist_append(e->to, to);
	       break;
	  case 'C':
	       e->created = atol(res);
	       break;
	  case 'L':
	       e->lasttry = atol(res);
	       break;
	  case 'D':
	       e->sendt = atol(res);
	       break;
	  case 'X':
	       e->expiryt = atol(res);
	       break;
	  case 'N':
	       e->attempts = atol(res);
	       break;
	  case 'P':
	       e->fromproxy = octstr_create(res);
	       break;
	  case 'M':
	       e->mdata = octstr_create(res);
	       break;
	  case 'p':
	       e->viaproxy = octstr_create(res);
	       break;
	  case 'S':
	       e->msize = atol(res);
	    break;
	  case 's':
	       e->subject = octstr_create(res);
	       break;	
	  case 't':
	       e->token = octstr_create(res);
	       break;
	  case 'f':
	       e->lastaccess = atol(res);
	       break;
	  case 'b':
	       e->bill.billed = 1;
	       e->bill.amt = atof(res);
	    break;
	  case 'r':
	       e->dlr = 1;
	       break;
	  case 'V':
	       e->vaspid = octstr_create(res);
	       break;
	  case 'v':
	       e->vasid = octstr_create(res);
	       break;

	  case 'U':
	       e->url1 = octstr_create(res);
	       break;

	  case 'u':
	       e->url2 = octstr_create(res);
	       break;
	  case 'H':
	       if (e->hdrs == NULL)
		    e->hdrs = http_create_empty_headers();
	       if ((ptmp = index(res, ':')) == NULL)
		    error(0, "Incorrectly formatted line %s in queue file %s!",
			  line, xqf);
	       else {
		    char *value = ptmp + 1;
		    char hname[512];
		    int xlen = (ptmp - res < sizeof hname) ? ptmp - res : -1 + sizeof hname;
		    strncpy(hname, res, xlen);
		    hname[xlen] = 0; /* terminate it. */
		    http_header_add(e->hdrs, hname, value);
	       }
	       break;
	  case '.':
	       okfile = 1;
	       break;
	  default:
	       error(0, "Unknown QF header %c in file %s!", ch, xqf);
	       break;
	  }
	  octstr_destroy(s);
	  if (okfile) 
	       break; /* We are done. */
     }
     parse_context_destroy(p);
     octstr_destroy(qdata);

     /* We should properly validate the queue file here. */
     if (!okfile) {
	  free_envelope(e,0);
	  e = NULL;
	  error(0, "Corrupt queue control file: %s",  xqf);
     }
     return e;     
}

/* Updates envelope to queue file:
 * - opens temp file
 * - writes output to temp file, if not new else writes directly.
 * - renames temp file to queue file (if not new)
 * This function doesn't check that this envelope is useless (i.e. no recipients)
 * - If function returns -1, caller should check errno for error.
 */
static int writeenvelope(MmsEnvelope *e, int newenv)
{
     Octstr *tfname = NULL;
     char *s;
     char buf[512];
     int fd;
     int i, n;
     int res = 0;
     struct qfile_t *qfs = e ? e->qfs_data : NULL;
     
     gw_assert(e);
     
     if (newenv)
	  fd = qfs->fd;
     else {
	  tfname = octstr_format( 
	       "%s/%s%c%s.%d", qfs->dir, qfs->subdir,
	       MTF, qfs->name + 1, random());
	  fd = open(octstr_get_cstr(tfname),
		    O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
	  if (fd < 0 ) {
	       error(0, "mms_queueadd: Failed to open temp file %s: error = %s\n",
		     octstr_get_cstr(tfname), strerror(errno));
	       res = -1;
	       goto done;
	  } else if (mm_lockfile(fd, octstr_get_cstr(tfname), 0) != 0) { /* Lock it. */
	       error(0, "mms_queueadd: Failed lock  temp file %s: error = %s\n", 
		     octstr_get_cstr(tfname), strerror(errno));
	       res = -1;	  
	       goto done;
	  }
     }
	  
     /* Write out. */

     s = (char *)mms_message_type_to_cstr(e->msgtype);
     if (!s) {
	  error(0, "mms_queuewrite: Unknown MMS message type %d! Skipped\n", e->msgtype);
	  s = "";
     }
     _putline(fd, "T", s);
     
     if (e->msgId) 
	  _putline(fd, "I", octstr_get_cstr(e->msgId));

     if (e->src_interface[0])
	  _putline(fd, "i", e->src_interface);
     
     if (e->from)
	  _putline(fd, "F", octstr_get_cstr(e->from));

     if (e->to)
	  n = gwlist_len(e->to);
     else
	  n = 0;

     for (i = 0; i < n; i++) {
	  MmsEnvelopeTo *to = gwlist_get(e->to, i);
	  
	  if (to->process)	       
	       _putline(fd, "R", octstr_get_cstr(to->rcpt));
     }

     /* Output headers if any. */
     n = (e->hdrs) ? gwlist_len(e->hdrs) : 0;
     for (i = 0; i < n; i++) {
	  Octstr *h = NULL, *v = NULL;

	  http_header_get(e->hdrs, i, &h, &v);
	  if (h && v) {
	       Octstr *x = octstr_format("%s:%s", octstr_get_cstr(h), 
					 octstr_get_cstr(v));
	       _putline(fd, "H", octstr_get_cstr(x));
	       octstr_destroy(x);	       
	  }
	  if (h) octstr_destroy(h);
	  if (v) octstr_destroy(v);

     }

     sprintf(buf, "%ld", e->created);
     _putline(fd, "C", buf);

     if (e->lasttry) {
	  sprintf(buf, "%ld", e->lasttry);
	  _putline(fd, "L", buf);
     }

     if (e->sendt) {
	  sprintf(buf, "%ld", e->sendt);
	  _putline(fd, "D", buf);
     }

     if (e->expiryt) {
	  sprintf(buf, "%ld", e->expiryt);
	  _putline(fd, "X", buf);
     }

     if (e->attempts) {
	  sprintf(buf, "%ld", e->attempts);
	  _putline(fd, "N", buf);
     }

     if (e->lastaccess) {
	  sprintf(buf, "%ld", e->lastaccess);
	  _putline(fd, "f", buf);
     }

     sprintf(buf, "%ld", e->msize);
     _putline(fd, "S", buf);


     if (e->fromproxy) 
	  _putline(fd, "P", octstr_get_cstr(e->fromproxy));


     if (e->mdata) 
	  _putline(fd, "M", octstr_get_cstr(e->mdata));

     if (e->subject)
	  _putline(fd, "s", octstr_get_cstr(e->subject));
     

     if (e->viaproxy) 
	  _putline(fd, "p", octstr_get_cstr(e->viaproxy));

     if (e->token) 
	  _putline(fd, "t", octstr_get_cstr(e->token));
     

      if (e->vaspid) 
	  _putline(fd, "V", octstr_get_cstr(e->vaspid));
     
      if (e->vasid) 
	  _putline(fd, "v", octstr_get_cstr(e->vasid));
     
      if (e->url1) 
	  _putline(fd, "U", octstr_get_cstr(e->url1));

      if (e->url2) 
	  _putline(fd, "u", octstr_get_cstr(e->url2));

     if (e->dlr) 
	  _putline(fd, "r", "Yes");

     if (e->bill.billed) {
	  sprintf(buf, "%.3f", e->bill.amt);
	  _putline(fd,"b", buf);
     }

     _putline(fd, "", ".");

     fsync(fd); /* Sync data. */
     
     if (!newenv) { /* An update */
	  Octstr *qfname;
	 
	  qfname = octstr_format("%s/%s%s", qfs->dir, qfs->subdir, qfs->name);
	
	  if (rename(octstr_get_cstr(tfname), octstr_get_cstr(qfname)) < 0) {
	       error(0, "mms_queuewrite: Failed to rename %s to %s: error = %s\n", 
		     octstr_get_cstr(qfname), octstr_get_cstr(tfname), strerror(errno));

	       unlock_and_close(fd); /* Close new one, keep old one. */
		   res = -1;
	  } else { /* On success, new descriptor replaces old one and we close old one. */
	       unlock_and_close(qfs->fd);
	       qfs->fd = fd;
	  }
	  octstr_destroy(qfname);
     }

 done:
     octstr_destroy(tfname);
     return res;
}
Пример #11
0
List *mms_mmbox_search(char *mmbox_root, char *user,
		       List *state, List *flag_cmds, int start, int limit, 
		       List *msgrefs)
{
     int tmpfd = -1;
     FILE *fp = NULL;
     char linbuf[1024];

     Octstr *home = user_mmbox_dir(mmbox_root,user);
     List *flags = NULL;
     List *dflist = NULL;

     int ifd = -1;
     int ct;
     
     ifd = open_mmbox_index(octstr_get_cstr(home),1);
     
     if (ifd < 0) 
	  goto done;

     if ((tmpfd = dup(ifd)) < 0 || 
	 (fp = fdopen(tmpfd, "r")) == NULL) {
	  error(0, "mmbox.search_index: %s Failed to dup descriptor for index "
		"file, fp = %p: error = %s\n", octstr_get_cstr(home), 
		fp, strerror(errno));	  
	  goto done;
     }

     flags = make_mm_flags(NULL, flag_cmds);
     
     ct = 1;
     dflist = gwlist_create();
     while (fgets(linbuf, sizeof linbuf, fp) != NULL) {
	  char idx[128], xstate[32];
	  List *xflags = NULL;
	  int i, size;

	  int match = (!state && (!msgrefs || gwlist_len(msgrefs) == 0) && (!xflags || gwlist_len(xflags) == 0));
	  
	  sscanf(linbuf, "%s %s %d%n", idx, xstate, &size, &i);
	  
	  /* search: by id list if given, by  states if given, by flags if given */
	  if (!match && state && gwlist_search(state, xstate, 
				   (gwlist_item_matches_t *)_x_octstr_str_compare) != NULL) 
	       match = 1;
	  
	  /* For the rest we only match if nothing else matched. Save time */
	  replace_slash(idx);
	  if (!match && msgrefs &&  	       
	      gwlist_search(msgrefs, idx, 
			  (gwlist_item_matches_t *)_x_octstr_str_compare) != NULL)
	       match = 1;
	  
	  if (!match &&
	      flag_cmds  &&
	       ((xflags = parse_string_list(linbuf + i)) != NULL && 
		gwlist_search(xflags, flags, (gwlist_item_matches_t *)string_in_list) != NULL))
	       match = 1;

	  if (match && ct >= start && gwlist_len(dflist) <= limit) {
		    Octstr *x = octstr_create(idx);
		    /* octstr_replace(x, octstr_imm("/"), octstr_imm("-")); */
		    gwlist_append(dflist, x);	       
	  }
	  ct++;
	  if (xflags)
	       gwlist_destroy(xflags, (gwlist_item_destructor_t *)octstr_destroy);     	  
     }     

 done:
     if (fp) 
	  unlock_and_fclose(fp);
     else if (tmpfd)
	  unlock_and_close(tmpfd);
     
     if (ifd > 0)
	  unlock_and_close(ifd);

     if (flags)
	  gwlist_destroy(flags, (gwlist_item_destructor_t *)octstr_destroy);     

     if (home) 
	  octstr_destroy(home);

     return dflist;
}
Пример #12
0
int mms_mmbox_modmsg(char *mmbox_root, char *user, Octstr *msgref, 
		      Octstr *state, List *flag_cmds)
{
     Octstr *sdf = octstr_duplicate(msgref);
     Octstr *fname = NULL, *ftmp = NULL; 
     Octstr *home = user_mmbox_dir(mmbox_root,user);
     Octstr *s = NULL;
     List  *flags = NULL;
     Octstr *nstate = NULL;
     
     int ifd = -1, nifd, tmpfd = -1;
     MmsMsg *m  = NULL;
     int res = -1;
     int msize;
     
     octstr_replace(sdf, octstr_imm("-"), octstr_imm("/"));

     if (!home)
	  goto done;

     ifd = open_mmbox_index(octstr_get_cstr(home),1);
     
     if (ifd < 0) 
	  goto done;

     fname = octstr_format("%S/%S", home, sdf);
     s  = octstr_read_file(octstr_get_cstr(fname));
     
     if ( s == NULL || octstr_len(s) == 0) {
	  error(0, "mmbox.mod: failed to read data file [%s] - %s!",
		octstr_get_cstr(fname), strerror(errno));
	  goto done;
     }
     
     m = mms_frombinary(s, octstr_imm("anon@anon"));     

     if (!m) {
	  error(0, "mmbox.mod: failed to read data file [%s]!",
		octstr_get_cstr(fname));
	  goto done;
     }

     if (state == NULL)
	  nstate = mms_get_header_value(m, octstr_imm("X-Mms-MM-State"));
     else {
	  nstate = octstr_duplicate(state);
	  mms_replace_header_value(m, "X-Mms-MM-State", octstr_get_cstr(nstate));
     }
     
     flags = mms_get_header_values(m, octstr_imm("X-Mms-MM-Flags"));     
     flags = make_mm_flags(flags, flag_cmds);     
     mms_replace_header_values(m, "X-Mms-MM-Flags", flags);


     ftmp = octstr_format("%S.%ld.%d", fname, time(NULL), getpid());
     tmpfd =  open(octstr_get_cstr(ftmp), O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
     
     if (tmpfd < 0) 
	  goto done;
     
     s = mms_tobinary(m);
     msize = octstr_len(s);

     octstr_write_to_socket(tmpfd, s);    

     rename(octstr_get_cstr(ftmp), octstr_get_cstr(fname));
     unlock_and_close(tmpfd);

     if ((nifd = update_mmbox_index(ifd, octstr_get_cstr(home), ITEM_MOD, sdf, nstate, flags, msize)) < 0) {
	  /* Not good, we wrote but could not update the index file. scream. */
	  error(0, "mmbox.mod: failed to update index file, home is %s!",
		octstr_get_cstr(home));
	  goto done;
     }     
     ifd = nifd;
     res = 0;

 done:
     if (ifd > 0) 
	  unlock_and_close(ifd);

     if (fname)
	  octstr_destroy(fname);
     
     if (ftmp)
	  octstr_destroy(ftmp);

     if (sdf)
	  octstr_destroy(sdf);

     if (s)
	  octstr_destroy(s);
     if (home) 
	  octstr_destroy(home);
     if (nstate)
	  octstr_destroy(nstate);
     if (flags)
	  gwlist_destroy(flags, (gwlist_item_destructor_t *)octstr_destroy);     
     if (m)
	  mms_destroy(m);
     return res;
}
Пример #13
0
Octstr *mms_mmbox_addmsg(char *mmbox_root, char *user, MmsMsg *msg, List *flag_cmds, Octstr *dfltstate)
{
     int ifd = -1, nifd, dfd = -1;
     char df[128];
     Octstr *home = user_mmbox_dir(mmbox_root,user);
     Octstr *s = octstr_create(""), *sdf = NULL;
     List *flags = NULL;
     Octstr *state = NULL;
     int msize;
     
     if (!home)
	  goto done;
     ifd = open_mmbox_index(octstr_get_cstr(home),1);
     
     if (ifd < 0) 
	  goto done;
     
     if ((dfd = mkdf(df, octstr_get_cstr(home))) < 0) {
	  error(0, "mmbox_add: failed to create data file, home=%s - %s!", 
		octstr_get_cstr(home), strerror(errno));
	  goto done;
     }
     
     state = mms_get_header_value(msg, octstr_imm("X-Mms-MM-State"));
     flags = make_mm_flags(mms_get_header_values(msg, octstr_imm("X-Mms-MM-Flags")), flag_cmds);
     
     if (state == NULL)
	  state = dfltstate ? octstr_duplicate(dfltstate) : octstr_create("Sent");
     
     mms_replace_header_values(msg, "X-Mms-MM-Flags", flags);
     mms_replace_header_value(msg, "X-Mms-MM-State", octstr_get_cstr(state));
     
     s = mms_tobinary(msg);   
     msize = octstr_len(s);
     
     octstr_write_to_socket(dfd, s);	       
     sdf = octstr_create(df);
     
     if ((nifd = update_mmbox_index(ifd, octstr_get_cstr(home), ITEM_ADD, sdf, state, flags, msize)) < 0 ) {
	  char fbuf[256];	  
	  sprintf(fbuf, "%s/%s", octstr_get_cstr(home), df);
	  unlink(fbuf);	  
	  octstr_destroy(sdf);
	  sdf = NULL;
	  goto done;
     }
     
     ifd = nifd;
     octstr_replace(sdf, octstr_imm("/"), octstr_imm("-"));
 done:
     if (dfd > 0) 
	  unlock_and_close(dfd);
     if (ifd > 0) 
	  unlock_and_close(ifd);

     if (s)
	  octstr_destroy(s);
     if (home) 
	  octstr_destroy(home);
     if (state)
	  octstr_destroy(state);
     if (flags)
	  gwlist_destroy(flags, (gwlist_item_destructor_t *)octstr_destroy);
     
     return sdf;
}
Пример #14
0
/* Format of Index file:
 * each message is described by a single line:
 * df state flag1 flag2 flag3 ...
 */
static int update_mmbox_index(int fd, char *mmbox_dir, int cmd, 
			      Octstr *df, Octstr *state, List *flags, long msgsize)
{
     char fbuf[256], linbuf[1024];
     int tempfd;
     FILE *fp;
     
     /* Make a temp file. */
     
     sprintf(fbuf, "%.128s/t%s.%ld.%ld",
	     mmbox_dir, IDXFILE, time(NULL), random() % 1000);

     tempfd = open(fbuf, 
		   O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
     if (tempfd < 0 ) { 
	  error(0, "mmbox.update_index: Failed to open temp file %s: error = %s\n", 
		fbuf, strerror(errno));
	  
	  goto done;
     } else if (mm_lockfile(tempfd, fbuf, 0) != 0) { /* Lock it. */
	  error(0, "mmbox.update_index: Failed lock  temp file %s: error = %s\n", 
		     fbuf, strerror(errno));

	  unlock_and_close(tempfd);
	  tempfd = -1;
	  goto done;
	  
     }
     fp = fdopen(fd, "r");
     
     if (!fp) {
	  error(0, "mmbox.update_index: Failed fdopen on tempfd, file %s: error = %s\n",
		
		fbuf, strerror(errno));
		  
	  unlock_and_close(tempfd);
	  tempfd = -1;
	  goto done;
     }
     
     while (fgets(linbuf, sizeof linbuf, fp) != NULL) {
	  char idx[128], xstate[32];
	  Octstr *outs = NULL;
	  int i;
	  int size;
	  
	  sscanf(linbuf, "%s %s %d%n", idx, xstate, &size, &i);
	  
	  if (df && octstr_str_compare(df, idx) == 0)
	       if (cmd == ITEM_DEL || cmd == ITEM_ADD)
		    goto loop; /* Skip it. */
	       else  { /* MOD. */
		    Octstr *p = linearise_string_list(flags, " ");
		    outs = octstr_format("%S %S %d %S\n", df, state, msgsize, p);
		    octstr_destroy(p);
	       }
	  else { /* Copy out as-is */
	       char *p = skip_space(linbuf + i);
	       outs = octstr_format("%s %s %d %s%s",
				    idx, xstate, 
				    size,
				    p,
				    (strchr(p, '\n') != NULL ? "" : "\n"));
	  }
     loop:
	  if (outs) {
	       if (octstr_len(outs) > 0) 
		    octstr_write_to_socket(tempfd, outs);	       
	       octstr_destroy(outs);
	  }
     }     

     if (cmd == ITEM_ADD) { /* Finally, for ADD, just add it. */
	  Octstr *s, *p = linearise_string_list(flags, " ");
	  s = octstr_format("%S %S %d %S\n", df, state, msgsize, p);
	  octstr_destroy(p);	  
	  octstr_write_to_socket(tempfd, s);	       
	  octstr_destroy(s);	  
     }
     fsync(tempfd);     

     sprintf(linbuf, "%.128s/%s",
	     mmbox_dir, IDXFILE);
     rename(fbuf, linbuf);

     unlock_and_fclose(fp);
 done:

     return tempfd;
}
Пример #15
0
/* Makes a file name in the nested directory structure, where we can store 
 * data. Makes a number of tries -- similar to mkqf in queue module. 
 */
static int mkdf(char df[64], char *mmbox_home)
{

     int i = 0, fd = -1;
     static int ect;
     
     if (!mmbox_home)
	  gw_panic(0, "Mmbox directory passed as null!");
     
     do {	 	  
	  char d1[2], d2[3];
	  Octstr *tmp;
	  char *ctmp;
	  
	  d1[0] = _TT[random() % _TTSIZE];
	  d1[1] = '\0';
	  
	  /* Make first level. */
	  tmp = octstr_format("%.128s/%s", mmbox_home, d1);	  
	  if (mkdir(octstr_get_cstr(tmp), 
		    S_IRWXU|S_IRWXG) < 0 && 
	      errno != EEXIST) {
	       error(0, "mmbox.mkdf: failed to create dir [%s] "
		     " in mmbox home %s: %s!",
		     octstr_get_cstr(tmp), mmbox_home, strerror(errno));
	       octstr_destroy(tmp);
	       return -1;
	  }

	  octstr_destroy(tmp);

	  d2[0] = _TT[random() % _TTSIZE];
	  d2[1] = _TT[random() % _TTSIZE];
	  d2[2] = '\0';

	  /* Make second level. */
	  tmp = octstr_format("%.128s/%s/%s", mmbox_home, d1,d2);
	  
	  if (mkdir(octstr_get_cstr(tmp), 
		    S_IRWXU|S_IRWXG) < 0 && 
	      errno != EEXIST) {
	       error(0, "mmbox.mkdf: failed to create dir [%s] "
		     " in mmbox home %s: %s!",
		     octstr_get_cstr(tmp), mmbox_home, strerror(errno));
	       octstr_destroy(tmp);
	       return -1;
	  }
	  octstr_destroy(tmp);
	  
	  /* use df[] to store candidate so when we hit success it is already there...*/
	  sprintf(df, "%s/%s/%cf%ld.%d.x%d%ld", 
			      d1,d2, MDF, 
			      time(NULL), 
			      ++ect, getpid(), random() % 100);
	  tmp = octstr_format("%s/%s", mmbox_home, df);
	  ctmp = octstr_get_cstr(tmp);
	  fd = open(ctmp, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
	  if (fd >= 0 && 
	      mm_lockfile(fd,ctmp,1) != 0) {
	       unlink(ctmp);
	       unlock_and_close(fd);
	       fd = -1;
	  }
	  octstr_destroy(tmp);
	  
     } while (i++ < MAXTRIES && fd < 0);

     return fd;
}