source: trunk/module-monitor.c @ 5375

Last change on this file since 5375 was 5354, checked in by neoen, 8 years ago

NDS: added support for mail messages from provider.
Text mail messages sent by provider to subscriber are saved to file.
These messages are encapsulated into Unique EMMs.
Two new options in global section of oscam.conf are used to enable this feature:
disablemail = 0 (default is 1)
mailfile = /path/to/file
Tested only with SkyIT.

File size: 21.3 KB
Line 
1#include "globals.h"
2
3#define CS_VERSION_X  CS_VERSION
4
5static void monitor_check_ip()
6{
7    int32_t ok=0;
8    struct s_client *cur_cl = cur_client();
9   
10    if (cur_cl->auth) return;
11    ok = check_ip(cfg.mon_allowed, cur_cl->ip);
12    if (!ok)
13    {
14        cs_auth_client(cur_cl, (struct s_auth *)0, "invalid ip");
15        cs_exit(0);
16    }
17}
18
19static void monitor_auth_client(char *usr, char *pwd)
20{
21    struct s_auth *account;
22    struct s_client *cur_cl = cur_client();
23   
24    if (cur_cl->auth) return;
25    if ((!usr) || (!pwd))
26    {
27        cs_auth_client(cur_cl, (struct s_auth *)0, NULL);
28        cs_exit(0);
29    }
30    for (account=cfg.account, cur_cl->auth=0; (account) && (!cur_cl->auth);)
31    {
32        if (account->monlvl)
33            cur_cl->auth=!(strcmp(usr, account->usr) | strcmp(pwd, account->pwd));
34        if (!cur_cl->auth)
35            account=account->next;
36    }
37    if (!cur_cl->auth)
38    {
39        cs_auth_client(cur_cl, (struct s_auth *)0, "invalid account");
40        cs_exit(0);
41    }
42    if (cs_auth_client(cur_cl, account, NULL))
43        cs_exit(0);
44}
45
46static int32_t secmon_auth_client(uchar *ucrc)
47{
48    uint32_t crc;
49    struct s_auth *account;
50    struct s_client *cur_cl = cur_client();
51    unsigned char md5tmp[MD5_DIGEST_LENGTH];
52   
53    if (cur_cl->auth)
54    {
55        int32_t s=memcmp(cur_cl->ucrc, ucrc, 4);
56        if (s)
57            cs_log("wrong user-crc or garbage !?");
58        return(!s);
59    }
60    cur_cl->crypted=1;
61    crc=(ucrc[0]<<24) | (ucrc[1]<<16) | (ucrc[2]<<8) | ucrc[3];
62    for (account=cfg.account; (account) && (!cur_cl->auth); account=account->next)
63        if ((account->monlvl) &&
64                (crc==crc32(0L, MD5((unsigned char *)account->usr, strlen(account->usr), md5tmp), MD5_DIGEST_LENGTH)))
65        {
66            memcpy(cur_cl->ucrc, ucrc, 4);
67            aes_set_key((char *)MD5((unsigned char *)account->pwd, strlen(account->pwd), md5tmp));
68            if (cs_auth_client(cur_cl, account, NULL))
69                cs_exit(0);
70            cur_cl->auth=1;
71        }
72    if (!cur_cl->auth)
73    {
74        cs_auth_client(cur_cl, (struct s_auth *)0, "invalid user");
75        cs_exit(0);
76    }
77    return(cur_cl->auth);
78}
79
80int32_t monitor_send_idx(struct s_client *cl, char *txt)
81{
82    int32_t l;
83    unsigned char buf[256+32];
84    if (!cl->udp_fd)
85        return(-1);
86    struct timespec req_ts;
87    req_ts.tv_sec = 0;
88    req_ts.tv_nsec = 500000;
89    nanosleep (&req_ts, NULL);//avoid lost udp-pakkets
90    if (!cl->crypted)
91        return(sendto(cl->udp_fd, txt, strlen(txt), 0,
92                (struct sockaddr *)&cl->udp_sa,
93                sizeof(cl->udp_sa)));
94    buf[0]='&';
95    buf[9]=l=strlen(txt);
96    l=boundary(4, l+5)+5;
97    memcpy(buf+1, cl->ucrc, 4);
98    cs_strncpy((char *)buf+10, txt, sizeof(buf)-10);
99    uchar tmp[10];
100    memcpy(buf+5, i2b_buf(4, crc32(0L, buf+10, l-10), tmp), 4);
101    aes_encrypt_idx(cl, buf+5, l-5);
102    return(sendto(cl->udp_fd, buf, l, 0,
103            (struct sockaddr *)&cl->udp_sa,
104            sizeof(cl->udp_sa)));
105}
106
107#define monitor_send(t) monitor_send_idx(cur_client(), t)
108
109static int32_t monitor_recv(struct s_client * client, uchar *buf, int32_t l)
110{
111    int32_t n;
112    uchar nbuf[3] = { 'U', 0, 0 };
113    static int32_t bpos=0;
114    static uchar *bbuf=NULL;
115    if (!bbuf)
116    {
117        bbuf = cs_malloc(&bbuf, l, 1);
118    }
119    if (bpos)
120        memcpy(buf, bbuf, n=bpos);
121    else
122        n=recv_from_udpipe(buf);
123    bpos=0;
124    if (!n) return(buf[0]=0);
125    if (buf[0]=='&')
126    {
127        int32_t bsize;
128        if (n<21)   // 5+16 is minimum
129        {
130            cs_log("packet to int16_t !");
131            return(buf[0]=0);
132        }
133        if (!secmon_auth_client(buf+1))
134            return(buf[0]=0);
135        aes_decrypt(buf+5, 16);
136        bsize=boundary(4, buf[9]+5)+5;
137        // cs_log("n=%d bsize=%d", n, bsize);
138        if (n>bsize)
139        {
140            // cs_log("DO >>>> copy-back");
141            memcpy(bbuf, buf+bsize, bpos=n-bsize);
142            n=bsize;
143            write_to_pipe(client->fd_m2c, PIP_ID_UDP, (uchar*)&nbuf, sizeof(nbuf));
144        }
145        else if (n<bsize)
146        {
147            cs_log("packet-size mismatch !");
148            return(buf[0]=0);
149        }
150        aes_decrypt(buf+21, n-21);
151        uchar tmp[10];
152        if (memcmp(buf+5, i2b_buf(4, crc32(0L, buf+10, n-10), tmp), 4))
153        {
154            cs_log("CRC error ! wrong password ?");
155            return(buf[0]=0);
156        }
157        n=buf[9];
158        memmove(buf, buf+10, n);
159    }
160    else
161    {
162        uchar *p;
163        monitor_check_ip();
164        buf[n]='\0';
165        if ((p=(uchar *)strchr((char *)buf, 10)) && (bpos=n-(p-buf)-1))
166        {
167            memcpy(bbuf, p+1, bpos);
168            n=p-buf;
169            write_to_pipe(client->fd_m2c, PIP_ID_UDP, (uchar*)&nbuf, sizeof(nbuf));
170        }
171    }
172    buf[n]='\0';
173    n=strlen(trim((char *)buf));
174    if (n) client->last=time((time_t *) 0);
175    return(n);
176}
177
178static void monitor_send_info(char *txt, int32_t last)
179{
180    static int32_t seq=0, counter=0;
181    static char btxt[256] = {0};
182    char buf[8];
183    if (txt)
184    {
185        if (!btxt[0])
186        {
187            counter=0;
188            txt[2]='B';
189        }
190        else
191            counter++;
192        snprintf(buf, sizeof(buf), "%03d", counter);
193        memcpy(txt+4, buf, 3);
194        txt[3]='0'+seq;
195    }
196    else
197        if (!last)
198            return;
199
200    if (!last)
201    {
202        if (btxt[0]) monitor_send(btxt);
203        cs_strncpy(btxt, txt, sizeof(btxt));
204        return;
205    }
206
207    if (txt && btxt[0])
208    {
209        monitor_send(btxt);
210        txt[2]='E';
211        cs_strncpy(btxt, txt, sizeof(btxt));
212    }
213    else
214    {
215        if (txt)
216            cs_strncpy(btxt, txt, sizeof(btxt));
217        btxt[2]=(btxt[2]=='B') ? 'S' : 'E';
218    }
219
220    if (btxt[0])
221    {
222        monitor_send(btxt);
223        seq=(seq+1)%10;
224    }
225    btxt[0]=0;
226}
227
228static char *monitor_client_info(char id, struct s_client *cl, char *sbuf){
229    char channame[32];
230    sbuf[0] = '\0';
231
232    if (cl){
233        char ldate[16], ltime[16], *usr;
234        int32_t lsec, isec, con, cau, lrt =- 1;
235        time_t now;
236        struct tm lt;
237        now=time((time_t)0);
238
239        if  ((cfg.mon_hideclient_to <= 0) ||
240                (now-cl->lastecm < cfg.mon_hideclient_to) ||
241                (now-cl->lastemm < cfg.mon_hideclient_to) ||
242                (cl->typ != 'c'))
243        {
244            lsec = now - cl->login;
245            isec = now - cl->last;
246            usr = username(cl);
247            if (cl->dup)
248                con = 2;
249            else
250                if ((cl->tosleep) && (now-cl->lastswitch>cl->tosleep))
251                    con = 1;
252                else
253                    con = 0;
254
255            // no AU reader == 0 / AU ok == 1 / Last EMM > aulow == -1
256            if(cl->typ == 'c' || cl->typ == 'p' || cl->typ == 'r') {
257
258                if ((cl->typ == 'c' && !cl->aureader_list) ||
259                        ((cl->typ == 'p' || cl->typ == 'r') && cl->reader->audisabled))
260                    cau = 0;
261
262                else if ((now-cl->lastemm) / 60 > cfg.mon_aulow)
263                    cau = (-1);
264
265                else
266                    cau = 1;
267
268            } else {
269                cau = 0;
270            }
271
272            if( cl->typ == 'r')
273            {
274                int32_t i;
275                struct s_reader *rdr;
276                for (i=0,rdr=first_active_reader; rdr ; rdr=rdr->next, i++)
277                    if (cl->reader == rdr)
278                        lrt=i;
279
280                if( lrt >= 0 )
281                    lrt = 10 + cl->reader->card_status;
282            }
283            else
284                lrt = cl->cwlastresptime;
285            localtime_r(&cl->login, &lt);
286            snprintf(ldate, sizeof(ldate), "%02d.%02d.%02d", lt.tm_mday, lt.tm_mon+1, lt.tm_year % 100);
287            int32_t cnr=get_threadnum(cl);
288            snprintf(ltime, sizeof(ldate), "%02d:%02d:%02d", lt.tm_hour, lt.tm_min, lt.tm_sec);
289            snprintf(sbuf, 256, "[%c--CCC]%8X|%c|%d|%s|%d|%d|%s|%d|%s|%s|%s|%d|%04X:%04X|%s|%d|%d|%d|%d|%d|%d|%d|%d|%d|%d\n",
290                    id, (uint32_t)cl->thread, cl->typ, cnr, usr, cau, cl->crypted,
291                    cs_inet_ntoa(cl->ip), cl->port, monitor_get_proto(cl),
292                    ldate, ltime, lsec, cl->last_caid, cl->last_srvid,
293                    get_servicename(cl, cl->last_srvid, cl->last_caid, channame), isec, con,
294                                        cl->cwfound, cl->cwnot, cl->cwcache, cl->cwignored,
295                                        cl->cwtout, cl->emmok, cl->emmnok, lrt);
296        }
297    }
298    return(sbuf);
299}
300
301static void monitor_process_info(){
302    time_t now = time((time_t)0);
303    char sbuf[256];
304
305    struct s_client *cl, *cur_cl = cur_client();
306   
307    for (cl=first_client; cl ; cl=cl->next) {
308        if  ((cfg.mon_hideclient_to <= 0) ||
309                ( now-cl->lastecm < cfg.mon_hideclient_to) ||
310                ( now-cl->lastemm < cfg.mon_hideclient_to) ||
311                ( cl->typ != 'c')){
312            if ((cur_cl->monlvl < 2) && (cl->typ != 's')) {
313                    if ((cur_cl->account && cl->account && strcmp(cur_cl->account->usr, cl->account->usr)) ||
314                            ((cl->typ != 'c') && (cl->typ != 'm')))
315                        continue;
316            }
317            monitor_send_info(monitor_client_info('I', cl, sbuf), 0);
318        }
319    }
320    monitor_send_info(NULL, 1);
321}
322
323static void monitor_send_details(char *txt, uint32_t tid){
324    char buf[256];
325    snprintf(buf, 255, "[D-----]%8X|%s\n", tid, txt);
326    monitor_send_info(buf, 0);
327}
328
329static void monitor_send_details_version(){
330    char buf[256];
331    snprintf(buf, sizeof(buf), "[V-0000]version=%s, build=%s, system=%s-%s-%s\n", CS_VERSION_X, CS_SVN_VERSION,  CS_OS_CPU, CS_OS_HW, CS_OS_SYS);
332    monitor_send_info(buf, 1);
333}
334
335static void monitor_send_keepalive_ack(){
336    char buf[32];
337    snprintf(buf, sizeof(buf), "[K-0000]keepalive_ack\n");
338    monitor_send_info(buf, 1);
339}
340
341static void monitor_process_details_master(char *buf, uint32_t pid){
342    snprintf(buf, 256, "Version=%s#%s", CS_VERSION_X, CS_SVN_VERSION);
343    monitor_send_details(buf, pid);
344    snprintf(buf, 256, "System=%s-%s-%s",  CS_OS_CPU, CS_OS_HW, CS_OS_SYS);
345    monitor_send_details(buf, pid);
346    snprintf(buf, 256, "DebugLevel=%d", cs_dblevel);
347    monitor_send_details(buf, pid);
348    snprintf(buf, 256, "MaxClients=UNLIMITED");
349    monitor_send_details(buf, pid);
350    snprintf(buf, 256, "ClientMaxIdle=%d sec", cfg.cmaxidle);
351    monitor_send_details(buf, pid);
352    if( cfg.max_log_size )
353        snprintf(buf + 200, 56, "%d Kb", cfg.max_log_size);
354    else
355        cs_strncpy(buf + 200, "unlimited", 56);
356    snprintf(buf, 256, "MaxLogsize=%s", buf + 200);
357    monitor_send_details(buf, pid);
358    snprintf(buf, 256, "ClientTimeout=%u ms", cfg.ctimeout);
359    monitor_send_details(buf, pid);
360    snprintf(buf, 256, "CacheDelay=%d ms", cfg.delay);
361    monitor_send_details(buf, pid);
362    if( cfg.cwlogdir ) {
363                snprintf(buf, 256, "CwlogDir=%s", cfg.cwlogdir);
364            monitor_send_details(buf, pid);
365        }
366    if( cfg.preferlocalcards ) {
367            snprintf(buf, 256, "PreferlocalCards=%d", cfg.preferlocalcards);
368            monitor_send_details(buf, pid);
369        }
370    if( cfg.waitforcards ) {
371            snprintf(buf, 256, "WaitforCards=%d", cfg.waitforcards);
372            monitor_send_details(buf, pid);
373        }
374    snprintf(buf, 256, "LogFile=%s", cfg.logfile);
375    monitor_send_details(buf, pid);
376    if( cfg.mailfile ) {
377            snprintf(buf, 256, "MailFile=%s", cfg.mailfile);
378            monitor_send_details(buf, pid);
379        }
380    if( cfg.usrfile ) {
381            snprintf(buf, 256, "UsrFile=%s", cfg.usrfile);
382            monitor_send_details(buf, pid);
383        }
384    monitor_send_details(buf, pid);
385    snprintf(buf, 256, "Sleep=%d", cfg.tosleep);
386    monitor_send_details(buf, pid);
387    snprintf(buf, 256, "Monitorport=%d", cfg.mon_port);
388    monitor_send_details(buf, pid);
389    snprintf(buf, 256, "Nice=%d", cfg.nice);
390    monitor_send_details(buf, pid);
391#ifdef WEBIF
392    snprintf(buf, 256, "Restartmode=%d", cs_get_restartmode());
393    monitor_send_details(buf, pid);
394#else
395    snprintf(buf, 256, "Restartmode=%s", "no");
396    monitor_send_details(buf, pid);
397#endif
398
399    //  monitor_send_details(buf, pid);
400}
401
402
403static void monitor_process_details_reader(struct s_client *cl) {
404
405    if (cfg.saveinithistory) {
406        if (cl->reader->init_history) {
407            char *ptr,*ptr1 = NULL;
408            for (ptr=strtok_r(cl->reader->init_history, "\n", &ptr1); ptr; ptr=strtok_r(NULL, "\n", &ptr1)) {
409                monitor_send_details(ptr, (uint32_t)(cl->thread));
410                ptr1[-1]='\n';
411            }
412        }
413    } else {
414        monitor_send_details("Missing reader index or entitlement not saved!", (uint32_t)(cl->thread));
415    }
416
417}
418
419
420static void monitor_process_details(char *arg){
421    uint32_t tid = 0; //using threadid 8 positions hex see oscam-log.c //FIXME untested but pid isnt working anyway with threading
422    struct s_client *cl;
423    char sbuf[256];
424
425    if (!arg)
426        cl = first_client; // no arg - show master
427    else
428        if (sscanf(arg,"%X",&tid) == 1)
429            cl = get_client_by_tid(tid);
430        else
431            cl = NULL;
432
433    if (!cl)
434        monitor_send_details("Invalid TID", tid);
435    else
436    {
437        //monitor_send_info(monitor_client_info('D', idx), 0); //FIXME
438        switch(cl->typ)
439        {
440        case 's':
441            monitor_process_details_master(sbuf, (uint32_t)(cl->thread));
442            break;
443        case 'c': case 'm':
444            monitor_send_details(monitor_client_info(1, cl, sbuf), (uint32_t)(cl->thread));
445            break;
446        case 'r':
447            monitor_process_details_reader(cl);//with client->typ='r' client->ridx is always filled and valid, so no need checking
448            break;
449        case 'p':
450            monitor_send_details(monitor_client_info(1, cl, sbuf), (uint32_t)(cl->thread));
451            break;
452        }
453    }
454    monitor_send_info(NULL, 1);
455}
456
457static void monitor_send_login(void){
458    char buf[64];
459    struct s_client *cur_cl = cur_client();
460    if (cur_cl->auth && cur_cl->account)
461        snprintf(buf, sizeof(buf), "[A-0000]1|%s logged in\n", cur_cl->account->usr);
462    else
463        cs_strncpy(buf, "[A-0000]0|not logged in\n", sizeof(buf));
464    monitor_send_info(buf, 1);
465}
466
467static void monitor_login(char *usr){
468    char *pwd=NULL;
469    if ((usr) && (pwd=strchr(usr, ' ')))
470        *pwd++=0;
471    if (pwd)
472        monitor_auth_client(trim(usr), trim(pwd));
473    else
474        monitor_auth_client(NULL, NULL);
475    monitor_send_login();
476}
477
478static void monitor_logsend(char *flag){
479    if (!flag) return; //no arg
480
481    struct s_client *cur_cl = cur_client();
482    if (strcmp(flag, "on")) {
483        if (strcmp(flag, "onwohist")) {
484            cur_cl->log=0;
485            return;
486        }
487    }
488
489    if (cur_cl->log)    // already on
490        return;
491
492    int32_t i, d = 0;
493    if (!strcmp(flag, "on") && loghist){
494        char *t_loghistptr = loghistptr, *ptr1 = NULL;
495        int32_t l1 = strlen(t_loghistptr+1) + 2;
496        char *lastpos = loghist + (cfg.loghistorysize)-1;
497
498        for (ptr1 = t_loghistptr + l1, i=0; i<200; i++, ptr1 = ptr1+l1) {
499            l1 = strlen(ptr1)+1;
500            if (!d && ((ptr1 >= lastpos) || (l1 < 2))) {
501                ptr1 = loghist;
502                l1 = strlen(ptr1)+1;
503                d++;
504            }
505
506            if (d && ((ptr1 >= t_loghistptr) || (l1 < 2)))
507                break;
508
509            char p_usr[32], p_txt[512];
510            size_t pos1 = strcspn(ptr1, "\t") + 1;
511
512            cs_strncpy(p_usr, ptr1 , pos1 > sizeof(p_usr) ? sizeof(p_usr) : pos1);
513
514            if ((p_usr[0]) && ((cur_cl->monlvl > 1) || (cur_cl->account && !strcmp(p_usr, cur_cl->account->usr)))) {
515                snprintf(p_txt, sizeof(p_txt), "[LOG%03d]%s", cur_cl->logcounter, ptr1+pos1);
516                cur_cl->logcounter=(cur_cl->logcounter + 1) % 1000;
517                monitor_send(p_txt);
518            }
519        }
520    }
521
522    cur_cl->log=1;
523}
524
525static void monitor_set_debuglevel(char *flag){
526    if (flag) {
527        cs_dblevel = atoi(flag);
528#ifndef WITH_DEBUG
529        cs_log("*** Warning: Debug Support not compiled in ***");
530#else
531        cs_log("%s debug_level=%d", "all", cs_dblevel);
532#endif
533    }
534}
535
536static void monitor_get_account(){
537    struct s_auth *account;
538    char buf[256];
539        int32_t count = 0;
540
541    for (account=cfg.account; (account); account=account->next){
542        count++;
543        snprintf(buf, sizeof(buf), "[U-----]%s\n", account->usr);
544        monitor_send_info(buf, 0);
545    }
546    snprintf(buf, sizeof(buf), "[U-----] %i User registered\n", count);
547    monitor_send_info(buf, 1);
548        return;
549}
550
551static void monitor_set_account(char *args){
552    struct s_auth *account;
553    char delimiter[] = " =";
554    char *ptr, *saveptr1 = NULL;
555    int32_t argidx, i, found;
556    char *argarray[3];
557    static const char *token[]={"au", "sleep", "uniq", "monlevel", "group", "services", "betatunnel", "ident", "caid", "chid", "class", "hostname", "expdate", "keepalive", "disabled"};
558    int32_t tokencnt = sizeof(token)/sizeof(char *);
559    char buf[256], tmp[64];
560
561    argidx = 0;
562    found = 0;
563
564    snprintf(tmp, sizeof(tmp), "%s",args);
565    snprintf(buf, sizeof(buf), "[S-0000]setuser: %s check\n", tmp);
566    monitor_send_info(buf, 0);
567
568    ptr = strtok_r(args, delimiter, &saveptr1);
569
570    // resolve arguments
571    while(ptr != NULL) {
572        argarray[argidx]=trim(ptr);
573        ptr = strtok_r(NULL, delimiter, &saveptr1);
574        argidx++;
575    }
576
577    if(argidx != 3) {
578        snprintf(buf, sizeof(buf), "[S-0000]setuser: %s failed - wrong number of parameters (%d)\n",tmp,  argidx);
579        monitor_send_info(buf, 0);
580        snprintf(buf, sizeof(buf), "[S-0000]setuser: %s end\n", tmp);
581        monitor_send_info(buf, 1);
582        return;
583    }
584
585    //search account
586    for (account=cfg.account; (account) ; account=account->next){
587        if (!strcmp(argarray[0], account->usr)){
588            found = 1;
589            break;
590        }
591    }
592
593    if (found != 1){
594        snprintf(buf, sizeof(buf), "[S-0000]setuser: %s failed - user %s not found\n",tmp , argarray[0]);
595        monitor_send_info(buf, 0);
596        snprintf(buf, sizeof(buf), "[S-0000]setuser: %s end\n", tmp);
597        monitor_send_info(buf, 1);
598        return;
599    }
600
601    found = -1;
602    for (i = 0; i < tokencnt; i++){
603        if (!strcmp(argarray[1], token[i])){
604            // preparing the parameters before re-load
605            switch(i) {
606
607            case    6: clear_tuntab(&account->ttab); break;     //betatunnel
608
609            case    8: clear_caidtab(&account->ctab); break;    //Caid
610            }
611            found = i;
612        }
613    }
614
615    if (found < 0){
616        snprintf(buf, sizeof(buf), "[S-0000]setuser: parameter %s not exist. possible values:\n", argarray[1]);
617        monitor_send_info(buf, 0);
618            for (i = 0; i < tokencnt; i++){
619                snprintf(buf, sizeof(buf), "[S-0000]%s\n", token[i]);
620                monitor_send_info(buf, 0);
621                }
622        snprintf(buf, sizeof(buf),"[S-0000]setuser: %s end\n", tmp);
623        monitor_send_info(buf, 1);
624        return;
625    } else {
626        chk_account(token[found], argarray[2], account);
627    }
628
629    if (write_userdb(cfg.account)==0)
630        cs_reinit_clients(cfg.account);
631
632    snprintf(buf, sizeof(buf),"[S-0000]setuser: %s done - param %s set to %s\n", tmp, argarray[1], argarray[2]);
633    monitor_send_info(buf, 1);
634}
635
636static void monitor_set_server(char *args){
637    char delimiter[] = "=";
638    char *ptr, *saveptr1;
639    int32_t argidx, i, found;
640    char *argarray[3];
641    static const char *token[]={"clienttimeout", "fallbacktimeout", "clientmaxidle", "cachedelay", "bindwait", "netprio", "sleep", "unlockparental", "serialreadertimeout", "maxlogsize", "showecmdw", "waitforcards", "preferlocalcards"};
642    char buf[256];
643
644    argidx=0;   found=0;
645    ptr = strtok_r(args, delimiter, &saveptr1);
646
647    // resolve arguments
648    while(ptr != NULL) {
649        argarray[argidx]=trim(ptr);
650        ptr = strtok_r(NULL, delimiter, &saveptr1);
651        argidx++;
652    }
653
654    if(argidx != 2) {
655        snprintf(buf, sizeof(buf),"[S-0000]setserver failed - wrong number of parameters (%d)\n", argidx);
656        monitor_send_info(buf, 1);
657        return;
658    }
659
660    trim(argarray[0]);
661    trim(argarray[1]);
662    strtolower(argarray[0]);
663
664    for (i = 0; i < 13; i++)
665        if (!strcmp(argarray[0], token[i])) break;
666
667    if (i < 13){
668        chk_t_global(token[i],argarray[1]);
669        snprintf(buf, sizeof(buf), "[S-0000]setserver done - param %s set to %s\n", argarray[0], argarray[1]);
670        monitor_send_info(buf, 1);
671    } else {
672        snprintf(buf, sizeof(buf), "[S-0000]setserver failed - parameter %s not exist\n", argarray[0]);
673        monitor_send_info(buf, 1);
674        return;
675    }
676
677    if (cfg.ftimeout>=cfg.ctimeout) {
678        cfg.ftimeout = cfg.ctimeout - 100;
679        snprintf(buf, sizeof(buf), "[S-0000]setserver WARNING: fallbacktimeout adjusted to %u ms\n", cfg.ftimeout);
680        monitor_send_info(buf, 1);
681    }
682    if(cfg.ftimeout < cfg.srtimeout) {
683        cfg.ftimeout = cfg.srtimeout + 100;
684        snprintf(buf, sizeof(buf), "[S-0000]setserver WARNING: fallbacktimeout adjusted to %u ms\n", cfg.ftimeout);
685        monitor_send_info(buf, 1);
686    }
687    if(cfg.ctimeout < cfg.srtimeout) {
688        cfg.ctimeout = cfg.srtimeout + 100;
689        snprintf(buf, sizeof(buf), "[S-0000]setserver WARNING: clienttimeout adjusted to %u ms\n", cfg.ctimeout);
690        monitor_send_info(buf, 1);
691    }
692    //kill(first_client->pid, SIGUSR1);
693}
694
695#ifdef WEBIF
696static void monitor_restart_server(){
697    cs_restart_oscam();
698}
699#endif
700
701static void monitor_list_commands(const char *args[], int32_t cmdcnt){
702    int32_t i;
703    for (i = 0; i < cmdcnt; i++) {
704        char buf[64];
705        snprintf(buf, sizeof(buf), "[S-0000]commands: %s\n", args[i]);
706        if(i < cmdcnt-1)
707            monitor_send_info(buf, 0);
708        else
709            monitor_send_info(buf, 1);
710    }
711}
712
713static int32_t monitor_process_request(char *req)
714{
715    int32_t i, rc;
716    static const char *cmd[] = {"login",
717                                "exit",
718                                "log",
719                                "status",
720                                "shutdown",
721                                "reload",
722                                "details",
723                                "version",
724                                "debug",
725                                "getuser",
726                                "setuser",
727                                "setserver",
728                                "commands",
729                                "keepalive",
730                                "reread"
731#ifdef WEBIF
732                                ,"restart"
733#endif
734                                };
735
736    int32_t cmdcnt = sizeof(cmd)/sizeof(char *);  // Calculate the amount of items in array
737    char *arg;
738    struct s_client *cur_cl = cur_client();
739
740    if( (arg = strchr(req, ' ')) ) { *arg++ = 0; trim(arg); }
741    //trim(req);
742    if ((!cur_cl->auth) && (strcmp(req, cmd[0])))   monitor_login(NULL);
743
744    for (rc=1, i = 0; i < cmdcnt; i++)
745        if (!strcmp(req, cmd[i])) {
746            switch(i) {
747            case  0:    monitor_login(arg); break;  // login
748            case  1:    rc=0; break;    // exit
749            case  2:    monitor_logsend(arg); break;    // log
750            case  3:    monitor_process_info(); break;  // status
751            case  4:    if (cur_cl->monlvl > 3) cs_exit(SIGQUIT); break;    // shutdown
752            case  5:    if (cur_cl->monlvl > 2) cs_accounts_chk(); break;   // reload
753            case  6:    monitor_process_details(arg); break;    // details
754            case  7:    monitor_send_details_version(); break;  // version
755            case  8:    if (cur_cl->monlvl > 3) monitor_set_debuglevel(arg); break; // debuglevel
756            case  9:    if (cur_cl->monlvl > 3) monitor_get_account(); break;   // getuser
757            case 10:    if (cur_cl->monlvl > 3) monitor_set_account(arg); break;    // setuser
758            case 11:    if (cur_cl->monlvl > 3) monitor_set_server(arg); break; // setserver
759            case 12:    if (cur_cl->monlvl > 3) monitor_list_commands(cmd, cmdcnt); break;  // list commands
760            case 13:    if (cur_cl->monlvl > 3) monitor_send_keepalive_ack(); break;    // keepalive
761            case 14:    { char buf[64];snprintf(buf, sizeof(buf), "[S-0000]reread\n");monitor_send_info(buf, 1); cs_card_info(); break; } // reread
762#ifdef WEBIF
763            case 15:    if (cur_cl->monlvl > 3) monitor_restart_server(); break;    // keepalive
764#endif
765            default:    continue;
766            }
767            break;
768        }
769    return(rc);
770}
771
772static void * monitor_server(void *cli){
773    int32_t n;
774    uchar mbuf[1024];
775
776    struct s_client * client = (struct s_client *) cli;
777    client->thread=pthread_self();
778    pthread_setspecific(getclient, cli);
779    client->typ='m';
780    while (((n = process_input(mbuf, sizeof(mbuf), cfg.cmaxidle)) >= 0) && monitor_process_request((char *)mbuf));
781    cs_disconnect_client(cli);
782    return NULL;
783}
784
785void module_monitor(struct s_module *ph){
786    static PTAB ptab; //since there is always only 1 monitor running, this is threadsafe
787    ptab.ports[0].s_port = cfg.mon_port;
788    ph->ptab = &ptab;
789    ph->ptab->nports = 1;
790
791    if (cfg.mon_aulow < 1)
792        cfg.mon_aulow = 30;
793    cs_strncpy(ph->desc, "monitor", sizeof(ph->desc));
794    ph->type=MOD_CONN_UDP;
795    ph->multi = 0;
796    ph->watchdog = 1;
797    ph->s_ip = cfg.mon_srvip;
798    ph->s_handler = monitor_server;
799    ph->recv = monitor_recv;
800    //  ph->send_dcw=NULL;
801}
802
803
Note: See TracBrowser for help on using the repository browser.