197static void rxqcheck (
char *dir,
char *queue,
char *process)
204 int ql = strlen (queue);
206 snprintf(temp,
sizeof(temp),
"sms/.smsq-%d", (
int)getpid ());
207 snprintf(dirname,
sizeof(dirname),
"sms/%s", dir);
208 d = opendir (dirname);
211 while ((fn = readdir (
d)))
212 if ((*fn->d_name !=
'.'
213 && ((!ql && (p = strchr (fn->d_name,
'.'))) || (ql && !strncmp (fn->d_name, queue, ql) && fn->d_name[ql] ==
'.'))))
217 unsigned short ud[160];
218 unsigned char udl = 0;
220 snprintf (filename,
sizeof(filename),
"sms/%s/%s", dir, fn->d_name);
221 if (rename (filename, temp))
223 f = fopen (temp,
"r");
248 setenv (
"queue", queue, 1);
250 while (fgets (line,
sizeof (line), f))
252 for (p = line; *p && *p !=
'\n' && *p !=
'\r'; p++);
255 if (!*p || *p ==
';')
267 if (!strcmp (line,
"oa") || !strcmp (line,
"da") || !strcmp (line,
"scts") || !strcmp (line,
"pid")
268 || !strcmp (line,
"dcs") || !strcmp (line,
"mr") || !strcmp (line,
"vp"))
270 else if ((!strcmp (line,
"srr") || !strcmp (line,
"rp")) && atoi (p))
272 else if (!strcmp (line,
"ud"))
277 if (v && v <= 0xFFFF)
280 }
else if (*p ==
'#')
286 if (!strcmp (line,
"udh"))
288 else if (!strcmp (line,
"ud"))
291 while (*p && udl < 160)
293 if (isxdigit (*p) && isxdigit (p[1]) && isxdigit (p[2]) && isxdigit (p[3]))
296 (((isalpha (*p) ? 9 : 0) + (*p & 0xF)) << 12) +
297 (((isalpha (p[1]) ? 9 : 0) + (p[1] & 0xF)) << 8) +
298 (((isalpha (p[2]) ? 9 : 0) + (p[2] & 0xF)) << 4) + ((isalpha (p[3]) ? 9 : 0) + (p[3] & 0xF));
306 if (!strcmp (line,
"ud"))
309 while (*p && udl < 160)
311 if (isxdigit (*p) && isxdigit (p[1]))
313 ud[udl++] = (((isalpha (*p) ? 9 : 0) + (*p & 0xF)) << 4) + ((isalpha (p[1]) ? 9 : 0) + (p[1] & 0xF));
327 for (n = 0, x = 0; x < udl; x++)
329 unsigned short v = ud[x];
336 tmp[n++] = (0xC0 + (v >> 6));
337 tmp[n++] = (0x80 + (v & 0x3F));
340 tmp[n++] = (0xE0 + (v >> 12));
341 tmp[n++] = (0x80 + ((v >> 6) & 0x3F));
342 tmp[n++] = (0x80 + (v & 0x3F));
348 for (n = 0, x = 0; x < udl; x++)
350 unsigned short v = ud[x];
351 if (v <
' ' || v ==
'\\')
366 tmp[n++] =
'0' + (v >> 6);
367 tmp[n++] =
'0' + ((v >> 3) & 7);
368 tmp[n++] =
'0' + (v & 7);
374 tmp[n++] = (0xC0 + (v >> 6));
375 tmp[n++] = (0x80 + (v & 0x3F));
378 tmp[n++] = (0xE0 + (v >> 12));
379 tmp[n++] = (0x80 + ((v >> 6) & 0x3F));
380 tmp[n++] = (0x80 + (v & 0x3F));
385 for (x = 0; x < udl && ud[x] < 0x100; x++);
388 for (n = 0, x = 0; x < udl; x++)
390 sprintf (tmp + n,
"%02hX", ud[x]);
395 for (n = 0, x = 0; x < udl; x++)
397 sprintf (tmp + n,
"%04hX", ud[x]);
403 if (system (process) == -1) {
404 fprintf(stderr,
"Failed to fork process '%s'\n", process);
412main (
int argc,
const char *argv[])
438 unsigned short ud[160];
439 unsigned char *uds = 0,
446 *spooldir =
"/var/spool/asterisk",
447 *motxchannel =
"Local/1709400X",
450 *mttxcallerid =
"080058752X0",
451 *defaultsubaddress =
"9",
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"},
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"},
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"},
500 optCon = poptGetContext (
NULL, argc, argv, optionsTable, 0);
501 poptSetOtherOptionHelp (optCon,
"<oa/da> <message>");
504 if ((
c = poptGetNextOpt (optCon)) < -1)
507 fprintf (stderr,
"%s: %s\n", poptBadOption (optCon, POPT_BADOPTION_NOALIAS), poptStrerror (
c));
512 if (utf8 + ucs1 + ucs2 > 1)
514 fprintf (stderr,
"Pick one of UTF-8, UCS-1 or UCS-2 only\n");
517 if (!udfile && (ucs1 || ucs2))
519 fprintf (stderr,
"Command line arguments always treated as UTF-8\n");
523 if (!mt && !mo && process)
525 if (!mt && !mo && oa)
531 fprintf (stderr,
"Cannot be --mt and --mo\n");
534 if (!rx && !tx && process)
540 fprintf (stderr,
"Cannot be --tx and --rx\n");
547 fprintf (stderr,
"Cannot have --ud and --ud-file\n");
550 if (mo && !da && poptPeekArg (optCon))
551 da = (
char *) poptGetArg (optCon);
552 if (mt && !oa && poptPeekArg (optCon))
553 oa = (
char *) poptGetArg (optCon);
556 fprintf (stderr,
"--oa makes no sense with --mo as CLI is used (i.e. queue name)\n");
561 fprintf (stderr,
"--da makes no sense with --mt as called number is used (i.e. queue name)\n");
564 if (da && strlen (da) > 20)
566 fprintf (stderr,
"--da too long\n");
569 if (oa && strlen (oa) > 20)
571 fprintf (stderr,
"--oa too long\n");
574 if (queue && strlen (queue) > 20)
576 fprintf (stderr,
"--queue name too long\n");
581 fprintf (stderr,
"scts is set my service centre\n");
586 while (udl < 160 && *uds)
591 fprintf (stderr,
"Invalid character U+%X at %d\n", v, udl);
597 if (!uds && !udfile && poptPeekArg (optCon))
599 while (poptPeekArg (optCon) && udl < 160)
601 unsigned char *
a = (
unsigned char *) poptGetArg (optCon);
602 if (udl && udl < 160)
604 while (udl < 160 && *
a)
609 fprintf (stderr,
"Invalid character U+%X at %d\n", v, udl);
616 if (poptPeekArg (optCon))
618 fprintf (stderr,
"Unknown argument %s\n", poptGetArg (optCon));
623 unsigned char dat[1204],
629 f = open (udfile, O_RDONLY);
637 n = read (f, dat,
sizeof (dat));
648 while (p < e && udl < 160 && *p)
652 while (p < e && udl < 160)
656 while (p + 1 < e && udl < 160)
658 ud[udl++] = (*p << 8) + p[1];
665 char *
d = strrchr (queue,
'-');
669 subaddress = *defaultsubaddress;
672 if (chdir (spooldir))
682 *dir = (mo ? rx ?
"sms/morx" :
"sms/motx" : rx ?
"sms/mtrx" :
"sms/mttx");
684 snprintf (temp,
sizeof(temp),
"sms/.smsq-%d", (
int)getpid ());
687 snprintf (queuename,
sizeof(queuename),
"%s/%s.%ld-%d", dir, *queue ? queue :
"0", (long)time (0), (int)getpid ());
688 f = fopen (temp,
"w");
695 fprintf (f,
"oa=%s\n", oa);
697 fprintf (f,
"da=%s\n", da);
699 fprintf (f,
"scts=%s\n", scts);
701 fprintf (f,
"pid=%d\n", pid);
703 fprintf (f,
"dcs=%d\n", dcs);
705 fprintf (f,
"mr=%d\n", mr);
707 fprintf (f,
"srr=1\n");
709 fprintf (f,
"rp=1\n");
711 fprintf (f,
"udh#%s\n", udh);
713 fprintf (f,
"vp=%d\n", vp);
717 for (p = 0; p < udl && ud[p] < 0x100; p++);
720 for (p = 0; p < udl && ud[p] < 0x80 && ud[p] >= 0x20; p++);
724 for (p = 0; p < udl; p++)
729 for (p = 0; p < udl; p++)
730 fprintf (f,
"%02hX", ud[p]);
735 for (p = 0; p < udl; p++)
736 fprintf (f,
"%04hX", ud[p]);
741 if (rename (temp, queuename))
749 if (!nodial && tx && !process)
758 ret =
txqcheck (
"motx", queue, subaddress, motxchannel, motxcallerid, motxwait, motxdelay, motxretries, concurrent);
760 ret =
txqcheck (
"mttx", queue, subaddress, mttxchannel, mttxcallerid, mttxwait, mttxdelay, mttxretries, concurrent);
766 if (ret == 2 && !nowait)
767 fprintf (stderr,
"No call scheduled as already sending\n");
770 rxqcheck (mo ? rx ?
"morx" :
"motx" : rx ?
"mtrx" :
"mttx", queue, process);