source: titan/titan/titan.c @ 40630

Last change on this file since 40630 was 40630, checked in by obi, 5 years ago

fix sh4 building

File size: 34.5 KB
Line 
1#include "struct.h"
2#ifdef CONFIG_ION
3#include "ion.h"
4#endif
5#include "header.h"
6#include "debug.h"
7#include "crc32.h"
8#include "sock.h"
9
10#define SYSCODE 0UL
11#define HTTPAUTH "aXBrLUdaRmg6RkhaVkJHaG56ZnZFaEZERlRHenVpZjU2NzZ6aGpHVFVHQk5Iam0="
12
13struct clist *config[LISTHASHSIZE] = {NULL};
14struct clist *ownconfig[LISTHASHSIZE] = {NULL};
15struct clist *rcconfig[LISTHASHSIZE] = {NULL};
16struct clist *skinconfig[LISTHASHSIZE] = {NULL};
17struct skin *skin = NULL;
18struct fb *fb = NULL;
19struct fb* skinfb = NULL;
20struct fb* accelfb = NULL;
21struct fb* fb1 = NULL;
22struct fb* lcdskinfb = NULL;
23struct fb* oledskinfb = NULL;
24struct font *font = NULL;
25struct rc *rc = NULL;
26struct dvbdev *dvbdev = NULL;
27struct dvbdev *dvbdevsim = NULL;
28struct channel *channel = NULL;
29struct transponder *transponder = NULL;
30struct provider *provider = NULL;
31struct sat *sat = NULL;
32struct service *service = NULL;
33struct mainbouquet *mainbouquet = NULL;
34struct mainplaylist *mainplaylist = NULL;
35struct pic *pic = NULL;
36struct rcmap *rcmap = NULL;
37struct inetwork *inetwork = NULL;
38struct stimerthread *stimerthread = NULL;
39struct rectimer *rectimer = NULL;
40struct subpage* subpage = NULL, *oldsubpage = NULL;
41struct epgscanlist* epgscanlist = NULL;
42struct screensaver* screensaver = NULL;
43struct channelcache* channelcache[CHANNELCACHEMAX] = {NULL};
44struct transpondercache* transpondercache[TRANSPONDERCACHEMAX] = {NULL};
45struct hdd* hdd = NULL;
46struct queue* queue = NULL;
47struct caservice caservice[MAXCASERVICE];
48struct channelhistory channelhistory[MAXCHANNELHISTORY];
49struct mostzap* mostzap = NULL;
50struct mediadbfilter* mediadbfilter = NULL;
51struct mediadbcategory* mediadbcategory = NULL;
52struct mediadb* mediadb = NULL;
53struct mediadbcache* mediadbcache[MEDIADBCACHEMAX] = {NULL};
54struct unicable* unicable = NULL;
55struct oldentry* oldentry = NULL;
56struct newsletter* newsletter = NULL;
57struct extepgcache* extepgcache = NULL;
58struct extepgchannel* extepgchannel = NULL;
59struct extepgconfig* extepgconfig = NULL;
60struct lastsubtitle* lastsubtitle = NULL;
61struct style* style = NULL;
62struct download* bgdownload[MAXBGDOWNLOAD] = {NULL};
63struct channelslot *channelslot = NULL;
64
65#ifdef SH4
66#include "sh4port.h"
67#endif
68
69#ifdef MIPSEL
70#include "mipselport.h"
71#endif
72
73#ifdef I386
74#include "i386port.h"
75#endif
76
77#include "oldentry.h"
78#include "tpk.h"
79#include "queue.h"
80#include "channelcache.h"
81#include "transpondercache.h"
82#include "strconvert.h"
83#include "numinput.h"
84#include "textinput.h"
85#include "radiotext.h"
86#include "list.h"
87#include "config.h"
88#include "defaults.h"
89#include "ownconfig.h"
90#include "rcconfig.h"
91#include "skinconfig.h"
92#include "thumb.h"
93#include "global.h"
94#include "security.h"
95#include "stream.h"
96#include "dvbdev.h"
97#include "rotorcalc.h"
98#include "frontenddev.h"
99#include "dmxdev.h"
100#include "videodev.h"
101#include "audiodev.h"
102#include "cidev.h"
103#include "cadev.h"
104#include "scdev.h"
105#include "cacc.h"
106#include "ca.h"
107#include "dvrdev.h"
108#include "cam.h"
109#include "dvb.h"
110#include "fb.h"
111#include "font.h"
112#include "rcmap.h"
113#include "rc.h"
114#include "sat.h"
115#include "transponder.h"
116#include "provider.h"
117#include "channel.h"
118#include "bouquets.h"
119#include "mainbouquets.h"
120#include "playlist.h"
121#include "mainplaylist.h"
122#include "pic.h"
123#include "filelist.h"
124#include "skinfunc.h"
125#include "style.h"
126#include "skin.h"
127#include "inputhelp.h"
128#include "rcfunc.h"
129#include "listbox.h"
130#include "choicebox.h"
131#include "vfd.h"
132#include "timerthread.h"
133#include "service.h"
134#include "pip.h"
135#include "player.h"
136#include "dvdplayer.h"
137#include "timeshift.h"
138#include "record.h"
139#include "zap.h"
140#include "showiframe.h"
141#include "epgrecord.h"
142#include "multiepg.h"
143#include "gmultiepg.h"
144#include "epg.h"
145#include "eit.h"
146#include "extepg.h"
147#include "epgscan.h"
148#include "menulist.h"
149#include "videomode.h"
150#include "inetwork.h"
151#include "keyactions.h"
152#include "scart.h"
153#include "standby.h"
154#include "dir.h"
155#include "spinner.h"
156#include "lnbconfig.h"
157#include "diseqcconfig.h"
158#include "tunerconfig.h"
159#include "epgsettings.h"
160#include "listedit.h"
161#include "channellist.h"
162#include "vfdisplay.h"
163#include "videosettings.h"
164#include "textbox.h"
165#include "autores.h"
166#include "language.h"
167#include "about.h"
168#include "serviceinfo.h"
169#include "avsettings.h"
170#include "mute.h"
171#include "volume.h"
172#include "timezone.h"
173#include "adjust.h"
174#include "skinadjust.h"
175#include "blindscanadjust.h"
176#include "moduleconfig.h"
177#include "scconfig.h"
178#include "possetup.h"
179#include "rectimer.h"
180#include "pin.h"
181#include "plugin.h"
182#include "recordpath.h"
183#include "subtitle.h"
184#include "audiotrack.h"
185#include "linkedchannel.h"
186#include "powerofftimer.h"
187#include "skinselector.h"
188#include "play.h"
189#include "satfinder.h"
190#include "menu.h"
191#include "channelbynr.h"
192#include "infobar.h"
193#include "network.h"
194#include "harddisk.h"
195#include "httpdfunc.h"
196#include "httpd.h"
197#include "download.h"
198#include "copyfile.h"
199#include "screensaver.h"
200#include "screensaveradjust.h"
201#include "scan.h"
202#include "restoredefault.h"
203#include "help.h"
204#include "httpdsettings.h"
205#include "epgsearch.h"
206#include "inadyn.h"
207#include "rguid.h"
208#include "channelhistroy.h"
209#include "mostzap.h"
210#include "settings_redbutton.h"
211#include "settings_bluebutton.h"
212#include "extensions.h"
213#include "system_update.h"
214#include "system_backup.h"
215#include "system_backup_restore.h"
216#include "info.h"
217#include "softcam.h"
218#include "id3.h"
219#include "mediadbcache.h"
220#include "mediadb.h"
221#include "mediadbsettings.h"
222#include "colorpicker.h"
223#include "ocrypt.h"
224#include "unlock.h"
225#include "md5.h"
226#include "rc4.h"
227#include "textinputhist.h"
228#include "system_infos.h"
229#include "system_infos_sysinfo.h"
230#include "unicable.h"
231#include "newsletter.h"
232#include "dirsort.h"
233#include "shortepg.h"
234#include "mediadbedit.h"
235#include "tpchoice.h"
236#include "marker.h"
237#include "timeshiftsettings.h"
238#include "log.h"
239#include "bgdownload.h"
240#include "fancontrol.h"
241#include "channelslot.h"
242#include "hwtest.h"
243#include "settings_autostart.h"
244#include "settings_overclocking.h"
245#include "settings_pluginbutton.h"
246#include "bcm.h"
247#include "settings_mediabutton.h"
248#include "oled.h"
249#ifdef MIPSEL
250#include "cec.h"
251#include "encoder.h"
252#endif
253
254#define TIMECODE "1472042241"
255
256// mipsel start
257/* Apparently, surfaces must be 64-byte aligned */
258#define ACCEL_ALIGNMENT_SHIFT   6
259#define ACCEL_ALIGNMENT_MASK    ((1<<ACCEL_ALIGNMENT_SHIFT)-1)
260
261#define ACCEL_DEBUG
262
263//gAccel *gAccel::instance;
264#define BCM_ACCEL
265
266#ifdef BCM_ACCEL
267extern int bcm_accel_init(void);
268extern void bcm_accel_close(void);
269extern void bcm_accel_blit(
270                int src_addr, int src_width, int src_height, int src_stride, int src_format,
271                int dst_addr, int dst_width, int dst_height, int dst_stride,
272                int src_x, int src_y, int width, int height,
273                int dst_x, int dst_y, int dwidth, int dheight,
274                int pal_addr, int flags);
275extern void bcm_accel_fill(
276                int dst_addr, int dst_width, int dst_height, int dst_stride,
277                int x, int y, int width, int height,
278                unsigned long color);
279extern bool bcm_accel_has_alphablending();
280#endif
281// mipsel end
282
283void demomodethread(struct stimerthread* self)
284{
285        textbox(_("Message"), _("!!! This is a DEMO Version !!!"), _("OK"), getrcconfigint("rcok", NULL), _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, 600, 600, 0, 1);
286}
287
288int createstartscreen()
289{
290        addscreen("<screen name=framebuffer/>", 0, 0);
291        if(skin == NULL)
292        {
293                err("can't set framebuffer skin");
294                return 1;
295        }
296        addscreen("<screen name=skinerror/>", 0, 0);
297        status.skinerr = getscreen("skinerror");
298        skin->width = skinfb->width;
299        skin->height = skinfb->height;
300        skin->iwidth = skinfb->width;
301        skin->iheight = skinfb->height;
302        skin->rwidth = skinfb->width;
303        skin->rheight = skinfb->height;
304        skin->bgcol = 0;
305        skin->transparent = 255;
306        skin->flag = 1;
307
308        return 0;
309}
310
311//exitcode: 1 power off
312//exitcode: 2 restart
313//exitcode: 3 Gui restart
314//flag: 0 do not check record
315//flag: 1 check record
316//flag: 2 check record / don't write config
317//flag: 3 check record with timeout
318//flag: 4 check record with increase fixpowerofftime
319//flag: 5 check record with increase powerofftime
320void oshutdown(int exitcode, int flag)
321{
322        struct dvbdev* dvbnode = dvbdev;
323        struct service* servicenode = service;
324        void* threadstatus;
325        int i = 0, faststop = 0, ret = 0;
326        char* tmpstr = NULL;
327        struct skin* logo = getscreen("logo");
328        pthread_attr_t writethreadattr = {};
329        pthread_t writethread = '\0';
330
331        //stop permanent timeshift
332        if(status.timeshift == 1)
333                timeshiftstop(3);
334
335        ret = checkshutdown(flag);
336        if(ret == 1) return;
337
338        ret = servicestop(status.aktservice, 1, 1);
339        if(ret == 1) return;
340       
341        if(exitcode == 1)
342                tmpstr = getconfig("userpowerofflogo", NULL);
343        else if(exitcode == 2)
344                tmpstr = getconfig("userrestartlogo", NULL);
345        else if(exitcode == 3)
346                tmpstr = getconfig("userguirestartlogo", NULL);
347       
348        if(tmpstr != NULL) {
349                if(file_exist(tmpstr) == 0)
350                        tmpstr = NULL;
351        }       
352        if(tmpstr == NULL) {   
353                if(exitcode == 1)
354                        tmpstr = getconfig("powerofflogo", NULL);
355                else if(exitcode == 2)
356                        tmpstr = getconfig("restartlogo", NULL);
357                else if(exitcode == 3)
358                        tmpstr = getconfig("guirestartlogo", NULL);
359        }
360                       
361        if(tmpstr != NULL)
362        {
363                changepic(logo, tmpstr);
364                tmpstr = NULL;
365                drawscreen(logo, 0, 0);
366        }
367        else
368                clearfball();
369
370        //stop all records
371        while(servicenode != NULL)
372        {
373                servicenode->recendtime = 1;
374                servicenode = servicenode->next;
375        }
376
377        faststop = getconfigint("faststop", NULL);
378
379        // Free memory, semaphores, etc. and say goodbye
380        if(faststop == 0) cleanupvfd();
381
382        if(status.servicetype != 99) //don't save tmp servicetype
383        {
384                tmpstr = oitoa(status.servicetype);
385                addconfig("servicetype", tmpstr);
386                free(tmpstr); tmpstr = NULL;
387        }
388
389        status.sec = 0;
390
391        if(flag != 2)
392        {
393                //start write thread
394                pthread_attr_init(&writethreadattr);
395                pthread_attr_setstacksize(&writethreadattr, 50000);
396                pthread_attr_setdetachstate(&writethreadattr, PTHREAD_CREATE_JOINABLE);
397
398                int epgsave = getconfigint("epgsave", NULL);
399                if((epgsave == 1 && exitcode == 3) || epgsave == 2)
400                        ret = pthread_create(&writethread, &writethreadattr, writeallconfigthread1, NULL); //do not save epg
401                else
402                        ret = pthread_create(&writethread, &writethreadattr, writeallconfigthread0, NULL); //save epg
403                if(ret)
404                {
405                        err("create write thread");
406                }
407        }
408       
409        //stop fan
410        if(checkchipset("BCM7424") == 1) //inihdp
411                writesys("/proc/stb/fp/fan", "1", 1);
412               
413        //reset ci devices
414        while(dvbnode != NULL)
415        {
416                if(dvbnode->type == CIDEV && dvbnode->fd > -1)
417                {
418                        if(dvbnode->caslot != NULL) dvbnode->caslot->status = 101;
419                        usleep(10000);
420                        careset(dvbnode, dvbnode->devnr);
421                }
422                dvbnode = dvbnode->next;
423        }
424
425        if(faststop == 0)
426        {
427                //wait for write thread
428                if(writethread != '\0')
429                        pthread_join(writethread, &threadstatus);
430                pthread_attr_destroy(&writethreadattr);
431
432                //stop timer thread
433                i = 0;
434                status.timerthreadaktion = STOP;
435                while(status.timerthreadstatus != DEACTIVE)
436                {
437                        usleep(100000);
438                        i++; if(i > 20) break;
439                }
440
441                if(i > 20)
442                {
443                        err("detect hanging timer thread");
444                }
445                else if(status.timerthread != '\0')
446                        pthread_join(status.timerthread, &threadstatus);
447                pthread_attr_destroy(&status.timerthreadattr);
448               
449                // free timerthread struct and stop all timer sub threads
450                freetimer(0);
451
452                status.skinerr = NULL;
453                free(status.gateway);
454                free(status.dnsserver1);
455                free(status.dnsserver2);
456                free(status.boxtype);
457                free(status.httpauth);
458                free(status.bgpic);
459
460                freeservice();
461                freecaservice();
462
463                freescreen();
464                freepic();
465                freefont();
466                deinitfont();
467
468                freerectimer();
469                freemostzap(0);
470                freechannelhistory();
471                freesat();
472                freeallplaylist();
473                freemainplaylist();
474                freeallbouquet();
475                freemainbouquet(0);
476                freechannel(0);
477                freetransponder();
478                freeprovider();
479                freeownconfig();
480                freeepgscanlist();
481                freercconfig();
482                freeskinconfig();
483                freequeue();
484                freehdd(0);
485
486                free(status.configfile);
487                freeconfig();
488
489                freedvbdev(0);
490
491                closefb(fb);
492                freefb();
493
494                closerc();
495                freerc();
496                freercmap();
497                free_shutdowntimervar();
498                freeinetwork();
499                freeoldentry();
500                freeextepgconfig();
501                freelastsubtitle();
502                freebgdownload();
503                freechannelslot();
504        }
505        else
506                freetimer(1);
507
508        if(exitcode == 1)
509                setcecstandby(1);
510
511        starthttpd(0);
512        startrguid(0);
513        initmutex(0);
514
515        if(faststop != 0)
516        {
517                //wait for write thread
518                if(writethread != '\0')
519                        pthread_join(writethread, &threadstatus);
520                pthread_attr_destroy(&writethreadattr);
521        }
522
523        exit(exitcode);
524}
525
526int main(int argc, char *argv[])
527{
528        int ret = 0, serviceret = 0, skincheck = 0;
529        char* tmpstr = NULL;
530        unsigned char *mmapfb = NULL;
531        struct sigaction sa;
532        struct stimerthread *tmpthread = NULL;
533        //struct sched_param schedparam;
534
535#ifdef SIMULATE
536        // for mem leak debug
537        setenv("MALLOC_TRACE", "/home/nit/titan/m.txt", 1);
538        mtrace();
539        status.security = 1;
540#endif
541
542        printf("[%s] copyright by %s - version %s (%d)\n", PROGNAME, COPYRIGHT, OVERSION, PLUGINVERSION);
543        printf("[%s] crontribut: %s\n", PROGNAME, CRONTRIBUT);
544
545        sa.sa_handler = (void *)sighandler;
546        sigemptyset(&sa.sa_mask);
547        sa.sa_flags = SA_RESTART;
548       
549        initsignal(&sa);
550
551        status.rguidfd = -1;
552        status.sec = time(NULL);
553        status.mainthread = pthread_self();
554
555        if(argc > 1)
556                status.configfile = ostrcat(argv[1], NULL, 0, 0);
557        else
558                status.configfile = ostrcat(CONFIGFILE, NULL, 0, 0);
559
560        printf("[%s] using config: %s\n", PROGNAME, status.configfile);
561        ret = readconfig(status.configfile, config);
562        if(ret != 0)
563        {
564                printf("error: status.configfile ret=%d\n", ret);
565                return 100;
566        }
567        //Workaround da ansonsten DVR4 nicht funktioniert (Treiberproblem)
568        status.setdvr0 = 0;
569       
570        //start timer thread
571        status.timerthreadaktion = START;
572        pthread_attr_init(&status.timerthreadattr);
573        pthread_attr_setstacksize(&status.timerthreadattr, 50000);
574        pthread_attr_setdetachstate(&status.timerthreadattr, PTHREAD_CREATE_JOINABLE);
575        ret = pthread_create(&status.timerthread, &status.timerthreadattr, timerthreadfunc, NULL);
576        if(ret)
577        {
578                err("create timer thread");
579                printf("error: create timer thread\n");
580                return 100;
581        }
582
583        //change working dir to /tmp
584        //chdir("/tmp");
585
586        //set main scheduler priority
587        //schedparam.sched_priority = 10;
588        //pthread_setschedparam(pthread_self(), SCHED_RR, &schedparam);
589
590        readconfig(getconfig("ownconfig", NULL), ownconfig);
591        readconfig(getconfig("rcconfig", NULL), rcconfig);
592
593        skincheck = checkskin();
594        readconfig(getconfig("skinconfig", NULL), skinconfig);
595
596        setprogress(100);
597        setdefaults();
598        setdebuglevel();
599        initmutex(1);
600        m_lock(&status.waitrcmutex, 24);
601        initvfd();
602
603        if(checkbox("UFS922") == 1)
604                setfanspeed(-1, 0);
605        if(checkchipset("BCM7424") == 1) //inihdp
606        {
607                if(getconfigint("fanmode", NULL) == 0)
608                        addconfig("fanmode", "3");
609                writesys("/proc/stb/fp/fan", getconfig("fanmode", NULL), 1);
610        }
611        if(getconfigint("wol", NULL) == 1)
612                system("echo enable > /proc/stb/fp/wol");
613        else
614                system("echo disable > /proc/stb/fp/wol");
615
616#ifdef MIPSEL
617        addtimer(&cecinit, START, 10000, 1, NULL, NULL, NULL);
618        //cecinit();
619#endif 
620        system(getconfig("skriptbeforetv", NULL));
621//      ret = setcecstandby(0); --- > jetzt in checkboxstart
622        ret = setvideomode(getconfig("av_videomode", NULL), 0);
623#ifndef MIPSEL
624        ret = setaspect(getconfig("av_aspect", NULL));
625#endif
626        ret = setpolicy(getconfig("av_policy", NULL));
627        ret = setcolorformat(getconfig("av_colorformat", NULL), 0);
628        ret = setcolorformat(getconfig("av_colorformatscart", NULL), 1);
629        ret = setaudiosource(getconfig("av_audiosource", NULL));
630        ret = setac3(getconfig("av_ac3mode", NULL));
631
632        if(checkbox("DM900") == 1 || checkbox("DM520") == 1 || checkbox("DM525") == 1)
633        {
634                if(getconfig("av_ac3plusmode", NULL) == NULL)
635                        addconfig("av_ac3plusmode", "force_ac3");
636                if(getconfig("av_dtshdmode", NULL) == NULL)
637                        addconfig("av_dtshdmode", "force_dts");
638                if(getconfig("av_wmapromode", NULL) == NULL)
639                        addconfig("av_wmapromode", "downmix");
640                ret = setac3plus(getconfig("av_ac3plusmode", NULL));
641                ret = setdtshd(getconfig("av_dtshdmode", NULL));
642                ret = setwmapro(getconfig("av_wmapromode", NULL));
643       
644                addconfig("mode3ddev", "/proc/stb/fb/primary/3d");     //24.02.17
645        }
646               
647#ifdef MIPSEL
648        ret = setaac(getconfig("av_aacmode", NULL));
649        ret = setwss(getconfig("av_wssmode", NULL));
650#endif
651        ret = setpolicy(getconfig("av_policy", NULL));
652        ret = setmode3d(getconfig("av_mode3d", NULL));
653        ret = setvfdbrightness(getconfigint("vfdbrightness", NULL));
654        ret = setaudiodelaybitstream(getconfig("audiodelaybitstream", NULL));
655        ret = addinetworkall(NULL);
656       
657        ret = 1;
658        if(file_exist("/var/etc/.usbimage"))
659                ret = system("mount | grep titan");
660 
661#ifndef SIMULATE
662        if(checkrealbox("DM900") == 1 || checkbox("DM520") == 1 || checkbox("DM525") == 1)
663                ret = 0;
664
665        // set pvr 1 = allowed , 0 = disabled
666        status.pvr = 1;
667        if(file_exist("/etc/.stable") && (checkbox("ATEMIO6000") == 1 || checkbox("ATEMIO6100") == 1 || checkbox("ATEMIO6200") == 1))
668                status.pvr = 0;
669
670        if(getconfigint("sos", NULL) == 0)
671        {
672                if(ostrcmp(string_newline(gettimeinfo()), TIMECODE) == 1)
673                {
674                        printf("error: 1\n");
675                        destroy();
676                        exit(100);
677                }
678                if(ostrcmp(string_newline(gettimeinfovar()), TIMECODE) == 1)
679                {
680                        printf("error: 2\n");           
681                        destroy();
682                        exit(100);
683                }
684                if(checkreseller() != 0)
685                {
686                        printf("error: 3\n");           
687                        destroy();
688                        exit(100);
689                }
690                if(ret > 0)
691                {
692                        if(getsysinfo() != SYSCODE)
693                        {
694                                printf("error: 4\n");           
695                                destroy();
696                                exit(100);
697                        }
698                }
699                if(file_exist("/mnt/swapextensions/etc/.vnumber") == 1)
700                {
701                        printf("error: 5\n");           
702                        destroy();
703                        exit(100);
704                }
705                if(ret > 0)
706                {
707                        if(checkflash() != 0)
708                        {
709                                printf("error: 6\n");           
710                                destroy();
711                                exit(100);
712                        }
713                }
714                if(ret > 0)
715                {
716                        if((checkchipset("BCM7424") == 1 || checkchipset("BCM7358") == 1 || checkchipset("BCM7362") == 1 || checkbox("UFS913") == 1 || checkbox("SPARK") == 1 || checkbox("SPARK7162") == 1 || checkbox("IPBOX91") == 1 || checkbox("IPBOX900") == 1 || checkbox("IPBOX910") == 1 || checkbox("IPBOX9000") == 1) && checkhighflash() != 0)
717                        {
718                                printf("error: 7\n");           
719                                destroy();
720                                exit(100);
721                        }
722                }
723                if(checkbox("UFS910") == 1 && checklowflash() != 0)
724                {
725                        printf("error: 8\n");           
726                        destroy();
727                        exit(100);
728                }
729       
730                char* cpuid = getcpuid();
731                checkserial(cpuid);
732                free(cpuid); cpuid = NULL;
733        }
734        else
735        {
736                status.security = 5;
737                startnet();
738                setskinnodeslocked(0);
739        }
740#endif
741
742        if(file_exist("/mnt/config/dualboot.enigma2"))
743        {
744                printf("error: found /mnt/config/dualboot.enigma2\n");
745                return 0;
746        }
747
748        ret = initfont();
749        if(ret != 0)
750        {
751                printf("error: initfont\n");
752                return 100;
753        }
754        ret = openfont(getconfig("fontfile1", NULL));
755        if(ret != 0)
756        {
757                err("open fontfile1 font");
758                printf("error: open fontfile1 font\n");
759                return 100;
760        }
761        openfont(getconfig("fontfile2", NULL));
762        openfont(getconfig("fontfile3", NULL));
763        openfont(getconfig("fontfile4", NULL));
764        openfont(getconfig("fontfile5", NULL));
765
766        //skin defined fonts
767        openfont(getskinconfig("fontfile1", NULL));
768        openfont(getskinconfig("fontfile2", NULL));
769        openfont(getskinconfig("fontfile3", NULL));
770        openfont(getskinconfig("fontfile4", NULL));
771        openfont(getskinconfig("fontfile5", NULL));
772
773
774        status.volume = -1;
775        setvol(getconfigint("vol", NULL));
776
777       
778        setlang(getconfig("lang", NULL));
779        initlocale(getconfig("localepath", NULL));
780
781#ifdef MIPSEL
782        bcm_accel_init();
783#endif
784
785        fb = openfb(getconfig("fbdev", NULL), 0);
786        if(fb == NULL)
787        {
788                printf("error: openfb %s\n", getconfig("fbdev", NULL));
789                return 100;
790        }
791        clearfball();
792        enablemanualblit();
793       
794        tmpstr = getconfig("fb1dev", NULL);
795        if(tmpstr != NULL)
796                fb1 = openfb(tmpstr, 1);
797        tmpstr = NULL;
798
799#ifdef MIPSEL
800        waitvsync();
801        if(checkbox("DM7020HD") == 0 && checkbox("DM7020HDV2") == 0 && checkbox("VUSOLO2") == 0 && checkbox("DM900") == 0 && checkbox("DM520") == 0 && checkbox("DM525") == 0)
802                setfbosd();
803        status.usedirectfb = 1;
804#endif
805#ifndef CONFIG_ION
806        if(status.usedirectfb != 1)
807        {
808                skinfb = addfb(SKINFB, 0, getconfigint("skinfbwidth", NULL), getconfigint("skinfbheight", NULL), 4, fb->fd, fb->fb + fb->varfbsize, fb->fixfbsize, 0);
809                if(skinfb != NULL)
810                {
811                        ret = getfbsize(0);
812                        if(ret > 0)
813                                accelfb = addfb(ACCELFB, 0, ret / 4, 1, 4, fb->fd, skinfb->fb + skinfb->varfbsize, fb->fixfbsize, 0);
814                }
815                else
816                {
817                        debug(100, "use directfb");
818                        status.usedirectfb = 1;
819                }
820        }
821        if(status.usedirectfb == 1)
822        {
823                skinfb = fb;
824#ifndef MIPSEL
825                ret = getfbsize(0);
826                if(ret > 0)
827                        accelfb = addfb(ACCELFB, 0, ret / 4, 1, 4, fb->fd, skinfb->fb + skinfb->varfbsize, fb->fixfbsize, fb->data_phys + fb->varfbsize);
828        }
829#else
830                ret = getfbsize(0);
831                if(ret > 0 && status.bcm == 1)
832                {
833                        skinfb = addfb(SKINFB, 0, getconfigint("skinfbwidth", NULL), getconfigint("skinfbheight", NULL), 4, fb->fd, fb->fb + fb->varfbsize, fb->fixfbsize, fb->data_phys + fb->varfbsize);
834                        if(skinfb != NULL)
835                        {
836                                status.usedirectfb = 0;
837                                ret = getfbsize(0);
838                                if(ret > 0)
839                                        accelfb = addfb(ACCELFB, 0, ret / 4, 1, 4, fb->fd, skinfb->fb + skinfb->varfbsize, fb->fixfbsize, skinfb->data_phys + skinfb->varfbsize);
840                        }
841                }
842        }
843#endif 
844#else
845        status.usedirectfb = 0;
846        //SetMode();
847#endif
848       
849
850        //if(lcdskinfb == NULL) {
851                //mmapfb = malloc(4 * 320 * 240);
852                //mmapfb = malloc(4 * 1024 * 768);
853                //mmapfb = NULL;
854                /* dev=999 ist LCD Buffer */
855                //lcdskinfb = addfb("lcdskinfb", 999, 320, 240, 4, -1, mmapfb, 4 * 320 * 240);
856                //lcdskinfb = addfb("lcdskinfb", 999, 1024, 768, 4, -1, mmapfb, 4 * 1024 * 768);
857                // mmapfb = NULL;
858        //}
859
860        ret = createstartscreen();
861        if(ret != 0)
862        {
863                printf("error: createstartscreen\n");
864                return 100;
865        }
866        //from here we can use starterror screen
867        ret = openrc();
868        if(ret != 0)
869        {
870                tmpstr = ostrcat(tmpstr, _("Error: open rc device !!"), 1, 0);
871                goto starterror;
872        }
873
874        if(fegetdev() < 1)
875        {
876                tmpstr = ostrcat(tmpstr, _("Error: no frontend device found !!"), 1, 0);
877                err("no frontend device found");
878                goto starterror;
879        }
880        if(dmxgetdev() < 1)
881        {
882                tmpstr = ostrcat(tmpstr, _("Error: no demux device found !!"), 1, 0);
883                err("no demux device found");
884                goto starterror;
885        }
886        if(videogetdev() < 1)
887        {
888                tmpstr = ostrcat(tmpstr, _("Error: no video device found !!"), 1, 0);
889                err("no video device found");
890                goto starterror;
891        }
892        if(audiogetdev() < 1)
893        {
894                tmpstr = ostrcat(tmpstr, _("Error: no audio device found !!"), 1, 0);
895                err("no audio device found");
896                goto starterror;
897        }
898        ret = fecreatedummy();
899        ret = cagetdev();
900        ret = cigetdev();
901        ret = dvrgetdev();
902        ret = scgetdev();
903#ifdef MIPSEL
904        if(checkchipset("BCM7424") == 1) //inihdp
905                ret = encodergetdev();
906#endif
907
908        settunerstatus();
909
910        //start ca slot watching threads
911        castart();
912
913        //check skin
914        if(skincheck > 0)
915        {
916
917                tmpstr = ostrcat(tmpstr, _("Error: skin not found !!"), 1, 0);
918                err("skin not found");
919                goto starterror;
920        }
921
922        ret = readsat(getconfig("satfile", NULL));
923        ret = readtransponder(getconfig("transponderfile", NULL));
924        ret = readprovider(getconfig("providerfile", NULL));
925        ret = readchannel(getconfig("channelfile", NULL));
926        ret = readtransponderencoding(getconfig("transponderencodingfile", NULL));
927        ret = readmostzap(getconfig("mostzapfile", NULL));
928        ret = readlastsubtitle(getconfig("lastsubtitle", NULL));
929        ret = readchannelslot(getconfig("channelslotfile", NULL));
930
931        status.aktservice = addservice(NULL);
932        status.lastservice = addservice(NULL);
933        status.pipservice = addservice(NULL);
934
935        //check if startchannel defined
936        char* startchannellist = getconfig("startchannellist", NULL);
937        int startserviceid = getconfigint("startserviceid", NULL);
938        uint64_t starttransponderid = getconfigllu("starttransponderid", NULL);
939        int startservicetype = getconfigint("startservicetype", NULL);
940        if(startchannellist != NULL && startserviceid != 0)
941        {
942                if(startservicetype == 0)
943                {
944                        addconfig("channellist", startchannellist);
945                        addconfigint("serviceid", startserviceid);
946                        addconfigllu("transponderid", starttransponderid);
947                }
948                else
949                {
950                        addconfig("rchannellist", startchannellist);
951                        addconfigint("rserviceid", startserviceid);
952                        addconfigllu("rtransponderid", starttransponderid);
953                }
954                addconfigint("servicetype", startservicetype);
955        }
956        setvol(getconfigint("vol", NULL));
957        //tune to channel
958        if(status.servicetype == 0)
959                serviceret = servicestart(getchannel(getconfigint("serviceid", NULL), getconfigllu("transponderid", NULL)), getconfig("channellist", NULL), NULL, 0);
960        else
961                serviceret = servicestart(getchannel(getconfigint("rserviceid", NULL), getconfigllu("rtransponderid", NULL)), getconfig("rchannellist", NULL),  NULL, 0);
962
963        if(checkbox("IPBOX9000") == 1 && !file_exist("/tmp/.opticum9600.workaround"))
964        {
965                printf("opticum.workaround start\n");
966                system("touch /tmp/.opticum9600.workaround");
967                oshutdown(3, 1);
968                printf("opticum.workaround end\n");
969        }
970
971        ret = readscreen(getconfig("skinfile", NULL), 0, 0);
972        if(getconfig("keyskin_file", NULL) == NULL)
973                ret = readscreen("/var/usr/local/share/titan/skin/default/keyskin.xml", 0, 0);
974        else
975                ret = readscreen(getconfig("keyskin_file", NULL), 0, 0);
976        if(checkchipset("BCM7424") == 1 || checkbox("DM7020HD") == 1 || checkbox("DM7020HDV2") == 1 || checkbox("DM900") == 1)  //inihdp
977        {
978                if(getconfig("oledskin_path", NULL) == NULL)
979                        ret = readscreen("/var/usr/local/share/titan/skin/default/oledskin.xml", 0, 0);
980                else
981                {
982                        tmpstr = ostrcat(getconfig("oledskin_path", NULL),"/oledskin.xml", 0, 0);
983                        ret = readscreen(tmpstr, 0, 0);
984                        free(tmpstr);tmpstr=NULL;
985                }
986        }
987        ret = readmainbouquet(getconfig("bouquetfile", NULL));
988        ret = readallbouquet();
989        ret = readmainplaylist(getconfig("playlistfile", NULL));
990        ret = readallplaylist();
991        ret = readrcmap(getconfig("rcmapfile", NULL));
992        ret = readepgscanlist(getconfig("epgchannelfile", NULL));
993        ret = settimezone(getconfig("timezone", NULL));
994        ret = readextepgconfig(getconfig("extepgfile", NULL));
995
996        //check to remove preinstalled tpk packages
997        ret = tpkupdatepre();
998
999        addtimer(&checkdate, START, 2000, -1, NULL, NULL, NULL);
1000        if(checkbox("ATEMIO510") == 0)
1001                addtimer(&updatevfd, START, 1000, -1, NULL, NULL, NULL);
1002
1003        if(getconfigint("firststart", NULL) == 1)
1004        {
1005                if(file_exist("/var/etc/.scart"))
1006                {
1007                        setvideomode("pal", 0);
1008                        changefbresolution("pal", 0);
1009                        autoresolution();
1010                }
1011                addconfig("firststart", "0");
1012        }
1013
1014        if(getconfig("remotecontrol", NULL) == NULL)
1015        {
1016                if(checkbox("ATEMIO520") == 1 || checkbox("ATEMIO530") == 1)
1017                {
1018                        //autopo work
1019                        char* tmptxt = NULL;
1020                        tmptxt = ostrcat(tmptxt, _("RemoteControl Old Version"), 0, 0);
1021                        tmptxt = ostrcat(tmptxt, _("RemoteControl Long Version"), 0, 0);
1022                        free(tmptxt), tmptxt = NULL;
1023
1024                        struct menulist* mlist = NULL, *mbox = NULL;
1025                        addmenulist(&mlist, "RemoteControl Old Version", "0", NULL, 0, 0);
1026                        addmenulist(&mlist, "RemoteControl Long Version", "1", NULL, 0, 0);
1027                        // remotecontrol try menulist
1028                        mbox = menulistbox(mlist, "menulist", _("Select Your Remote Control"), _("Choose your Remotecontrol Model from the following list"), NULL, NULL, 3, 0);
1029                        if(mbox != NULL)
1030                        {
1031                                debug(10, "mbox->name %s", mbox->name);
1032                                debug(10, "mbox->text %s", mbox->text);
1033                                addconfig("remotecontrol", mbox->text);
1034                                writeallconfig(1);                             
1035                        }
1036                }
1037                if(checkbox("DM7020HD") == 1 || checkbox("DM7020HDV2") == 1 || checkbox("DM900") == 1 || checkbox("DM520") == 1 || checkbox("DM525") == 1)
1038                {
1039                        addconfig("remotecontrol", "0");
1040                        writeallconfig(1);     
1041                }                       
1042        }
1043
1044        if(getconfigint("autoscan", NULL) == 1)
1045        {
1046                status.updatevfd = PAUSE;
1047                resettvpic();
1048                screentunerconfig();
1049                resettvpic();
1050                screenscanconfig(1);
1051                resettvpic();
1052                writevfd("");
1053                status.updatevfd = START;
1054                drawscreen(skin, 0, 0);
1055                addconfig("autoscan", "0");
1056        }
1057               
1058        //first wizzard
1059        if(getconfigint("nofirstwizzard", NULL) < 2)
1060        {
1061                if(file_exist("/var/etc/.scart"))
1062                {
1063                        setvideomode("pal", 0);
1064                        changefbresolution("pal", 0);
1065                }
1066
1067                autoresolution();
1068                       
1069                if(getconfigint("nofirstwizzard", NULL) == 0)
1070                {
1071firstwizzardstep1:
1072
1073                        status.updatevfd = PAUSE;
1074//                      screenavsettings(1);
1075//                      resettvpic();
1076                        //this screen can reload the skin (on language change)
1077                        //all skin changes before here than are deleted
1078//                      if(screenlanguage(2) == 2) return 100;
1079//                      resettvpic();
1080
1081                        screentunerconfig();
1082                        resettvpic();
1083                        screenscanconfig(1);
1084                        resettvpic();
1085//                      screennetwork_adapter();
1086//                      resettvpic();
1087                        writevfd("Setting OK ?");
1088                        if(textbox(_("First Wizzard"), _("Settings OK ?"), _("OK"), getrcconfigint("rcok", NULL), _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, 600, 200, 0, 0) == 2)
1089                        {
1090                                goto firstwizzardstep1;
1091                        }
1092                }
1093                resettvpic();
1094
1095                char* msg = NULL;
1096                msg = readfiletomem("/etc/imageinfo", 0);
1097                textbox(_("Info"), _(msg), _("OK"), getrcconfigint("rcok", NULL), _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, 1100, 680, 30, 0);
1098                free(msg); msg = NULL;
1099               
1100                writevfd("");
1101                status.updatevfd = START;
1102                drawscreen(skin, 0, 0);
1103                addconfig("nofirstwizzard", "2");
1104        }
1105        else
1106        {
1107                // workaround, remove bootlogo on startup
1108                drawscreen(skin, 0, 0);
1109
1110                //check servicestart
1111                if(serviceret != 21) // no message if startchannel empty
1112                        servicecheckret(serviceret, 0);
1113        }
1114
1115// fixt manual start
1116        resettvpic();
1117
1118        //start auto shutdown thread
1119        addtimer(&checkshutdowntimer, START, 10000, -1, NULL, NULL, NULL);
1120        //start demo mode
1121        if(checkbox("WHITEBOX") == 1)
1122                addtimer(&demomodethread, START, 600000, -1, NULL, NULL, NULL);
1123
1124        status.lastrcaction = time(NULL);
1125        ret = loadplugin();
1126        setosdtransparent(getskinconfigint("osdtransparent", NULL));
1127        ret = setsaturation(getconfigint("vs_saturation", NULL));
1128        ret = setbrightness(getconfigint("vs_brightness", NULL));
1129        ret = setcontrast(getconfigint("vs_contrast", NULL));
1130        ret = settint(getconfigint("vs_tint", NULL));
1131        videoApplySettings();
1132       
1133#ifndef SIMULATE
1134        //set skinentrys locked
1135        if(status.security == 0)
1136                setskinnodeslocked(1);
1137        else
1138                setskinnodeslocked(0);
1139#endif
1140
1141        //start epg thread
1142        status.epgthread = addtimer(&epgthreadfunc, START, 1000, -1, NULL, NULL, NULL);
1143        //start record timer thread (on delay change you must change rectimer.h also)
1144        status.rectimerthread = addtimer(&checkrectimer, START, 1000, -1, NULL, NULL, NULL);
1145        //check if cam socket connected
1146        addtimer(&checkcam, START, 3000, -1, NULL, NULL, NULL);
1147        //start stream server
1148        tmpthread = addtimer(&streamthreadfunc, START, 10000, -1, NULL, NULL, NULL);
1149        if(tmpthread != NULL)
1150        {
1151                tmpthread->flag = setbit(tmpthread->flag, 0);
1152                tmpthread = NULL;
1153        }
1154        //start epg scanlist
1155        status.epgscanlistthread = addtimer(&epgscanlistthread, START, 1000, 1, NULL, NULL, NULL);
1156        //get pmt
1157        if(getconfigint("checkpmtalways", NULL) == 1)
1158                addtimer(&dvbgetpmtthread, START, 2000, -1, NULL, NULL, NULL);
1159        //check hdd
1160        status.addhddall = addtimer(&addhddall, START, 6000, -1, NULL, NULL, NULL);
1161        //check net
1162        addtimer(&addinetworkall, START, 15000, -1, NULL, NULL, NULL);
1163        //check kill net (security)
1164        addtimer(&ckeckkillnetthread, START, 1000, 1, NULL, NULL, NULL);
1165        //check old entrys and remove from mem
1166        addtimer(&oldentrythreadfunc, START, 60000 * 60, -1, NULL, NULL, NULL);
1167
1168        //start newsletter
1169        startnewsletter(1);
1170
1171        //thumb create thread
1172        startthumb(1);
1173
1174        //start webserver
1175        starthttpd(1);
1176       
1177        //start rguid
1178        startrguid(1);
1179
1180        //init the player
1181        playerinit(argc, argv);
1182       
1183        //start spinner thread
1184        addtimer(&checkspinner, START, 2000, -1, NULL, NULL, NULL);
1185
1186        system(getconfig("skriptaftertv", NULL));
1187
1188        // work
1189        resettvpic();
1190       
1191        char* cmd = NULL;
1192#ifdef SH4
1193        cmd = ostrcat("/media/hdd/movie/titankey.sh4", NULL, 0, 0);
1194#endif
1195
1196#ifdef MIPSEL
1197        cmd = ostrcat("/media/hdd/movie/titankey.mipsel", NULL, 0, 0);
1198#endif
1199
1200        //for atemio to unlock box with stick
1201        if(file_exist(cmd))
1202        {
1203                char* cpuid = getcpuid();
1204                cmd = ostrcat(cmd, " ", 1, 0);
1205                cmd = ostrcat(cmd, cpuid, 1, 0);
1206
1207                system(cmd);
1208                checkserial(cpuid);
1209                free(cmd); cmd = NULL;
1210
1211                if(status.security >= 1)
1212                {
1213                        char* mac = getmacfromcmdline();
1214                        if(mac != NULL)
1215                        {
1216                                cmd = ostrcat(cmd, cpuid, 1, 0);
1217                                cmd = ostrcat(cmd, ",", 1, 0);
1218                                cmd = ostrcat(cmd, mac, 1, 0);
1219                               
1220                                free(mac); mac = NULL;
1221                        }
1222                        else
1223                                cmd = ostrcat(cmd, cpuid, 1, 0);
1224
1225                        writesys("/media/hdd/movie/codelist.txt", cmd, 3);
1226                        textbox(_("Message"), _("Receiver successful unlocked"), _("OK"), getrcconfigint("rcok", NULL), _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, 600, 200, 0, 0);
1227                }
1228
1229                free(cpuid); cpuid = NULL;
1230        }
1231        free(cmd); cmd = NULL;
1232
1233        //must called direct befor screeninfobar
1234        if(getconfigint("saverun", NULL) == 1)
1235        {
1236                ret = sigsetjmp(status.longjumpbuf, 1);
1237                if(ret != 0 && ret != 999)
1238                {
1239                        err("set sigsegjump");
1240                }
1241        }
1242
1243        if(checkbox("UFS910") == 0 && checkbox("UFS922") == 0)
1244        {
1245                //check free space in /var
1246                if(getfreespace("/var") / 1024 < 50) //200kb
1247                        textbox(_("Message"), _("Free space in /var to little!\nThis can make problems!"), _("OK"), getrcconfigint("rcok", NULL), _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, 600, 200, 7, 0);
1248                else
1249                {
1250                        //check writeable in /var
1251                        if(mkdir("/var/writetest", 0777) != 0 && errno != EEXIST)
1252                        {
1253                                if(textbox(_("Message"), _("/var not writeable!\nRepair it?"), _("OK"), getrcconfigint("rcok", NULL), _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, 600, 200, 15, 0) == 1)
1254                                {
1255                                        system("repairjffs2.sh var &"); //this script kills titan an reboot
1256                                        sleep(10);
1257                                }
1258                        }
1259                        rmdir("/var/writetest");
1260                }
1261       
1262                //check free space in /mnt
1263                if(getfreespace("/mnt") / 1024 < 50) //200kb
1264                        textbox(_("Message"), _("Free space in /mnt to little!\nThis can make problems!"), _("OK"), getrcconfigint("rcok", NULL), _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, 600, 200, 7, 0);
1265                else
1266                {
1267                        //check writeable in /mnt
1268                        if(mkdir("/mnt/writetest", 0777) != 0 && errno != EEXIST)
1269                        {
1270                                if(textbox(_("Message"), _("/mnt not writeable!\nRepair it?"), _("OK"), getrcconfigint("rcok", NULL), _("EXIT"), getrcconfigint("rcexit", NULL), NULL, 0, NULL, 0, 600, 200, 15, 0) == 1)
1271                                {
1272                                        if(file_exist("/mnt/swapextensions/epg.dat"))
1273                                        {
1274                                                unlink("/mnt/swapextensions/epg.dat");
1275                                                system("sync");
1276                                                oshutdown(3, 0);
1277                                        }
1278                                        else
1279                                        {
1280                                                system("repairjffs2.sh mnt &"); //this script kills titan an reboot
1281                                                sleep(10);
1282                                        }
1283                                }
1284                        }
1285                        rmdir("/mnt/writetest");
1286                }
1287        }
1288
1289        addtimer(&guestthread, START, 1000, 1, NULL, NULL, NULL);
1290        startinternreader(1);
1291       
1292        screeninfobar();
1293
1294        //for testign screens
1295        //screenmanualscan();
1296        //screeninputhelp();
1297        //screendownload("test", "www.orf.at", NULL, 80, "test.html", 0);
1298        //screenrectimer();
1299        //screenepgsettings();
1300        //screenlnb("1");
1301        //screendiseqc("1");
1302        //screenlanguage();
1303        //screenvideosettings();
1304        //screenskinselect();
1305        //screenrectimer();
1306        //screennetwork_adapter(2);
1307        //screenpin();
1308        //screenchannellist();
1309        //recordstart(channel, RECDIRECT);
1310        //mc_main();
1311        //screenmc_videoplayer();
1312        //screenserviceinfo();
1313        //screentunerconfig();
1314        //screenvfdisplay();
1315        //screenavsettings(1);
1316        //screenadjust();
1317        //subtitlestart();
1318
1319        if(mmapfb != NULL) {
1320                free(mmapfb); mmapfb=NULL;
1321        }
1322        oshutdown(1, 1);
1323        return 0;
1324
1325starterror:
1326        addscreen("<screen hspace=5 vspace=5 type=textbox name=starterror posx=center posy=center bordersize=2 bordercol=#ffffff fontsize=30 fontcol=#ffffff width=600 height=150/>", 0, 0);
1327        struct skin *starterror = getscreen("starterror");
1328        if(tmpstr == NULL)
1329                tmpstr = ostrcat(tmpstr, _("Unknown Error."), 1, 0);
1330        tmpstr = ostrcat(tmpstr, "\n", 1, 0);
1331        tmpstr = ostrcat(tmpstr, _("Automatic stop in 10 seconds."), 1, 0);
1332        changetext(starterror, _(tmpstr));
1333        drawscreen(starterror, 0, 0);
1334        sleep(10);
1335        printf("error: starterror=%s\n", tmpstr);
1336        free(tmpstr);
1337        return 100;
1338}
Note: See TracBrowser for help on using the repository browser.