1 /*
2  * Return values :
3  *  -1 -> Cannot connect to the host
4  *  -2 -> Connection timed out
5  *  -3 -> Provider not specified
6  *  -4 -> Provider file not found or error in provider script
7  *  -5 -> Arguments list requested
8  *  -6 -> Missing Provider arguments (or too many)
9  *  -7 -> Message is too long
10  *  -8 -> Substitution error during execution
11  *  -9 -> 404 from server
12  * -10 -> Option not supported
13  * -11 -> Unknown reply
14 */
15 
16 /* Define __unix__ in order smssend to compile successfully on Mac OS X */
17 #if defined __MACH__ && defined __APPLE__
18 #define __unix__
19 #endif
20 
21 #ifndef _CONSOLE
22 #ifdef __unix__
23 #include "smssend.h"
24 #else /* !__unix__ */
25 #include "Unit1.h"
26 #endif /* __unix__ */
27 #else /* _CONSOLE */
28 #include "smssend.h"
29 #endif /* !_CONSOLE */
30 
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif /* HAVE_CONFIG_H */
34 
35 #ifndef __unix__
36 #define strcasecmp stricmp
37 #define strncasecmp strnicmp
38 #endif /* !__unix__ */
39 #ifdef _CONSOLE
40 #define __unix__
41 #endif /* _CONSOLE */
42 
43 #ifdef USE_PCRE
44 static int PM_GetRegexMatch(char *data, char*regex, int gpos, int pos, char *buf, int blen);
45 #endif /* USE_PCRE */
46 
47 char MsgBufTempo[40000];
48 char BufTempo[40000];
49 SMS_PProvider CurrentProviderRunning;
50 int CurrentRunningPhase;
51 SU_PList CurrentNoAdd;
52 char *CurrentScriptCheckUpdateName;
53 char CurrentScriptCheckUpdateVersion[10];
54 bool SMS_Quiet = false;
55 #ifdef __unix__
56 int DebugLevel = 0;
57 SU_PList SMS_Alias = NULL;
58 SU_PList SMS_Profiles = NULL; /* SU_PList */
59 #else /* !__unix__ */
60 int Sms_ErrorCode;
61 #endif /* __unix__ */
62 
63 //---------------------------------------------------------------------------
CB_OnOkSmsSend(SU_PAnswer Ans,void * User)64 void CB_OnOkSmsSend(SU_PAnswer Ans,void *User)
65 {
66   if(!SMS_Quiet)
67   {
68     if(strncmp(Ans->Data,SMSSEND_VERSION,3) > 0)
69       printf("A new version of SmsSend is available at https://BSDforge.com/projects/misc/smssend/\n");
70     else
71       printf("You already have the latest version of SmsSend\n");
72     printf("You should now check that you have the latest version of your favourite provider script with 'smssend <provider> -update'\n");
73   }
74 }
75 
CB_OnNotFoundSmsSend(SU_PAnswer Ans,void * User)76 void CB_OnNotFoundSmsSend(SU_PAnswer Ans,void *User)
77 {
78   if(!SMS_Quiet)
79     printf("SmsSend Warning : Page not found\n");
80 }
81 //---------------------------------------------------------------------------
CB_OnOk(SU_PAnswer Ans,void * User)82 void CB_OnOk(SU_PAnswer Ans,void *User)
83 {
84   FILE *fp;
85   char *pos,*pos2,saf;
86   char buf[1024];
87   char FileName[512];
88 
89   pos = strstr(Ans->Data,"Version");
90   if(pos == NULL)
91   {
92     if(!SMS_Quiet)
93       printf("SmsSend Error : Version tag not found in %s script. Aborting\n",CurrentScriptCheckUpdateName);
94     return;
95   }
96   pos+=8; // Zap "Version "
97   pos2 = pos;
98   while((pos2[0] != ' ') && (pos2[0] != 0x0A) && (pos2[0] != 0x0D) && (pos2[0] != '\t'))
99     pos2++;
100   saf = pos2[0];
101   pos2[0] = 0;
102 #ifdef DEBUG
103   printf("Your version : %s - Found version : %s\n",CurrentScriptCheckUpdateVersion,pos);
104 #endif /* DEBUG */
105   if(strcmp(pos,CurrentScriptCheckUpdateVersion) <= 0)
106   {
107     if(!SMS_Quiet)
108       printf("You already have the latest version of %s\n",CurrentScriptCheckUpdateName);
109     return;
110   }
111   pos2[0] = saf;
112   if(!SMS_Quiet)
113     printf("A new version of %s was found, trying to update...\n",CurrentScriptCheckUpdateName);
114   SU_ExtractFileName(CurrentScriptCheckUpdateName,FileName,sizeof(FileName));
115   fp = fopen(CurrentScriptCheckUpdateName,"wt");
116   if(fp == NULL)
117   {
118 #ifndef _WIN32
119     snprintf(buf,sizeof(buf),"%s/.smssend",getenv("HOME"));
120     mkdir(buf,0xFFFF);
121     snprintf(buf,sizeof(buf),"%s/.smssend/%s",getenv("HOME"),FileName);
122     fp = fopen(buf,"wt");
123     if(fp == NULL)
124 #endif /* !_WIN32 */
125     {
126       if(!SMS_Quiet)
127         printf("SmsSend Error : Couldn't open %s. Aborting.\n",buf);
128       return;
129     }
130     if(!SMS_Quiet)
131       printf("SmsSend Warning : Couldn't open %s, saving new script to %s\n",CurrentScriptCheckUpdateName,buf);
132   }
133   fwrite(Ans->Data,1,Ans->Data_Length,fp);
134   fclose(fp);
135   if(!SMS_Quiet)
136     printf("Successfully downloaded new version of %s\n",FileName);
137 }
CB_OnNotFound(SU_PAnswer Ans,void * User)138 void CB_OnNotFound(SU_PAnswer Ans,void *User)
139 {
140   if(!SMS_Quiet)
141     printf("SmsSend Warning : Page not found\n");
142 }
CB_OnOkInstall(SU_PAnswer Ans,void * User)143 void CB_OnOkInstall(SU_PAnswer Ans,void *User)
144 {
145   FILE *fp;
146   char buf[1024];
147   char FileName[512];
148 
149   snprintf(FileName,sizeof(FileName),"%s/%s",SMSSEND_SHAREPATH,CurrentScriptCheckUpdateName);
150   fp = fopen(FileName,"wt");
151   if(fp == NULL)
152   {
153 #ifndef _WIN32
154     snprintf(buf,sizeof(buf),"%s/.smssend",getenv("HOME"));
155     mkdir(buf,0xFFFF);
156     snprintf(buf,sizeof(buf),"%s/.smssend/%s",getenv("HOME"),CurrentScriptCheckUpdateName);
157     fp = fopen(buf,"wt");
158     if(fp == NULL)
159 #endif /* !_WIN32 */
160     {
161       if(!SMS_Quiet)
162         printf("SmsSend Error : Couldn't open %s. Aborting.\n",buf);
163       return;
164     }
165     if(!SMS_Quiet)
166       printf("SmsSend Warning : Couldn't open %s, saving new script to %s\n",FileName,buf);
167   }
168   fwrite(Ans->Data,1,Ans->Data_Length,fp);
169   fclose(fp);
170   if(!SMS_Quiet)
171     printf("Successfully installed new script %s\n",CurrentScriptCheckUpdateName);
172 }
CB_OnNotFoundInstall(SU_PAnswer Ans,void * User)173 void CB_OnNotFoundInstall(SU_PAnswer Ans,void *User)
174 {
175   if(!SMS_Quiet)
176     printf("SmsSend Error : Script %s not found in SmsSend home page. Check script name\n",CurrentScriptCheckUpdateName);
177 }
178 //---------------------------------------------------------------------------
CheckForUpdateSmsSend(void)179 void CheckForUpdateSmsSend(void)
180 {
181   int ret;
182   SU_PList Exec;
183   SU_PHTTPActions Act;
184 
185   Exec = NULL;
186   Act = (SU_PHTTPActions) malloc(sizeof(SU_THTTPActions));
187   memset(Act,0,sizeof(SU_THTTPActions));
188   Act->User = (void *)1;
189   Act->Command = ACT_GET;
190   snprintf(Act->URL,sizeof(Act->URL),"%s%s",SMSSEND_URL_SCRIPTS,"Version.unix");
191   Act->CB.OnOk = CB_OnOkSmsSend;
192   Act->CB.OnNotFound = CB_OnNotFoundSmsSend;
193   Exec = SU_AddElementHead(Exec,Act);
194   ret = SU_ExecuteActions(Exec);
195   SU_FreeAction(Act);
196   SU_FreeList(Exec);
197   if(ret != 0)
198   {
199     if(!SMS_Quiet)
200       printf("SmsSend Error : Cannot connect\n");
201     return;
202   }
203 }
204 
CheckForUpdate(const char Name[])205 void CheckForUpdate(const char Name[])
206 {
207   int ret;
208   SU_PList Exec;
209   SU_PHTTPActions Act;
210   FILE *fp;
211   char FileName[512];
212   char buf[1024];
213   char *pos,*pos2;
214 
215   fp = fopen(Name,"rt");
216   if(fp == NULL)
217     return;
218   fread(buf,1,sizeof(buf),fp);
219   fclose(fp);
220   pos = strstr(buf,"Version");
221   if(pos == NULL)
222     return;
223   pos+=8; // Zap "Version "
224   pos2 = pos;
225   while((pos2[0] != ' ') && (pos2[0] != 0x0A) && (pos2[0] != 0x0D) && (pos2[0] != '\t'))
226     pos2++;
227   pos2[0] = 0;
228   SU_strcpy(CurrentScriptCheckUpdateVersion,pos,sizeof(CurrentScriptCheckUpdateVersion));
229   CurrentScriptCheckUpdateName = (char *)Name;
230 
231   Exec = NULL;
232   Act = (SU_PHTTPActions) malloc(sizeof(SU_THTTPActions));
233   memset(Act,0,sizeof(SU_THTTPActions));
234   Act->User = (void *)1;
235   Act->Command = ACT_GET;
236   SU_ExtractFileName(Name,FileName,sizeof(FileName));
237   snprintf(Act->URL,sizeof(Act->URL),"%s%s",SMSSEND_URL_SCRIPTS,FileName);
238   Act->CB.OnOk = CB_OnOk;
239   Act->CB.OnNotFound = CB_OnNotFound;
240 
241   Exec = SU_AddElementHead(Exec,Act);
242   ret = SU_ExecuteActions(Exec);
243   SU_FreeAction(Act);
244   SU_FreeList(Exec);
245   if(ret != 0)
246   {
247     if(!SMS_Quiet)
248       printf("SmsSend Error : Cannot connect\n");
249     return;
250   }
251 }
252 
InstallScript(const char Name[])253 void InstallScript(const char Name[])
254 {
255   int ret;
256   SU_PList Exec;
257   SU_PHTTPActions Act;
258   char FileName[512];
259 
260   CurrentScriptCheckUpdateName = (char *)Name;
261 
262   Exec = NULL;
263   Act = (SU_PHTTPActions) malloc(sizeof(SU_THTTPActions));
264   memset(Act,0,sizeof(SU_THTTPActions));
265   Act->User = (void *)1;
266   Act->Command = ACT_GET;
267   SU_ExtractFileName(Name,FileName,sizeof(FileName));
268   snprintf(Act->URL,sizeof(Act->URL),"%s%s",SMSSEND_URL_SCRIPTS,FileName);
269   Act->CB.OnOk = CB_OnOkInstall;
270   Act->CB.OnNotFound = CB_OnNotFoundInstall;
271 
272   Exec = SU_AddElementHead(Exec,Act);
273   ret = SU_ExecuteActions(Exec);
274   SU_FreeAction(Act);
275   SU_FreeList(Exec);
276   if(ret != 0)
277   {
278     if(!SMS_Quiet)
279       printf("SmsSend Error : Cannot connect\n");
280     return;
281   }
282 }
283 
RemoveComments(char * Ans,long int len)284 void RemoveComments(char *Ans,long int len)
285 {
286   char last,*tmp,*pos,*pos2;
287 
288   last = Ans[len-1];
289   Ans[len-1] = 0;
290   tmp = Ans;
291   pos = strstr(tmp,"<!--");
292   while(pos != NULL)
293   {
294     pos2 = strstr(pos,"-->");
295     pos += 4;
296     if(pos2 != NULL)
297     {
298       memset(pos,' ',pos2-pos);
299     }
300     tmp = pos;
301     pos = strstr(tmp,"<!--");
302   }
303 
304   Ans[len-1] = last;
305 }
306 
CB_Execute_SendingCommand(SU_PHTTPActions Act)307 void CB_Execute_SendingCommand(SU_PHTTPActions Act)
308 {
309   SMS_PRunTime RT;
310   char *tt;
311 
312 #ifdef __unix__
313   if(DebugLevel >= 1)
314     printf("Executing Phase %d\n",CurrentRunningPhase);
315 #else /* !__unix__ */
316   Form1->StatusBar1->SimpleText = (AnsiString)"Executing phase "+IntToStr(CurrentRunningPhase)+"...";
317   Sms_ErrorCode = 0;
318 #endif /* __unix__ */
319 
320   if(CurrentProviderRunning->Cookies != NULL)
321   {
322     SU_PList Ptr;
323     SMS_PCookie C;
324 
325     Ptr = CurrentProviderRunning->Cookies;
326     C = NULL;
327     while(Ptr != NULL)
328     {
329       C = (SMS_PCookie) Ptr->Data;
330       if(C->Phase == CurrentRunningPhase)
331       {
332 #ifdef __unix__
333         if(DebugLevel >= 4)
334           printf("Phase %d reached. Adding cookie %s\n",CurrentRunningPhase,C->Cookie->Name);
335 #endif /* __unix__ */
336         SW_Cookies = SU_AddElementHead(SW_Cookies,C->Cookie);
337         if(Ptr == CurrentProviderRunning->Cookies)
338         {
339           CurrentProviderRunning->Cookies = SU_DelElementHead(CurrentProviderRunning->Cookies);
340           Ptr = CurrentProviderRunning->Cookies;
341         }
342         else
343           Ptr = SU_DelElementHead(Ptr);
344         free(C);
345       }
346       else
347         Ptr = Ptr->Next;
348     }
349   }
350   CurrentRunningPhase++;
351 
352   RT = (SMS_PRunTime) malloc(sizeof(SMS_TRunTime));
353   memset(RT,0,sizeof(SMS_TRunTime));
354   /* Split Params and URL */
355   tt = strchr(Act->URL,'?');
356   if((tt != NULL) && (Act->URL_Params == NULL))
357   {
358     tt[0] = 0;
359     Act->URL_Params = strdup(tt+1);
360   }
361   RT->URL = strdup(Act->URL);
362   if(Act->URL_Params != NULL)
363     RT->Params = strdup(Act->URL_Params);
364   RT->Host = strdup(Act->Host);
365 #ifdef __unix__
366   if(DebugLevel >= 4)
367     printf("Adding RunTime variables : %s ? %s (%s)\n",RT->URL,(RT->Params == NULL)?"":RT->Params,RT->Host);
368 #endif /* __unix__ */
369   CurrentProviderRunning->RunTime = SU_AddElementTail(CurrentProviderRunning->RunTime,RT);
370 }
371 
CB_Execute_Answer(SU_PAnswer Ans,void * User)372 void CB_Execute_Answer(SU_PAnswer Ans,void *User)
373 {
374   SMS_PRunTime RT;
375 
376   if(Ans->Data == NULL) /* Is there some data here ? */
377     return;
378 #ifdef __unix__
379   if(DebugLevel >= 4)
380     printf("Adding RunTime data\n");
381 #endif /* __unix__ */
382   RT = (SMS_PRunTime)SU_GetElementTail(CurrentProviderRunning->RunTime);
383   if(RT == NULL)
384   {
385     printf("Warning : No runtime struct set.... shouldn't happen !\n");
386   }
387   else
388   {
389     RemoveComments(Ans->Data,Ans->Data_Length);
390     RT->Data = (char *) malloc(Ans->Data_Length+1);
391     memcpy(RT->Data,Ans->Data,Ans->Data_Length);
392     RT->Data[Ans->Data_Length] = 0; /* Safer */
393   }
394 }
395 
CB_Execute_Other(SU_PAnswer Ans,int Code,void * User)396 void CB_Execute_Other(SU_PAnswer Ans,int Code,void *User)
397 {
398 #ifdef __unix__
399   if(!SMS_Quiet)
400     printf("SmsSend Error : Untrapped reply from server (%d).... error in the script ? Contact the author of the script\n",Code);
401   exit(-11);
402 #else /* !__unix__ */
403   Form1->StatusBar1->SimpleText = (AnsiString)"Error : Untrapped reply from server ("+IntToStr(Code)+").... error in the script ? Contact the author of the script";
404   Sms_ErrorCode = -11;
405   return;
406 #endif /* __unix__ */
407 }
408 
CB_Execute_404(SU_PAnswer Ans,void * User)409 void CB_Execute_404(SU_PAnswer Ans,void *User)
410 {
411 #ifdef __unix__
412   if(!SMS_Quiet)
413     printf("SmsSend Error : 404 answer from server.... error in the script ? Contact the author of the script\n");
414   exit(-9);
415 #else /* !__unix__ */
416   Form1->StatusBar1->SimpleText = (AnsiString)"Error : 404 answer from server.... error in the script ? Contact the author of the script";
417   Sms_ErrorCode = -9;
418   return;
419 #endif /* __unix__ */
420 }
421 
422 char *TranslateString(char *Strng,SMS_PProvider Pv);
423 
CB_Execute_200(SU_PAnswer Ans,void * User)424 void CB_Execute_200(SU_PAnswer Ans,void *User)
425 {
426   SU_PList Ptr;
427   SMS_PSearch S;
428   int Group;
429   int Found;
430   SMS_PActUser AU;
431 
432   AU = (SMS_PActUser) User;
433   if(AU == NULL)
434     return;
435   Ptr = AU->Search;
436   Found = 0;
437   Group = -1;
438   while(Ptr != NULL)
439   {
440     S = (SMS_PSearch)Ptr->Data;
441     if(S->Group != Group)
442     {
443       Group = S->Group;
444       Found = 0;
445     }
446     if(!Found)
447     {
448       if(S->String == NULL)
449       {
450         if(S->Error != 0)
451         {
452 #ifdef __unix__
453           if(!SMS_Quiet)
454             printf("SmsSend Error : %s\n",TranslateString(S->Msg,CurrentProviderRunning));
455           exit(S->Error);
456 #else /* !__unix__ */
457           Form1->StatusBar1->SimpleText = (AnsiString)"Error : " + (AnsiString)TranslateString(S->Msg,CurrentProviderRunning);
458           Sms_ErrorCode = S->Error;
459           return;
460 #endif /* __unix__ */
461         }
462         else
463         {
464 #ifdef __unix__
465           if(!SMS_Quiet)
466 #endif /* __unix__ */
467             printf("Result : %s\n",TranslateString(S->Msg,CurrentProviderRunning));
468         }
469         Found = 1;
470       }
471       else
472       {
473         if(Ans->Data != NULL)
474         {
475           if(strstr(Ans->Data,S->String) != NULL)
476           {
477             if(S->Error != 0)
478             {
479 #ifdef __unix__
480               if(!SMS_Quiet)
481                 printf("SmsSend Error : %s\n",TranslateString(S->Msg,CurrentProviderRunning));
482               exit(S->Error);
483 #else /* !__unix__ */
484               Form1->StatusBar1->SimpleText = (AnsiString)"Error : " + (AnsiString)TranslateString(S->Msg,CurrentProviderRunning);
485               Sms_ErrorCode = S->Error;
486               return;
487 #endif /* __unix__ */
488             }
489             else
490             {
491 #ifdef __unix__
492               if(!SMS_Quiet)
493 #endif /* __unix__ */
494                 printf("Result : %s\n",TranslateString(S->Msg,CurrentProviderRunning));
495             }
496             Found = 1;
497           }
498         }
499       }
500     }
501     Ptr = Ptr->Next;
502   }
503 }
504 
CheckMessage(char Msg[],const int LenMax)505 char *CheckMessage(char Msg[],const int LenMax)
506 {
507   int i,len,pos,val;
508   char NB[10];
509 
510   len = strlen(Msg);
511   if(len > LenMax)
512   {
513 #ifdef __unix__
514     if(!SMS_Quiet)
515       printf("Message too long : %d caracters max (yours is %d long)\n",LenMax,len);
516     exit(-7);
517 #else /* !__unix__ */
518     Form1->StatusBar1->SimpleText = "Message too long : "+IntToStr(LenMax)+" caracters max (yours is "+IntToStr(len)+" long)";
519     Sms_ErrorCode = -7;
520     return NULL;
521 #endif /* __unix__ */
522   }
523   pos = 0;
524   for(i=0;i<len;i++)
525   {
526     if(Msg[i] == 0)
527       continue;
528     if((Msg[i] == ' ')/* || (Msg[i] == 0x0a) || (Msg[i] == 0x0d)*/)
529       MsgBufTempo[pos++] = '+';
530     else if(((Msg[i] >='A') && (Msg[i] <='Z')) || ((Msg[i] >='a') && (Msg[i] <='z')) || ((Msg[i] >='0') && (Msg[i] <='9')) || (Msg[i] == '.') || (Msg[i] == '-') || (Msg[i] == '_') || (Msg[i] == '*'))
531       MsgBufTempo[pos++] = Msg[i];
532     else if(Msg[i] == '\\')
533     {
534       NB[0] = Msg[i+1];
535       NB[1] = Msg[i+2];
536       NB[2] = 0;
537       sscanf(NB,"%x",&val);
538       printf("val:%d\n",val);
539       Msg[i+1] = 0;
540       Msg[i+2] = val;
541     }
542     else
543     {
544       MsgBufTempo[pos++] = '%';
545       snprintf(NB,sizeof(NB),"%.2x",Msg[i]);
546       MsgBufTempo[pos++] = NB[strlen(NB)-2];
547       MsgBufTempo[pos++] = NB[strlen(NB)-1];
548     }
549   }
550   MsgBufTempo[pos] = 0;
551   return MsgBufTempo;
552 }
553 
FreeRunTime(SMS_PRunTime RT)554 void FreeRunTime(SMS_PRunTime RT)
555 {
556   if(RT->URL != NULL)
557     free(RT->URL);
558   if(RT->Params != NULL)
559     free(RT->Params);
560   if(RT->Host != NULL)
561     free(RT->Host);
562   if(RT->Data != NULL)
563     free(RT->Data);
564   free(RT);
565 }
566 
FreeRunTimeList(SU_PList RTL)567 void FreeRunTimeList(SU_PList RTL)
568 {
569   SU_PList Ptr;
570 
571   Ptr = RTL;
572   while(Ptr != NULL)
573   {
574     FreeRunTime((SMS_PRunTime)Ptr->Data);
575     Ptr = Ptr->Next;
576   }
577   SU_FreeList(RTL);
578 }
579 
FreeProviderCookies(SU_PList Cookies)580 void FreeProviderCookies(SU_PList Cookies)
581 {
582   SU_PList Ptr;
583 
584   Ptr = Cookies;
585   while(Ptr != NULL)
586   {
587     SU_FreeCookie(((SMS_PCookie)Ptr->Data)->Cookie);
588     Ptr = Ptr->Next;
589   }
590   SU_FreeList(Cookies);
591 }
592 
FreeProvider(SMS_PProvider Pv)593 void FreeProvider(SMS_PProvider Pv)
594 {
595   int i;
596   SU_PList Ptr,Read;
597   SMS_PSearch S;
598   SMS_PActUser AU;
599 
600   if(Pv->Params != NULL)
601   {
602     for(i=0;i<Pv->NbParams;i++)
603     {
604       if(Pv->Params[i].Name != NULL)
605         free(Pv->Params[i].Name);
606       if(Pv->Params[i].Value != NULL)
607         free(Pv->Params[i].Value);
608       if(Pv->Params[i].Help != NULL)
609         free(Pv->Params[i].Help);
610       if(Pv->Params[i].Alias != NULL)
611         free(Pv->Params[i].Alias);
612     }
613     free(Pv->Params);
614   }
615   Read = Pv->Act;
616   while(Read != NULL)
617   {
618     AU = (SMS_PActUser) ((SU_PHTTPActions)Read->Data)->User;
619     if(AU != NULL)
620     {
621       Ptr = AU->Search;
622       while(Ptr != NULL)
623       {
624         S = (SMS_PSearch)Ptr->Data;
625         if(S->String != NULL)
626           free(S->String);
627         free(S->Msg);
628         free(S);
629         Ptr = Ptr->Next;
630       }
631       SU_FreeList(AU->Search);
632       SU_FreeListElem(AU->NoAdd);
633     }
634     SU_FreeAction((SU_PHTTPActions)Read->Data);
635     Read = Read->Next;
636   }
637   if(Pv->Act != NULL)
638     SU_FreeList(Pv->Act);
639   if(Pv->RunTime != NULL)
640     FreeRunTimeList(Pv->RunTime);
641   if(Pv->Cookies != NULL)
642     FreeProviderCookies(Pv->Cookies);
643 #ifndef __unix__
644   if(Pv->Path != NULL)
645     free(Pv->Path);
646 #endif /* __unix__ */
647   free(Pv);
648 }
649 
LoadProviderFile(const char FileName[])650 SMS_PProvider LoadProviderFile(const char FileName[])
651 {
652   FILE *fp;
653   char Name[1024],Value[1024],Saf[1024],*Str;
654   SMS_PProvider Pv;
655   int NbParams;
656   int Group,i,found,Phase;
657   SU_PHTTPActions Act;
658   SU_PList SearchPtr,NoAddPtr;
659   SU_PCookie Cookie;
660   SMS_PSearch S;
661   SMS_PCookie C;
662   char *tmp;
663   SMS_PActUser AU;
664 
665   fp = fopen(FileName,"rt");
666   if(fp == NULL)
667     return NULL;
668 
669   Pv = (SMS_PProvider) malloc(sizeof(SMS_TProvider));
670   memset(Pv,0,sizeof(SMS_TProvider));
671 #ifndef __unix__
672   Pv->Path = strdup(FileName);
673 #endif /* __unix__ */
674   NbParams = 0;
675   Group = 0;
676   SearchPtr = NULL;
677   NoAddPtr = NULL;
678   Act = NULL;
679   S = NULL;
680 
681   while(SU_ParseConfig(fp,Name,sizeof(Name),Value,sizeof(Value)))
682   {
683     if(strcasecmp(Name,"NbParams") == 0)
684     {
685       Pv->NbParams = atoi(Value);
686       Pv->Params = (SMS_TParam *) malloc(Pv->NbParams*sizeof(SMS_TParam));
687       memset(Pv->Params,0,Pv->NbParams*sizeof(SMS_TParam));
688     }
689     else if(Name[0] == '%')
690     {
691       if(NbParams >= Pv->NbParams)
692       {
693         printf("SmsSend Error in provider loader : More than NbParams has been found\n");
694         FreeProvider(Pv);
695         return NULL;
696       }
697       Pv->Params[NbParams].Name = strdup(Name+1);
698       if(Value[0] != 0)
699       {
700         if(Value[0] == ':')
701         {
702           Pv->Params[NbParams].Help = strdup(SU_TrimLeft(Value+1));
703         }
704         strcpy(Saf,Value);
705         Str = strtok(Value," ");
706         while(Str != NULL)
707         {
708           if(strcasecmp(Str,"Hidden") == 0)
709             Pv->Params[NbParams].Hidden = 1;
710           else if(strcasecmp(Str,"Convert") == 0)
711             Pv->Params[NbParams].Convert = 1;
712           else if(strncasecmp(Str,"Size",4) == 0)
713             Pv->Params[NbParams].Size = atoi(Str+5);
714           else if(Str[0] == ':')
715           {
716             Str = strchr(Saf,':');
717             Pv->Params[NbParams].Help = strdup(SU_TrimLeft(Str+1));
718             break;
719           }
720           else
721             printf("Unknown option in Param values : %s\n",Str);
722           Str = strtok(NULL," ");
723         }
724       }
725       NbParams++;
726 #ifndef __unix__
727       if(NbParams > 8)
728       {
729         Application->MessageBox("This version of SmsSend doesn't support more than 8 parameters... If you really need more than 8, please contact me for an upgrade","SmsSend Error",MB_OK);
730         FreeProvider(Pv);
731         return NULL;
732       }
733 #endif /* !__unix__ */
734     }
735     else if(Name[0] == '$')
736     {
737       if(Value[0] == 0)
738         printf("SmsSend Warning in provider loader : Alias value not found for %s\n",Name+1);
739       else
740       {
741         found = 0;
742         for(i=0;i<NbParams;i++)
743         {
744           if(strcasecmp(Pv->Params[i].Name,Name+1) == 0)
745           {
746 #ifdef __unix__
747             if(DebugLevel >= 4)
748               printf("Adding alias : %s <-> %s\n",Name+1,Value);
749 #endif /* __unix__ */
750             Pv->Params[i].Alias = strdup(Value);
751             found = 1;
752           }
753         }
754         if(found == 0)
755           printf("SmsSend Warning in provider loader : Parameter %s not found for alias %s\n",Name+1,Value);
756       }
757     }
758     else if(strcasecmp(Name,"GetURL") == 0)
759     {
760       if(Act != NULL)
761         printf("SmsSend Warning in provider loader : Multiple GetURL/PostURL found in the same block : %s %s\n",Name,Value);
762       Act = (SU_PHTTPActions) malloc(sizeof(SU_THTTPActions));
763       memset(Act,0,sizeof(SU_THTTPActions));
764       Act->Command = ACT_GET;
765       SU_strcpy(Act->URL,Value,sizeof(Act->URL));
766     }
767     else if(strcasecmp(Name,"Params") == 0)
768     {
769       if(Act == NULL)
770         printf("SmsSend Warning in provider loader : Params found, but no GetURL/PostURL found in this block : %s %s\n",Name,Value);
771       else
772         Act->URL_Params = strdup(Value);
773     }
774     else if(strcasecmp(Name,"Referer") == 0)
775     {
776       if(Act == NULL)
777         printf("SmsSend Warning in provider loader : Referer found, but no GetURL/PostURL found in this block : %s %s\n",Name,Value);
778       else
779         Act->Referer = strdup(Value);
780     }
781     else if(strcasecmp(Name,"Dump") == 0)
782     {
783       if(Act == NULL)
784         printf("SmsSend Warning in provider loader : Dump found, but no GetURL/PostURL found in this block : %s %s\n",Name,Value);
785       else
786         Act->FileName = strdup(Value);
787     }
788     else if(strcasecmp(Name,"PostURL") == 0)
789     {
790       if(Act != NULL)
791         printf("SmsSend Warning in provider loader : Multiple GetURL/PostURL found in the same block : %s %s\n",Name,Value);
792       Act = (SU_PHTTPActions) malloc(sizeof(SU_THTTPActions));
793       memset(Act,0,sizeof(SU_THTTPActions));
794       Act->Command = ACT_POST;
795       SU_strcpy(Act->URL,Value,sizeof(Act->URL));
796     }
797     else if(strcasecmp(Name,"PostData") == 0)
798     {
799       if(Act == NULL)
800         printf("SmsSend Warning in provider loader : PostData found, but no GetURL/PostURL found in this block : %s %s\n",Name,Value);
801       else
802       {
803         Act->Post_Data = strdup(Value);
804         Act->Post_Length = strlen(Act->Post_Data);
805       }
806     }
807     else if(strcasecmp(Name,"Search") == 0)
808     {
809       if(Act == NULL)
810         printf("SmsSend Warning in provider loader : Search found, but no GetURL/PostURL found in this block : %s %s\n",Name,Value);
811       Group++;
812       S = (SMS_PSearch) malloc(sizeof(SMS_TSearch));
813       memset(S,0,sizeof(SMS_TSearch));
814       S->String = strdup(Value);
815       S->Group = Group;
816     }
817     else if(strcasecmp(Name,"ElseSearch") == 0)
818     {
819       if(Act == NULL)
820         printf("SmsSend Warning in provider loader : ElseSearch found, but no GetURL/PostURL found in this block : %s %s\n",Name,Value);
821       S = (SMS_PSearch) malloc(sizeof(SMS_TSearch));
822       memset(S,0,sizeof(SMS_TSearch));
823       S->String = strdup(Value);
824       S->Group = Group;
825     }
826     else if(strcasecmp(Name,"Else") == 0)
827     {
828       if(Act == NULL)
829         printf("SmsSend Warning in provider loader : Else found, but no GetURL/PostURL found in this block : %s %s\n",Name,Value);
830       S = (SMS_PSearch) malloc(sizeof(SMS_TSearch));
831       memset(S,0,sizeof(SMS_TSearch));
832       S->Group = Group;
833     }
834     else if(strcasecmp(Name,"ErrorMsg") == 0)
835     {
836       if(Act == NULL)
837         printf("SmsSend Warning in provider loader : ErrorMsg found, but no GetURL/PostURL found in this block : %s %s\n",Name,Value);
838       if(S == NULL)
839         printf("SmsSend Warning in provider loader : ErrorMsg defined without Search option : %s %s\n",Name,Value);
840       else
841       {
842         tmp = strtok(Value," ");
843         if(tmp == NULL)
844           printf("SmsSend Warning in provider loader : Missing either Exit code or Error String : %s %s\n",Name,Value);
845         else
846         {
847           S->Error = atoi(tmp);
848           tmp = strtok(NULL,"\0");
849           if(tmp == NULL)
850             printf("SmsSend Warning in provider loader : Missing Error String : %s %s\n",Name,Value);
851           else
852           {
853             S->Msg = strdup(tmp);
854             SearchPtr = SU_AddElementTail(SearchPtr,S);
855           }
856         }
857         S = NULL; /* Just in case */
858       }
859     }
860     else if(strcasecmp(Name,"PrintMsg") == 0)
861     {
862       if(Act == NULL)
863         printf("SmsSend Warning in provider loader : PrintMsg found, but no GetURL/PostURL found in this block : %s %s\n",Name,Value);
864       if(S == NULL)
865         printf("SmsSend Warning in provider loader : PrintMsg defined without Search option : %s %s\n",Name,Value);
866       else
867       {
868         S->Msg = strdup(Value);
869         SearchPtr = SU_AddElementTail(SearchPtr,S);
870         S = NULL; /* Just in case */
871       }
872     }
873     else if(strcasecmp(Name,"GO") == 0)
874     {
875       if(Act == NULL)
876         printf("SmsSend Warning in provider loader : GO found, but no GetURL/PostURL found in this block : %s %s\n",Name,Value);
877       else
878       {
879         if((SearchPtr != NULL) || (NoAddPtr != NULL))
880         {
881           AU = (SMS_PActUser) malloc(sizeof(SMS_TActUser));
882           memset(AU,0,sizeof(SMS_TActUser));
883           AU->Search = SearchPtr;
884           AU->NoAdd = NoAddPtr;
885           Act->User = AU;
886           SearchPtr = NULL;
887           NoAddPtr = NULL;
888           Act->CB.OnOtherReply = CB_Execute_Other;
889           Act->CB.OnNotFound = CB_Execute_404;
890           Act->CB.OnOk = CB_Execute_200;
891         }
892         Act->CB.OnSendingCommand = CB_Execute_SendingCommand;
893         Act->CB.OnAnswer = CB_Execute_Answer;
894         Pv->Act = SU_AddElementTail(Pv->Act,Act);
895         Act = NULL; /* Just in case */
896       }
897     }
898     else if(strcasecmp(Name,"NoAdd") == 0)
899     {
900       if(Act == NULL)
901         printf("SmsSend Warning in provider loader : NoAdd found, but no GetURL/PostURL found in this block : %s %s\n",Name,Value);
902       else
903         NoAddPtr = SU_AddElementTail(NoAddPtr,strdup(Value));
904     }
905     else if(strcasecmp(Name,"Sleep") == 0)
906     {
907       if(Act == NULL)
908         printf("SmsSend Warning in provider loader : Sleep found, but no GetURL/PostURL found in this block : %s %s\n",Name,Value);
909       else
910         Act->Sleep = atoi(Value);
911     }
912     else if(strcasecmp(Name,"SetCookie") == 0)
913     {
914       Cookie = (SU_PCookie) malloc(sizeof(SU_TCookie));
915       memset(Cookie,0,sizeof(SU_TCookie));
916       tmp = strtok(Value," ");
917       if(tmp == NULL)
918       {
919         printf("SmsSend Warning in provider loader : Cookie has no phase, ignoring : %s\n",Value);
920         SU_FreeCookie(Cookie);
921         continue;
922       }
923       Phase = atoi(tmp);
924       if(Phase == 0)
925       {
926         printf("SmsSend Warning in provider loader : Bad phase number for cookie (or not set) : %s\n",tmp);
927         SU_FreeCookie(Cookie);
928         continue;
929       }
930       tmp = strtok(NULL,"-");
931       if(tmp == NULL)
932       {
933         printf("SmsSend Warning in provider loader : Cookie has no domain, ignoring : %s\n",Value);
934         SU_FreeCookie(Cookie);
935         continue;
936       }
937       Cookie->Domain = strdup(tmp);
938       tmp = strtok(NULL,"-");
939       if(tmp == NULL)
940       {
941         printf("SmsSend Warning in provider loader : Cookie has no path, ignoring : %s\n",Value);
942         SU_FreeCookie(Cookie);
943         continue;
944       }
945       Cookie->Path = strdup(tmp);
946       tmp = strtok(NULL,"=");
947       if(tmp == NULL)
948       {
949         printf("SmsSend Warning in provider loader : Cookie has no value, ignoring : %s\n",Value);
950         SU_FreeCookie(Cookie);
951         continue;
952       }
953       Cookie->Name = strdup(tmp);
954       Cookie->Value = strdup(strtok(NULL,"\0"));
955 
956       //SW_Cookies = SU_AddElementHead(SW_Cookies,Cookie);
957       C = (SMS_PCookie) malloc(sizeof(SMS_TCookie));
958       memset(C,0,sizeof(SMS_TCookie));
959       C->Phase = Phase;
960       C->Cookie = Cookie;
961       Pv->Cookies = SU_AddElementTail(Pv->Cookies,C);
962 #ifdef __unix__
963       if(DebugLevel >= 4)
964         printf("Adding cookie %s=%s for %s%s at phase %d\n",Cookie->Name,Cookie->Value,Cookie->Domain,Cookie->Path,Phase);
965 #endif /* __unix__ */
966     }
967     else if(strcasecmp(Name,"UserAgent") == 0)
968     {
969       SU_SetUserAgent(Value);
970     }
971     else
972     {
973       printf("SmsSend Warning in provider loader : Unknown option : %s %s\n",Name,Value);
974     }
975   }
976 
977   fclose(fp);
978 
979   return Pv;
980 }
981 
GetRunTimeValue(SMS_PProvider Pv,char * Num,int Type)982 char *GetRunTimeValue(SMS_PProvider Pv,char *Num,int Type)
983 {
984   int val;
985   SMS_PRunTime RT;
986 
987   val = atoi(Num);
988   if(val == 0)
989   {
990     printf("Warning : RunTime value seems to be invalid (0) : %s\n",Num);
991     return NULL;
992   }
993 #ifdef __unix__
994   if(DebugLevel >= 4)
995     printf("Getting run time value from phase %d\n",val);
996 #endif /* __unix__ */
997   RT = (SMS_PRunTime)SU_GetElementPos(Pv->RunTime,val-1); /* First Run time is 1, but first SU_PList element is 0 */
998   if(RT == NULL)
999   {
1000     printf("Warning : RunTime value not found in SU_PList at pos %d\n",val);
1001     return NULL;
1002   }
1003   switch(Type)
1004   {
1005     case RUNTIME_URL : return RT->URL;
1006     case RUNTIME_PARAMS : return RT->Params;
1007     case RUNTIME_HOST : return RT->Host;
1008     case RUNTIME_DATA : return RT->Data;
1009     default : return NULL;
1010   }
1011 }
1012 
TranslateString(char * Strng,SMS_PProvider Pv)1013 char *TranslateString(char *Strng,SMS_PProvider Pv)
1014 {
1015   int i,pos,found,do_it,read,j;
1016   char *p,*str=NULL,*S,*saf,*hst;
1017   char *data,*q,*r;
1018   SU_PHTTPActions Act = NULL;
1019   char buf[20000];
1020   char fbuf[40000];
1021   char cmd[1024];
1022   char *tmpname,*tmpname2;
1023   SU_PInput In;
1024   SU_PForm Form;
1025   SU_PList Ptr,Ptr2,InputGet = NULL;
1026   FILE *fp_out;
1027   char tbuf[1024];
1028 
1029   saf = strdup(Strng);
1030   S = saf;
1031   BufTempo[0] = 0;
1032   pos = 0;
1033   while(*S != 0)
1034   {
1035     if((*S == '\\') && (S[1] == '%'))
1036     {
1037       S+=2;
1038       found = -1;
1039       p = strchr(S,'%');
1040       if(p != NULL)
1041       {
1042         p[0] = 0;
1043         p++;
1044         if(strncasecmp(S,"RTURL-",6) == 0)
1045         {
1046           str = GetRunTimeValue(Pv,S+6,RUNTIME_URL);
1047           if(str != NULL)
1048             found = 0;
1049         }
1050         else if(strncasecmp(S,"RTParams-",9) == 0)
1051         {
1052           str = GetRunTimeValue(Pv,S+9,RUNTIME_PARAMS);
1053           if(str != NULL)
1054             found = 0;
1055         }
1056         else if(strncasecmp(S,"RTHost-",7) == 0)
1057         {
1058           str = GetRunTimeValue(Pv,S+7,RUNTIME_HOST);
1059           if(str != NULL)
1060             found = 0;
1061         }
1062         else if(strncasecmp(S,"RTFollowLink-",13) == 0)
1063         {
1064           int phase, numcount, index = 1;
1065           numcount = sscanf(S+13, "%d-%d-", &phase, &index);
1066           q = strchr(S+13,'-');
1067           if(numcount == 2)
1068             q = strchr(q+1, '-');
1069           if(q != NULL)
1070           {
1071             q[0] = 0;q++;
1072             str = GetRunTimeValue(Pv,S+13,RUNTIME_URL);
1073             data = GetRunTimeValue(Pv,S+13,RUNTIME_DATA);
1074             if((str != NULL) && (data != NULL))
1075             {
1076               Act = SU_RetrieveLink(str,data,q,index);
1077               if(Act != NULL)
1078               {
1079                 found = 0;
1080                 SU_strcpy(buf,Act->URL,sizeof(buf));
1081                 str = buf;
1082                 SU_FreeAction(Act);
1083               }
1084             }
1085           }
1086         }
1087         else if(strncasecmp(S,"RTFollowFrame-",14) == 0)
1088         {
1089           q = strchr(S+14,'-');
1090           if(q != NULL)
1091           {
1092             q[0] = 0;q++;
1093             str = GetRunTimeValue(Pv,S+14,RUNTIME_URL);
1094             data = GetRunTimeValue(Pv,S+14,RUNTIME_DATA);
1095             if((str != NULL) && (data != NULL))
1096             {
1097               Act = SU_RetrieveFrame(str,data,q);
1098               if(Act != NULL)
1099               {
1100                 found = 0;
1101                 SU_strcpy(buf,Act->URL,sizeof(buf));
1102                 str = buf;
1103                 SU_FreeAction(Act);
1104               }
1105             }
1106           }
1107         }
1108         else if(strncasecmp(S,"RTRegex-",8) == 0)
1109         {
1110 #ifdef USE_PCRE
1111           q = strchr(S+8,'-');
1112           if(q != NULL)
1113           {
1114             q[0] = 0;q++;
1115             data = GetRunTimeValue(Pv,S+8,RUNTIME_DATA);
1116             if(data != NULL) {
1117               r = strchr(q,'-');
1118               if (r != NULL) {
1119                 int gpos; char *s;
1120                 r[0] = 0;r++;
1121                 gpos = atoi(q);
1122                 s = strchr(r,'-');
1123                 if (s != NULL) {
1124                   int pos;
1125                   s[0] = 0;s++;
1126                   pos = atoi(r);
1127                   if (PM_GetRegexMatch(data,s,gpos,pos,buf,sizeof(buf)) == 0) {
1128                     found = 0;
1129                     str = buf;
1130 		  }
1131 		}
1132               }
1133             }
1134           }
1135 #else /* !USE_PCRE */
1136 #ifdef __unix__
1137           if(!SMS_Quiet)
1138             printf("Option RTRegex not supported by this version of smssend (try to recompile with pcre support)\n");
1139           exit(-10);
1140 #else /* !__unix__ */
1141           Form1->StatusBar1->SimpleText = "Option RTRegex not supported by this version of smssend (try to recompile with pcre support)";
1142           Sms_ErrorCode = -10;
1143           return NULL;
1144 #endif /* __unix__ */
1145 #endif /* USE_PCRE */
1146         }
1147         else if(strncasecmp(S,"RTGetInput-",11) == 0)
1148         {
1149           q = strchr(S+11,'-');
1150           if(q != NULL)
1151           {
1152             q[0] = 0;q++;
1153             data = GetRunTimeValue(Pv,S+11,RUNTIME_DATA);
1154             if(data != NULL)
1155             {
1156               In = SU_GetInput(data);
1157               while(In != NULL)
1158               {
1159                 if(strcasecmp(In->Name,q) == 0)
1160                 {
1161                   InputGet = SU_AddElementHead(InputGet,strdup(In->Name));
1162                   found = 0;
1163                   SU_strcpy(buf,In->Value,sizeof(buf));
1164                   str = buf;
1165                   SU_FreeInput(In);
1166                   break;
1167                 }
1168                 SU_FreeInput(In);
1169                 In = SU_GetNextInput();
1170               }
1171             }
1172           }
1173         }
1174         else if(strncasecmp(S,"RTGetInput2-",12) == 0)
1175         {
1176           q = strchr(S+12,'-');
1177           if(q != NULL)//      q     r
1178           {//RTGetInput2-<num>-<idx>-<flags>
1179             q[0] = 0;q++;
1180             data = GetRunTimeValue(Pv,S+12,RUNTIME_DATA);
1181             if(data != NULL)
1182             {
1183               r = strchr(q,'-');
1184               if(r != NULL)
1185               {
1186                 r[0] = 0;r++;
1187                 i = 1;
1188                 j = atoi(q);
1189                 In = SU_GetInput(data);
1190                 while(In != NULL)
1191                 {
1192                   if(i == j)
1193                   {
1194                     InputGet = SU_AddElementHead(InputGet,strdup(In->Name));
1195                     found = 0;
1196                     switch(*r)
1197                     {
1198                       case 'A' : /* want name and value */
1199                         snprintf(buf,sizeof(buf),"\"%s\"=\"%s\"",In->Name,In->Value);break;
1200                       case 'a' : /* want name and value */
1201                         snprintf(buf,sizeof(buf),"%s=%s",In->Name,In->Value);break;
1202                       case 'N' : /* want only name */
1203                         snprintf(buf,sizeof(buf),"\"%s\"",In->Name);break;
1204                       case 'n' : /* want only name */
1205                         snprintf(buf,sizeof(buf),"%s",In->Name);break;
1206                       case 'V' : /* want only value */
1207                         snprintf(buf,sizeof(buf),"\"%s\"",In->Value);break;
1208                       case 'v' : /* want only value */
1209                         snprintf(buf,sizeof(buf),"%s",In->Value);break;
1210                       case 'T' : /* want only type */
1211                         snprintf(buf,sizeof(buf),"\"%s\"",In->Type);break;
1212                       case 't' : /* want only type */
1213                         snprintf(buf,sizeof(buf),"%s",In->Type);break;
1214                       default :
1215 #ifdef __unix__
1216                         printf("SmsSend Error in Execute : Unknown flag in RTGetInput2 : %c\n",*r);
1217                         free(saf);
1218                         exit(-8);
1219 #else /* !__unix__ */
1220                         Form1->StatusBar1->SimpleText = (AnsiString)"Error in Execute : Unknown flag in RTGetInput2";
1221                         free(saf);
1222                         Sms_ErrorCode = -8;
1223                         return NULL;
1224 #endif /* __unix__ */
1225                     }
1226                     str = buf;
1227                     SU_FreeInput(In);
1228                     break;
1229                   }
1230                   SU_FreeInput(In);
1231                   In = SU_GetNextInput();
1232                   i++;
1233                 }
1234               }
1235             }
1236           }
1237         }
1238         else if(strncasecmp(S,"RTGetInput3-",12) == 0)
1239         {
1240           q = strchr(S+12,'-');
1241           if(q != NULL)
1242           {
1243             q[0] = 0;q++;
1244             data = GetRunTimeValue(Pv,S+12,RUNTIME_DATA);
1245             if(data != NULL)
1246             {
1247               r = strchr(q,'-');
1248               if(r != NULL)
1249               {
1250                 r[0] = 0;r++;
1251                 Form = SU_RetrieveForm(data,atoi(q));
1252                 if(Form != NULL)
1253                 {
1254                   Ptr = Form->Inputs;
1255                   i = 1;
1256                   j = atoi(r);
1257                   while(Ptr != NULL)
1258                   {
1259                     if(i == j)
1260                     {
1261                       In = (SU_PInput)Ptr->Data;
1262                       InputGet = SU_AddElementHead(InputGet,strdup(In->Name));
1263                       found = 0;
1264                       snprintf(buf,sizeof(buf),"\"%s\"=\"%s\"",In->Name,In->Value);
1265                       str = buf;
1266                       SU_FreeForm(Form);
1267                       break;
1268                     }
1269                     Ptr = Ptr->Next;
1270                     i++;
1271                   }
1272                   SU_FreeForm(Form);
1273                 }
1274               }
1275             }
1276           }
1277         }
1278         else if(strncasecmp(S,"RTFormAction-",13) == 0)
1279         {
1280           q = strchr(S+13,'-');
1281           if(q != NULL)
1282           {
1283             q[0] = 0;q++;
1284             data = GetRunTimeValue(Pv,S+13,RUNTIME_DATA);
1285             if(data != NULL)
1286             {
1287               Form = SU_RetrieveForm(data,atoi(q));
1288               if(Form != NULL)
1289               {
1290                 if(strncmp(Form->Action,"http://",7) != 0) /* If Action is relative */
1291                 {
1292                   if(strncmp(Form->Action,"https://",8) != 0) /* If Action is REALLY relative */
1293                   {
1294                     str = GetRunTimeValue(Pv,S+13,RUNTIME_URL);
1295                     hst = GetRunTimeValue(Pv,S+13,RUNTIME_HOST);
1296                     if((str != NULL) && (hst != NULL))
1297                     {
1298                       str = SU_AddLocationToUrl(str,hst,Form->Action,strncasecmp(str,"https://",8) == 0);
1299                       SU_strcpy(fbuf,str,sizeof(fbuf));
1300                       free(str);
1301                       found = 0;
1302                     }
1303                   }
1304                   else
1305                   {
1306                     SU_strcpy(fbuf,Form->Action,sizeof(fbuf));
1307                     found = 0;
1308                   }
1309                 }
1310                 else
1311                 {
1312                   SU_strcpy(fbuf,Form->Action,sizeof(fbuf));
1313                   found = 0;
1314                 }
1315                 str = fbuf;
1316                 SU_FreeForm(Form);
1317               }
1318             }
1319           }
1320         }
1321         else if(strncasecmp(S,"RTGetForm-",10) == 0)
1322         {
1323           q = strchr(S+10,'-');
1324           if(q != NULL)
1325           {
1326             q[0] = 0;q++;
1327             data = GetRunTimeValue(Pv,S+10,RUNTIME_DATA);
1328             if(data != NULL)
1329             {
1330               Form = SU_RetrieveForm(data,atoi(q));
1331               if(Form != NULL)
1332               {
1333                 Ptr = Form->Inputs;
1334                 fbuf[0] = 0;
1335                 while(Ptr != NULL)
1336                 {
1337                   In = (SU_PInput)Ptr->Data;
1338                   do_it = true;
1339                   Ptr2 = InputGet;
1340                   while(Ptr2 != NULL)
1341                   {
1342                     if(In->Name != NULL)
1343                     {
1344                       if(strcasecmp((char *)Ptr2->Data,In->Name) == 0)
1345                       {
1346 #ifdef __unix__
1347                         if(DebugLevel >= 4)
1348                           printf("Not adding %s input, because already added by script\n",In->Name);
1349 #endif /* __unix__ */
1350                         do_it = false;
1351                         break;
1352                       }
1353                     }
1354                     Ptr2 = Ptr2->Next;
1355                   }
1356                   if(do_it)
1357                   {
1358                     Ptr2 = CurrentNoAdd;
1359                     while(Ptr2 != NULL)
1360                     {
1361                       if(In->Name != NULL)
1362                       {
1363                         if(strcasecmp((char *)Ptr2->Data,In->Name) == 0)
1364                         {
1365 #ifdef __unix__
1366                           if(DebugLevel >= 4)
1367                             printf("Not adding %s input, because set to NoAdd state by script\n",In->Name);
1368 #endif /* __unix__ */
1369                           do_it = false;
1370                           break;
1371                         }
1372                       }
1373                       Ptr2 = Ptr2->Next;
1374                     }
1375                   }
1376                   if(do_it)
1377                   {
1378 #ifdef __unix__
1379                     if(DebugLevel >= 4)
1380                       printf("Adding %s input from form %d\n",In->Name,atoi(q));
1381 #endif /* __unix__ */
1382                     if(fbuf[0] != 0)
1383                       SU_strcat(fbuf,"&",sizeof(fbuf));
1384                     if(strcasecmp(In->Type,"image") == 0)
1385                     {
1386                       if(In->Name != NULL)
1387                       {
1388                         SU_strcat(fbuf,In->Name,sizeof(fbuf));
1389                         SU_strcat(fbuf,".",sizeof(fbuf));
1390                       }
1391                       SU_strcat(fbuf,"x=1",sizeof(fbuf));
1392                       SU_strcat(fbuf,"&",sizeof(fbuf));
1393                       if(In->Name != NULL)
1394                       {
1395                         SU_strcat(fbuf,In->Name,sizeof(fbuf));
1396                         SU_strcat(fbuf,".",sizeof(fbuf));
1397                       }
1398                       SU_strcat(fbuf,"y=1",sizeof(fbuf));
1399                     }
1400                     else
1401                     {
1402                       SU_strcat(fbuf,In->Name,sizeof(fbuf));
1403                       SU_strcat(fbuf,"=",sizeof(fbuf));
1404                       if(In->Value != NULL)
1405                         SU_strcat(fbuf,In->Value,sizeof(fbuf));
1406                     }
1407                   }
1408                   Ptr = Ptr->Next;
1409                 }
1410                 SU_FreeForm(Form);
1411                 found = 0;
1412                 str = fbuf;
1413               }
1414             }
1415           }
1416         }
1417         else if(strncasecmp(S,"RTExec-",7) == 0)
1418         {
1419           q = strchr(S+7,'-');
1420           if(q != NULL)
1421           {
1422             q[0] = 0;q++;
1423             data = GetRunTimeValue(Pv,S+7,RUNTIME_DATA);
1424             if(data != NULL)
1425             {
1426               tmpname = tmpnam(NULL);
1427               if(tmpname != NULL)
1428               {
1429                 fp_out = fopen(tmpname,"wb");
1430                 if(fp_out != NULL)
1431                 {
1432                   fwrite(data,strlen(data),1,fp_out);
1433                   fclose(fp_out);
1434                   tmpname2 = strdup(tmpname);
1435                   tmpname = tmpnam(NULL);
1436                   if(tmpname != NULL)
1437                   {
1438                     snprintf(cmd,sizeof(cmd),"more %s | %s > %s",tmpname2,q,tmpname);
1439 #ifdef DEBUG
1440                     printf("Executing command : %s\n",cmd);
1441 #endif /* DEBUG */
1442                     system(cmd);
1443                     fp_out = fopen(tmpname,"rb");
1444                     if(fp_out != NULL)
1445                     {
1446                       read = fread(fbuf,1,sizeof(fbuf)-1,fp_out);
1447                       fclose(fp_out);
1448                       fbuf[read] = 0;
1449                       read--;
1450                       while((fbuf[read] == 0x0A) || (fbuf[read] == 0x0D))
1451                       {
1452                         fbuf[read] = 0;
1453                         read--;
1454                       }
1455 #ifdef DEBUG
1456                       printf("Returned buffer : %s\n",fbuf);
1457 #endif /* DEBUG */
1458                       str = fbuf;
1459                       found = 0;
1460                     }
1461                     unlink(tmpname);
1462                   }
1463                   unlink(tmpname2);
1464                   free(tmpname2);
1465                 }
1466               }
1467             }
1468           }
1469         }
1470         else if(strncasecmp(S,"RTGetString-",12) == 0)
1471         {
1472           q = strchr(S+12,'-');
1473           if(q != NULL)
1474           {
1475             q[0] = 0;q++;
1476             data = GetRunTimeValue(Pv,S+12,RUNTIME_DATA);
1477             if(data != NULL)
1478             {
1479               str = SU_GetStringFromHtml(data,q);
1480               if(str != NULL)
1481               {
1482                 found = 0;
1483                 SU_strcpy(buf,str,sizeof(buf));
1484 #ifdef DEBUG
1485                 printf("String found : %s\n",buf);
1486 #endif /* DEBUG */
1487                 free(str);
1488                 str = buf;
1489               }
1490             }
1491           }
1492         }
1493         else if(strncasecmp(S,"RTSubURL-",9) == 0)
1494         {
1495           q = strchr(S+9,'-');
1496           if(q != NULL)
1497           {
1498             q[0] = 0;q++;
1499             data = GetRunTimeValue(Pv,S+9,RUNTIME_URL);
1500             if(data != NULL)
1501             {
1502               SU_strcpy(buf,data,sizeof(buf));
1503               data = buf;
1504               i = atoi(q);
1505               data = strstr(data,"://");
1506               if((data != NULL) && (i != 0))
1507               {
1508                 data = strchr(data+3,'/'); /* Skip host name */
1509                 if(data != NULL)
1510                 {
1511                   data++; /* Ready to parse */
1512                   while(i > 0)
1513                   {
1514                     i--;
1515                     q = strchr(data,'/');
1516                     if(q == NULL)
1517                     {
1518                       if(i != 0) /* Not enough '/' */
1519                         break;
1520                       if(data[0] == 0) /* Ending '/' */
1521                         break;
1522                       found = 0;
1523                       str = data;
1524                       break;
1525                     }
1526                     if(i == 0)
1527                     {
1528                       q[0] = 0;
1529                       found = 0;
1530                       str = data;
1531                       break;
1532                     }
1533                     data = q + 1;
1534                   }
1535                 }
1536 #ifdef DEBUG
1537                 if(found == 0)
1538                   printf("SubURL found : %s\n",str);
1539 #endif /* DEBUG */
1540               }
1541             }
1542           }
1543         }
1544 #if 0
1545         else if(strncasecmp(S,"RTIf-",5) == 0)
1546         {
1547           q = strchr(S+5,'-'); // RTIf-ParamName-ParamValue
1548           if(q != NULL)
1549           {
1550             q[0] = 0;q++;
1551             //if(S != NULL) /* useless */
1552             {
1553               for(i=0;i<Pv->NbParams;i++)
1554               {
1555                 if(strcasecmp(S+5,Pv->Params[i].Name) == 0)
1556                 {
1557                   found = 0;
1558                   if(strlen(Pv->Params[i].Value) > 0)
1559                   {
1560                     SU_strcpy(buf,q,sizeof(buf));
1561                     str = buf;
1562                   }
1563                   else
1564                     str = "";
1565                   break;
1566                 }
1567               }
1568             }
1569           }
1570         }
1571 #endif /* 0 */
1572         else
1573         {
1574           char *dum = strchr(S,'-'); /* Search for sub-string */
1575 
1576           if(dum != NULL)
1577           {
1578             dum[0] = 0;
1579             dum++;
1580           }
1581           for(i=0;i<Pv->NbParams;i++)
1582           {
1583             if(strcasecmp(S,Pv->Params[i].Name) == 0)
1584             {
1585               found = i;
1586               if(Pv->Params[i].Alias != NULL)
1587                 InputGet = SU_AddElementHead(InputGet,strdup(Pv->Params[i].Alias));
1588               else
1589                 InputGet = SU_AddElementHead(InputGet,strdup(Pv->Params[i].Name));
1590               break;
1591             }
1592           }
1593           if(found == -1)
1594           {
1595             SU_FreeListElem(InputGet);
1596 #ifdef __unix__
1597             printf("SmsSend Error in Execute : Substitution name not found in params : %s (error in the script ? Contact the author of the script)\n",S);
1598             free(saf);
1599             exit(-8);
1600           }
1601 #else /* !__unix__ */
1602             Form1->StatusBar1->SimpleText = (AnsiString)"Error in Execute : Substitution name not found in params : " + (AnsiString)S + " (error in the script ? Contact the author of the script)";
1603             free(saf);
1604             Sms_ErrorCode = -8;
1605             return NULL;
1606           }
1607           Sms_ErrorCode = 0;
1608 #endif /* __unix__ */
1609           if(dum != NULL)
1610           {
1611             char *dum2 = strchr(dum,'-');
1612             int vv,xx;
1613             if(dum2 == NULL)
1614               SU_strcpy(tbuf,Pv->Params[found].Value,sizeof(tbuf));
1615             else
1616             {
1617               dum2[0] = 0;
1618               dum2++;
1619               xx = atoi(dum);
1620               if(xx >= strlen(Pv->Params[found].Value))
1621                 xx = 0;
1622               vv = atoi(dum2) + 1;
1623               if(vv > sizeof(tbuf))
1624                 vv = sizeof(tbuf);
1625               SU_strcpy(tbuf,Pv->Params[found].Value+xx,vv);
1626             }
1627           }
1628           else
1629             SU_strcpy(tbuf,Pv->Params[found].Value,sizeof(tbuf));
1630 
1631           if(Pv->Params[found].Convert || (Pv->Params[found].Size != 0))
1632             str = CheckMessage(tbuf,(Pv->Params[found].Size == 0)?512:Pv->Params[found].Size);
1633           else
1634             str = tbuf;
1635 #ifndef __unix__
1636           if(Sms_ErrorCode != 0)
1637           {
1638             SU_FreeListElem(InputGet);
1639             free(saf);
1640             return NULL;
1641           }
1642 #endif /* !__unix__ */
1643         }
1644       }
1645       if(found == -1)
1646       {
1647         SU_FreeListElem(InputGet);
1648 #ifdef __unix__
1649         printf("SmsSend Error in Execute : Substitution name not found in params : %s (error in the script ? Contact the author of the script)\n",S);
1650         free(saf);
1651         exit(-8);
1652 #else /* !__unix__ */
1653         Form1->StatusBar1->SimpleText = (AnsiString)"Error in Execute : Substitution name not found in params : " + (AnsiString)S + " (error in the script ? Contact the author of the script)";
1654         free(saf);
1655         Sms_ErrorCode = -8;
1656         return NULL;
1657 #endif /* __unix__ */
1658       }
1659       strcpy(&BufTempo[pos],str);
1660       pos = strlen(BufTempo);
1661       S = p;
1662     }
1663     else
1664     {
1665       BufTempo[pos++] = *S;
1666       S++;
1667     }
1668   }
1669   BufTempo[pos++] = 0;
1670   SU_FreeListElem(InputGet);
1671   free(saf);
1672   return BufTempo;
1673 }
1674 
1675 #ifdef __unix__
ExecuteProvider(SMS_PProvider Pv)1676 void ExecuteProvider(SMS_PProvider Pv)
1677 #else /* !__unix__ */
1678 int ExecuteProvider(SMS_PProvider Pv)
1679 #endif /* __unix__ */
1680 {
1681   SU_PList Exec,Read;
1682   SU_PHTTPActions Act;
1683   int ret;
1684   char *tmp;
1685 
1686   CurrentProviderRunning = Pv;
1687   CurrentRunningPhase = 1;
1688   if(Pv->RunTime != NULL)
1689   {
1690     FreeRunTimeList(Pv->RunTime);
1691     Pv->RunTime = NULL;
1692   }
1693   Read = Pv->Act;
1694   while(Read != NULL)
1695   {
1696     Act = (SU_PHTTPActions) malloc(sizeof(SU_THTTPActions));
1697     memcpy(Act,Read->Data,sizeof(SU_THTTPActions));
1698     if(Act->User != NULL) /* SMS_PActUser struct not null */
1699       CurrentNoAdd = ((SMS_PActUser)Act->User)->NoAdd;
1700     else
1701       CurrentNoAdd = NULL;
1702     if(((SU_PHTTPActions)Read->Data)->FileName != NULL)
1703       Act->FileName = strdup(((SU_PHTTPActions)Read->Data)->FileName);
1704     if(Act->Referer != NULL)
1705     {
1706 #ifdef __unix__
1707       Act->Referer = strdup(TranslateString(Act->Referer,Pv));
1708 #else /* !__unix__ */
1709       tmp = TranslateString(Act->Referer,Pv);
1710       if(tmp == NULL)
1711         return Sms_ErrorCode;
1712       Act->Referer = strdup(tmp);
1713 #endif /* __unix__ */
1714     }
1715     Exec = NULL;
1716     tmp = TranslateString(Act->URL,Pv);
1717 #ifndef __unix__
1718     if(tmp == NULL)
1719       return Sms_ErrorCode;
1720 #endif /* !__unix__ */
1721     SU_strcpy(Act->URL,tmp,sizeof(Act->URL));
1722     if(Act->URL_Params != NULL)
1723     {
1724 #ifdef __unix__
1725       Act->URL_Params = strdup(TranslateString(Act->URL_Params,Pv));
1726 #else /* !__unix__ */
1727       tmp = TranslateString(Act->URL_Params,Pv);
1728       if(tmp == NULL)
1729         return Sms_ErrorCode;
1730       Act->URL_Params = strdup(tmp);
1731 #endif /* __unix__ */
1732     }
1733     if(Act->Post_Data != NULL)
1734     {
1735 #ifdef __unix__
1736       Act->Post_Data = strdup(TranslateString(Act->Post_Data,Pv));
1737 #else /* !__unix__ */
1738       tmp = TranslateString(Act->Post_Data,Pv);
1739       if(tmp == NULL)
1740         return Sms_ErrorCode;
1741       Act->Post_Data = strdup(tmp);
1742 #endif /* __unix__ */
1743       Act->Post_Length = strlen(Act->Post_Data);
1744     }
1745 
1746     Exec = SU_AddElementHead(Exec,Act);
1747 #ifndef __unix__
1748     Sms_ErrorCode = 0;
1749 #endif /* !__unix__ */
1750     ret = SU_ExecuteActions(Exec);
1751     SU_FreeAction(Act);
1752     SU_FreeList(Exec);
1753 #ifdef __unix__
1754     if(ret != 0)
1755       exit(ret);
1756 #else /* !__unix__ */
1757     if(ret != 0)
1758       return ret;
1759     if(Sms_ErrorCode != 0)
1760       return Sms_ErrorCode;
1761 #endif /* __unix__ */
1762     Read = Read->Next;
1763   }
1764 #ifndef __unix__
1765   return 0;
1766 #endif /* !__unix__ */
1767 }
1768 
1769 #ifdef __unix__
GetProfile(const char ProfileName[])1770 SU_PList GetProfile(const char ProfileName[])
1771 {
1772   SU_PList Ptr = SMS_Profiles;
1773 
1774   while(Ptr != NULL)
1775   {
1776     if(SU_strcasecmp(ProfileName,(char *)(((SU_PList)(Ptr->Data))->Data)))
1777     {
1778       if(DebugLevel >= 1)
1779         printf("Using Profile '%s'\n",ProfileName);
1780       return Ptr->Data;
1781     }
1782     Ptr = Ptr->Next;
1783   }
1784   return NULL;
1785 }
1786 
ParseProfile(const char S[])1787 SU_PList ParseProfile(const char S[])
1788 {
1789   char *s,*p,*q;
1790   SU_PList prof = NULL;
1791 
1792   s = (char *)S;
1793   p = strtok(s," ");
1794   if(p == NULL)
1795     return NULL;
1796   q = strtok(NULL," ");
1797   if(q == NULL)
1798     return NULL;
1799   prof = SU_AddElementTail(prof,strdup(p));
1800   prof = SU_AddElementTail(prof,strdup(q));
1801   if(DebugLevel >= 1)
1802     printf("Loading Profile : %s = %s",p,q);
1803   p = strtok(NULL," ");
1804   while(p != NULL)
1805   {
1806     prof = SU_AddElementTail(prof,strdup(p));
1807     if(DebugLevel >= 1)
1808       printf(" %s",p);
1809     p = strtok(NULL," ");
1810   }
1811   if(DebugLevel >= 1)
1812     printf("\n");
1813   return prof;
1814 }
1815 
LoadProfiles(const char FileName[])1816 void LoadProfiles(const char FileName[])
1817 {
1818   FILE *fp;
1819   char S[1024];
1820 
1821   if(SMS_Profiles != NULL)
1822   {
1823     SU_PList Ptr = SMS_Profiles;
1824     while(Ptr != NULL)
1825     {
1826       SU_FreeListElem(Ptr->Data);
1827       Ptr = Ptr->Next;
1828     }
1829     SU_FreeListElem(SMS_Profiles);
1830     SMS_Profiles = NULL;
1831   }
1832   fp = fopen(FileName,"rt");
1833   if(fp == NULL)
1834     return;
1835   while(SU_ReadLine(fp,S,sizeof(S)))
1836   {
1837     SU_PList prof;
1838 
1839     if((S[0] == '#') || (S[0] == 0))
1840       continue;
1841     prof = ParseProfile(S);
1842     if(prof != NULL)
1843       SMS_Profiles = SU_AddElementHead(SMS_Profiles,prof);
1844   }
1845   fclose(fp);
1846 }
1847 
LoadAliases(const char FileName[])1848 void LoadAliases(const char FileName[])
1849 {
1850   FILE *fp;
1851   char S[1024];
1852 
1853   if(SMS_Alias != NULL)
1854   {
1855     SU_FreeListElem(SMS_Alias);
1856     SMS_Alias = NULL;
1857   }
1858   fp = fopen(FileName,"rt");
1859   if(fp == NULL)
1860     return;
1861   while(SU_ReadLine(fp,S,sizeof(S)))
1862   {
1863     if((S[0] == '#') || (S[0] == 0))
1864       continue;
1865     if(DebugLevel >= 1)
1866       printf("Loading Alias : %s\n",S);
1867     SMS_Alias = SU_AddElementHead(SMS_Alias,strdup(S));
1868   }
1869   fclose(fp);
1870 }
1871 
FreeAliases(void)1872 void FreeAliases(void)
1873 {
1874   if(SMS_Alias != NULL)
1875   {
1876     SU_FreeListElem(SMS_Alias);
1877     SMS_Alias = NULL;
1878   }
1879 }
1880 
SearchAlias(const char Name[])1881 char *SearchAlias(const char Name[])
1882 {
1883   SU_PList Ptr;
1884   bool found;
1885   char *p;
1886   char *tmp;
1887   char *ret;
1888 
1889   if(Name[0] != '@')
1890     return (char *)Name;
1891   ret = (char *)Name+1;
1892   found = false;
1893   Ptr = SMS_Alias;
1894   while(Ptr != NULL)
1895   {
1896     tmp = strdup((char *)Ptr->Data);
1897     p = strchr(tmp,' ');
1898     if(p == NULL)
1899       printf("Warning in SearchAlias : Invalid alias : %s\n",tmp);
1900     else
1901     {
1902       p[0] = 0;
1903       p = SU_TrimLeft(p+1);
1904       if(strcasecmp(Name+1,tmp) == 0) /* Found alias */
1905       {
1906         ret = ((char *)Ptr->Data) + (p-tmp);
1907         if(DebugLevel >= 1)
1908           printf("Found alias for %s, replacing with %s\n",Name+1,ret);
1909         found = true;
1910       }
1911     }
1912     free(tmp);
1913     if(found)
1914       break;
1915     Ptr = Ptr->Next;
1916   }
1917   return ret;
1918 }
1919 
PrintProviderHelp(const char ProviderName[],SMS_PProvider Pv)1920 void PrintProviderHelp(const char ProviderName[],SMS_PProvider Pv)
1921 {
1922   int i;
1923 
1924   printf("SmsSend version %s - Copyright(c) Chris Hutchinson - 2020'11\n",SMSSEND_VERSION);
1925   printf("Arguments for provider %s :\n",ProviderName);
1926   for(i=0;i<Pv->NbParams;i++)
1927   {
1928     printf("  %s",Pv->Params[i].Name);
1929     if(Pv->Params[i].Size != 0)
1930       printf(" (Max size %d)",Pv->Params[i].Size);
1931     if(Pv->Params[i].Convert)
1932       printf(" (Non alphanum converted, except + - _ *)");
1933     if(Pv->Params[i].Help != NULL)
1934       printf(" /* %s */\n",Pv->Params[i].Help);
1935     else
1936       printf("\n");
1937   }
1938 }
1939 
PrintHelp(char * Msg,bool version)1940 void PrintHelp(char *Msg,bool version)
1941 {
1942   printf("SmsSend version %s - Copyright(c) Chris Hutchinson - 2020'11\n",SMSSEND_VERSION);
1943   if(version)
1944     return;
1945   printf("Usage : smssend [options] <provider> [arguments] -- [SkyUtils options]\n");
1946   printf("        Options : -q -v -h -update\n");
1947   printf("        SkyUtils Options :\n");
1948   printf("           %s\n",SU_GetOptionsString());
1949   printf("        * Use -help as the first provider option to get required\n          fields for this provider\n");
1950   printf("        * Use -update as the first provider option to search for\n          a new version of this script\n");
1951   printf("        * Use -install as the first provider option to download\n           and install this script\n");
1952   if(Msg != NULL)
1953     printf("\n%s\n",Msg);
1954 }
1955 
ReadParamFromStdin()1956 char *ReadParamFromStdin()
1957 {
1958   char Buf[1024],c;
1959   int i=0;
1960 
1961   while(i != (sizeof(Buf)-1))
1962   {
1963     c = getchar();
1964     if(c == '\n')
1965       break;
1966     Buf[i++] = c;
1967   }
1968   Buf[i] = 0;
1969   return strdup(SearchAlias(Buf));
1970 }
1971 
main(int argc,char * argv[])1972 int main(int argc,char *argv[])
1973 {
1974   SMS_PProvider Pv;
1975   int i,j,pvPos;
1976   char PvName[512],AName[512],PName[512];
1977   char Cmd[1024];
1978   int Nargc = 1;
1979   char *Nargv[50];
1980   bool OptDone = false;
1981 #ifdef _WIN32
1982   float fl; // This float is needed to force VC to link the math lib.. VC bug ;(
1983 
1984   fl = 2.2;
1985   if(Cmd[0] == 66)
1986     printf("%f\n",fl);
1987   if(!SU_WSInit(2,2))
1988   {
1989     printf("SmsSend error : Couldn't find a usable WinSock dll\n");
1990     return -1;
1991   }
1992 #endif /* _WIN32 */
1993 
1994   argc = SU_GetSkyutilsParams(argc,argv);
1995   if(argc == 1)
1996   {
1997     PrintHelp("Provider not specified.",false);
1998     return -3;
1999   }
2000   DebugLevel = SU_GetDebugLevel();
2001 #ifdef _WIN32
2002   snprintf(PName,sizeof(PName),"%s\\profiles",SMSSEND_SHAREPATH);
2003 #else /* !_WIN32 */
2004   snprintf(PName,sizeof(PName),"%s/.smssend/profiles",getenv("HOME"));
2005 #endif /* _WIN32 */
2006   LoadProfiles(PName);
2007   /* Parse options */
2008   i = j = 1;
2009   Nargv[0] = argv[0];
2010   while(i < argc)
2011   {
2012     j++;
2013     if((argv[i][0] == '-') && (!OptDone))
2014     {
2015       if(strcasecmp(argv[i],"-update") == 0)
2016       {
2017         if(!SMS_Quiet)
2018         {
2019           printf("SmsSend version %s - Copyright(c) Chris Hutchinson - 2020'11\n",SMSSEND_VERSION);
2020           printf("Trying to update SmsSend...\n");
2021         }
2022         CheckForUpdateSmsSend();
2023         return 0;
2024       }
2025       else if((strcasecmp(argv[i],"--help") == 0) || (strcasecmp(argv[i],"-h") == 0))
2026       {
2027         PrintHelp(NULL,false);
2028         return 0;
2029       }
2030       else if((strcasecmp(argv[i],"--version") == 0) || (strcasecmp(argv[i],"-v") == 0))
2031       {
2032         PrintHelp(NULL,true);
2033         printf("This is free opensource software. However there is NO warranty\n");
2034         printf("not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
2035         return 0;
2036       }
2037       else if(strcasecmp(argv[i],"-q") == 0)
2038       {
2039         SMS_Quiet = true;
2040         j--;
2041       }
2042       else
2043       {
2044         snprintf(Cmd,sizeof(Cmd),"Unknown option : %s",argv[i]);
2045         PrintHelp(Cmd,false);
2046         return -3;
2047       }
2048     }
2049     else if(argv[i][0] == '%') /* Search for profile */
2050     {
2051       SU_PList Prof = GetProfile((const char *)&argv[i][1]);
2052       if(Prof == NULL)
2053       {
2054         printf("SmsSend version %s - Copyright(c) Chris Hutchinson - 2020'11\n",SMSSEND_VERSION);
2055         printf("Unknown profile '%s'\n",(char *)&argv[i][1]);
2056         return -3;
2057       }
2058       Prof = Prof->Next;
2059       while(Prof != NULL)
2060       {
2061         Nargv[Nargc++] = (char *)Prof->Data;
2062         Prof = Prof->Next;
2063       }
2064       j--;
2065     }
2066     else
2067     {
2068       OptDone = true;
2069       Nargv[Nargc++] = argv[i];
2070       j--;
2071     }
2072     i++;
2073   }
2074   i = j;
2075   if(i >= Nargc)
2076   {
2077     PrintHelp("Provider not specified.",false);
2078     return -3;
2079   }
2080   if(strstr(Nargv[i],".sms") == NULL)
2081     snprintf(PvName,sizeof(PvName),"%s.sms",Nargv[i]);
2082   else
2083     strcpy(PvName,Nargv[i]);
2084   /* Check for a new script to install */
2085   if(((i+1) < Nargc) && (strcasecmp(Nargv[i+1],"-install") == 0))
2086   {
2087     if(!SMS_Quiet)
2088     {
2089       printf("SmsSend version %s - Copyright(c) Chris Hutchinson - 2020'11\n",SMSSEND_VERSION);
2090       printf("Trying to install %s script...\n",PvName);
2091     }
2092     InstallScript(PvName);
2093     return 0;
2094   }
2095   /* First try to load local .sms script */
2096   Pv = LoadProviderFile(PvName);
2097   if(Pv == NULL)
2098   {
2099 #ifndef _WIN32
2100     /* Then try to load user script */
2101     if(strstr(Nargv[i],".sms") == NULL)
2102       snprintf(PvName,sizeof(PvName),"%s/.smssend/%s.sms",getenv("HOME"),Nargv[i]);
2103     else
2104       snprintf(PvName,sizeof(PvName),"%s/.smssend/%s",getenv("HOME"),Nargv[i]);
2105     Pv = LoadProviderFile(PvName);
2106     if(Pv == NULL)
2107 #endif /* !_WIN32 */
2108     {
2109       /* Then try to load global shared scripts */
2110       if(strstr(Nargv[i],".sms") == NULL)
2111         snprintf(PvName,sizeof(PvName),"%s/%s.sms",SMSSEND_SHAREPATH,Nargv[i]);
2112       else
2113         snprintf(PvName,sizeof(PvName),"%s/%s",SMSSEND_SHAREPATH,Nargv[i]);
2114       Pv = LoadProviderFile(PvName);
2115       if(Pv == NULL)
2116       {
2117         snprintf(Cmd,sizeof(Cmd),"Cannot load provider file (not found in ./ , ~/.smssend or %s/) : %s%s\n",SMSSEND_SHAREPATH,Nargv[i],(strstr(Nargv[i],".sms") != NULL)?"":".sms");
2118         PrintHelp(Cmd,false);
2119         return -4;
2120       }
2121     }
2122   }
2123   pvPos = i;
2124   i++;
2125   if(i >= Nargc)
2126   {
2127     PrintProviderHelp(Nargv[pvPos],Pv);
2128     return -6;
2129   }
2130   if(strcasecmp(Nargv[i],"-help") == 0)
2131   {
2132     PrintProviderHelp(Nargv[pvPos],Pv);
2133     return -5;
2134   }
2135   else if(strcasecmp(Nargv[i],"-update") == 0)
2136   {
2137     if(!SMS_Quiet)
2138     {
2139       printf("SmsSend version %s - Copyright(c) Chris Hutchinson - 2020'11\n",SMSSEND_VERSION);
2140       printf("Trying to update %s script...\n",Nargv[pvPos]);
2141     }
2142     CheckForUpdate(PvName);
2143     return 0;
2144   }
2145   if(Nargc < (Pv->NbParams+pvPos+1))
2146   {
2147     PrintHelp("Not enough arguments for this provider. Try -help as first provider argument.",false);
2148     return -6;
2149   }
2150   else if(Nargc > (Pv->NbParams+pvPos+1))
2151   {
2152     PrintHelp("Too many arguments for this provider. Try -help as first provider argument.",false);
2153     return -6;
2154   }
2155 #ifdef _WIN32
2156   snprintf(AName,sizeof(AName),"%s\\aliases",SMSSEND_SHAREPATH);
2157 #else /* !_WIN32 */
2158   snprintf(AName,sizeof(AName),"%s/.smssend/aliases",getenv("HOME"));
2159 #endif /* _WIN32 */
2160   LoadAliases(AName);
2161   for(i=0;i<Pv->NbParams;i++)
2162   {
2163     if(strcmp(Nargv[i+pvPos+1],"-") == 0)
2164     {
2165       if(!SMS_Quiet)
2166         printf("Enter parameter %s :\n",Pv->Params[i].Name);
2167       Pv->Params[i].Value = ReadParamFromStdin();
2168     }
2169     else
2170       Pv->Params[i].Value = strdup(SearchAlias(Nargv[i+pvPos+1]));
2171   }
2172 
2173   ExecuteProvider(Pv);
2174   FreeProvider(Pv);
2175   FreeAliases();
2176 
2177   return 0;
2178 }
2179 #endif /* __unix__ */
2180 
2181 #ifdef USE_PCRE
2182 #ifdef _WIN32
2183 #include "pcre.h"
2184 #else /* !_WIN32 */
2185 #include <pcre.h>
2186 #endif /* _WIN32 */
2187 
2188 /** this should be always multiple of 3 */
2189 #define OVECTOR_SIZE  120
2190 
2191 /*
2192  * PM_GetRegexMatch -- find and return specified regex match.
2193  *
2194  *    data    -- input source
2195  *    regex   -- matching regex
2196  *    gpos    -- which global match to return
2197  *    pos     -- which single match to return
2198  *    buf     -- output buffer
2199  *    blen    -- output buffer size
2200  *
2201  *
2202  *  Function repeats pattern matching gpos-times, than copies
2203  *  pos-th match to the buf buffer. On success returns 0 else
2204  *  non-zero value.
2205  */
2206 
PM_GetRegexMatch(char * data,char * regex,int gpos,int pos,char * buf,int blen)2207 static int PM_GetRegexMatch (char *data, char *regex, int gpos, int pos, char *buf, int blen)
2208 {
2209   pcre *pcre;
2210   const char *error;
2211   int erroffset;
2212   int rc, c, dpos;
2213   int ovector[OVECTOR_SIZE];
2214 
2215   /* invalid input */
2216   if (data == NULL || regex == NULL || buf == NULL || blen < 0)
2217     return 1;
2218 
2219   /* indexes out of bounds */
2220   if (gpos < 1 || pos < 1 || pos+1 >= OVECTOR_SIZE/3)
2221     return 1;
2222 
2223   /* compile regular expression, no option support yet */
2224   pcre = pcre_compile (regex, 0, &error, &erroffset, NULL);
2225   if (pcre == NULL)
2226     {
2227 #ifdef DEBUG
2228       printf ("RTRegex failed: %s: %s\n", error ? error : "",
2229 	      erroffset > 0 ? data + erroffset : "");
2230 #endif /* DEBUG */
2231       return 1;
2232     }
2233 
2234   rc = -1;
2235   dpos = 0;
2236   for (c = 0; c < gpos; c++)
2237     {
2238       rc =
2239 	pcre_exec (pcre, NULL, data, strlen (data), dpos, 0, ovector,
2240 		   OVECTOR_SIZE);
2241       if (rc < 0)
2242 	{
2243 	  break;
2244 	}
2245       dpos = ovector[1] + 1;
2246     }
2247 
2248   pcre_free (pcre);
2249 
2250   if (rc > 0)
2251     {
2252       int start = ovector[pos * 2], stop = ovector[pos * 2 + 1];
2253       if (start != -1 && stop != -1)
2254 	{
2255 	  int len = stop - start;
2256           if (len > 0) {
2257 	    len = (len < blen) ? len : blen - 1;
2258 	    strncpy (buf, data + start, len);
2259 	    buf[len] = 0;
2260 	    return 0;
2261           }
2262 	}
2263     }
2264   return 1;
2265 }
2266 #endif /* USE_PCRE */
2267