413{
415 int mt = 0,
416 mo = 0,
417 tx = 0,
418 rx = 0,
419 nodial = 0,
420 nowait = 0,
421 concurrent = 1,
422 motxwait = 10,
423 motxdelay = 1,
424 motxretries = 10,
425 mttxwait = 10,
426 mttxdelay = 30,
427 mttxretries = 100,
428 mr = -1,
429 pid = -1,
430 dcs = -1,
431 srr = 0,
432 rp = 0,
433 vp = 0,
434 udl = 0,
435 utf8 = 0,
436 ucs1 = 0,
437 ucs2 = 0;
438 unsigned short ud[160];
439 unsigned char *uds = 0,
440 *udh = 0;
441 char *da = 0,
442 *oa = 0,
443 *queue = "",
444 *udfile = 0,
445 *process = 0,
446 *spooldir = "/var/spool/asterisk",
447 *motxchannel = "Local/1709400X",
448 *motxcallerid = 0,
449 *mttxchannel = 0,
450 *mttxcallerid = "080058752X0",
451 *defaultsubaddress = "9",
452 subaddress = 0,
453 *scts = 0;
454 poptContext optCon;
455 const struct poptOption optionsTable[] = {
457 {"da", 'd', POPT_ARG_STRING, &da, 0, "Destination address", "number"},
458 {"oa", 'o', POPT_ARG_STRING, &oa, 0, "Origination address", "number"},
459 {"ud", 'm', POPT_ARG_STRING, &uds, 0, "Message", "text"},
460 {"ud-file", 'f', POPT_ARG_STRING, &udfile, 0, "Message file", "filename"},
461 {"UTF-8", 0, POPT_ARG_NONE, &utf8, 0, "File treated as null terminated UTF-8 (default)", 0},
462 {"UCS-1", 0, POPT_ARG_NONE, &ucs1, 0, "File treated as UCS-1", 0},
463 {"UCS-2", 0, POPT_ARG_NONE, &ucs2, 0, "File treated as UCS-2", 0},
464 {"mt", 't', POPT_ARG_NONE, &mt, 0, "Mobile Terminated", 0},
465 {"mo", 0, POPT_ARG_NONE, &mo, 0, "Mobile Originated", 0},
466 {"tx", 0, POPT_ARG_NONE, &tx, 0, "Send message", 0},
467 {"rx", 'r', POPT_ARG_NONE, &rx, 0, "Queue for receipt", 0},
468 {"process", 'e', POPT_ARG_STRING, &process, 0, "Rx queue process command", "command"},
469 {"no-dial", 'x', POPT_ARG_NONE, &nodial, 0, "Do not dial", 0},
470 {"no-wait", 0, POPT_ARG_NONE, &nowait, 0, "Do not wait if already calling", 0},
473 {"motx-callerid", 0, POPT_ARG_STRING, &motxcallerid, 0,
474 "Caller ID for motx calls (default is queue name without sub address)", "number"},
476 "seconds"},
479 {"mttx-channel", 0, POPT_ARG_STRING, &mttxchannel, 0,
480 "Channel for mttx calls (default is Local/ and queue name without sub address)", "channel"},
482 "Caller ID for mttx calls (default is queue name without sub address)", "number"},
484 "seconds"},
487 {"mr", 'n', POPT_ARG_INT, &mr, 0, "Message reference", "n"},
488 {"pid", 'p', POPT_ARG_INT, &pid, 0, "Protocol ID", "n"},
489 {"dcs", 'c', POPT_ARG_INT, &dcs, 0, "Data Coding Scheme", "n"},
490 {"udh", 0, POPT_ARG_STRING, &udh, 0, "User data header", "hex"},
491 {"srr", 0, POPT_ARG_NONE, &srr, 0, "Status Report Request", 0},
492 {"rp", 0, POPT_ARG_NONE, &rp, 0, "Return Path request", 0},
493 {"v", 0, POPT_ARG_INT, &vp, 0, "Validity Period", "seconds"},
494 {"scts", 0, POPT_ARG_STRING, &scts, 0, "Timestamp", "YYYY-MM-SSTHH:MM:SS"},
495 {
"default-sub-address", 0, POPT_ARG_STRING |
POPT_ARGFLAG_SHOW_DEFAULT, &defaultsubaddress, 0,
"Default sub address",
"X"},
498 };
499
500 optCon = poptGetContext (
NULL, argc, argv, optionsTable, 0);
501 poptSetOtherOptionHelp (optCon, "<oa/da> <message>");
502
503
504 if ((
c = poptGetNextOpt (optCon)) < -1)
505 {
506
507 fprintf (stderr,
"%s: %s\n", poptBadOption (optCon, POPT_BADOPTION_NOALIAS), poptStrerror (
c));
508 return 1;
509 }
510 if (!ucs1 && !ucs2)
511 utf8 = 1;
512 if (utf8 + ucs1 + ucs2 > 1)
513 {
514 fprintf (stderr, "Pick one of UTF-8, UCS-1 or UCS-2 only\n");
515 return 1;
516 }
517 if (!udfile && (ucs1 || ucs2))
518 {
519 fprintf (stderr, "Command line arguments always treated as UTF-8\n");
520 return 1;
521 }
522
523 if (!mt && !mo && process)
524 mt = 1;
525 if (!mt && !mo && oa)
526 mt = 1;
527 if (!mt)
528 mo = 1;
529 if (mt && mo)
530 {
531 fprintf (stderr, "Cannot be --mt and --mo\n");
532 return 1;
533 }
534 if (!rx && !tx && process)
535 rx = 1;
536 if (!rx)
537 tx = 1;
538 if (tx && rx)
539 {
540 fprintf (stderr, "Cannot be --tx and --rx\n");
541 return 1;
542 }
543 if (rx)
544 nodial = 1;
545 if (uds && udfile)
546 {
547 fprintf (stderr, "Cannot have --ud and --ud-file\n");
548 return 1;
549 }
550 if (mo && !da && poptPeekArg (optCon))
551 da = (char *) poptGetArg (optCon);
552 if (mt && !oa && poptPeekArg (optCon))
553 oa = (char *) poptGetArg (optCon);
554 if (tx && oa && mo)
555 {
556 fprintf (stderr, "--oa makes no sense with --mo as CLI is used (i.e. queue name)\n");
557 return 1;
558 }
559 if (tx && da && mt)
560 {
561 fprintf (stderr, "--da makes no sense with --mt as called number is used (i.e. queue name)\n");
562 return 1;
563 }
564 if (da && strlen (da) > 20)
565 {
566 fprintf (stderr, "--da too long\n");
567 return 1;
568 }
569 if (oa && strlen (oa) > 20)
570 {
571 fprintf (stderr, "--oa too long\n");
572 return 1;
573 }
574 if (queue && strlen (queue) > 20)
575 {
576 fprintf (stderr, "--queue name too long\n");
577 return 1;
578 }
579 if (mo && scts)
580 {
581 fprintf (stderr, "scts is set my service centre\n");
582 return 1;
583 }
584 if (uds)
585 {
586 while (udl < 160 && *uds)
587 {
589 if (v > 0xFFFF)
590 {
591 fprintf (stderr, "Invalid character U+%X at %d\n", v, udl);
592 return 1;
593 }
594 ud[udl++] = v;
595 }
596 }
597 if (!uds && !udfile && poptPeekArg (optCon))
598 {
599 while (poptPeekArg (optCon) && udl < 160)
600 {
601 unsigned char *
a = (
unsigned char *) poptGetArg (optCon);
602 if (udl && udl < 160)
603 ud[udl++] = ' ';
604 while (udl < 160 && *
a)
605 {
607 if (v > 0xFFFF)
608 {
609 fprintf (stderr, "Invalid character U+%X at %d\n", v, udl);
610 return 1;
611 }
612 ud[udl++] = v;
613 }
614 }
615 }
616 if (poptPeekArg (optCon))
617 {
618 fprintf (stderr, "Unknown argument %s\n", poptGetArg (optCon));
619 return 1;
620 }
621 if (udfile)
622 {
623 unsigned char dat[1204],
624 *p = dat,
625 *e;
626 int f,
627 n;
628 if (*udfile)
629 f = open (udfile, O_RDONLY);
630 else
631 f = fileno (stdin);
632 if (f < 0)
633 {
634 perror (udfile);
635 return 1;
636 }
637 n = read (f, dat, sizeof (dat));
638 if (n < 0)
639 {
640 perror (udfile);
641 return 1;
642 }
643 if (*udfile)
644 close (f);
645 e = dat + n;
646 if (utf8)
647 {
648 while (p < e && udl < 160 && *p)
650 } else if (ucs1)
651 {
652 while (p < e && udl < 160)
653 ud[udl++] = *p++;
654 } else
655 {
656 while (p + 1 < e && udl < 160)
657 {
658 ud[udl++] = (*p << 8) + p[1];
659 p += 2;
660 }
661 }
662 }
663 if (queue)
664 {
665 char *
d = strrchr (queue,
'-');
668 else
669 subaddress = *defaultsubaddress;
670 }
671
672 if (chdir (spooldir))
673 {
674 perror (spooldir);
675 return 1;
676 }
677
678 if (oa || da)
679 {
680 char temp[100],
681 queuename[100],
682 *dir = (mo ? rx ? "sms/morx" : "sms/motx" : rx ? "sms/mtrx" : "sms/mttx");
683 FILE *f;
684 snprintf (temp, sizeof(temp), "sms/.smsq-%d", (int)getpid ());
685 mkdir ("sms", 0777);
686 mkdir (dir, 0777);
687 snprintf (queuename, sizeof(queuename), "%s/%s.%ld-%d", dir, *queue ? queue : "0", (long)time (0), (int)getpid ());
688 f = fopen (temp, "w");
689 if (!f)
690 {
691 perror (temp);
692 return 1;
693 }
694 if (oa)
695 fprintf (f, "oa=%s\n", oa);
696 if (da)
697 fprintf (f, "da=%s\n", da);
698 if (scts)
699 fprintf (f, "scts=%s\n", scts);
700 if (pid >= 0)
701 fprintf (f, "pid=%d\n", pid);
702 if (dcs >= 0)
703 fprintf (f, "dcs=%d\n", dcs);
704 if (mr >= 0)
705 fprintf (f, "mr=%d\n", mr);
706 if (srr)
707 fprintf (f, "srr=1\n");
708 if (rp)
709 fprintf (f, "rp=1\n");
710 if (udh)
711 fprintf (f, "udh#%s\n", udh);
712 if (vp > 0)
713 fprintf (f, "vp=%d\n", vp);
714 if (udl)
715 {
716 int p;
717 for (p = 0; p < udl && ud[p] < 0x100; p++);
718 if (p == udl)
719 {
720 for (p = 0; p < udl && ud[p] < 0x80 && ud[p] >= 0x20; p++);
721 if (p == udl)
722 {
723 fprintf (f, "ud=");
724 for (p = 0; p < udl; p++)
725 fputc (ud[p], f);
726 } else
727 {
728 fprintf (f, "ud#");
729 for (p = 0; p < udl; p++)
730 fprintf (f, "%02hX", ud[p]);
731 }
732 } else
733 {
734 fprintf (f, "ud##");
735 for (p = 0; p < udl; p++)
736 fprintf (f, "%04hX", ud[p]);
737 }
738 fprintf (f, "\n");
739 }
740 fclose (f);
741 if (rename (temp, queuename))
742 {
743 perror (queuename);
744 unlink (temp);
745 return 1;
746 }
747 }
748
749 if (!nodial && tx && !process)
750 {
751 char ret=0,
752 try = 3;
753 if (nowait)
754 try = 1;
755 while (try--)
756 {
757 if (mo)
758 ret =
txqcheck (
"motx", queue, subaddress, motxchannel, motxcallerid, motxwait, motxdelay, motxretries, concurrent);
759 else
760 ret =
txqcheck (
"mttx", queue, subaddress, mttxchannel, mttxcallerid, mttxwait, mttxdelay, mttxretries, concurrent);
761 if (ret < 2)
762 break;
763 if (try)
764 sleep (1);
765 }
766 if (ret == 2 && !nowait)
767 fprintf (stderr, "No call scheduled as already sending\n");
768 }
769 if (process)
770 rxqcheck (mo ? rx ?
"morx" :
"motx" : rx ?
"mtrx" :
"mttx", queue, process);
771
772 return 0;
773}
static char txqcheck(char *dir, char *queue, char subaddress, char *channel, char *callerid, int wait, int delay, int retries, int concurrent)
check for any queued messages in specific queue (queue="" means any queue)
#define POPT_ARGFLAG_SHOW_DEFAULT
static int utf8decode(unsigned char **pp)
reads next USC character from null terminated UTF-8 string and advanced pointer for non valid UTF-8 s...
static void rxqcheck(char *dir, char *queue, char *process)
Process received queue entries Run through a process, setting environment variables.