Exemple #1
0
int main(int argc, char *argv[])
{
     Octstr *fname, *s;
     
     int cfidx;
     int msize;

     List *h = NULL;

     if (argc < 2)
	  return -1;
     
     mms_lib_init();

     cfidx = get_and_set_debugs(argc, argv, find_own);
     
     if (argv[cfidx] == NULL)
	  fname = octstr_imm("mmsc.conf");
     else 
	  fname = octstr_create(argv[cfidx]);

     mms_info(0, "mmssend", NULL, "----------------------------------------");
     mms_info(0,  "mmssend", NULL, " MMSC Message sender runner  version %s starting", MMSC_VERSION);
     
     
     /* Load settings. */     
     settings = mms_load_mmsc_settings(fname, &proxyrelays,1);          
    
     if (!settings) 
	  panic(0, "No global MMSC configuration, or failed to read conf from <%s>!", octstr_get_cstr(fname));

     octstr_destroy(fname);
     if (from == NULL ||
	 to == NULL) {
	  mms_error(0, "mmssend", NULL, "Sender and recipient addresses required!\n");
	  exit(-1);
     } else { /* fix up 'to' list */
	  List *l = gwlist_create();
	  Octstr *x;
	  while ((x = gwlist_extract_first(to)) != NULL) {	       
	       octstr_strip_blanks(x);
	       _mms_fixup_address(&x, 
				  settings->unified_prefix ? octstr_get_cstr(settings->unified_prefix) : NULL,
				  settings->strip_prefixes, 1);
	       gwlist_append(l, x);
	  }
	  gwlist_destroy(to, NULL);
	  to = l;
     }

     /* fix from address. */
     _mms_fixup_address(&from,  
			settings->unified_prefix ? octstr_get_cstr(settings->unified_prefix) : NULL,
			settings->strip_prefixes, 1);

#if 0
     mms_start_profile_engine(octstr_get_cstr(settings->ua_profile_cache_dir));
#endif 
     if (data) {
	  /* try and detect if we are looking at plain text (mime-encoded) or binary encoded message. */
	  int ch = octstr_get_char(data, 0);
	  if (isprint(ch)) {
		    MIMEEntity *mime = mime_octstr_to_entity(data);

		    if (mime) {
			 m = mms_frommime(mime);
			 mime_entity_destroy(mime);
		    }
	  } else 	       
	       m = mms_frombinary_ex(data, from ? from : octstr_imm("anon@anon"),
				     octstr_get_cstr(settings->unified_prefix), 
				     settings->strip_prefixes);
	  if (m) 
	       mms_msgdump(m,1);       
	  msize = octstr_len(data);
	  octstr_destroy(data);
     } else
	     msize = 0;
     if (!m)
	     panic(0, "No Message supplied, or failed to decode binary data!");
     

     h = http_create_empty_headers();
     http_header_add(h, "X-Mbuni-Tool", "mmssend");
     http_header_add(h, "X-Mbuni-CalledFrom", "Terminal");

     if (binfo) {
             mms_info(0, "add.info", NULL, "Adding extra headers billing info `X-Mms-Binfo' :");
             http_header_add(h, "X-Mms-Binfo", octstr_get_cstr(binfo));
     }
     s = settings->qfs->mms_queue_add(from, to, NULL, NULL, NULL, time(NULL), 
				      time(NULL) + settings->default_msgexpiry, m,
				      NULL, 
				      NULL, NULL,
				      NULL, NULL,
				      h,
				      dlr, 
				      octstr_get_cstr(settings->global_queuedir), 
				      "MM3",
				      settings->host_alias);
     
     if (savetommbox) 
	  mmbox = mms_mmbox_addmsg(octstr_get_cstr(settings->mmbox_rootdir),
				   octstr_get_cstr(from), m, NULL, octstr_imm("Sent"));
     
     mms_log("Received", from, to, msize, s, NULL, NULL, "MM3",NULL,NULL);
     
     printf("Queued: %s, mmbox=%s\n", 
	    octstr_get_cstr(s), mmbox ? octstr_get_cstr(mmbox) : "");
     octstr_destroy(s);
     
     http_destroy_headers(h);
     mms_cleanup_mmsc_settings(settings);
     mms_lib_shutdown();
  return 0;
}
Exemple #2
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;
}