source: trunk/globals.h@ 1

Last change on this file since 1 was 1, checked in by root, 14 years ago

initial import

File size: 18.2 KB
Line 
1#include <stdlib.h>
2#include <stdio.h>
3#include <assert.h>
4#include <fcntl.h>
5#include <sys/ioctl.h>
6#include <sys/poll.h>
7#include <ctype.h>
8#include <sys/types.h>
9#include <sys/stat.h>
10#include <sys/shm.h>
11#include <sys/wait.h>
12#include <unistd.h>
13#include <sys/mman.h>
14#include <stdarg.h>
15#include <time.h>
16#include <sys/timeb.h>
17#include <limits.h>
18
19#include <sys/socket.h>
20#include <netinet/in.h>
21#include <netdb.h>
22#include <string.h>
23#include <signal.h>
24#include <errno.h>
25
26#include <pthread.h>
27
28#ifndef CS_GLOBALS
29#define CS_GLOBALS
30#define CS_VERSION "0.99.1"
31
32#if defined(__GNUC__)
33# define GCC_PACK __attribute__((packed))
34#else
35# define GCC_PACK
36#endif
37
38#include "oscam-config.h"
39#include "oscam-ostype.h"
40#include "oscam-types.h"
41#include "cscrypt/cscrypt.h"
42
43#ifndef CS_CONFDIR
44#define CS_CONFDIR "/usr/local/etc"
45#endif
46#ifndef CS_MMAPFILE
47#define CS_MMAPFILE "/tmp/mcps.mem"
48#endif
49#ifndef CS_LOGFILE
50#define CS_LOGFILE "/var/log/mcps.log"
51#endif
52#define CS_QLEN 128 // size of request queue
53#define CS_MAXQLEN 128 // size of request queue for cardreader
54#define CS_MAXCAIDTAB 32 // max. caid-defs/user
55#define CS_MAXTUNTAB 4 // max. betatunnel mappings
56#define CS_MAXPROV 32
57#define CS_MAXPORTS 32 // max server ports
58#define CS_MAXFILTERS 16
59
60#define CS_MAXCARDS 4096
61#define CS_MAXIGNORE 1024
62#define CS_MAXLOCALS 16
63#define CS_ECMSTORESIZE 16 // use MD5()
64#define CS_EMMSTORESIZE 270
65#define CS_CLIENT_TIMEOUT 5
66#define CS_CLIENT_MAXIDLE 120
67#define CS_BIND_TIMEOUT 120
68#define CS_DELAY 0
69#define CS_RESOLVE_DELAY 30
70#define CS_MAXLOGHIST 30
71#define CS_LOGHISTSIZE 160 // 32+128: username + logline
72
73#ifdef OLD_DEFS
74#ifdef CS_EMBEDDED
75#define CS_MAXPENDING 32
76#define CS_ECMCACHESIZE 32
77#define CS_EMMCACHESIZE 64
78#define CS_MAXPID 32
79#define CS_MAXREADER 8
80#else
81#define CS_MAXPENDING 128
82#define CS_ECMCACHESIZE 128
83#define CS_EMMCACHESIZE 256
84#define CS_MAXPID 128
85#define CS_MAXREADER 64
86#endif
87#endif
88
89#ifdef CS_EMBEDDED
90#define CS_MAXPID 32
91#define CS_MAXREADER (CS_MAXPID>>1)
92#define CS_MAXPENDING CS_MAXPID
93#define CS_ECMCACHESIZE CS_MAXPID
94#define CS_EMMCACHESIZE (CS_MAXPID<<1)
95#else
96#define CS_MAXPID 512
97#define CS_MAXREADER (CS_MAXPID>>2)
98#define CS_MAXPENDING (CS_MAXPID<<1)
99#define CS_ECMCACHESIZE CS_MAXPID
100#define CS_EMMCACHESIZE (CS_MAXPID<<1)
101#define CS_RDR_INIT_HIST
102#endif
103
104#define D_DUMP 1 // Debug Dumps
105#define D_MASTER 2 // Debug Master Process
106#define D_READER 4 // Debug Reader/Proxy Process
107#define D_CLIENT 8 // Debug Client Process
108#define D_DEVICE 16 // Debug Reader I/O
109#define D_WATCHDOG 32 // Debug Watchdog
110#define D_ALL_DUMP 63
111
112#define R_MOUSE 0x1 // Reader smartcard mouse
113#define R_INTERN 0x2 // Reader smartcard intern
114#define R_CAMD35 0x10 // Reader cascading camd 3.5x
115#define R_CAMD33 0x11 // Reader cascading camd 3.3x
116#define R_NEWCAMD 0x12 // Reader cascading newcamd
117#define R_RADEGAST 0x13 // Reader cascading radegast
118#define R_CS378X 0x14 // Reader cascading camd 3.5x TCP
119#define R_GBOX 0x20 // Reader cascading gbox
120#define R_SERIAL 0x80 // Reader serial
121#define R_IS_NETWORK 0x70
122#define R_IS_CASCADING 0xF0
123
124#define CS_MAX_MOD 8
125#define MOD_CONN_TCP 1
126#define MOD_CONN_UDP 2
127#define MOD_CONN_NET 3
128#define MOD_CONN_SERIAL 4
129
130#ifdef CS_CORE
131char *PIP_ID_TXT[] = { "ECM", "EMM", "LOG", "CIN", "HUP", NULL };
132char *RDR_CD_TXT[] = { "cd", "dsr", "cts", "ring", "none",
133#ifdef USE_GPIO
134 "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
135#endif
136 NULL };
137#else
138extern char *PIP_ID_TXT[];
139extern char *RDR_CD_TXT[];
140#endif
141
142#define PIP_ID_ECM 0
143#define PIP_ID_EMM 1
144#define PIP_ID_LOG 2
145#define PIP_ID_CIN 3 // CARD_INFO
146#define PIP_ID_HUP 4
147#define PIP_ID_MAX PIP_ID_HUP
148#define PIP_ID_DCW 5
149
150#define PIP_ID_ERR (-1)
151#define PIP_ID_DIR (-2)
152#define PIP_ID_NUL (-3)
153
154#define cdiff *c_start
155
156#define NCD_AUTO 0
157#define NCD_524 1
158#define NCD_525 2
159
160#define CS_ANTICASC
161
162enum {E1_GLOBAL=0, E1_USER, E1_READER, E1_SERVER, E1_LSERVER};
163enum {E2_GLOBAL=0, E2_GROUP, E2_CAID, E2_IDENT, E2_CLASS, E2_CHID, E2_QUEUE,
164 E2_EA_LEN, E2_F0_LEN, E2_OFFLINE, E2_SID};
165
166//typedef unsigned char uchar;
167//typedef unsigned long ulong;
168
169typedef struct s_classtab
170{
171 uchar an;
172 uchar bn;
173 uchar aclass[31];
174 uchar bclass[31];
175} GCC_PACK CLASSTAB;
176
177typedef struct s_caidtab
178{
179 ushort caid[CS_MAXCAIDTAB];
180 ushort mask[CS_MAXCAIDTAB];
181 ushort cmap[CS_MAXCAIDTAB];
182} GCC_PACK CAIDTAB;
183
184typedef struct s_tuntab
185{
186 ushort bt_caidfrom[CS_MAXTUNTAB];
187 ushort bt_caidto[CS_MAXTUNTAB];
188 ushort bt_srvid[CS_MAXTUNTAB];
189} GCC_PACK TUNTAB;
190
191typedef struct s_sidtab
192{
193 char label[33];
194 ushort num_caid;
195 ushort num_provid;
196 ushort num_srvid;
197 ushort *caid;
198 ulong *provid;
199 ushort *srvid;
200 struct s_sidtab *next;
201} GCC_PACK SIDTAB;
202
203
204typedef struct s_filter
205{
206 ushort caid;
207 uchar nprids;
208 ulong prids[CS_MAXPROV];
209} GCC_PACK FILTER;
210
211typedef struct s_ftab
212{
213 int nfilts;
214 FILTER filts[CS_MAXFILTERS];
215} GCC_PACK FTAB;
216
217typedef struct s_port
218{
219 int fd;
220 int s_port;
221 FTAB ftab;
222} GCC_PACK PORT;
223
224typedef struct s_ptab
225{
226 int nports;
227 PORT ports[CS_MAXPORTS];
228} GCC_PACK PTAB;
229
230struct s_ecm
231{
232 uchar ecmd5[CS_ECMSTORESIZE];
233 uchar cw[16];
234 ushort caid;
235 ulong prid;
236 ulong grp;
237// int level;
238};
239
240struct s_emm
241{
242 uchar emm[CS_EMMSTORESIZE];
243 uchar type;
244 int count;
245};
246
247struct s_module
248{
249 //int fd;
250 int multi;
251 int type;
252 int watchdog;
253 char desc[16];
254 char *logtxt;
255 //int s_port;
256 in_addr_t s_ip;
257 void (*s_handler)();
258 int (*recv)();
259 void (*send_dcw)();
260 int c_multi;
261 int (*c_recv_chk)();
262 int (*c_init)();
263 int (*c_send_ecm)();
264 int (*c_init_log)();
265 int (*c_recv_log)();
266 int c_port;
267 PTAB *ptab;
268};
269
270struct s_irdeto_quess
271{
272 int b47;
273 ushort caid;
274 ushort sid;
275 struct s_irdeto_quess *next;
276};
277
278struct s_client
279{
280 pid_t pid;
281 in_addr_t ip;
282 in_port_t port;
283 time_t login;
284 time_t last;
285 time_t lastswitch;
286 time_t lastemm;
287 time_t lastecm;
288 ulong grp;
289 int crypted;
290 int dup;
291 int au;
292 int monlvl;
293 int dbglvl;
294 CAIDTAB ctab;
295 TUNTAB ttab;
296 ulong sidtabok; // positiv services
297 ulong sidtabno; // negative services
298 int typ;
299 int ctyp;
300 int stat;
301 int ufd;
302 int last_srvid;
303 int last_caid;
304 int tosleep;
305 char usr[32];
306 int udp_fd;
307 int fd_m2c;
308 struct sockaddr_in udp_sa;
309 int log;
310 int logcounter;
311 int cwfound;
312 int cwcache;
313 int cwnot;
314 uchar ucrc[4]; // needed by monitor and used by camd35
315 ulong pcrc; // pwd crc
316 AES_KEY aeskey; // needed by monitor and used by camd33, camd35
317 ushort ncd_msgid;
318 uchar ncd_skey[16];
319 int port_idx; // index in server ptab
320 int ncd_server; // newcamd server?
321#ifdef CS_ANTICASC
322 ushort ac_idx;
323 ushort ac_limit;
324 uchar ac_penalty;
325#endif
326 FTAB fchid;
327 FTAB ftab; // user [caid] and ident filter
328 CLASSTAB cltab;
329};
330
331struct s_reader
332{
333 int cs_idx;
334 int fd;
335 ulong grp;
336 int fallback;
337 int typ;
338 int card_system;
339 char label[32];
340 char device[128];
341 int detect;
342 int mhz;
343 int custom_speed;
344 int r_port;
345 char r_usr[64];
346 char r_pwd[64];
347 int r_crypted;
348 int l_port;
349 int log_port;
350 CAIDTAB ctab;
351 ulong sidtabok; // positiv services
352 ulong sidtabno; // negative services
353 uchar hexserial[8];
354 int nprov;
355 uchar prid[CS_MAXPROV][8];
356 uchar availkeys[CS_MAXPROV][16]; // viaccess; misused in seca, if availkeys[PROV][0]=0 then expired, 1 then valid.
357 uchar sa[CS_MAXPROV][4]; // viaccess & seca
358 ushort acs; // irdeto
359 ushort caid[16];
360 uchar b_nano[256];
361 char pincode[5];
362 int logemm;
363 int cachemm;
364 int rewritemm;
365 int online;
366 struct s_module ph;
367 uchar ncd_key[16];
368 uchar ncd_skey[16];
369 int ncd_disable_server_filt;
370 ushort ncd_msgid;
371 int ncd_proto;
372 uchar tcp_connected;
373 int tcp_ito; // inactivity timeout
374 int tcp_rto; // reconnect timeout
375 time_t last_g; // get (if last_s-last_g>tcp_rto - reconnect )
376 time_t last_s; // send
377 uchar show_cls; // number of classes subscription showed on kill -31
378 int maxqlen; // max queue length
379 int qlen; // current queue length
380 FTAB fchid;
381 FTAB ftab;
382 CLASSTAB cltab;
383 uchar gbox_pwd[4];
384 uchar gbox_timecode[7];
385 int gbox_online;
386 uchar gbox_vers;
387 uchar gbox_prem;
388 int gbox_fd;
389 struct timeb gbox_lasthello; // incoming time stamp
390#ifdef CS_RDR_INIT_HIST
391 uchar init_history[1024];
392 int init_history_pos;
393#endif
394};
395
396#ifdef CS_ANTICASC
397
398struct s_acasc_shm {
399 ushort count : 15;
400 ushort deny : 1;
401};
402
403struct s_acasc {
404 ushort stat[10];
405 uchar idx; // current active index in stat[]
406};
407
408struct s_cpmap
409{
410 ushort caid;
411 ulong provid;
412 ushort sid;
413 ushort chid;
414 ushort dwtime;
415 struct s_cpmap *next;
416};
417#endif
418
419struct s_auth
420{
421 char usr[33];
422 char pwd[33];
423 int uniq;
424 int au;
425 int monlvl;
426 ulong grp;
427 int tosleep;
428 CAIDTAB ctab;
429 ulong sidtabok; // positiv services
430 ulong sidtabno; // negative services
431 FTAB fchid;
432 FTAB ftab; // user [caid] and ident filter
433 CLASSTAB cltab;
434 TUNTAB ttab;
435#ifdef CS_ANTICASC
436 int ac_idx;
437 int ac_users; // 0 - unlimited
438 uchar ac_penalty; // 0 - log, >0 - fake dw
439#endif
440 in_addr_t dynip;
441 uchar dyndns[64];
442 struct s_auth *next;
443};
444
445struct s_srvid
446{
447 int srvid;
448 char name[33];
449 struct s_srvid *next;
450};
451
452struct s_ip
453{
454 in_addr_t ip[2];
455 struct s_ip *next;
456};
457
458struct s_config
459{
460 int nice;
461 ulong netprio;
462 int ctimeout;
463 int ftimeout;
464 int cmaxidle;
465 ulong delay;
466 int bindwait;
467 int resolvedelay;
468 int tosleep;
469 in_addr_t srvip;
470 char pidfile[128];
471 char usrfile[128];
472 struct s_auth *account;
473 struct s_srvid *srvid;
474 struct s_sidtab *sidtab;
475 int mon_port;
476 in_addr_t mon_srvip;
477 struct s_ip *mon_allowed;
478 int mon_aulow;
479 int mon_hideclient_to;
480 int mon_level;
481 int c33_port;
482 in_addr_t c33_srvip;
483 uchar c33_key[16];
484 int c33_crypted;
485 int c33_passive;
486 struct s_ip *c33_plain;
487 int c35_port;
488 in_addr_t c35_srvip;
489 PTAB c35_tcp_ptab;
490 in_addr_t c35_tcp_srvip;
491 PTAB ncd_ptab;
492 in_addr_t ncd_srvip;
493 uchar ncd_key[16];
494 int rad_port;
495 in_addr_t rad_srvip;
496 struct s_ip *rad_allowed;
497 char rad_usr[32];
498 char ser_device[512];
499 int srtimeout; // SerialReaderTimeount in millisec
500 int max_log_size;
501 int show_ecm_dw;
502 uchar gbox_pwd[8];
503 uchar ignorefile[512];
504 uchar cardfile[512];
505 uchar gbxShareOnl[512];
506 int maxdist;
507 int num_locals;
508 unsigned long locals[CS_MAXLOCALS];
509 //struct s_irdeto_quess *itab[0xff];
510#ifdef CS_ANTICASC
511 char ac_enabled;
512 int ac_users; // num of users for account (0 - default)
513 int ac_stime; // time to collect AC statistics (3 min - default)
514 int ac_samples; // qty of samples
515 int ac_penalty; // 0 - write to log
516 int ac_fakedelay; // 100-1000 ms
517 int ac_denysamples;
518 char ac_logfile[128];
519 struct s_cpmap *cpmap;
520#endif
521// struct s_reader reader[];
522};
523
524typedef struct ecm_request_t
525{
526
527 uchar ecm[256];
528 uchar cw[16];
529 uchar ecmd5[CS_ECMSTORESIZE];
530// uchar l;
531 short l;
532 ushort caid;
533 ushort ocaid;
534 ushort srvid;
535 ushort chid;
536 ushort pid;
537 ushort idx;
538 ulong prid;
539 int reader[CS_MAXREADER];
540 int cidx; // client index
541 int cpti; // client pending table index
542 int stage; // processing stage in server module
543 int level; // send-level in client module
544 int rc;
545 uchar rcEx;
546 struct timeb tps; // incoming time stamp
547 ushort gbxCWFrom;
548 ushort gbxFrom;
549 ushort gbxTo;
550
551 uchar gbxForward[16];
552 int gbxRidx;
553} GCC_PACK ECM_REQUEST;
554
555typedef struct emm_packet_t
556{
557 uchar emm[258];
558 uchar l;
559 uchar caid[2];
560 uchar provid[4];
561 uchar hexserial[8];
562 uchar type;
563 int cidx;
564} GCC_PACK EMM_PACKET;
565
566// oscam-simples
567extern char *remote_txt(void);
568extern char *trim(char *);
569extern char *strtolower(char *);
570extern int gethexval(char);
571extern int cs_atob(uchar *, char *, int);
572extern ulong cs_atoi(char *, int, int);
573extern int byte_atob(char *);
574extern long word_atob(char *);
575extern int key_atob(char *, uchar *);
576extern int key_atob4(char *, uchar *);
577extern char *key_btoa(char *, uchar *);
578extern char *cs_hexdump(int, uchar *, int);
579extern in_addr_t cs_inet_order(in_addr_t);
580extern char *cs_inet_ntoa(in_addr_t);
581extern in_addr_t cs_inet_addr(char *txt);
582extern ulong b2i(int, uchar *);
583extern ullong b2ll(int, uchar *);
584extern uchar *i2b(int, ulong);
585extern ulong a2i(char *, int);
586extern int boundary(int, int);
587extern void cs_ftime(struct timeb *);
588extern void cs_sleepms(int);
589extern int bytes_available(int);
590extern void cs_setpriority(int);
591extern struct s_auth *find_user(char *);
592
593// oscam variables
594extern int pfd, rfd, fd_c2m, fd_m2c, cs_idx, *c_start, cs_ptyp, cs_dblevel, cs_hw;
595extern int *logidx, *loghistidx, *log_fd;
596extern int is_server, *mcl;
597extern uchar mbuf[1024];
598extern ushort len4caid[256];
599extern pid_t master_pid;
600extern struct s_ecm *ecmcache;
601extern struct s_client *client;
602extern struct s_reader *reader;
603
604extern struct card_struct *Cards;
605extern struct idstore_struct *idstore;
606extern unsigned long *IgnoreList;
607
608extern struct s_config *cfg;
609extern char cs_confdir[], *loghist;
610extern EMM_PACKET epg;
611extern struct s_module ph[CS_MAX_MOD];
612extern ECM_REQUEST *ecmtask;
613extern char logfile[256];
614#ifdef CS_ANTICASC
615extern struct s_acasc_shm *acasc;
616extern FILE *fpa;
617extern int use_ac_log;
618#endif
619
620
621// oscam
622extern char *cs_platform(char *);
623extern int recv_from_udpipe(uchar *, int);
624extern char* username(int);
625extern int idx_from_pid(pid_t);
626extern int chk_bcaid(ECM_REQUEST *, CAIDTAB *);
627extern void cs_exit(int sig);
628extern int cs_fork(in_addr_t, in_port_t);
629extern void wait4master(void);
630extern int cs_auth_client(struct s_auth *, char*);
631extern void cs_disconnect_client(void);
632extern int check_ecmcache(ECM_REQUEST *, ulong);
633extern int write_to_pipe(int, int, uchar *, int);
634extern int read_from_pipe(int, uchar **, int);
635extern int write_ecm_request(int, ECM_REQUEST *);
636extern int write_ecm_answer(int, ECM_REQUEST *);
637extern void log_emm_request(int);
638extern ulong chk_provid(uchar *, ushort);
639extern void guess_cardsystem(ECM_REQUEST *);
640extern void guess_irdeto(ECM_REQUEST *);
641extern void get_cw(ECM_REQUEST *);
642extern void do_emm(EMM_PACKET *);
643extern ECM_REQUEST *get_ecmtask(void);
644extern void request_cw(ECM_REQUEST *, int);
645extern int send_dcw(ECM_REQUEST *);
646extern int process_input(uchar *, int, int);
647extern int chk_srvid(ECM_REQUEST *, int);
648extern int chk_sfilter(ECM_REQUEST *, PTAB*);
649extern int chk_ufilters(ECM_REQUEST *);
650extern int chk_rfilter(ECM_REQUEST *, struct s_reader *);
651extern int chk_rsfilter(ECM_REQUEST *, int);
652extern int chk_avail_reader(ECM_REQUEST *, struct s_reader *);
653extern void set_signal_handler(int , int , void (*)(int));
654extern void cs_log_config(void);
655
656#ifdef CS_ANTICASC
657//extern void start_anticascader(void);
658extern void init_ac(void);
659extern void ac_init_stat(int);
660extern int ac_init_log(char*);
661extern void ac_do_stat(void);
662extern void ac_init_client(struct s_auth *);
663extern void ac_chk(ECM_REQUEST*, int);
664#endif
665
666// oscam-nano
667extern int chk_class(ECM_REQUEST *, CLASSTAB*, const char*, const char*);
668
669// oscam-config
670extern int init_config(void);
671extern int init_userdb(void);
672extern int init_readerdb(void);
673extern int init_sidtab(void);
674extern int init_srvid(void);
675extern int search_boxkey(ushort, ulong, char *);
676extern void init_len4caid(void);
677extern int init_irdeto_guess_tab(void);
678
679// oscam-reader
680extern int ridx, logfd;
681extern void cs_ri_brk(int);
682extern void cs_ri_log(char *,...);
683extern void start_cardreader(void);
684extern void reader_card_info(void);
685
686// oscam-log
687extern int cs_init_log(char *);
688extern void cs_log(char *,...);
689extern void cs_debug(char *,...);
690extern void cs_ddump(uchar *, int, char *, ...);
691extern void cs_close_log(void);
692extern int cs_init_statistics(char *);
693extern void cs_statistics(int);
694extern void cs_dump(uchar *, int, char *, ...);
695
696// oscam-aes
697extern void aes_set_key(char *);
698extern void aes_encrypt_idx(int, uchar *, int);
699extern void aes_decrypt(uchar *, int);
700#define aes_encrypt(b, n) aes_encrypt_idx(cs_idx, b, n)
701
702// reader-common
703extern int reader_device_init(char *, int);
704extern int reader_checkhealth(void);
705extern int reader_ecm(ECM_REQUEST *);
706extern int reader_emm(EMM_PACKET *);
707
708// reader-irdeto
709extern int irdeto_card_init(uchar *, int);
710extern int irdeto_do_ecm(ECM_REQUEST *);
711extern int irdeto_do_emm(EMM_PACKET *);
712extern int irdeto_card_info(void);
713
714// reader-viaccess
715extern int viaccess_card_init(uchar *, int);
716extern int viaccess_do_ecm(ECM_REQUEST *);
717extern int viaccess_do_emm(EMM_PACKET *);
718extern int viaccess_card_info(void);
719
720// reader-videoguard
721extern int videoguard_card_init(uchar *, int);
722extern int videoguard_do_ecm(ECM_REQUEST *);
723extern int videoguard_do_emm(EMM_PACKET *);
724extern int videoguard_card_info(void);
725
726// reader-cryptoworks
727extern int cryptoworks_card_init(uchar *, int);
728extern int cryptoworks_do_ecm(ECM_REQUEST *);
729extern int cryptoworks_do_emm(EMM_PACKET *);
730extern int cryptoworks_card_info(void);
731
732// reader-seca
733extern int seca_card_init(uchar *, int);
734extern int seca_do_ecm(ECM_REQUEST *);
735extern int seca_do_emm(EMM_PACKET *);
736extern int seca_card_info(void);
737
738// protocol modules
739extern int monitor_send_idx(int, char *);
740extern void module_monitor(struct s_module *);
741extern void module_camd35(struct s_module *);
742extern void module_camd35_tcp(struct s_module *);
743extern void module_camd33(struct s_module *);
744extern void module_newcamd(struct s_module *);
745extern void module_radegast(struct s_module *);
746extern void module_oscam_ser(struct s_module *);
747extern void module_gbox(struct s_module *);
748extern struct timeval *chk_pending(struct timeb tp_ctimeout);
749#endif // CS_GLOBALS
Note: See TracBrowser for help on using the repository browser.