OSDN Git Service

7cd8d6ac652da82cddf9f4b2d6e504c06d63d38d
[rec10/rec10-git.git] / epgdump / eit.c
1 // -*- tab-width:4 -*-
2 // see TR-B14 4-296 (p.318)
3
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7
8 #include "eit.h"
9
10 char            *subtitle_cnv_str[] = {
11         NULL
12 };
13 static void timecmp(int *,int *,int *,
14                                         int, int, int);
15 void append_desc(EIT_CONTROL* eittop, int service_id, int event_id, EEVTDitem* eevtitem);
16
17 int parseEIThead(unsigned char *data, EIThead *h) {
18         int boff = 0;
19
20         memset(h, 0, sizeof(EIThead));
21
22         h->table_id = getBit(data, &boff, 8);
23         h->section_syntax_indicator = getBit(data, &boff, 1);
24         h->reserved_future_use = getBit(data, &boff, 1);
25         h->reserved1 = getBit(data, &boff, 2);
26         h->section_length =getBit(data, &boff,12);
27         h->service_id = getBit(data, &boff, 16);
28         h->reserved2 = getBit(data, &boff, 2);
29         h->version_number = getBit(data, &boff, 5);
30         h->current_next_indicator = getBit(data, &boff, 1);
31         h->section_number = getBit(data, &boff, 8);
32         h->last_section_number = getBit(data, &boff, 8);
33         h->transport_stream_id = getBit(data, &boff, 16);
34         h->original_network_id = getBit(data, &boff, 16);
35         h->segment_last_section_number = getBit(data, &boff, 8);
36         h->last_table_id = getBit(data, &boff, 8);
37   
38         return 14;
39 }
40
41 int parseEITbody(unsigned char *data, EITbody *b)
42 {
43         int boff = 0;
44         int tnum;
45         char buf[4];
46
47         memset(b, 0, sizeof(EITbody));
48
49         b->event_id = getBit(data, &boff, 16);
50
51         memcpy(b->start_time, data + boff / 8, 5);
52         /* b->start_time = getBit(data, &boff, 40); */
53         boff += 40;
54         memcpy(b->duration, data + boff / 8, 3);
55         /* b->duration = getBit(data, &boff, 24); */
56         boff += 24;
57         b->running_status = getBit(data, &boff, 3);
58         b->free_CA_mode = getBit(data, &boff, 1);
59         b->descriptors_loop_length = getBit(data, &boff, 12);
60
61         /* 日付変換 */
62         tnum = (b->start_time[0] & 0xFF) << 8 | (b->start_time[1] & 0xFF);
63   
64         b->yy = (tnum - 15078.2) / 365.25;
65         b->mm = ((tnum - 14956.1) - (int)(b->yy * 365.25)) / 30.6001;
66         b->dd = (tnum - 14956) - (int)(b->yy * 365.25) - (int)(b->mm * 30.6001);
67
68         if(b->dd == 0) {
69                 printf("aa");
70         }
71
72         if(b->mm == 14 || b->mm == 15) {
73                 b->yy += 1;
74                 b->mm = b->mm - 1 - (1 * 12);
75         } else {
76                 b->mm = b->mm - 1;
77         }
78
79         b->yy += 1900;
80   
81         memset(buf, '\0', sizeof(buf));
82         sprintf(buf, "%x", b->start_time[2]);
83         b->hh = atoi(buf);
84         memset(buf, '\0', sizeof(buf));
85         sprintf(buf, "%x", b->start_time[3]);
86         b->hm = atoi(buf);
87         memset(buf, '\0', sizeof(buf));
88         sprintf(buf, "%x", b->start_time[4]);
89         b->ss = atoi(buf);
90
91         if((b->duration[0] == 0xFF) && (b->duration[1] == 0xFF) && (b->duration[2] == 0xFF)){
92                 b->dhh = b->dhm = b->dss = 0;
93         }else{
94                 memset(buf, '\0', sizeof(buf));
95                 sprintf(buf, "%x", b->duration[0]);
96                 b->dhh = atoi(buf);
97                 memset(buf, '\0', sizeof(buf));
98                 sprintf(buf, "%x", b->duration[1]);
99                 b->dhm = atoi(buf);
100                 memset(buf, '\0', sizeof(buf));
101                 sprintf(buf, "%x", b->duration[2]);
102                 b->dss = atoi(buf);
103         }
104         return 12;
105 }
106
107 int parseSEVTdesc(unsigned char *data, SEVTdesc *desc) {
108         int boff = 0;
109   
110         memset(desc, 0, sizeof(SEVTdesc));
111
112         desc->descriptor_tag = getBit(data, &boff, 8);
113         if((desc->descriptor_tag & 0xFF) != 0x4D) {
114                 return -1;
115         }
116         desc->descriptor_length = getBit(data, &boff, 8);
117         memcpy(desc->ISO_639_language_code, data + boff / 8, 3);
118         /* desc->ISO_639_language_code = getBit(data, &boff, 24); */
119         boff += 24;
120         desc->event_name_length = getBit(data, &boff, 8);
121         getStr(desc->event_name, data, &boff, desc->event_name_length);
122         desc->text_length = getBit(data, &boff, 8);
123         getStr(desc->text, data, &boff, desc->text_length);
124
125         return desc->descriptor_length + 2;
126 }
127
128 int parseContentDesc(unsigned char *data, ContentDesc *desc) {
129         int boff = 0;
130   
131         memset(desc, 0, sizeof(ContentDesc));
132
133         desc->descriptor_tag = getBit(data, &boff, 8);
134         if((desc->descriptor_tag & 0xFF) != 0x54) {
135                 return -1;
136         }
137         desc->descriptor_length = getBit(data, &boff, 8);
138         //memcpy(desc->content, data+(boff/8), desc->descriptor_length);
139         // FIXME: 1つ目のコンテント記述子のみパース
140         desc->content_nibble_level_1 = getBit(data, &boff, 4);
141         desc->content_nibble_level_2 = getBit(data, &boff, 4);
142         desc->user_nibble_1 = getBit(data, &boff, 4);
143         desc->user_nibble_2 = getBit(data, &boff, 4);
144         return desc->descriptor_length + 2;
145 }
146
147 int parseSeriesDesc(unsigned char *data, SeriesDesc *desc) {
148         int boff = 0;
149   
150         memset(desc, 0, sizeof(SeriesDesc));
151
152         desc->descriptor_tag = getBit(data, &boff, 8);
153         if((desc->descriptor_tag & 0xFF) != 0xD5) {
154                 return -1;
155         }
156         desc->descriptor_length = getBit(data, &boff, 8);
157         desc->series_id = getBit(data, &boff, 16);
158         desc->repeat_label = getBit(data, &boff, 4);
159         desc->program_pattern = getBit(data, &boff, 3);
160         desc->expire_date_valid_flag = getBit(data, &boff, 1);
161
162         desc->expire_date = getBit(data, &boff, 16);
163         //memcpy(desc->expire_date, data + boff / 8, 2);
164         //boff += 16;
165
166         desc->episode_number = getBit(data, &boff, 12);
167         desc->last_episode_number = getBit(data, &boff, 12);
168
169         getStr(desc->series_name_char, data, &boff, desc->descriptor_length - 8);
170         return desc->descriptor_length + 2;
171 }
172
173 int parseEEVTDhead(unsigned char *data, EEVTDhead *desc) {
174         int boff = 0;
175   
176         memset(desc, 0, sizeof(EEVTDhead));
177
178         desc->descriptor_tag = getBit(data, &boff, 8);
179         if((desc->descriptor_tag & 0xFF) != 0x4E) {
180                 return -1;
181         }
182         desc->descriptor_length = getBit(data, &boff, 8);
183         desc->descriptor_number = getBit(data, &boff, 4);
184         desc->last_descriptor_number = getBit(data, &boff, 4);
185         memcpy(desc->ISO_639_language_code, data + boff / 8, 3);
186         /* desc->ISO_639_language_code = getBit(data, &boff, 24); */
187         boff += 24;
188
189         desc->length_of_items = getBit(data, &boff, 8);
190
191         return 7;
192 }
193
194 int parseEEVTDitem(unsigned char *data, EEVTDitem *desc) {
195         int boff = 0;
196   
197         memset(desc, 0, sizeof(EEVTDitem));
198
199         desc->item_description_length = getBit(data, &boff, 8);
200         memset(desc->item_description, 0, MAXSECLEN);
201         getStr(desc->item_description, data, &boff, desc->item_description_length);
202
203         desc->item_length = getBit(data, &boff, 8);
204         memset(desc->item, 0, MAXSECLEN);
205         memcpy(desc->item, data + (boff / 8), desc->item_length);
206         /* getStr(desc->item, data, &boff, desc->item_length); */
207
208         return desc->item_description_length + desc->item_length + 2;
209 }
210
211 int parseEEVTDtail(unsigned char *data, EEVTDtail *desc) {
212         int boff = 0;
213   
214         memset(desc, 0, sizeof(EEVTDtail));
215
216         desc->text_length = getBit(data, &boff, 8);
217         memset(desc->text, 0, MAXSECLEN);
218         getStr(desc->text, data, &boff, desc->text_length);
219
220         return desc->text_length + 1;
221 }
222
223 int checkEEVTDitem(EEVTDitem *save, EEVTDitem *new, int descriptor_number) {
224
225         EEVTDitem swap;
226         int boff = 0;
227
228         if(new == NULL) {
229                 if(save->item_length != 0) {
230                         swap = *save;
231                         memset(save->item, 0, MAXSECLEN);
232                         getStr(save->item, (unsigned char*)swap.item, &boff, swap.item_length);
233                         return 1;
234                 } else {
235                         return 0;
236                 }
237         }
238
239         if(new->item_description_length == 0) {
240                 /* 続き 保存 */
241                 memcpy(save->item + save->item_length, new->item, new->item_length);
242                 save->item_length += new->item_length;
243                 return 0;
244         } else {
245                 /* ブレーク。saveを印刷対象にする。saveをクリア? */
246                 if(save->item_length != 0) {
247                         /* 退避済みがあり */
248                         swap = *save;
249                         memset(save->item, 0, MAXSECLEN);
250                         getStr(save->item, (unsigned char*)swap.item, &boff, swap.item_length);
251
252                         // swap save new -> swap save new
253                         //         b   c -> ( c)    c   b
254                         swap = *new;
255                         *new = *save;
256                         *save = swap;
257                         save->descriptor_number = descriptor_number;
258                         return 1;
259                 } else {
260                         *save = *new;
261                         save->descriptor_number = descriptor_number;
262                         return 0;
263                 }
264         }
265 }
266 EIT_CONTROL     *searcheit(EIT_CONTROL *top, int servid, int eventid)
267 {
268         EIT_CONTROL     *cur ;
269         cur = top ;
270
271         while(cur != NULL){
272                 if((cur->event_id == eventid) && (cur->servid == servid)){
273                         return cur ;
274                 }
275
276                 cur = cur->next ;
277         }
278         return NULL ;
279 }
280 char    *strstr_eucjp(const char *str, const char *search)
281 {
282         char *pos ;
283         pos = (char *)str ;
284
285         while (*pos != '\0') {
286                 if (*pos == *search) {
287                         if (strncmp(pos, search, strlen(search)) == 0) {
288                                 return pos ;
289                         }
290                 }
291                 if ((unsigned char)*pos == 0x8Fu) {
292                         pos += 3 ;
293                 } else if ((unsigned char)*pos >= 0x80u) {
294                         pos += 2 ;
295                 } else {
296                         pos += 1 ;
297                 }
298         }
299
300         return NULL ;
301 }
302 void    conv_title_subtitle(EIT_CONTROL *eitptr)
303 {
304         int             lp = 0 ;
305 //      size_t  addsize ;
306         char    *ptr ;
307         char    *ptr2 ;
308         char    *newsubtitle ;
309
310         for(lp = 0 ; subtitle_cnv_str[lp] != NULL ; lp++){
311                 ptr = strstr(eitptr->title, subtitle_cnv_str[lp]);
312                 if(ptr == NULL){
313                         continue ;
314                 }
315                 // タイトルがなくならないように
316                 if(ptr == eitptr->title){
317                         continue ;
318                 }
319                 /*
320                 ptr2 = ptr ;
321                 for( ; (unsigned char)*ptr2 == 0x20u ; ptr2++ );
322                 for( ; (unsigned char)*ptr2 == 0xA1u && (unsigned char)*(ptr2+1) == 0xA1u ; ptr2 += 2);
323                 for( ; (unsigned char)*ptr2 == 0x20u ; ptr2++ );
324                 newsubtitle = calloc(1, ((strlen(ptr2) + 2) + (strlen(eitptr->subtitle) + 1)));
325                 memcpy(newsubtitle, ptr2, strlen(ptr2));
326 //              *(newsubtitle+strlen(ptr)) = ' ';
327                 strcat(newsubtitle, "▽");
328                 */
329                 newsubtitle = calloc(1, ((strlen(ptr) + 1) + (strlen(eitptr->subtitle) + 1)));
330                 memcpy(newsubtitle, ptr, strlen(ptr));
331                 newsubtitle[strlen(ptr)] = ' ';
332
333                 *ptr = '\0';
334                 strcat(newsubtitle, eitptr->subtitle);
335                 free(eitptr->subtitle);
336                 eitptr->subtitle = newsubtitle ;
337                 return ;
338         }
339 }
340 void    enqueue(EIT_CONTROL *top, EIT_CONTROL *eitptr)
341 {
342         EIT_CONTROL     *cur ;
343         cur = top ;
344         int             rc ;
345
346         if(top->next == NULL){
347                 top->next = eitptr ;
348                 eitptr->prev = top ;
349                 return ;
350         }
351         cur = top->next ;
352         while(cur != NULL){
353                 rc = memcmp(&cur->yy, &eitptr->yy, (sizeof(int) * 3));
354                 if(rc == 0){
355                         rc = memcmp(&cur->hh, &eitptr->hh, (sizeof(int) * 3));
356                         if(rc == 0){
357                                 free(eitptr->title);
358                                 free(eitptr->subtitle);
359                                 free(eitptr);
360                                 return ;
361                         }
362                         if(rc > 0){
363                                 if(cur->prev != 0){
364                                         cur->prev->next = eitptr ;
365                                         eitptr->prev = cur->prev ;
366                                 }
367                                 cur->prev = eitptr ;
368                                 eitptr->next = cur ;
369                                 conv_title_subtitle(eitptr);
370                                 return ;
371                         }
372                 }
373                 if(rc > 0){
374                         if(cur->prev != 0){
375                                 cur->prev->next = eitptr ;
376                                 eitptr->prev = cur->prev ;
377                         }
378                         cur->prev = eitptr ;
379                         eitptr->next = cur ;
380                         conv_title_subtitle(eitptr);
381                         return ;
382                 }
383                 if(cur->next == NULL){
384                         cur->next = eitptr ;
385                         eitptr->prev = cur ;
386                         conv_title_subtitle(eitptr);
387                         return ;
388                 }
389                 cur = cur->next ;
390         }
391         return ;
392
393 }
394
395 void dumpEIT(unsigned char *ptr, int serv_id, int original_network_id, int transport_stream_id, EIT_CONTROL *eittop)
396 {
397
398         EIThead  eith;
399         EITbody  eitb;
400         SEVTdesc sevtd;
401
402         EEVTDhead eevthead;
403         EEVTDitem eevtitem;
404         EEVTDtail eevttail;
405
406         EEVTDitem save_eevtitem;
407
408         EIT_CONTROL     *cur ;
409         EIT_CONTROL     *curtmp ;
410
411         int len = 0;
412         int loop_len = 0;
413         int loop_blen = 0;
414         int loop_elen = 0;
415
416         int ehh, emm, ess;
417
418         /* EIT */
419         len = parseEIThead(ptr, &eith); 
420
421         ptr += len;
422         loop_len = eith.section_length - (len - 3 + 4); // 3は共通ヘッダ長 4はCRC
423         while(loop_len > 0) {
424                 /* 連続する拡張イベントは、漢字コードが泣き別れして
425                    分割されるようだ。連続かどうかは、item_description_lengthが
426                    設定されているかどうかで判断できるようだ。 */
427                 memset(&save_eevtitem, 0, sizeof(EEVTDitem));
428
429                 len = parseEITbody(ptr, &eitb);
430                 ptr += len;
431                 loop_len -= len;
432
433                 /* printf("evtid:%d\n", eitb.event_id); */
434
435                 loop_blen = eitb.descriptors_loop_length;
436                 loop_len -= loop_blen;
437
438                 while(loop_blen > 0) {
439
440                         /*yukikaze-test*/
441                         //printf("desc_tag");
442                         //int itt=getBit(*ptr,0,8);
443                         //printf("%x",itt);
444
445                         len = parseSEVTdesc(ptr, &sevtd);
446                         if(len > 0) {
447
448                                 /*
449                                   if(eith.service_id == 19304 && 
450                                   eitb.event_id == 46564) {
451                                   printf("aa");
452                                   }
453                                 */
454
455                                 ehh = eitb.hh;
456                                 emm = eitb.hm;
457                                 ess = eitb.ss;
458                                 if(eith.service_id != serv_id){
459                                         ptr += len;
460                                         loop_blen -= len;
461                                         continue ;
462                                 }
463
464                                 timecmp(&ehh, &emm, &ess,
465                                                 eitb.dhh, eitb.dhm, eitb.dss);
466                                 cur = searcheit(eittop, eith.service_id, eitb.event_id);
467                                 if(cur == NULL){
468                                         curtmp = NULL;
469                                         cur = calloc(1, sizeof(EIT_CONTROL));
470                                 }
471                                 else {
472                                         curtmp = cur;
473                                 }
474                                 cur->event_id = eitb.event_id ;
475                                 cur->servid = eith.service_id ;
476                                 cur->title = calloc(1, (strlen(sevtd.event_name) + 1));
477
478                                 memcpy(cur->title, sevtd.event_name, strlen(sevtd.event_name));
479                                 cur->subtitle = calloc(1, (strlen(sevtd.text) + 1));
480                                 memcpy(cur->subtitle, sevtd.text, strlen(sevtd.text));
481                                 cur->yy = eitb.yy;
482                                 cur->mm = eitb.mm;
483                                 cur->dd = eitb.dd;
484                                 cur->hh = eitb.hh;
485                                 cur->hm = eitb.hm;
486                                 cur->ss = eitb.ss;
487                                 cur->ehh = eitb.dhh;
488                                 cur->emm = eitb.dhm;
489                                 cur->ess = eitb.dss ;
490                                 cur->table_id = eith.table_id ;
491                                 if ( !curtmp ) enqueue(eittop, cur);
492                         } else {
493                                 len = parseEEVTDhead(ptr, &eevthead);
494
495                                 /*
496                                 if(eith.service_id == 19304 && 
497                                 eitb.event_id == 46564) {
498                                 printf("aa");
499                                 }
500                                 */
501
502                                 if(len > 0) {
503                                         ptr += len;
504                                         loop_blen -= len;
505
506                                         loop_elen = eevthead.length_of_items;
507                                         loop_len -= loop_elen;
508                                         while(loop_elen > 0) {
509                                                 len = parseEEVTDitem(ptr, &eevtitem);
510
511                                                 ptr += len;
512                                                 loop_elen -= len;
513                                                 loop_blen -= len;
514
515                                                 if(checkEEVTDitem(&save_eevtitem, &eevtitem, 
516                                                         eevthead.descriptor_number)) {
517
518                                                         {
519                                                                 if (eevtitem.descriptor_number>0){
520                                                                         //printf("descriptor_num %d\n",eevtitem.descriptor_number);
521                                                                 }
522                                                                 /* long format */
523                                                                 //printf("descriptor_num %d\n",eevtitem.descriptor_number);
524 #if 0
525                                                                 printf("EEVT,%d,%d,%d,%s,%s\n",
526                                                                         eith.service_id,
527                                                                         eitb.event_id,
528                                                                         eevtitem.descriptor_number, // 退避項目
529                                                                         eevtitem.item_description,
530                                                                         eevtitem.item);
531 #endif
532                                                         }
533                                                         append_desc(eittop, eith.service_id, eitb.event_id, &eevtitem);
534
535                                                 }
536                                         }
537
538                                         len = parseEEVTDtail(ptr, &eevttail);
539 #if 0
540                                         { /* long format */
541                                                 printf("EEVTt,%d,%d,%d,%s\n", 
542                                                                 eith.service_id,
543                                                                 eitb.event_id,
544                                                                 eevthead.descriptor_number,
545                                                                 eevttail.text);
546                                         }
547 #endif
548                                 } else {
549                                         ContentDesc contentDesc;
550                                         len = parseContentDesc(ptr, &contentDesc);
551                                         if (len > 0) {
552                                                 //int header_printed = 0;
553                                                 for (int i = 0; i < contentDesc.descriptor_length - 1; i+=2) {
554                                                         /*
555                                                         if (0xff == (unsigned char)contentDesc.content[i])
556                                                                 continue;
557                                                         */
558 #if 0
559                                                         if (!header_printed) {
560                                                                 fprintf(out, "Content,%d,%d\n",
561                                                                         eith.service_id,
562                                                                         eitb.event_id);
563                                                                 header_printed = 1;
564                                                         }
565 #endif
566
567                                                         //fprintf(out, ",%02x%02x", (unsigned char)contentDesc.content[i], (unsigned char)contentDesc.content[i+1]);
568
569                                                 }
570                                                 if((eith.original_network_id == original_network_id) && (eith.transport_stream_id == transport_stream_id)){
571                                                         cur = searcheit(eittop, eith.service_id, eitb.event_id);
572                                                         if(cur != NULL){
573                                                                 cur->content_type = (unsigned char)contentDesc.content_nibble_level_1;
574 #if 0
575                                                                 fprintf(stdout, "%s:", cur->title);
576                                                                 fprintf(stdout, ",%02x%02x", (unsigned char)contentDesc.content[0], (unsigned char)contentDesc.content[1]);
577                                                                 fprintf(stdout, ",%02x%02x\n", (unsigned char)contentDesc.content[2], (unsigned char)contentDesc.content[3]);
578 #endif
579                                                         }
580
581 #if 0
582                                                         if (header_printed) {
583                                                                 fprintf(out, "\n");
584                                                         }
585 #endif
586                                                 }
587                                         } else {
588                                                 SeriesDesc seriesDesc;
589                                                 len = parseSeriesDesc(ptr, &seriesDesc);
590                                                 if (len > 0) {
591 #if 0
592                                                         printf("Series,%d,%d,series=%d,repeat=%01x,pattern=%d,expire_valid=%d,expire=%04x,epinum=%d,lastepinum=%d,%s\n",
593                                                                 eith.service_id,
594                                                                 eitb.event_id,
595                                                                 seriesDesc.series_id,
596                                                                 seriesDesc.repeat_label,
597                                                                 seriesDesc.program_pattern,
598                                                                 seriesDesc.expire_date_valid_flag,
599                                                                 seriesDesc.expire_date,
600                                                                 seriesDesc.episode_number,
601                                                                 seriesDesc.last_episode_number,
602                                                                 seriesDesc.series_name_char);
603 #endif
604                                                 } else {
605                                                         len = parseOTHERdesc(ptr);
606                                                 }
607                                         }
608                                 }
609                         }
610                         ptr += len;
611                         loop_blen -= len;
612                 }
613                 /* 最後のブレークチェック */
614
615                 if(checkEEVTDitem(&save_eevtitem, NULL, 0)) {
616 #if 0
617                         { /* long format */
618                                 fprintf(stdout, "EEVT,%d,%d,%d,%s,%s\n", 
619                                                 eith.service_id,
620                                                 eitb.event_id,
621                                                 save_eevtitem.descriptor_number,
622                                                 save_eevtitem.item_description,
623                                                 save_eevtitem.item);
624                         }
625 #endif
626                         append_desc(eittop, eith.service_id, eitb.event_id, &save_eevtitem);
627                 }
628         }
629
630         return;
631 }
632
633 void append_desc(EIT_CONTROL* eittop, int service_id, int event_id, EEVTDitem* eevtitem) {
634         EIT_CONTROL *cur;
635         int str_alen = 0;
636
637         cur = searcheit(eittop, service_id, event_id);
638         if (cur == NULL) {
639                 return;
640         }
641
642         if ( cur->desc ) {
643                 str_alen = strlen( cur->desc );
644         }
645         else {
646                 str_alen = 0;
647         }
648         //eevtitem->item_description_length = strlen(eevtitem->item_description);
649         //eevtitem->item_length = strlen(eevtitem->item);
650         cur->desc = realloc(cur->desc, str_alen + eevtitem->item_description_length + eevtitem->item_length + 1000);
651         if ( !str_alen ) *cur->desc = '\0';
652
653         if ( eevtitem->item_description_length && !strstr(cur->desc, eevtitem->item_description) ) {
654                 strcat(cur->desc + str_alen, eevtitem->item_description);
655                 strcat(cur->desc, "\t");
656         }
657
658         if ( eevtitem->item_length && !strstr(cur->desc, eevtitem->item) ) {
659                 strcat(cur->desc + str_alen, eevtitem->item);
660         //printf("%s\n",eevtitem->item);
661                 strcat(cur->desc, "\\n");
662         }
663 }
664
665 void timecmp(int *thh, int *tmm, int *tss,
666                          int dhh, int dmm, int dss) {
667
668         int ama;
669
670         *tss += dss;
671         ama = *tss % 60;
672         *tmm += (*tss / 60);
673         *tss = ama;
674
675         *tmm += dmm;
676         ama   = *tmm % 60;
677         *thh += (*tmm / 60);
678         *tmm  = ama;
679
680         *thh += dhh;
681
682 }