Exemplo n.º 1
0
int
checker_main(int argc, char *argv[])
{
  char outsbuf[BUFSIZE], corrsbuf[BUFSIZE];
  char *outdbuf = 0, *corrdbuf = 0;
  size_t outdsz = 0, corrdsz = 0;
  char *outval, *corrval;

  checker_l10n_prepare();

  if (getenv("EJ_REQUIRE_NL")) {
    if (fseek(f_out, -1L, SEEK_END) >= 0) {
      if (getc(f_out) != '\n') fatal_PE(_("No final \\n in the output file"));
      fseek(f_out, 0L, SEEK_SET);
    }
  }

  corrval = checker_read_buf_2(2,_("correct"),1,corrsbuf,BUFSIZE,&corrdbuf,&corrdsz);
  checker_corr_eof();
  if (!is_number(corrval)) fatal_CF(_("correct: not a number"));
  normalize_number(corrval);

  outval = checker_read_buf_2(1, _("output"), 1, outsbuf, BUFSIZE, &outdbuf, &outdsz);
  checker_out_eof();
  if (!is_number(outval)) fatal_PE(_("output: not a number"));
  normalize_number(outval);

  if (strcmp(outval, corrval) != 0)
    fatal_WA(_("Wrong answer: output: %s, correct: %s"), outval, corrval);

  checker_OK();
}
Exemplo n.º 2
0
Octstr *radius_acct_get_msisdn(Octstr *client_ip)
{
    Octstr *m, *r;
    char *uf;

    /* if no proxy thread is running, then pass NULL as result */
    if (radius_table == NULL || client_ip == NULL)
        return NULL;

    mutex_lock(radius_mutex);
    m = dict_get(radius_table, client_ip);
    mutex_unlock(radius_mutex);
    r = m ? octstr_duplicate(m) : NULL;

    /* apply number normalization */
    uf = unified_prefix ? octstr_get_cstr(unified_prefix) : NULL;
    normalize_number(uf, &r);

    return r;
}
Exemplo n.º 3
0
int smscconn_send(SMSCConn *conn, Msg *msg)
{
    int ret = -1;
    List *parts = NULL;
    
    gw_assert(conn != NULL);
    mutex_lock(conn->flow_mutex);
    if (conn->status == SMSCCONN_DEAD || conn->why_killed != SMSCCONN_ALIVE) {
        mutex_unlock(conn->flow_mutex);
        return -1;
    }

    /* if this a retry of splitted message, don't unify prefix and don't try to split */
    if (msg->sms.split_parts == NULL) {    
        /* normalize the destination number for this smsc */
        char *uf = conn->unified_prefix ? octstr_get_cstr(conn->unified_prefix) : NULL;
        normalize_number(uf, &(msg->sms.receiver));

        /* split msg */
        parts = sms_split(msg, NULL, NULL, NULL, NULL, 1, 
            counter_increase(split_msg_counter) & 0xff, 0xff, conn->max_sms_octets);
        if (gwlist_len(parts) == 1) {
            /* don't create split_parts of sms fit into one */
            gwlist_destroy(parts, msg_destroy_item);
            parts = NULL;
        }
    }
    
    if (parts == NULL)
        ret = conn->send_msg(conn, msg);
    else {
        long i, parts_len = gwlist_len(parts);
        struct split_parts *split = gw_malloc(sizeof(*split));
         /* must duplicate, because smsc2_route will destroy this msg */
        split->orig = msg_duplicate(msg);
        split->parts_left = counter_create();
        split->status = SMSCCONN_SUCCESS;
        counter_set(split->parts_left, parts_len);
        split->smsc_conn = conn;
        debug("bb.sms.splits", 0, "new split_parts created %p", split);
        for (i = 0; i < parts_len; i++) {
            msg = gwlist_get(parts, i);
            msg->sms.split_parts = split;
            ret = conn->send_msg(conn, msg);
            if (ret < 0) {
                if (i == 0) {
                    counter_destroy(split->parts_left);
                    gwlist_destroy(parts, msg_destroy_item);
                    gw_free(split);
                    mutex_unlock(conn->flow_mutex);
                    return ret;
                }
                /*
                 * Some parts were sent. So handle this within
                 * bb_smscconn_XXX().
                 */
                split->status = SMSCCONN_FAILED_REJECTED;
                counter_increase_with(split->parts_left, -(parts_len - i));
                warning(0, "Could not send all parts of a split message");
                break;
            }
        }
        gwlist_destroy(parts, msg_destroy_item);
    }
    mutex_unlock(conn->flow_mutex);
    return ret;
}
Exemplo n.º 4
0
static int sendNotify(MmsEnvelope *e)
{
     Octstr *to;
     MmsMsg *msg, *smsg = NULL;
     MmsEnvelopeTo *xto = gwlist_get(e->to, 0);
     Octstr *err = NULL;
     time_t tnow = time(NULL);
     int j, k, len;
     Octstr *phonenum = NULL, *rcpt_ip = NULL, *msgId, *from, *fromproxy;
     int mtype, msize;
     int res = MMS_SEND_OK, dlr;
     time_t expiryt;
     char *prov_notify_event = NULL;
     char *rtype = NULL;

          
     if (e->lastaccess != 0) { /* This message has been fetched at least once, no more signals. */	  
	  e->sendt = e->expiryt + 3600*24*30*12;
	  info(0, "MM1: Message [ID: %s] fetched/touched at least once. Skipping",
	       e->xqfname);
	  return settings->qfs->mms_queue_update(e);
     }

     if (!xto) {
	  error(0, "mobilesender: Queue entry %s with no recipients!", 
		e->xqfname);
	  return 0;
     }

     msg = settings->qfs->mms_queue_getdata(e);
     to = octstr_duplicate(xto->rcpt);
     expiryt = e->expiryt;
     msgId = e->msgId ? octstr_duplicate(e->msgId) : NULL;
     from = octstr_duplicate(e->from);
     fromproxy = e->fromproxy ? octstr_duplicate(e->fromproxy) : NULL;
     msize = e->msize;
     dlr = e->dlr;

     if (e->expiryt != 0 &&  /* Handle message expiry. */
	 e->expiryt < tnow) {
	  err = octstr_format("MMSC error: Message expired while sending to %S!", to);
	  res = MMS_SEND_ERROR_FATAL;
	  prov_notify_event = "failedfetch";
	  rtype = "Expired";	  
	  goto done;
     } else if (e->attempts >= settings->maxsendattempts) {
	  err = octstr_format("MMSC error: Failed to deliver to %S after %ld attempts!", 
			      to, e->attempts);
	  res = MMS_SEND_ERROR_FATAL;

	  prov_notify_event = "failedfetch";
	  rtype = "Expired";	  
	  goto done;
     }
     
     j = octstr_case_search(to, octstr_imm("/TYPE=PLMN"), 0);
     k = octstr_case_search(to, octstr_imm("/TYPE=IPv"), 0);
     len = octstr_len(to);
     
     if (j > 0 && j - 1 +  sizeof "/TYPE=PLMN" == len) { /* A proper number. */
	  phonenum = octstr_copy(to, 0, j);
#if 0
	  normalize_number(octstr_get_cstr(settings->unified_prefix), &phonenum);
#else
	  mms_normalize_phonenum(&phonenum, 
				 octstr_get_cstr(settings->unified_prefix), 
				 settings->strip_prefixes);	  
#endif
     }     else if (k > 0 && k + sizeof "/TYPE=IPv" == len) 
	  rcpt_ip = octstr_copy(to, 0, k);
     else {
	  /* We only handle phone numbers here. */
	  err = octstr_format("Unexpected recipient %s in MT queue!", octstr_get_cstr(to));	  
	  res = MMS_SEND_ERROR_FATAL;	  
	  goto done;
     }
     
     mtype = mms_messagetype(msg);     
     
     /* For phone, getting here means the message can be delivered. So: 
      * - Check whether the recipient is provisioned, if not, wait (script called will queue creation req)
      * - If the recipient can't take MMS, then send SMS.
      */
     
     /* We handle two types of requests: send and delivery/read notifications. 
      * other types of messages cannot possibly be in this queue!
      */
     
     if (mtype == MMS_MSGTYPE_SEND_REQ ||
	 mtype == MMS_MSGTYPE_RETRIEVE_CONF) {
	  Octstr *url, *transid;
	  
	  if (phonenum) {
	       int send_ind = mms_ind_send(settings->prov_getstatus, phonenum);
	       
	       if (send_ind < 0 && 
		   settings->notify_unprovisioned)
		    send_ind = 0;

	       if (send_ind < 0) { /* That is, recipient is not (yet) provisioned. */
		    res = MMS_SEND_ERROR_TRANSIENT;
		    err = octstr_format("%S is not provisioned for MMS reception, delivery deferred!", 
					phonenum);
		    
		    /* Do not increase delivery attempts counter. */
		    e->lasttry = tnow;		    
		    e->sendt = e->lasttry + settings->send_back_off * (1 + e->attempts);
		    
		    if (settings->qfs->mms_queue_update(e) == 1) 
			 e = NULL; /* Queue entry gone. */	
		    else 	  
			 settings->qfs->mms_queue_free_env(e);		    		    
		    goto done;
	       } else if (send_ind == 0) { /*  provisioned but does not support */		    
		    Octstr *s = octstr_format(octstr_get_cstr(settings->mms_notify_txt),
					      from);
		    if (settings->notify_unprovisioned && s && octstr_len(s) > 0) { /* Only send if the string was set. */
			 List *pheaders;					    
			 Octstr *sto = octstr_duplicate(phonenum);
			 
			 octstr_url_encode(s);
			 octstr_url_encode(sto);
			 
			 url = octstr_format("%S&text=%S&to=%S",settings->sendsms_url,s, sto);
			 pheaders = http_create_empty_headers();
			 http_header_add(pheaders, "Connection", "close");
			 http_header_add(pheaders, "User-Agent", MM_NAME "/" VERSION);      
			 
			 http_start_request(httpcaller, HTTP_METHOD_GET, url, 
					    pheaders, NULL, 0, &edummy, NULL);			 			 
			 http_destroy_headers(pheaders);
			 octstr_destroy(url);
			 octstr_destroy(sto);		   		 
		    } else if (s)
			 octstr_destroy(s);	
		    res = MMS_SEND_OK;
		    err = octstr_imm("No MMS Ind support, sent SMS instead");
		    
		    xto->process = 0; /* No more processing. */
		    if (settings->qfs->mms_queue_update(e) == 1) 
			 e = NULL; 
		    else 	  
			 settings->qfs->mms_queue_free_env(e);		    
		    goto done;

	       }	       
	  }
	  
	  /* To get here means we can send Ind. */
	  url = mms_makefetchurl(e->xqfname, e->token, MMS_LOC_MQUEUE,
				 phonenum ? phonenum : to,
				 settings);
	  info(0, "Preparing to notify client to fetch message at URL: %s",
	       octstr_get_cstr(url));
	  transid = mms_maketransid(e->xqfname, settings->host_alias);	  
	  
	  smsg = mms_notification(msg, e->msize, url, transid, 
				  e->expiryt ? e->expiryt :
				  tnow + settings->default_msgexpiry,
				  settings->optimize_notification_size);
	  octstr_destroy(transid);
	  octstr_destroy(url);
     } else if (mtype == MMS_MSGTYPE_DELIVERY_IND ||
		mtype == MMS_MSGTYPE_READ_ORIG_IND) 
	  smsg = msg;
     else {
	  error(0, "Unexpected message type %s for %s found in MT queue!", 
		mms_message_type_to_cstr(mtype), octstr_get_cstr(to));
	  res = MMS_SEND_ERROR_FATAL;
	  goto done;
     }
     
     if (smsg)
	  start_push(phonenum ? phonenum : rcpt_ip, 
		     phonenum ? 1 : 0, 
		     e, smsg); /* Send the message. 
				* Don't touch 'e' after this point!
				* It may be freed by receive thread. 
				*/
     
     if (smsg != msg && smsg)
	  mms_destroy(smsg);
    
 done:
     if (err != NULL && 
	 res != MMS_SEND_ERROR_TRANSIENT) { /* If there was a report request and this is a legit error
					     *  queue it. 
					     */
	  
	  if (dlr) {	       
	       MmsMsg *m = mms_deliveryreport(msgId, to, tnow, 
					      rtype ? octstr_imm(rtype) : 
					      octstr_imm("Indeterminate"));
	       
	       List *l = gwlist_create();
	       Octstr *res;
	       gwlist_append(l, from);
	       
	       /* Add to queue, switch via proxy to be from proxy. */
	       res = settings->qfs->mms_queue_add(to ? to : settings->system_user, l,  err, 
						  NULL, fromproxy,  
						  tnow, tnow+settings->default_msgexpiry, m, NULL, 
						  NULL, NULL,
						  NULL, NULL,
						  NULL,
						  0,
						  octstr_get_cstr(settings->mm1_queuedir), 
						  "MM2",
						  settings->host_alias);
	       gwlist_destroy(l, NULL);
	       mms_destroy(m);
	       octstr_destroy(res);
	  }
	  
     }
     
     /* Write to log */
     info(0, "%s Mobile Queue MMS Send Notify: From=%s, to=%s, msgsize=%d, reason=%s", 
	  SEND_ERROR_STR(res),
	  octstr_get_cstr(from), octstr_get_cstr(to), msize,
	  err ? octstr_get_cstr(err) : "");
     
     
     if (res == MMS_SEND_ERROR_FATAL) {
	  xto->process = 0;  /* No more attempts to deliver, delete this. */	       
	  if (settings->qfs->mms_queue_update(e) == 1) 
	       e = NULL; /* Queue entry gone. */	
	  else 	  
	       settings->qfs->mms_queue_free_env(e);
     }    /* Else queue will be updated/freed elsewhere. */
     
     
     if (prov_notify_event)
	  notify_prov_server(octstr_get_cstr(settings->prov_notify), 
			     to ? octstr_get_cstr(to) : "unknown", 
			     prov_notify_event, 
			     rtype ? rtype : "",
			     e ? e->msgId : NULL, NULL, NULL);

     if (msg) mms_destroy(msg);       

     octstr_destroy(phonenum);
     
     octstr_destroy(rcpt_ip);
     octstr_destroy(to);
     octstr_destroy(msgId);
     octstr_destroy(fromproxy);
     octstr_destroy(from);
     octstr_destroy(err);

     return 1;
}