Annotation of multiplexer/en300468ts.c, revision 1.4

1.1       oskar       1: /*
                      2:  * SI table generator (EN 300468)
1.3       oskar       3:  * Copyright (C) 2004,2005 Oskar Schirmer (schirmer@scara.com)
1.1       oskar       4:  *
                      5:  * This program is free software; you can redistribute it and/or modify
                      6:  * it under the terms of the GNU General Public License as published by
                      7:  * the Free Software Foundation; either version 2 of the License, or
                      8:  * (at your option) any later version.
                      9:  *
                     10:  * This program is distributed in the hope that it will be useful,
                     11:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     12:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     13:  * GNU General Public License for more details.
                     14:  *
                     15:  * You should have received a copy of the GNU General Public License
                     16:  * along with this program; if not, write to the Free Software
                     17:  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     18:  */
                     19: 
                     20: /*
                     21:  * Module:  SI table generator
                     22:  * Purpose: From a list of desciptive files generate SI tables and feed
                     23:  *          them to stdout.
                     24:  * known bug: missing check for section length <= 1021
                     25:  */
                     26: 
                     27: //#define DEBUG
                     28: 
                     29: #include <limits.h>
                     30: #include <unistd.h>
                     31: #include <stdio.h>
                     32: #include <stdlib.h>
                     33: #include <sys/types.h>
                     34: #include <sys/stat.h>
                     35: #include <fcntl.h>
                     36: #include <signal.h>
                     37: #include <sys/poll.h>
                     38: #include <errno.h>
                     39: #include <string.h>
                     40: #include <ctype.h>
                     41: #include <sys/time.h>
                     42: 
                     43: #include "crc32.h"
                     44: 
                     45: #ifdef PATH_MAX
                     46: #define MY_PATH_MAX PATH_MAX
                     47: #else
                     48: #define MY_PATH_MAX 4096
                     49: #endif
                     50: 
                     51: static struct pollfd *pfd = NULL;
                     52: static int npfd = 0;
                     53: static int ipfd;
                     54: 
                     55: #define TABLE_PID_FIRST 0x10
                     56: #define TABLE_PID_LAST  0x1F
                     57: #define TABBUF_SIZE     (1<<15)
                     58: #define MAX_PSI_SIZE    (4096+1)
                     59: 
                     60: static unsigned int tabin[TABLE_PID_LAST-TABLE_PID_FIRST+1];
                     61: static unsigned int tabinold[TABLE_PID_LAST-TABLE_PID_FIRST+1];
                     62: static unsigned int tabout[TABLE_PID_LAST-TABLE_PID_FIRST+1];
                     63: static unsigned char conticnt[TABLE_PID_LAST-TABLE_PID_FIRST+1];
                     64: static unsigned char *tabbuf[TABLE_PID_LAST-TABLE_PID_FIRST+1];
                     65: 
                     66: #define TABLEID_FIRST   0x40
                     67: #define TABLEID_LAST    0x7F
                     68: 
                     69: static unsigned char nextversion[TABLEID_LAST-TABLEID_FIRST+1];
                     70: 
                     71: #define TS_PACKET_SIZE  188
                     72: #define TS_HEADSLEN     3
                     73: #define TS_PACKET_HEADSIZE      4
1.4     ! oskar      74: #define TS_PFIELDLEN    1
1.1       oskar      75: #define TS_SYNC_BYTE    0x47
                     76: #define OUTBUF_PACKETS  256
                     77: #define OUTBUF_SIZE     (TS_PACKET_SIZE*OUTBUF_PACKETS)
                     78: 
                     79: static unsigned int outin = 0;
                     80: static unsigned int outout = 0;
                     81: static unsigned char outbuf[OUTBUF_SIZE];
                     82: 
                     83: static void pollfd_init()
                     84: {
                     85:   ipfd = 0;
                     86: }
                     87: 
                     88: static int pollfd_add(int f, short e)
                     89: {
                     90:   if (npfd <= ipfd) {
                     91:     npfd = 2*npfd+1;
                     92:     pfd = realloc(pfd, npfd * sizeof(struct pollfd));
                     93:   }
                     94:   pfd[ipfd].fd = f;
                     95:   pfd[ipfd].events = e;
                     96:   return ipfd++;
                     97: }
                     98: 
                     99: static int pollfd_poll(int timeout)
                    100: {
                    101:   return poll(pfd, ipfd, timeout);
                    102: }
                    103: 
                    104: static int pollfd_rev(int i)
                    105: {
                    106:   return pfd[i].revents;
                    107: }
                    108: 
                    109: static void signalhandler(int sig)
                    110: {
                    111:   exit(0);
                    112: }
                    113: 
                    114: static void system_init()
                    115: {
                    116:   signal(SIGINT, (void *) (*signalhandler));
                    117:   signal(SIGPIPE, SIG_IGN);
                    118: }
                    119: 
                    120: static void unblockf(int f)
                    121: {
                    122:   int r;
                    123:   r = fcntl(f, F_GETFL);
                    124:   if (r >= 0) {
                    125:     r = fcntl(f, F_SETFL, r | O_NONBLOCK);
                    126:   }
                    127:   if (r < 0) {
                    128:     fprintf(stderr, "fcntl failed(%d): %d\n", errno, f);
                    129:   }
                    130: }
                    131: 
                    132: enum enumsi {
                    133:   nit,
                    134:   sdt,
                    135:   bat,
                    136:   eit,
                    137:   rst,
                    138:   tdt,
                    139:   tot,
                    140:   sit,
                    141:   dit,
                    142:   num_si,
                    143:   si_none = -1
                    144: };
                    145: 
                    146: #define DESCR_FIRST     0x40
                    147: #define DESCR_LAST      0x6E
                    148: #define PMT_POSS        0
                    149: 
                    150: static unsigned char descrcnt[DESCR_LAST-DESCR_FIRST+1];
                    151: 
                    152: const static unsigned char possible_descr[DESCR_LAST-DESCR_FIRST+1] = {
                    153:   (1<<nit),
                    154:   (1<<nit) | (1<<bat),
                    155:   0 /* (1<<nit) | (1<<bat) | (1<<sdt) | (1<<eit) | (1<<sit) */,
                    156:   (1<<nit),
                    157:   (1<<nit),
                    158:   PMT_POSS,
                    159:   PMT_POSS,
                    160:   (1<<bat) | (1<<sdt) | (1<<sit),
                    161:   (1<<sdt) | (1<<sit),
                    162:   (1<<bat) | (1<<sdt) | (1<<sit),
                    163:   (1<<nit) | (1<<bat) | (1<<sdt) | (1<<eit) | (1<<sit),
                    164:   (1<<sdt) | (1<<sit),
                    165:   (1<<sdt) | (1<<sit),
                    166:   (1<<eit) | (1<<sit),
                    167:   (1<<eit) | (1<<sit),
                    168:   (1<<eit) | (1<<sit),
                    169:   (1<<eit) | (1<<sit),
                    170:   (1<<sdt) | PMT_POSS | (1<<sit),
                    171:   PMT_POSS,
                    172:   (1<<bat) | (1<<sdt) | (1<<eit) | (1<<sit),
                    173:   (1<<eit) | (1<<sit),
                    174:   (1<<eit) | (1<<sit),
                    175:   PMT_POSS,
                    176:   (1<<sdt) | (1<<eit) | (1<<sit),
                    177:   (1<<tot),
                    178:   PMT_POSS,
                    179:   (1<<nit),
                    180:   (1<<nit),
                    181:   (1<<bat),
                    182:   (1<<sdt) | (1<<sit),
                    183:   (1<<eit) | (1<<sit),
                    184:   (1<<nit) | (1<<bat) | (1<<sdt) | (1<<eit) | PMT_POSS | (1<<sit),
                    185:   PMT_POSS,
                    186:   (1<<eit) | (1<<sit),
                    187:   (1<<nit),
                    188:   (1<<sit),
                    189:   (1<<sdt) | (1<<eit) | (1<<sit),
                    190:   PMT_POSS,
                    191:   PMT_POSS,
                    192:   0,
                    193:   0,
                    194:   (1<<eit),
                    195:   PMT_POSS,
                    196:   PMT_POSS,
                    197:   (1<<nit),
                    198:   (1<<nit),
                    199:   (1<<nit)
                    200: };
                    201: 
                    202: #define LOOP_DEPTH      4
                    203: #define REALLOC_CHUNK   32
                    204: 
                    205: struct sitab {
                    206:   struct sitab *next;
                    207:   char typ;
                    208:   unsigned char version;
                    209:   unsigned char tableid;
                    210:   long pid;
                    211:   long freqmsec;
                    212:   enum enumsi esi;
                    213:   unsigned long *tab;
                    214:   union {
                    215:     struct {
                    216:       int tablen;
                    217:       int itab;
                    218:       int fd;
                    219:       int isdescr; /* 0: main table, >0: descr loop depth */
                    220:       int descrtag;
                    221:       int isyn;
                    222:       int isyntab;
                    223:       int numcount;
                    224:       int loopbegin[LOOP_DEPTH];
                    225:       int loopcount[LOOP_DEPTH];
                    226:       int ibuf;
                    227:       char buf[256];
                    228:     } a;
                    229:     struct {
                    230:       struct timeval next;
                    231:     } s;
                    232:   } u;
                    233:   unsigned char descrnum[DESCR_LAST-DESCR_FIRST+1];
                    234: };
                    235: 
                    236: static struct sitab *newtab = NULL;
                    237: static struct sitab *runtab = NULL;
                    238: 
                    239: #define SYNTAX_END      0
                    240: #define SYNTAX_LOOPEND  1
                    241: #define SYNTAX_LOOP     2
                    242: #define SYNTAX_DESCR    3
                    243: #define SYNTAX_DESCRTAG 4
                    244: #define SYNTAX_DATETIME 5
                    245: #define SYNTAX_STRING   6
                    246: #define SYNTAX_NUMBER(name)     -1
                    247: 
                    248: const static signed char syntax_network_name[] = {
                    249:   SYNTAX_DESCRTAG,
                    250:   SYNTAX_STRING,
                    251:   SYNTAX_END
                    252: };
                    253: 
                    254: static unsigned char *gen_network_name(struct sitab *st, unsigned char *p,
                    255:         unsigned long **tt)
                    256: {
                    257:   unsigned char *d = p;
                    258:   unsigned long *t = *tt;
                    259:   int i;
                    260:   i = *t++;
                    261:   memcpy(d, t, i);
                    262:   d += i;
                    263:   t += (i + sizeof(long) - 1) / sizeof(long);
                    264:   *tt = t;
                    265:   return d;
                    266: }
                    267: 
                    268: const static signed char syntax_service_list[] = {
                    269:   SYNTAX_DESCRTAG,
                    270:   SYNTAX_LOOP,
                    271:   SYNTAX_NUMBER(service_id)
                    272:   SYNTAX_NUMBER(service_type),
                    273:   SYNTAX_END
                    274: };
                    275: 
                    276: static unsigned char *gen_service_list(struct sitab *st, unsigned char *p,
                    277:         unsigned long **tt)
                    278: {
                    279:   unsigned char *d = p;
                    280:   unsigned long *t = *tt;
                    281:   int i;
                    282:   i = *t++;
                    283:   while (i > 0) {
                    284:     *d++ = *t >> 8;
                    285:     *d++ = *t++;
                    286:     *d++ = *t++;
                    287:     i -= 1;
                    288:   }
                    289:   *tt = t;
                    290:   return d;
                    291: }
                    292: 
                    293: const static signed char syntax_satellite_delivery_system[] = {
                    294:   SYNTAX_DESCRTAG,
                    295:   SYNTAX_NUMBER(frequency)
                    296:   SYNTAX_NUMBER(orbital_position)
                    297:   SYNTAX_NUMBER(west_east_flag)
                    298:   SYNTAX_NUMBER(polarization)
                    299:   SYNTAX_NUMBER(modulation)
                    300:   SYNTAX_NUMBER(symbol_rate)
                    301:   SYNTAX_NUMBER(fec_inner),
                    302:   SYNTAX_END
                    303: };
                    304: 
                    305: static unsigned char *gen_satellite_delivery_system(struct sitab *st,
                    306:         unsigned char *p, unsigned long **tt)
                    307: {
                    308:   unsigned char *d = p;
                    309:   unsigned long *t = *tt;
                    310:   unsigned char c;
                    311:   *d++ = *t >> 24;
                    312:   *d++ = *t >> 16;
                    313:   *d++ = *t >> 8;
                    314:   *d++ = *t++;
                    315:   *d++ = *t >> 8;
                    316:   *d++ = *t++;
                    317:   c = *t++ << 7;
                    318:   c |= (*t++ & 0x03) << 5;
                    319:   *d++ = c | (*t++ & 0x1F);
                    320:   *d++ = *t >> 20;
                    321:   *d++ = *t >> 12;
                    322:   *d++ = *t >> 4;
                    323:   c = *t++ << 4;
                    324:   *d++ = c | (*t++ & 0x0F);
                    325:   *tt = t;
                    326:   return d;
                    327: }
                    328: 
                    329: const static signed char syntax_cable_delivery_system[] = {
                    330:   SYNTAX_DESCRTAG,
                    331:   SYNTAX_NUMBER(frequency)
                    332:   SYNTAX_NUMBER(fec_outer)
                    333:   SYNTAX_NUMBER(modulation)
                    334:   SYNTAX_NUMBER(symbol_rate)
                    335:   SYNTAX_NUMBER(fec_inner),
                    336:   SYNTAX_END
                    337: };
                    338: 
                    339: static unsigned char *gen_cable_delivery_system(struct sitab *st,
                    340:         unsigned char *p, unsigned long **tt)
                    341: {
                    342:   unsigned char *d = p;
                    343:   unsigned long *t = *tt;
                    344:   unsigned char c;
                    345:   *d++ = *t >> 24;
                    346:   *d++ = *t >> 16;
                    347:   *d++ = *t >> 8;
                    348:   *d++ = *t++;
                    349:   *d++ = 0xFF;
                    350:   *d++ = 0xF0 | *t++;
                    351:   *d++ = *t++;
                    352:   *d++ = *t >> 20;
                    353:   *d++ = *t >> 12;
                    354:   *d++ = *t >> 4;
                    355:   c = *t++ << 4;
                    356:   *d++ = c | (*t++ & 0x0F);
                    357:   *tt = t;
                    358:   return d;
                    359: }
                    360: 
                    361: const static signed char syntax_bouquet_name[] = {
                    362:   SYNTAX_DESCRTAG,
                    363:   SYNTAX_STRING,
                    364:   SYNTAX_END
                    365: };
                    366: 
                    367: static unsigned char *gen_bouquet_name(struct sitab *st, unsigned char *p,
                    368:         unsigned long **tt)
                    369: {
                    370:   unsigned char *d = p;
                    371:   unsigned long *t = *tt;
                    372:   int i;
                    373:   i = *t++;
                    374:   memcpy(d, t, i);
                    375:   d += i;
                    376:   t += (i + sizeof(long) - 1) / sizeof(long);
                    377:   *tt = t;
                    378:   return d;
                    379: }
                    380: 
                    381: const static signed char syntax_service[] = {
                    382:   SYNTAX_DESCRTAG,
                    383:   SYNTAX_NUMBER(service_type),
                    384:   SYNTAX_STRING,
                    385:   SYNTAX_STRING,
                    386:   SYNTAX_END
                    387: };
                    388: 
                    389: static unsigned char *gen_service(struct sitab *st, unsigned char *p,
                    390:         unsigned long **tt)
                    391: {
                    392:   unsigned char *d = p;
                    393:   unsigned long *t = *tt;
                    394:   int i;
                    395:   *d++ = *t++;
                    396:   *d++ = i = *t++;
                    397:   memcpy(d, t, i);
                    398:   d += i;
                    399:   t += (i + sizeof(long) - 1) / sizeof(long);
                    400:   *d++ = i = *t++;
                    401:   memcpy(d, t, i);
                    402:   d += i;
                    403:   t += (i + sizeof(long) - 1) / sizeof(long);
                    404:   *tt = t;
                    405:   return d;
                    406: }
                    407: 
                    408: const static signed char syntax_country_availability[] = {
                    409:   SYNTAX_DESCRTAG,
                    410:   SYNTAX_NUMBER(country_availability_flag),
                    411:   SYNTAX_LOOP,
                    412:   SYNTAX_STRING,
                    413:   SYNTAX_END
                    414: };
                    415: 
                    416: static unsigned char *gen_country_availability(struct sitab *st,
                    417:         unsigned char *p, unsigned long **tt)
                    418: {
                    419:   unsigned char *d = p;
                    420:   unsigned long *t = *tt;
                    421:   int i, j;
                    422:   *d++ = (*t++ << 7) | 0x7F;
                    423:   i = *t++;
                    424:   while (i > 0) {
                    425:     j = *t++;
                    426:     memcpy(d, t, 3);
                    427:     d += 3;
                    428:     t += (j + sizeof(long) - 1) / sizeof(long);
                    429:     i -= 1;
                    430:   }
                    431:   *tt = t;
                    432:   return d;
                    433: }
                    434: 
                    435: const static signed char syntax_linkage[] = {
                    436:   SYNTAX_DESCRTAG,
                    437:   SYNTAX_NUMBER(transport_stream_id)
                    438:   SYNTAX_NUMBER(original_network_id)
                    439:   SYNTAX_NUMBER(service_id)
                    440:   SYNTAX_NUMBER(linkage_type)
                    441:   SYNTAX_NUMBER(hand_over_type)
                    442:   SYNTAX_NUMBER(origin_type)
                    443:   SYNTAX_NUMBER(network_id)
                    444:   SYNTAX_NUMBER(initial_service_id),
                    445:   SYNTAX_LOOP,
                    446:   SYNTAX_NUMBER(private_data_byte),
                    447:   SYNTAX_END
                    448: };
                    449: 
                    450: static unsigned char *gen_linkage(struct sitab *st, unsigned char *p,
                    451:         unsigned long **tt)
                    452: {
                    453:   unsigned char *d = p;
                    454:   unsigned long *t = *tt;
                    455:   int i;
                    456:   unsigned char l, h, o;
                    457:   unsigned long n, s;
                    458:   *d++ = *t >> 8;
                    459:   *d++ = *t++;
                    460:   *d++ = *t >> 8;
                    461:   *d++ = *t++;
                    462:   *d++ = *t >> 8;
                    463:   *d++ = *t++;
                    464:   *d++ = l = *t++;
                    465:   h = *t++ & 0x0F;
                    466:   o = *t++ & 0x01;
                    467:   n = *t++;
                    468:   s = *t++;
                    469:   if (l == 8) {
                    470:     *d++ = (h << 4) | 0x0E | o;
                    471:     if ((h >= 1) && (h <= 3)) {
                    472:       *d++ = n >> 8;
                    473:       *d++ = n;
                    474:     }
                    475:     if (o == 0) {
                    476:       *d++ = s >> 8;
                    477:       *d++ = s;
                    478:     }
                    479:   }
                    480:   i = *t++;
                    481:   while (i > 0) {
                    482:     *d++ = *t++;
                    483:     i -= 1;
                    484:   }
                    485:   *tt = t;
                    486:   return d;
                    487: }
                    488: 
                    489: const static signed char syntax_nvod_reference[] = {
                    490:   SYNTAX_DESCRTAG,
                    491:   SYNTAX_LOOP,
                    492:   SYNTAX_NUMBER(transport_stream_id)
                    493:   SYNTAX_NUMBER(original_network_id)
                    494:   SYNTAX_NUMBER(service_id),
                    495:   SYNTAX_END
                    496: };
                    497: 
                    498: static unsigned char *gen_nvod_reference(struct sitab *st, unsigned char *p,
                    499:         unsigned long **tt)
                    500: {
                    501:   unsigned char *d = p;
                    502:   unsigned long *t = *tt;
                    503:   int i;
                    504:   i = *t++;
                    505:   while (i > 0) {
                    506:     *d++ = *t >> 8;
                    507:     *d++ = *t++;
                    508:     *d++ = *t >> 8;
                    509:     *d++ = *t++;
                    510:     *d++ = *t >> 8;
                    511:     *d++ = *t++;
                    512:     i -= 1;
                    513:   }
                    514:   *tt = t;
                    515:   return d;
                    516: }
                    517: 
                    518: const static signed char syntax_time_shifted_service[] = {
                    519:   SYNTAX_DESCRTAG,
                    520:   SYNTAX_NUMBER(reference_service_id),
                    521:   SYNTAX_END
                    522: };
                    523: 
                    524: static unsigned char *gen_time_shifted_service(struct sitab *st,
                    525:         unsigned char *p, unsigned long **tt)
                    526: {
                    527:   unsigned char *d = p;
                    528:   unsigned long *t = *tt;
                    529:   *d++ = *t >> 8;
                    530:   *d++ = *t++;
                    531:   *tt = t;
                    532:   return d;
                    533: }
                    534: 
                    535: const static signed char syntax_short_event[] = {
                    536:   SYNTAX_DESCRTAG,
                    537:   SYNTAX_STRING,
                    538:   SYNTAX_STRING,
                    539:   SYNTAX_STRING,
                    540:   SYNTAX_END
                    541: };
                    542: 
                    543: static unsigned char *gen_short_event(struct sitab *st, unsigned char *p,
                    544:         unsigned long **tt)
                    545: {
                    546:   unsigned char *d = p;
                    547:   unsigned long *t = *tt;
                    548:   int i;
                    549:   i = *t++;
                    550:   memcpy(d, t, 3);
                    551:   d += 3;
                    552:   t += (i + sizeof(long) - 1) / sizeof(long);
                    553:   *d++ = i = *t++;
                    554:   memcpy(d, t, i);
                    555:   d += i;
                    556:   t += (i + sizeof(long) - 1) / sizeof(long);
                    557:   *d++ = i = *t++;
                    558:   memcpy(d, t, i);
                    559:   d += i;
                    560:   t += (i + sizeof(long) - 1) / sizeof(long);
                    561:   *tt = t;
                    562:   return d;
                    563: }
                    564: 
                    565: const static signed char syntax_extended_event[] = {
                    566:   SYNTAX_DESCRTAG,
                    567:   SYNTAX_STRING,
                    568:   SYNTAX_LOOP,
                    569:   SYNTAX_STRING,
                    570:   SYNTAX_STRING,
                    571:   SYNTAX_LOOPEND,
                    572:   SYNTAX_STRING,
                    573:   SYNTAX_END
                    574: };
                    575: 
                    576: static unsigned char *gen_extended_event(struct sitab *st, unsigned char *p,
                    577:         unsigned long **tt)
                    578: {
                    579:   unsigned char *d = p;
                    580:   unsigned long *t = *tt;
                    581:   int i, j;
                    582:   *d++ = (descrcnt[0x4E - DESCR_FIRST] << 4)
                    583:        | (st->descrnum[0x4E - DESCR_FIRST] & 0x0F);
                    584:   i = *t++;
                    585:   memcpy(d, t, 3);
                    586:   d += 4;
                    587:   t += (i + sizeof(long) - 1) / sizeof(long);
                    588:   i = *t++;
                    589:   while (i > 0) {
                    590:     *d++ = j = *t++;
                    591:     memcpy(d, t, j);
                    592:     d += j;
                    593:     t += (j + sizeof(long) - 1) / sizeof(long);
                    594:     *d++ = j = *t++;
                    595:     memcpy(d, t, j);
                    596:     d += j;
                    597:     t += (j + sizeof(long) - 1) / sizeof(long);
                    598:     i -= 1;
                    599:   }
                    600:   p[4] = d-p-5;
                    601:   *d++ = i = *t++;
                    602:   memcpy(d, t, i);
                    603:   d += i;
                    604:   t += (i + sizeof(long) - 1) / sizeof(long);
                    605:   *tt = t;
                    606:   return d;
                    607: }
                    608: 
                    609: const static signed char syntax_time_shifted_event[] = {
                    610:   SYNTAX_DESCRTAG,
                    611:   SYNTAX_NUMBER(reference_service_id)
                    612:   SYNTAX_NUMBER(reference_event_id),
                    613:   SYNTAX_END
                    614: };
                    615: 
                    616: static unsigned char *gen_time_shifted_event(struct sitab *st, unsigned char *p,
                    617:         unsigned long **tt)
                    618: {
                    619:   unsigned char *d = p;
                    620:   unsigned long *t = *tt;
                    621:   *d++ = *t >> 8;
                    622:   *d++ = *t++;
                    623:   *d++ = *t >> 8;
                    624:   *d++ = *t++;
                    625:   *tt = t;
                    626:   return d;
                    627: }
                    628: 
                    629: const static signed char syntax_component[] = {
                    630:   SYNTAX_DESCRTAG,
                    631:   SYNTAX_NUMBER(stream_content)
                    632:   SYNTAX_NUMBER(component_type)
                    633:   SYNTAX_NUMBER(component_tag),
                    634:   SYNTAX_STRING,
                    635:   SYNTAX_STRING,
                    636:   SYNTAX_END
                    637: };
                    638: 
                    639: static unsigned char *gen_component(struct sitab *st, unsigned char *p,
                    640:         unsigned long **tt)
                    641: {
                    642:   unsigned char *d = p;
                    643:   unsigned long *t = *tt;
                    644:   int i;
                    645:   *d++ = 0xF0 | *t++;
                    646:   *d++ = *t++;
                    647:   *d++ = *t++;
                    648:   i = *t++;
                    649:   memcpy(d, t, 3);
                    650:   d += 3;
                    651:   t += (i + sizeof(long) - 1) / sizeof(long);
                    652:   i = *t++;
                    653:   memcpy(d, t, i);
                    654:   d += i;
                    655:   t += (i + sizeof(long) - 1) / sizeof(long);
                    656:   *tt = t;
                    657:   return d;
                    658: }
                    659: 
                    660: const static signed char syntax_mosaic[] = {
                    661:   SYNTAX_DESCRTAG,
                    662:   SYNTAX_NUMBER(mosaic_entry_point)
                    663:   SYNTAX_NUMBER(number_of_horizontal_elementary_cells)
                    664:   SYNTAX_NUMBER(number_of_vertical_elementary_cells),
                    665:   SYNTAX_LOOP,
                    666:   SYNTAX_NUMBER(logical_cell_id)
                    667:   SYNTAX_NUMBER(logical_cell_presentation_info),
                    668:   SYNTAX_LOOP,
                    669:   SYNTAX_NUMBER(elementary_cell_id),
                    670:   SYNTAX_LOOPEND,
                    671:   SYNTAX_NUMBER(cell_linkage_info)
                    672:   SYNTAX_NUMBER(bouquet_id)
                    673:   SYNTAX_NUMBER(original_network_id)
                    674:   SYNTAX_NUMBER(transport_stream_id)
                    675:   SYNTAX_NUMBER(service_id)
                    676:   SYNTAX_NUMBER(event_id),
                    677:   SYNTAX_END
                    678: };
                    679: 
                    680: static unsigned char *gen_mosaic(struct sitab *st, unsigned char *p,
                    681:         unsigned long **tt)
                    682: {
                    683:   unsigned char *d = p;
                    684:   unsigned long *t = *tt;
                    685:   unsigned char *e;
                    686:   unsigned char c;
                    687:   int i, j;
                    688:   c = *t++ << 7;
                    689:   c = c | ((*t++ & 0x07) << 4);
                    690:   *d++ = c | 0x08 | (*t++ & 0x07);
                    691:   i = *t++;
                    692:   while (i > 0) {
                    693:     *d++ = (*t++ << 2) | 0x03;
                    694:     *d++ = 0xF8 | *t++;
                    695:     e = d++;
                    696:     j = *t++;
                    697:     while (j > 0) {
                    698:       *d++ = 0xC0 | *t++;
                    699:       j -= 1;
                    700:     }
                    701:     *e = d-e-1;
                    702:     switch (*d++ = *t++) {
                    703:       case 0x01:
                    704:         *d++ = t[0] >> 8;
                    705:         *d++ = t[0];
                    706:         break;
                    707:       case 0x02:
                    708:       case 0x03:
                    709:         *d++ = t[1] >> 8;
                    710:         *d++ = t[1];
                    711:         *d++ = t[2] >> 8;
                    712:         *d++ = t[2];
                    713:         *d++ = t[3] >> 8;
                    714:         *d++ = t[3];
                    715:         break;
                    716:       case 0x04:
                    717:         *d++ = t[1] >> 8;
                    718:         *d++ = t[1];
                    719:         *d++ = t[2] >> 8;
                    720:         *d++ = t[2];
                    721:         *d++ = t[3] >> 8;
                    722:         *d++ = t[3];
                    723:         *d++ = t[4] >> 8;
                    724:         *d++ = t[4];
                    725:         break;
                    726:     }
                    727:     t += 5;
                    728:     i -= 1;
                    729:   }
                    730:   *tt = t;
                    731:   return d;
                    732: }
                    733: 
                    734: const static signed char syntax_ca_identifier[] = {
                    735:   SYNTAX_DESCRTAG,
                    736:   SYNTAX_LOOP,
                    737:   SYNTAX_NUMBER(ca_system_id),
                    738:   SYNTAX_END
                    739: };
                    740: 
                    741: static unsigned char *gen_ca_identifier(struct sitab *st, unsigned char *p,
                    742:         unsigned long **tt)
                    743: {
                    744:   unsigned char *d = p;
                    745:   unsigned long *t = *tt;
                    746:   int i;
                    747:   i = *t++;
                    748:   while (i > 0) {
                    749:     *d++ = *t >> 8;
                    750:     *d++ = *t++;
                    751:     i -= 1;
                    752:   }
                    753:   *tt = t;
                    754:   return d;
                    755: }
                    756: 
                    757: const static signed char syntax_content[] = {
                    758:   SYNTAX_DESCRTAG,
                    759:   SYNTAX_LOOP,
                    760:   SYNTAX_NUMBER(content_nibbles)
                    761:   SYNTAX_NUMBER(user_nibbles),
                    762:   SYNTAX_END
                    763: };
                    764: 
                    765: static unsigned char *gen_content(struct sitab *st, unsigned char *p,
                    766:         unsigned long **tt)
                    767: {
                    768:   unsigned char *d = p;
                    769:   unsigned long *t = *tt;
                    770:   int i;
                    771:   i = *t++;
                    772:   while (i > 0) {
                    773:     *d++ = *t++;
                    774:     *d++ = *t++;
                    775:     i -= 1;
                    776:   }
                    777:   *tt = t;
                    778:   return d;
                    779: }
                    780: 
                    781: const static signed char syntax_parental_rating[] = {
                    782:   SYNTAX_DESCRTAG,
                    783:   SYNTAX_STRING,
                    784:   SYNTAX_NUMBER(rating),
                    785:   SYNTAX_END
                    786: };
                    787: 
                    788: static unsigned char *gen_parental_rating(struct sitab *st, unsigned char *p,
                    789:         unsigned long **tt)
                    790: {
                    791:   unsigned char *d = p;
                    792:   unsigned long *t = *tt;
                    793:   int i, j;
                    794:   i = *t++;
                    795:   while (i > 0) {
                    796:     j = *t++;
                    797:     memcpy(d, t, 3);
                    798:     d += 3;
                    799:     t += (j + sizeof(long) - 1) / sizeof(long);
                    800:     *d++ = *t++;
                    801:     i -= 1;
                    802:   }
                    803:   *tt = t;
                    804:   return d;
                    805: }
                    806: 
                    807: const static signed char syntax_telephone[] = {
                    808:   SYNTAX_DESCRTAG,
                    809:   SYNTAX_NUMBER(foreign_availability)
                    810:   SYNTAX_NUMBER(connection_type),
                    811:   SYNTAX_STRING,
                    812:   SYNTAX_STRING,
                    813:   SYNTAX_STRING,
                    814:   SYNTAX_STRING,
                    815:   SYNTAX_STRING,
                    816:   SYNTAX_END
                    817: };
                    818: 
                    819: static unsigned char *gen_telephone(struct sitab *st, unsigned char *p,
                    820:         unsigned long **tt)
                    821: {
                    822:   unsigned char *d = p;
                    823:   unsigned long *t = *tt;
                    824:   unsigned char c;
                    825:   int i;
                    826:   c = *t++ << 5;
                    827:   *d = 0xC0 | c | (*t++ & 0x1F);
                    828:   d += 3;
                    829:   i = *t++;
                    830:   c = i << 5;
                    831:   memcpy(d, t, i);
                    832:   d += i;
                    833:   t += (i + sizeof(long) - 1) / sizeof(long);
                    834:   i = *t++;
                    835:   c |= (i & 0x07) << 2;
                    836:   memcpy(d, t, i);
                    837:   d += i;
                    838:   t += (i + sizeof(long) - 1) / sizeof(long);
                    839:   i = *t++;
                    840:   p[1] = 0x80 | c | (i & 0x03);
                    841:   memcpy(d, t, i);
                    842:   d += i;
                    843:   t += (i + sizeof(long) - 1) / sizeof(long);
                    844:   i = *t++;
                    845:   c = i << 4;
                    846:   memcpy(d, t, i);
                    847:   d += i;
                    848:   t += (i + sizeof(long) - 1) / sizeof(long);
                    849:   i = *t++;
                    850:   p[2] = 0x80 | c | (i & 0x0F);
                    851:   memcpy(d, t, i);
                    852:   d += i;
                    853:   t += (i + sizeof(long) - 1) / sizeof(long);
                    854:   *tt = t;
                    855:   return d;
                    856: }
                    857: 
                    858: const static signed char syntax_local_time_offset[] = {
                    859:   SYNTAX_DESCRTAG,
                    860:   SYNTAX_LOOP,
                    861:   SYNTAX_STRING,
                    862:   SYNTAX_NUMBER(country_region)
                    863:   SYNTAX_NUMBER(local_time_offset_polarity)
                    864:   SYNTAX_NUMBER(local_time_offset),
                    865:   SYNTAX_DATETIME,
                    866:   SYNTAX_NUMBER(next_time_offset),
                    867:   SYNTAX_END
                    868: };
                    869: 
                    870: static unsigned char *gen_local_time_offset(struct sitab *st, unsigned char *p,
                    871:         unsigned long **tt)
                    872: {
                    873:   unsigned char *d = p;
                    874:   unsigned long *t = *tt;
                    875:   unsigned char c;
                    876:   int i, j;
                    877:   i = *t++;
                    878:   while (i > 0) {
                    879:     j = *t++;
                    880:     memcpy(d, t, 3);
                    881:     d += 3;
                    882:     t += (j + sizeof(long) - 1) / sizeof(long);
                    883:     c = *t++ << 2;
                    884:     *d++ = c | 0x02 | (*t++ & 0x01);
                    885:     *d++ = *t >> 8;
                    886:     *d++ = *t++;
                    887:     *d++ = *t >> 8;
                    888:     *d++ = *t++;
                    889:     *d++ = *t >> 16;
                    890:     *d++ = *t >> 8;
                    891:     *d++ = *t++;
                    892:     *d++ = *t >> 8;
                    893:     *d++ = *t++;
                    894:     i -= 1;
                    895:   }
                    896:   *tt = t;
                    897:   return d;
                    898: }
                    899: 
                    900: const static signed char syntax_terrestrial_delivery_system[] = {
                    901:   SYNTAX_DESCRTAG,
                    902:   SYNTAX_NUMBER(centre_frequency)
                    903:   SYNTAX_NUMBER(bandwidth)
                    904:   SYNTAX_NUMBER(constellation)
                    905:   SYNTAX_NUMBER(hierarchy_information)
                    906:   SYNTAX_NUMBER(code_rate_hp_stream)
                    907:   SYNTAX_NUMBER(code_rate_lp_stream)
                    908:   SYNTAX_NUMBER(guard_interval)
                    909:   SYNTAX_NUMBER(transmission_mode)
                    910:   SYNTAX_NUMBER(other_frequency_flag),
                    911:   SYNTAX_END
                    912: };
                    913: 
                    914: static unsigned char *gen_terrestrial_delivery_system(struct sitab *st,
                    915:         unsigned char *p, unsigned long **tt)
                    916: {
                    917:   unsigned char *d = p;
                    918:   unsigned long *t = *tt;
                    919:   unsigned char c;
                    920:   *d++ = *t >> 24;
                    921:   *d++ = *t >> 16;
                    922:   *d++ = *t >> 8;
                    923:   *d++ = *t++;
                    924:   *d++ = (*t++ << 5) | 0x1F;
                    925:   c = *t++ << 6;
                    926:   c |= (*t++ & 0x07) << 3;
                    927:   *d++ = c | (*t++ & 0x07);
                    928:   c = *t++ << 5;
                    929:   c |= (*t++ & 0x03) << 3;
                    930:   c |= (*t++ & 0x03) << 1;
                    931:   *d++ = c | (*t++ & 0x01);
                    932:   *d++ = 0xFF;
                    933:   *d++ = 0xFF;
                    934:   *d++ = 0xFF;
                    935:   *d++ = 0xFF;
                    936:   *tt = t;
                    937:   return d;
                    938: }
                    939: 
                    940: const static signed char syntax_multilingual_network_name[] = {
                    941:   SYNTAX_DESCRTAG,
                    942:   SYNTAX_LOOP,
                    943:   SYNTAX_STRING,
                    944:   SYNTAX_STRING,
                    945:   SYNTAX_END
                    946: };
                    947: 
                    948: static unsigned char *gen_multilingual_network_name(struct sitab *st,
                    949:         unsigned char *p, unsigned long **tt)
                    950: {
                    951:   unsigned char *d = p;
                    952:   unsigned long *t = *tt;
                    953:   int i, j;
                    954:   i = *t++;
                    955:   while (i > 0) {
                    956:     j = *t++;
                    957:     memcpy(d, t, 3);
                    958:     d += 3;
                    959:     t += (j + sizeof(long) - 1) / sizeof(long);
                    960:     *d++ = j = *t++;
                    961:     memcpy(d, t, j);
                    962:     d += j;
                    963:     t += (j + sizeof(long) - 1) / sizeof(long);
                    964:     i -= 1;
                    965:   }
                    966:   *tt = t;
                    967:   return d;
                    968: }
                    969: 
                    970: const static signed char syntax_multilingual_bouquet_name[] = {
                    971:   SYNTAX_DESCRTAG,
                    972:   SYNTAX_LOOP,
                    973:   SYNTAX_STRING,
                    974:   SYNTAX_STRING,
                    975:   SYNTAX_END
                    976: };
                    977: 
                    978: static unsigned char *gen_multilingual_bouquet_name(struct sitab *st,
                    979:         unsigned char *p, unsigned long **tt)
                    980: {
                    981:   unsigned char *d = p;
                    982:   unsigned long *t = *tt;
                    983:   int i, j;
                    984:   i = *t++;
                    985:   while (i > 0) {
                    986:     j = *t++;
                    987:     memcpy(d, t, 3);
                    988:     d += 3;
                    989:     t += (j + sizeof(long) - 1) / sizeof(long);
                    990:     *d++ = j = *t++;
                    991:     memcpy(d, t, j);
                    992:     d += j;
                    993:     t += (j + sizeof(long) - 1) / sizeof(long);
                    994:     i -= 1;
                    995:   }
                    996:   *tt = t;
                    997:   return d;
                    998: }
                    999: 
                   1000: const static signed char syntax_multilingual_service_name[] = {
                   1001:   SYNTAX_DESCRTAG,
                   1002:   SYNTAX_LOOP,
                   1003:   SYNTAX_STRING,
                   1004:   SYNTAX_STRING,
                   1005:   SYNTAX_STRING,
                   1006:   SYNTAX_END
                   1007: };
                   1008: 
                   1009: static unsigned char *gen_multilingual_service_name(struct sitab *st,
                   1010:         unsigned char *p, unsigned long **tt)
                   1011: {
                   1012:   unsigned char *d = p;
                   1013:   unsigned long *t = *tt;
                   1014:   int i, j;
                   1015:   i = *t++;
                   1016:   while (i > 0) {
                   1017:     j = *t++;
                   1018:     memcpy(d, t, 3);
                   1019:     d += 3;
                   1020:     t += (j + sizeof(long) - 1) / sizeof(long);
                   1021:     *d++ = j = *t++;
                   1022:     memcpy(d, t, j);
                   1023:     d += j;
                   1024:     t += (j + sizeof(long) - 1) / sizeof(long);
                   1025:     *d++ = j = *t++;
                   1026:     memcpy(d, t, j);
                   1027:     d += j;
                   1028:     t += (j + sizeof(long) - 1) / sizeof(long);
                   1029:     i -= 1;
                   1030:   }
                   1031:   *tt = t;
                   1032:   return d;
                   1033: }
                   1034: 
                   1035: const static signed char syntax_multilingual_component[] = {
                   1036:   SYNTAX_DESCRTAG,
                   1037:   SYNTAX_NUMBER(component_tag),
                   1038:   SYNTAX_LOOP,
                   1039:   SYNTAX_STRING,
                   1040:   SYNTAX_STRING,
                   1041:   SYNTAX_END
                   1042: };
                   1043: 
                   1044: static unsigned char *gen_multilingual_component(struct sitab *st,
                   1045:         unsigned char *p, unsigned long **tt)
                   1046: {
                   1047:   unsigned char *d = p;
                   1048:   unsigned long *t = *tt;
                   1049:   int i, j;
                   1050:   *d++ = *t++;
                   1051:   i = *t++;
                   1052:   while (i > 0) {
                   1053:     j = *t++;
                   1054:     memcpy(d, t, 3);
                   1055:     d += 3;
                   1056:     t += (j + sizeof(long) - 1) / sizeof(long);
                   1057:     *d++ = j = *t++;
                   1058:     memcpy(d, t, j);
                   1059:     d += j;
                   1060:     t += (j + sizeof(long) - 1) / sizeof(long);
                   1061:     i -= 1;
                   1062:   }
                   1063:   *tt = t;
                   1064:   return d;
                   1065: }
                   1066: 
                   1067: const static signed char syntax_private_data_specifier[] = {
                   1068:   SYNTAX_DESCRTAG,
                   1069:   SYNTAX_NUMBER(private_data_specifier),
                   1070:   SYNTAX_END
                   1071: };
                   1072: 
                   1073: static unsigned char *gen_private_data_specifier(struct sitab *st,
                   1074:         unsigned char *p, unsigned long **tt)
                   1075: {
                   1076:   unsigned char *d = p;
                   1077:   unsigned long *t = *tt;
                   1078:   *d++ = *t >> 24;
                   1079:   *d++ = *t >> 16;
                   1080:   *d++ = *t >> 8;
                   1081:   *d++ = *t++;
                   1082:   *tt = t;
                   1083:   return d;
                   1084: }
                   1085: 
                   1086: const static signed char syntax_short_smoothing_buffer[] = {
                   1087:   SYNTAX_DESCRTAG,
                   1088:   SYNTAX_NUMBER(sb_size)
                   1089:   SYNTAX_NUMBER(sb_leak_rate),
                   1090:   SYNTAX_END
                   1091: };
                   1092: 
                   1093: static unsigned char *gen_short_smoothing_buffer(struct sitab *st,
                   1094:         unsigned char *p, unsigned long **tt)
                   1095: {
                   1096:   unsigned char *d = p;
                   1097:   unsigned long *t = *tt;
                   1098:   unsigned char c;
                   1099:   c = *t++ << 6;
                   1100:   *d++ = c | (*t++ & 0x3F);
                   1101:   *tt = t;
                   1102:   return d;
                   1103: }
                   1104: 
                   1105: const static signed char syntax_frequency_list[] = {
                   1106:   SYNTAX_DESCRTAG,
                   1107:   SYNTAX_NUMBER(coding_type),
                   1108:   SYNTAX_LOOP,
                   1109:   SYNTAX_NUMBER(centre_frequency),
                   1110:   SYNTAX_END
                   1111: };
                   1112: 
                   1113: static unsigned char *gen_frequency_list(struct sitab *st, unsigned char *p,
                   1114:         unsigned long **tt)
                   1115: {
                   1116:   unsigned char *d = p;
                   1117:   unsigned long *t = *tt;
                   1118:   int i;
                   1119:   *d++ = 0xFC | *t++;
                   1120:   i = *t++;
                   1121:   while (i > 0) {
                   1122:     *d++ = *t >> 24;
                   1123:     *d++ = *t >> 16;
                   1124:     *d++ = *t >> 8;
                   1125:     *d++ = *t++;
                   1126:     i -= 1;
                   1127:   }
                   1128:   *tt = t;
                   1129:   return d;
                   1130: }
                   1131: 
                   1132: const static signed char syntax_partial_transport_stream[] = {
                   1133:   SYNTAX_DESCRTAG,
                   1134:   SYNTAX_NUMBER(peak_rate)
                   1135:   SYNTAX_NUMBER(minimum_overall_smoothing_rate)
                   1136:   SYNTAX_NUMBER(maximum_overall_smoothing_buffer),
                   1137:   SYNTAX_END
                   1138: };
                   1139: 
                   1140: static unsigned char *gen_partial_transport_stream(struct sitab *st,
                   1141:         unsigned char *p, unsigned long **tt)
                   1142: {
                   1143:   unsigned char *d = p;
                   1144:   unsigned long *t = *tt;
                   1145:   *d++ = 0xC0 | (*t >> 16);
                   1146:   *d++ = *t >> 8;
                   1147:   *d++ = *t++;
                   1148:   *d++ = 0xC0 | (*t >> 16);
                   1149:   *d++ = *t >> 8;
                   1150:   *d++ = *t++;
                   1151:   *d++ = 0xC0 | (*t >> 8);
                   1152:   *d++ = *t++;
                   1153:   *tt = t;
                   1154:   return d;
                   1155: }
                   1156: 
                   1157: const static signed char syntax_data_broadcast[] = {
                   1158:   SYNTAX_DESCRTAG,
                   1159:   SYNTAX_NUMBER(data_broadcast_id)
                   1160:   SYNTAX_NUMBER(component_tag),
                   1161:   SYNTAX_LOOP,
                   1162:   SYNTAX_NUMBER(selector_byte),
                   1163:   SYNTAX_LOOPEND,
                   1164:   SYNTAX_STRING,
                   1165:   SYNTAX_STRING,
                   1166:   SYNTAX_END
                   1167: };
                   1168: 
                   1169: static unsigned char *gen_data_broadcast(struct sitab *st, unsigned char *p,
                   1170:         unsigned long **tt)
                   1171: {
                   1172:   unsigned char *d = p;
                   1173:   unsigned long *t = *tt;
                   1174:   int i;
                   1175:   *d++ = *t >> 8;
                   1176:   *d++ = *t++;
                   1177:   *d++ = *t++;
                   1178:   *d++ = i = *t++;
                   1179:   while (i > 0) {
                   1180:     *d++ = *t++;
                   1181:     i -= 1;
                   1182:   }
                   1183:   i = *t++;
                   1184:   memcpy(d, t, 3);
                   1185:   d += 3;
                   1186:   t += (i + sizeof(long) - 1) / sizeof(long);
                   1187:   *d++ = i = *t++;
                   1188:   memcpy(d, t, i);
                   1189:   d += i;
                   1190:   t += (i + sizeof(long) - 1) / sizeof(long);
                   1191:   *tt = t;
                   1192:   return d;
                   1193: }
                   1194: 
                   1195: const static signed char syntax_pdc[] = {
                   1196:   SYNTAX_DESCRTAG,
                   1197:   SYNTAX_NUMBER(program_identification_label),
                   1198:   SYNTAX_END
                   1199: };
                   1200: 
                   1201: static unsigned char *gen_pdc(struct sitab *st, unsigned char *p,
                   1202:         unsigned long **tt)
                   1203: {
                   1204:   unsigned char *d = p;
                   1205:   unsigned long *t = *tt;
                   1206:   *d++ = 0xF0 | (*t >> 16);
                   1207:   *d++ = *t >> 8;
                   1208:   *d++ = *t++;
                   1209:   *tt = t;
                   1210:   return d;
                   1211: }
                   1212: 
                   1213: const static signed char syntax_cell_list[] = {
                   1214:   SYNTAX_DESCRTAG,
                   1215:   SYNTAX_LOOP,
                   1216:   SYNTAX_NUMBER(cell_id)
                   1217:   SYNTAX_NUMBER(cell_latitude)
                   1218:   SYNTAX_NUMBER(cell_longitude)
                   1219:   SYNTAX_NUMBER(cell_extend_of_latitude)
                   1220:   SYNTAX_NUMBER(cell_extend_of_longitude),
                   1221:   SYNTAX_LOOP,
                   1222:   SYNTAX_NUMBER(cell_id_extension)
                   1223:   SYNTAX_NUMBER(subcell_latitude)
                   1224:   SYNTAX_NUMBER(subcell_longitude)
                   1225:   SYNTAX_NUMBER(subcell_extend_of_latitude)
                   1226:   SYNTAX_NUMBER(subcell_extend_of_longitude),
                   1227:   SYNTAX_END
                   1228: };
                   1229: 
                   1230: static unsigned char *gen_cell_list(struct sitab *st, unsigned char *p,
                   1231:         unsigned long **tt)
                   1232: {
                   1233:   unsigned char *d = p;
                   1234:   unsigned long *t = *tt;
                   1235:   unsigned char c;
                   1236:   int i, j;
                   1237:   i = *t++;
                   1238:   while (i > 0) {
                   1239:     *d++ = *t >> 8;
                   1240:     *d++ = *t++;
                   1241:     *d++ = *t >> 8;
                   1242:     *d++ = *t++;
                   1243:     *d++ = *t >> 8;
                   1244:     *d++ = *t++;
                   1245:     *d++ = *t >> 4;
                   1246:     c = *t++ << 4;
                   1247:     *d++ = c | ((*t >> 8) & 0x0F); 
                   1248:     *d++ = *t++;
                   1249:     j = *t++;
                   1250:     *d++ = 8 * j;
                   1251:     while (j > 0) {
                   1252:       *d++ = *t++;
                   1253:       *d++ = *t >> 8;
                   1254:       *d++ = *t++;
                   1255:       *d++ = *t >> 8;
                   1256:       *d++ = *t++;
                   1257:       *d++ = *t >> 4;
                   1258:       c = *t++ << 4;
                   1259:       *d++ = c | ((*t >> 8) & 0x0F); 
                   1260:       *d++ = *t++;
                   1261:       j -= 1;
                   1262:     }
                   1263:     i -= 1;
                   1264:   }
                   1265:   *tt = t;
                   1266:   return d;
                   1267: }
                   1268: 
                   1269: const static signed char syntax_cell_frequency_link[] = {
                   1270:   SYNTAX_DESCRTAG,
                   1271:   SYNTAX_LOOP,
                   1272:   SYNTAX_NUMBER(cell_id)
                   1273:   SYNTAX_NUMBER(frequency),
                   1274:   SYNTAX_LOOP,
                   1275:   SYNTAX_NUMBER(cell_id_extension)
                   1276:   SYNTAX_NUMBER(transposer_frequency),
                   1277:   SYNTAX_END
                   1278: };
                   1279: 
                   1280: static unsigned char *gen_cell_frequency_link(struct sitab *st,
                   1281:         unsigned char *p, unsigned long **tt)
                   1282: {
                   1283:   unsigned char *d = p;
                   1284:   unsigned long *t = *tt;
                   1285:   int i, j;
                   1286:   i = *t++;
                   1287:   while (i > 0) {
                   1288:     *d++ = *t >> 8;
                   1289:     *d++ = *t++;
                   1290:     *d++ = *t >> 24;
                   1291:     *d++ = *t >> 16;
                   1292:     *d++ = *t >> 8;
                   1293:     *d++ = *t++;
                   1294:     j = *t++;
                   1295:     *d++ = 5 * j;
                   1296:     while (j > 0) {
                   1297:       *d++ = *t++;
                   1298:       *d++ = *t >> 24;
                   1299:       *d++ = *t >> 16;
                   1300:       *d++ = *t >> 8;
                   1301:       *d++ = *t++;
                   1302:       j -= 1;
                   1303:     }
                   1304:     i -= 1;
                   1305:   }
                   1306:   *tt = t;
                   1307:   return d;
                   1308: }
                   1309: 
                   1310: const static signed char syntax_announcement_support[] = {
                   1311:   SYNTAX_DESCRTAG,
                   1312:   SYNTAX_NUMBER(announcement_support_indicator),
                   1313:   SYNTAX_LOOP,
                   1314:   SYNTAX_NUMBER(announcement_type)
                   1315:   SYNTAX_NUMBER(reference_type)
                   1316:   SYNTAX_NUMBER(original_network_id)
                   1317:   SYNTAX_NUMBER(transport_stream_id)
                   1318:   SYNTAX_NUMBER(service_id)
                   1319:   SYNTAX_NUMBER(component_tag),
                   1320:   SYNTAX_END
                   1321: };
                   1322: 
                   1323: static unsigned char *gen_announcement_support(struct sitab *st,
                   1324:         unsigned char *p, unsigned long **tt)
                   1325: {
                   1326:   unsigned char *d = p;
                   1327:   unsigned long *t = *tt;
                   1328:   unsigned char c, v;
                   1329:   int i;
                   1330:   *d++ = *t >> 8;
                   1331:   *d++ = *t++;
                   1332:   i = *t++;
                   1333:   while (i > 0) {
                   1334:     c = *t++ << 4;
                   1335:     v = *t++ & 0x07;
                   1336:     *d++ = c | 0x08 | v;
                   1337:     switch (v) {
                   1338:       case 0x01:
                   1339:       case 0x02:
                   1340:       case 0x03:
                   1341:         *d++ = *t >> 8;
                   1342:         *d++ = *t++;
                   1343:         *d++ = *t >> 8;
                   1344:         *d++ = *t++;
                   1345:         *d++ = *t >> 8;
                   1346:         *d++ = *t++;
                   1347:         *d++ = *t++;
                   1348:         break;
                   1349:     }
                   1350:     i -= 1;
                   1351:   }
                   1352:   *tt = t;
                   1353:   return d;
                   1354: }
                   1355: 
                   1356: const static signed char *const descr_syntax[DESCR_LAST-DESCR_FIRST+1] = {
                   1357:   &syntax_network_name[0],
                   1358:   &syntax_service_list[0],
                   1359:   NULL,
                   1360:   &syntax_satellite_delivery_system[0],
                   1361:   &syntax_cable_delivery_system[0],
                   1362:   NULL,
                   1363:   NULL,
                   1364:   &syntax_bouquet_name[0],
                   1365:   &syntax_service[0],
                   1366:   &syntax_country_availability[0],
                   1367:   &syntax_linkage[0],
                   1368:   &syntax_nvod_reference[0],
                   1369:   &syntax_time_shifted_service[0],
                   1370:   &syntax_short_event[0],
                   1371:   &syntax_extended_event[0],
                   1372:   &syntax_time_shifted_event[0],
                   1373:   &syntax_component[0],
                   1374:   &syntax_mosaic[0],
                   1375:   NULL,
                   1376:   &syntax_ca_identifier[0],
                   1377:   &syntax_content[0],
                   1378:   &syntax_parental_rating[0],
                   1379:   NULL,
                   1380:   &syntax_telephone[0],
                   1381:   &syntax_local_time_offset[0],
                   1382:   NULL,
                   1383:   &syntax_terrestrial_delivery_system[0],
                   1384:   &syntax_multilingual_network_name[0],
                   1385:   &syntax_multilingual_bouquet_name[0],
                   1386:   &syntax_multilingual_service_name[0],
                   1387:   &syntax_multilingual_component[0],
                   1388:   &syntax_private_data_specifier[0],
                   1389:   NULL,
                   1390:   &syntax_short_smoothing_buffer[0],
                   1391:   &syntax_frequency_list[0],
                   1392:   &syntax_partial_transport_stream[0],
                   1393:   &syntax_data_broadcast[0],
                   1394:   NULL,
                   1395:   NULL,
                   1396:   NULL,
                   1397:   NULL,
                   1398:   &syntax_pdc[0],
                   1399:   NULL,
                   1400:   NULL,
                   1401:   &syntax_cell_list[0],
                   1402:   &syntax_cell_frequency_link[0],
                   1403:   &syntax_announcement_support[0]
                   1404: };
                   1405: 
                   1406: static unsigned char *gendescr(struct sitab *st, unsigned char *p,
                   1407:         unsigned long **tt, unsigned char msb)
                   1408: {
                   1409:   unsigned char *d = p+2;
                   1410:   unsigned long *t = *tt;
                   1411:   unsigned char *b;
                   1412:   unsigned char v;
                   1413:   int i;
                   1414:   i = *t++;
                   1415:   while (i > 0) {
                   1416:     b = d+2;
                   1417:     switch (*d = v = *t++) {
                   1418:       case 0x40: d = gen_network_name(st, b, &t); break;
                   1419:       case 0x41: d = gen_service_list(st, b, &t); break;
                   1420:       case 0x43: d = gen_satellite_delivery_system(st, b, &t); break;
                   1421:       case 0x44: d = gen_cable_delivery_system(st, b, &t); break;
                   1422:       case 0x47: d = gen_bouquet_name(st, b, &t); break;
                   1423:       case 0x48: d = gen_service(st, b, &t); break;
                   1424:       case 0x49: d = gen_country_availability(st, b, &t); break;
                   1425:       case 0x4A: d = gen_linkage(st, b, &t); break;
                   1426:       case 0x4B: d = gen_nvod_reference(st, b, &t); break;
                   1427:       case 0x4C: d = gen_time_shifted_service(st, b, &t); break;
                   1428:       case 0x4D: d = gen_short_event(st, b, &t); break;
                   1429:       case 0x4E: d = gen_extended_event(st, b, &t); break;
                   1430:       case 0x4F: d = gen_time_shifted_event(st, b, &t); break;
                   1431:       case 0x50: d = gen_component(st, b, &t); break;
                   1432:       case 0x51: d = gen_mosaic(st, b, &t); break;
                   1433:       case 0x53: d = gen_ca_identifier(st, b, &t); break;
                   1434:       case 0x54: d = gen_content(st, b, &t); break;
                   1435:       case 0x55: d = gen_parental_rating(st, b, &t); break;
                   1436:       case 0x57: d = gen_telephone(st, b, &t); break;
                   1437:       case 0x58: d = gen_local_time_offset(st, b, &t); break;
                   1438:       case 0x5A: d = gen_terrestrial_delivery_system(st, b, &t); break;
                   1439:       case 0x5B: d = gen_multilingual_network_name(st, b, &t); break;
                   1440:       case 0x5C: d = gen_multilingual_bouquet_name(st, b, &t); break;
                   1441:       case 0x5D: d = gen_multilingual_service_name(st, b, &t); break;
                   1442:       case 0x5E: d = gen_multilingual_component(st, b, &t); break;
                   1443:       case 0x5F: d = gen_private_data_specifier(st, b, &t); break;
                   1444:       case 0x61: d = gen_short_smoothing_buffer(st, b, &t); break;
                   1445:       case 0x62: d = gen_frequency_list(st, b, &t); break;
                   1446:       case 0x63: d = gen_partial_transport_stream(st, b, &t); break;
                   1447:       case 0x64: d = gen_data_broadcast(st, b, &t); break;
                   1448:       case 0x69: d = gen_pdc(st, b, &t); break;
                   1449:       case 0x6C: d = gen_cell_list(st, b, &t); break;
                   1450:       case 0x6D: d = gen_cell_frequency_link(st, b, &t); break;
                   1451:       case 0x6E: d = gen_announcement_support(st, b, &t); break;
                   1452:       default:
                   1453:         fprintf(stderr, "error: descr not implemented (%02x)\n", *d);
                   1454:         exit(1);
                   1455:     }
                   1456:     descrcnt[v-DESCR_FIRST] += 1;
                   1457:     b[-1] = d-b;
                   1458:     i -= 1;
                   1459:   }
                   1460:   i = d-p-2;
                   1461:   p[0] = msb | (i >> 8);
                   1462:   p[1] = i;
                   1463:   *tt = t;
                   1464:   return d;
                   1465: }
                   1466: 
                   1467: const static signed char syntax_nit[] = {
                   1468:   SYNTAX_NUMBER(network_id),
                   1469:   SYNTAX_DESCR,
                   1470:   SYNTAX_LOOP,
                   1471:   SYNTAX_NUMBER(transport_stream_id)
                   1472:   SYNTAX_NUMBER(original_network_id),
                   1473:   SYNTAX_DESCR,
                   1474:   SYNTAX_END
                   1475: };
                   1476: 
                   1477: static int gentab_nit(struct sitab *st, unsigned char *b)
                   1478: {
                   1479:   unsigned char *p = b;
                   1480:   unsigned long *t = st->tab;
                   1481:   unsigned char *q;
                   1482:   int i;
                   1483:   *p = st->tableid;
                   1484:   p += 3;
                   1485:   *p++ = *t >> 8;
                   1486:   *p++ = *t++;
                   1487:   *p++ = 0xC0 | (st->version << 1) | 0x01;
                   1488:   *p++ = 0;
                   1489:   *p++ = 0;
                   1490:   p = gendescr(st, p, &t, 0xF0);
                   1491:   q = p;
                   1492:   p += 2;
                   1493:   i = *t++;
                   1494:   while (i > 0) {
                   1495:     *p++ = *t >> 8;
                   1496:     *p++ = *t++;
                   1497:     *p++ = *t >> 8;
                   1498:     *p++ = *t++;
                   1499:     p = gendescr(st, p, &t, 0xF0);
                   1500:     i -= 1;
                   1501:   }
                   1502:   i = p-q-2;
                   1503:   q[0] = 0xF0 | (i >> 8);
                   1504:   q[1] = i;
                   1505:   i = p-b+1;
                   1506:   b[1] = 0xF0 | (i >> 8);
                   1507:   b[2] = i;
                   1508:   crc32_calc(b, i-1, p);
                   1509:   return p-b+4;
                   1510: }
                   1511: 
                   1512: const static signed char syntax_sdt[] = {
                   1513:   SYNTAX_NUMBER(transport_stream_id)
                   1514:   SYNTAX_NUMBER(original_network_id),
                   1515:   SYNTAX_LOOP,
                   1516:   SYNTAX_NUMBER(service_id)
                   1517:   SYNTAX_NUMBER(eit_schedule_flag)
                   1518:   SYNTAX_NUMBER(eit_present_following_flag)
                   1519:   SYNTAX_NUMBER(running_status),
                   1520:   SYNTAX_DESCR,
                   1521:   SYNTAX_END
                   1522: };
                   1523: 
                   1524: static int gentab_sdt(struct sitab *st, unsigned char *b)
                   1525: {
                   1526:   unsigned char *p = b;
                   1527:   unsigned long *t = st->tab;
                   1528:   int i;
                   1529:   unsigned char c;
                   1530:   *p = st->tableid;
                   1531:   p += 3;
                   1532:   *p++ = *t >> 8;
                   1533:   *p++ = *t++;
                   1534:   *p++ = 0xC0 | (st->version << 1) | 0x01;
                   1535:   *p++ = 0;
                   1536:   *p++ = 0;
                   1537:   *p++ = *t >> 8;
                   1538:   *p++ = *t++;
                   1539:   *p++ = 0xFF;
                   1540:   i = *t++;
                   1541:   while (i > 0) {
                   1542:     *p++ = *t >> 8;
                   1543:     *p++ = *t++;
                   1544:     c = *t++ << 1;
                   1545:     *p++ = 0xFC | c | (*t++ & 1);
                   1546:     c = *t++ << 5;
                   1547:     p = gendescr(st, p, &t, c);
                   1548:     i -= 1;
                   1549:   }
                   1550:   i = p-b+1;
                   1551:   b[1] = 0xF0 | (i >> 8);
                   1552:   b[2] = i;
                   1553:   crc32_calc(b, i-1, p);
                   1554:   return p-b+4;
                   1555: }
                   1556: 
                   1557: const static signed char syntax_bat[] = {
                   1558:   SYNTAX_NUMBER(bouquet_id),
                   1559:   SYNTAX_DESCR,
                   1560:   SYNTAX_LOOP,
                   1561:   SYNTAX_NUMBER(transport_stream_id)
                   1562:   SYNTAX_NUMBER(original_network_id),
                   1563:   SYNTAX_DESCR,
                   1564:   SYNTAX_END
                   1565: };
                   1566: 
                   1567: static int gentab_bat(struct sitab *st, unsigned char *b)
                   1568: {
                   1569:   unsigned char *p = b;
                   1570:   unsigned long *t = st->tab;
                   1571:   unsigned char *q;
                   1572:   int i;
                   1573:   *p = st->tableid;
                   1574:   p += 3;
                   1575:   *p++ = *t >> 8;
                   1576:   *p++ = *t++;
                   1577:   *p++ = 0xC0 | (st->version << 1) | 0x01;
                   1578:   *p++ = 0;
                   1579:   *p++ = 0;
                   1580:   p = gendescr(st, p, &t, 0xF0);
                   1581:   q = p;
                   1582:   p += 2;
                   1583:   i = *t++;
                   1584:   while (i > 0) {
                   1585:     *p++ = *t >> 8;
                   1586:     *p++ = *t++;
                   1587:     *p++ = *t >> 8;
                   1588:     *p++ = *t++;
                   1589:     p = gendescr(st, p, &t, 0xF0);
                   1590:     i -= 1;
                   1591:   }
                   1592:   i = p-q-2;
                   1593:   q[0] = 0xF0 | (i >> 8);
                   1594:   q[1] = i;
                   1595:   i = p-b+1;
                   1596:   b[1] = 0xF0 | (i >> 8);
                   1597:   b[2] = i;
                   1598:   crc32_calc(b, i-1, p);
                   1599:   return p-b+4;
                   1600: }
                   1601: 
                   1602: const static signed char syntax_eit[] = {
                   1603:   SYNTAX_NUMBER(service_id)
                   1604:   SYNTAX_NUMBER(transport_stream_id)
                   1605:   SYNTAX_NUMBER(original_network_id),
                   1606:   SYNTAX_LOOP,
                   1607:   SYNTAX_NUMBER(event_id),
                   1608:   SYNTAX_DATETIME,
                   1609:   SYNTAX_NUMBER(duration)
                   1610:   SYNTAX_NUMBER(running_status),
                   1611:   SYNTAX_DESCR,
                   1612:   SYNTAX_END
                   1613: };
                   1614: 
                   1615: static int gentab_eit(struct sitab *st, unsigned char *b)
                   1616: {
                   1617:   unsigned char *p = b;
                   1618:   unsigned long *t = st->tab;
                   1619:   int i;
                   1620:   struct sitab *gt;
                   1621:   *p = i = st->tableid;
                   1622:   p += 3;
                   1623:   *p++ = *t >> 8;
                   1624:   *p++ = *t++;
                   1625:   *p++ = 0xC0 | (st->version << 1) | 0x01;
                   1626:   *p++ = 0;
                   1627:   *p++ = 0;
                   1628:   *p++ = *t >> 8;
                   1629:   *p++ = *t++;
                   1630:   *p++ = *t >> 8;
                   1631:   *p++ = *t++;
                   1632:   *p++ = 0;
                   1633:   gt = runtab;
                   1634:   while (gt != NULL) {
                   1635:     if ((gt->esi == eit) && (gt->tableid > i)) {
                   1636:       i = gt->tableid;
                   1637:     }
                   1638:     gt = gt->next;
                   1639:   }
                   1640:   *p++ = i;
                   1641:   i = *t++;
                   1642:   *p++ = *t >> 8;
                   1643:   *p++ = *t++;
                   1644:   *p++ = *t >> 8;
                   1645:   *p++ = *t++;
                   1646:   *p++ = *t >> 16;
                   1647:   *p++ = *t >> 8;
                   1648:   *p++ = *t++;
                   1649:   *p++ = *t >> 16;
                   1650:   *p++ = *t >> 8;
                   1651:   *p++ = *t++;
                   1652:   i = *t++ << 5;
                   1653:   p = gendescr(st, p, &t, i);
                   1654:   i = p-b+1;
                   1655:   b[1] = 0xF0 | (i >> 8);
                   1656:   b[2] = i;
                   1657:   crc32_calc(b, i-1, p);
                   1658:   return p-b+4;
                   1659: }
                   1660: 
                   1661: const static signed char syntax_rst[] = {
                   1662:   SYNTAX_LOOP,
                   1663:   SYNTAX_NUMBER(transport_stream_id)
                   1664:   SYNTAX_NUMBER(original_network_id)
                   1665:   SYNTAX_NUMBER(service_id)
                   1666:   SYNTAX_NUMBER(event_id)
                   1667:   SYNTAX_NUMBER(running_status),
                   1668:   SYNTAX_END
                   1669: };
                   1670: 
                   1671: static int gentab_rst(struct sitab *st, unsigned char *b)
                   1672: {
                   1673:   unsigned char *p = b;
                   1674:   unsigned long *t = st->tab;
                   1675:   int i;
                   1676:   *p = st->tableid;
                   1677:   p += 3;
                   1678:   i = *t++;
                   1679:   while (i > 0) {
                   1680:     *p++ = *t >> 8;
                   1681:     *p++ = *t++;
                   1682:     *p++ = *t >> 8;
                   1683:     *p++ = *t++;
                   1684:     *p++ = *t >> 8;
                   1685:     *p++ = *t++;
                   1686:     *p++ = *t >> 8;
                   1687:     *p++ = *t++;
                   1688:     *p++ = 0xF8 | *t++;
                   1689:     i -= 1;
                   1690:   }
                   1691:   i = p-b-3;
                   1692:   b[1] = 0xF0 | (i >> 8);
                   1693:   b[2] = i;
                   1694:   return p-b;
                   1695: }
                   1696: 
                   1697: static unsigned char *gentvdatetime(unsigned char *p, struct timeval *tv)
                   1698: {
                   1699:   unsigned long d, s;
                   1700:   s = tv->tv_sec;
                   1701:   d = s / 86400;
                   1702:   s = s % 86400;
                   1703:   d += 40587;
                   1704:   *p++ = d >> 8;
                   1705:   *p++ = d;
                   1706:   d = s / 3600;
                   1707:   s = s % 3600;
                   1708:   d += (d / 10) * 6;
                   1709:   *p++ = d;
                   1710:   d = s / 60;
                   1711:   s = s % 60;
                   1712:   d += (d / 10) * 6;
                   1713:   *p++ = d;
                   1714:   s += (s / 10) * 6;
                   1715:   *p++ = s;
                   1716:   return p;
                   1717: }
                   1718: 
                   1719: const static signed char syntax_tdt[] = {
                   1720:   SYNTAX_END
                   1721: };
                   1722: 
                   1723: static int gentab_tdt(struct sitab *st, unsigned char *b, struct timeval *tv)
                   1724: {
                   1725:   unsigned char *p = b;
                   1726:   *p++ = st->tableid;
                   1727:   *p++ = 0xF0;
                   1728:   *p++ = 0x05;
                   1729:   p = gentvdatetime(p, tv);
                   1730:   return p-b;
                   1731: }
                   1732: 
                   1733: const static signed char syntax_tot[] = {
                   1734:   SYNTAX_DESCR,
                   1735:   SYNTAX_END
                   1736: };
                   1737: 
                   1738: static int gentab_tot(struct sitab *st, unsigned char *b, struct timeval *tv)
                   1739: {
                   1740:   unsigned char *p = b;
                   1741:   unsigned long *t = st->tab;
                   1742:   int i;
                   1743:   *p = st->tableid;
                   1744:   p += 3;
                   1745:   p = gentvdatetime(p, tv);
                   1746:   p = gendescr(st, p, &t, 0xF0);
                   1747:   i = p-b+1;
                   1748:   b[1] = 0xF0 | (i >> 8);
                   1749:   b[2] = i;
                   1750:   crc32_calc(b, i-1, p);
                   1751:   return p-b+4;
                   1752: }
                   1753: 
                   1754: const static signed char syntax_sit[] = {
                   1755:   SYNTAX_DESCR,
                   1756:   SYNTAX_LOOP,
                   1757:   SYNTAX_NUMBER(service_id)
                   1758:   SYNTAX_NUMBER(running_status),
                   1759:   SYNTAX_DESCR,
                   1760:   SYNTAX_END
                   1761: };
                   1762: 
                   1763: static int gentab_sit(struct sitab *st, unsigned char *b)
                   1764: {
                   1765:   unsigned char *p = b;
                   1766:   unsigned long *t = st->tab;
1.3       oskar    1767:   unsigned char c;
                   1768:   int i;
1.1       oskar    1769:   *p = st->tableid;
1.3       oskar    1770:   p += 3;
                   1771:   *p++ = 0xFF;
                   1772:   *p++ = 0xFF;
                   1773:   *p++ = 0xC0 | (st->version << 1) | 0x01;
                   1774:   *p++ = 0;
                   1775:   *p++ = 0;
                   1776:   p = gendescr(st, p, &t, 0xF0);
                   1777:   i = *t++;
                   1778:   while (i > 0) {
                   1779:     *p++ = *t >> 8;
                   1780:     *p++ = *t++;
                   1781:     c = *t++ << 4;
                   1782:     p = gendescr(st, p, &t, 0x80 | c);
                   1783:     i -= 1;
                   1784:   }
                   1785:   i = p-b+1;
                   1786:   b[1] = 0xF0 | (i >> 8);
                   1787:   b[2] = i;
                   1788:   crc32_calc(b, i-1, p);
                   1789:   return p-b+4;
1.1       oskar    1790: }
                   1791: 
                   1792: const static signed char syntax_dit[] = {
                   1793:   SYNTAX_NUMBER(transition_flag),
                   1794:   SYNTAX_END
                   1795: };
                   1796: 
                   1797: static int gentab_dit(struct sitab *st, unsigned char *b)
                   1798: {
                   1799:   unsigned char *p = b;
                   1800:   unsigned long *t = st->tab;
1.3       oskar    1801:   *p++ = st->tableid;
                   1802:   *p++ = 0xF0;
                   1803:   *p++ = 0x01;
                   1804:   *p++ = (*t++ << 7) | 0x7F;
1.1       oskar    1805:   return p-b;
                   1806: }
                   1807: 
                   1808: const static signed char *const tab_syntax[num_si] = {
                   1809:   &syntax_nit[0],
                   1810:   &syntax_sdt[0],
                   1811:   &syntax_bat[0],
                   1812:   &syntax_eit[0],
                   1813:   &syntax_rst[0],
                   1814:   &syntax_tdt[0],
                   1815:   &syntax_tot[0],
                   1816:   &syntax_sit[0],
                   1817:   &syntax_dit[0]
                   1818: };
                   1819: 
                   1820: const static signed char *const *const syntax[2] = {
                   1821:   &tab_syntax[0],
                   1822:   &descr_syntax[0]
                   1823: };
                   1824: 
                   1825: static void gentab(struct sitab *st, struct timeval *tv)
                   1826: {
                   1827:   int l;
                   1828:   unsigned char *b;
                   1829:   memset(&descrcnt[0], 0, sizeof(descrcnt));
                   1830:   l = st->pid - TABLE_PID_FIRST;
                   1831:   b = &tabbuf[l][tabin[l]];
                   1832:   *b++ = st->pid >> 8;
                   1833:   *b++ = st->pid;
                   1834:   switch (st->esi) {
                   1835:     case nit: l = gentab_nit(st, b); break;
                   1836:     case sdt: l = gentab_sdt(st, b); break;
                   1837:     case bat: l = gentab_bat(st, b); break;
                   1838:     case eit: l = gentab_eit(st, b); break;
                   1839:     case rst: l = gentab_rst(st, b); break;
                   1840:     case tdt: l = gentab_tdt(st, b, tv); break;
                   1841:     case tot: l = gentab_tot(st, b, tv); break;
                   1842:     case sit: l = gentab_sit(st, b); break;
                   1843:     case dit: l = gentab_dit(st, b); break;
                   1844:     default:
                   1845:       fprintf(stderr, "internal error (gentab, %d)\n", st->esi);
                   1846:       exit(1);
                   1847:   }
                   1848:   tabin[st->pid - TABLE_PID_FIRST] += l+2;
                   1849: }
                   1850: 
                   1851: static enum enumsi alloctab(long pid, long tid)
                   1852: {
                   1853:   enum enumsi e = si_none;
                   1854:   switch (pid) {
                   1855:     case 0x0010:
                   1856:       if ((tid == 0x40) || (tid == 0x41)) {
                   1857:         e = nit;
                   1858:       } else {
                   1859:         fprintf(stderr, "bad tableid: 0x%02lx (pid: 0x%04lx)\n", tid, pid);
                   1860:       }
                   1861:       break;
                   1862:     case 0x0011:
                   1863:       if ((tid == 0x42) || (tid == 0x46)) {
                   1864:         e = sdt;
                   1865:       } else if (tid == 0x4A) {
                   1866:         e = bat;
                   1867:       } else {
                   1868:         fprintf(stderr, "bad tableid: 0x%02lx (pid: 0x%04lx)\n", tid, pid);
                   1869:       }
                   1870:       break;
                   1871:     case 0x0012:
                   1872:       if ((tid >= 0x4E) && (tid <= 0x6F)) {
                   1873:         e = eit;
                   1874:       } else {
                   1875:         fprintf(stderr, "bad tableid: 0x%02lx (pid: 0x%04lx)\n", tid, pid);
                   1876:       }
                   1877:       break;
                   1878:     case 0x0013:
                   1879:       if (tid == 0x71) {
                   1880:         e = rst;
                   1881:       } else {
                   1882:         fprintf(stderr, "bad tableid: 0x%02lx (pid: 0x%04lx)\n", tid, pid);
                   1883:       }
                   1884:       break;
                   1885:     case 0x0014:
                   1886:       if (tid == 0x70) {
                   1887:         e = tdt;
                   1888:       } else if (tid == 0x73) {
                   1889:         e = tot;
                   1890:       } else {
                   1891:         fprintf(stderr, "bad tableid: 0x%02lx (pid: 0x%04lx)\n", tid, pid);
                   1892:       }
                   1893:       break;
                   1894:     case 0x001E:
                   1895:       if (tid == 0x7E) {
                   1896:         e = dit;
                   1897:       } else {
                   1898:         fprintf(stderr, "bad tableid: 0x%02lx (pid: 0x%04lx)\n", tid, pid);
                   1899:       }
                   1900:       break;
                   1901:     case 0x001F:
                   1902:       if (tid == 0x7F) {
                   1903:         e = sit;
                   1904:       } else {
                   1905:         fprintf(stderr, "bad tableid: 0x%02lx (pid: 0x%04lx)\n", tid, pid);
                   1906:       }
                   1907:       break;
                   1908:     default:
                   1909:       fprintf(stderr, "bad pid: 0x%04lx\n", pid);
                   1910:       break;
                   1911:   }
                   1912:   return e;
                   1913: }
                   1914: 
                   1915: static struct sitab **findtab(struct sitab **pst, long pid, long tableid)
                   1916: {
                   1917:   struct sitab *st = *pst;
                   1918:   while (st != NULL) {
                   1919:     if ((st->pid == pid) && (st->tableid == tableid)) {
                   1920:       return pst;
                   1921:     }
                   1922:     pst = &st->next;
                   1923:     st = *pst;
                   1924:   }
                   1925:   return NULL;
                   1926: }
                   1927: 
                   1928: static void droptab(long pid, long tableid)
                   1929: {
                   1930:   struct sitab **pst;
                   1931:   struct sitab *st;
                   1932:   pst = &newtab;
                   1933:   while ((pst = findtab(pst, pid, tableid)) != NULL) {
                   1934:     st = *pst;
                   1935:     *pst = st->next;
                   1936:     close(st->u.a.fd);
                   1937:     free(st->tab);
                   1938:     free(st);
                   1939:   }
                   1940:   pst = &runtab;
                   1941:   while ((pst = findtab(pst, pid, tableid)) != NULL) {
                   1942:     st = *pst;
                   1943:     *pst = st->next;
                   1944:     nextversion[st->tableid - TABLEID_FIRST] = (st->version + 1) & 0x1F;
                   1945:     free(st->tab);
                   1946:     free(st);
                   1947:   }
                   1948: }
                   1949: 
                   1950: static void maketab(char typ, long pid, long tableid, long freqmsec, int fd)
                   1951: {
                   1952:   struct sitab **pt;
                   1953:   struct sitab *t;
                   1954:   enum enumsi e;
                   1955:   e = alloctab(pid, tableid);
                   1956:   if (e >= 0) {
                   1957:     pt = findtab(&newtab, pid, tableid);
                   1958:     if (pt == NULL) {
                   1959:       pt = findtab(&runtab, pid, tableid);
                   1960:     } else {
                   1961:       t = *pt;
1.2       oskar    1962: #ifdef DEBUG
                   1963:       fprintf(stderr, "close old fd: %d\n", t->u.a.fd);
                   1964: #endif
1.1       oskar    1965:       close(t->u.a.fd);
                   1966:     }
                   1967:     if (pt == NULL) {
                   1968:       t = malloc(sizeof(struct sitab));
                   1969:       t->pid = pid;
                   1970:       t->tableid = tableid;
                   1971:       t->version = nextversion[tableid - TABLEID_FIRST];
                   1972:     } else {
                   1973:       t = *pt;
                   1974:       *pt = t->next;
                   1975:       free(t->tab);
                   1976:       t->version = (t->version + 1) & 0x1F;
                   1977:     }
                   1978:     t->typ = typ;
                   1979:     t->freqmsec = freqmsec;
                   1980:     t->esi = e;
                   1981:     t->tab = NULL;
                   1982:     memset(&t->descrnum[0], 0, sizeof(t->descrnum[0]));
1.2       oskar    1983:     memset(&t->u, 0, sizeof(t->u));
1.1       oskar    1984:     t->u.a.fd = fd;
                   1985:     t->next = newtab;
                   1986:     newtab = t;
                   1987:   }
                   1988: }
                   1989: 
                   1990: static int tabline(char *b, int n)
                   1991: {
                   1992:   char *e, *a, *z;
                   1993:   int i;
                   1994:   long v[3];
                   1995:   char c;
                   1996:   if ((n <= 0) || ((e = memchr(b, '\n', n)) == NULL)) {
                   1997:     return 0;
                   1998:   }
                   1999:   *e = 0;
                   2000:   if (b >= e) {
                   2001:     fprintf(stderr, "incomplete line: %s\n", b);
                   2002:   } else {
                   2003:     z = b+1;
                   2004:     i = 0;
                   2005:     c = toupper(*b);
                   2006:     switch (c) {
                   2007:       case '-':
                   2008:         do {
                   2009:           a = z;
                   2010:           v[i] = strtol(a, &z, 0);
                   2011:         } while ((a != z) && (++i < 2));
                   2012:         if (a == z) {
                   2013:           fprintf(stderr, "invalid line(%d): %s\n", a-b, b);
                   2014:         } else {
                   2015:           droptab(v[0], v[1]);
                   2016:         }
                   2017:         break;
                   2018:       case 'S':
                   2019:         do {
                   2020:           a = z;
                   2021:           v[i] = strtol(a, &z, 0);
                   2022:         } while ((a != z) && (++i < 3));
                   2023:         if (a == z) {
                   2024:           fprintf(stderr, "invalid line(%d): %s\n", a-b, b);
                   2025:         } else {
                   2026:           while (isspace(*z)) {
                   2027:             z += 1;
                   2028:           }
                   2029:           i = open(z, O_RDONLY | O_NONBLOCK);
                   2030:           if (i < 0) {
                   2031:             fprintf(stderr, "open failed(%d): %s\n", errno, z);
                   2032:           } else {
                   2033: #ifdef DEBUG
                   2034:             fprintf(stderr, "table: %c, %ld, %ld, %ld, <%s>\n",
                   2035:                 c, v[0], v[1], v[2], z);
                   2036: #endif
                   2037:             maketab(c, v[0], v[1], v[2], i);
                   2038:           }
                   2039:         }
                   2040:         break;
                   2041:     }
                   2042:   }
                   2043:   return e-b+1;
                   2044: }
                   2045: 
                   2046: static int taballoc(struct sitab *st, int cnt)
                   2047: {
                   2048:   while (st->u.a.tablen < (st->u.a.itab + cnt)) {
                   2049:     st->u.a.tablen += REALLOC_CHUNK;
                   2050:     st->tab = realloc(st->tab, st->u.a.tablen * sizeof(unsigned long));
                   2051:     if (st->tab == NULL) {
                   2052:       return -ENOMEM;
                   2053:     }
                   2054:   }
                   2055:   return 0;
                   2056: }
                   2057: 
                   2058: static long longval(char **n, int d)
                   2059: {
                   2060:   long v;
                   2061:   int i;
                   2062:   char c;
                   2063:   v = 0;
                   2064:   for (i = 0; i < d; i++) {
                   2065:     c = *(*n)++;
                   2066:     if (!isdigit(c)) {
                   2067:       return -ENOMEM;
                   2068:     }
                   2069:     v = 10*v+c-'0';
                   2070:   }
                   2071:   return v;
                   2072: }
                   2073: 
                   2074: static int siline(struct sitab *st, char *b, int n)
                   2075: {
                   2076:   char *e, *a, *z;
                   2077:   long v;
                   2078:   int s, i;
                   2079:   s = syntax[(st->u.a.isdescr > 0) ? 1 : 0]
                   2080:     [(st->u.a.isdescr > 0) ? st->u.a.descrtag : st->esi][st->u.a.isyn];
                   2081:   if ((s == SYNTAX_END) || (s == SYNTAX_LOOPEND)) {
                   2082:     int lc;
                   2083: #ifdef DEBUG
                   2084:     fprintf(stderr, "end:\n");
                   2085: #endif
                   2086:     if ((lc = --st->u.a.loopcount[0]) <= 0) {
                   2087:       if (lc == 0) {
                   2088:         for (i = 0; i < LOOP_DEPTH-1; i++) {
                   2089:           st->u.a.loopbegin[i] = st->u.a.loopbegin[i+1];
                   2090:           st->u.a.loopcount[i] = st->u.a.loopcount[i+1];
                   2091:         }
                   2092:         st->u.a.loopcount[LOOP_DEPTH-1] = 0;
                   2093:         if (s == SYNTAX_LOOPEND) {
                   2094:           st->u.a.isyn += 1;
                   2095:         } else if (st->u.a.isdescr > 0) {
                   2096:           if (--st->u.a.isdescr == 0) {
                   2097:             st->u.a.isyn = st->u.a.isyntab;
                   2098:           }
                   2099:         }
                   2100:         return 0;
                   2101:       } else {
                   2102:         st->u.a.tablen = st->u.a.itab;
                   2103:         st->tab = realloc(st->tab, st->u.a.itab * sizeof(unsigned long));
                   2104:         return -ENOBUFS;
                   2105:       }
                   2106:     } else {
                   2107:       st->u.a.isyn = st->u.a.loopbegin[0];
                   2108:       return 0;
                   2109:     }
                   2110:   }
                   2111:   if ((n <= 0) || ((e = memchr(b, '\n', n)) == NULL)) {
                   2112:     return -EAGAIN;
                   2113:   }
                   2114:   *e = 0;
                   2115:   a = b;
                   2116:   while (isspace(*a)) {
                   2117:     a += 1;
                   2118:   }
                   2119:   if (taballoc(st, 1)) {
                   2120:     return -ENOMEM;
                   2121:   }
                   2122:   if (a != e) {
                   2123:     switch (s) {
                   2124:       default:
                   2125:         if (s > 0) {
                   2126:           fprintf(stderr, "internal syntax error\n");
                   2127:           exit(1);
                   2128:         }
                   2129:         if (st->u.a.numcount == 0) {
                   2130:           st->u.a.numcount = s;
                   2131:         }
                   2132:         v = strtoul(a, &z, 0);
                   2133:         if (a == z) {
                   2134:           return -EINVAL;
                   2135:         }
                   2136: #ifdef DEBUG
                   2137:         fprintf(stderr, "number: %ld, %d..%d\n", v, a-b, z-b);
                   2138: #endif
                   2139:         st->tab[st->u.a.itab++] = v;
                   2140:         if (++st->u.a.numcount == 0) {
                   2141:           st->u.a.isyn += 1;
                   2142:         }
                   2143:         *e = '\n';
                   2144:         return z-b;
                   2145:       case SYNTAX_LOOP:
                   2146:         v = strtol(a, &z, 0);
                   2147:         if (a == z) {
                   2148:           return -EINVAL;
                   2149:         }
                   2150: #ifdef DEBUG
                   2151:         fprintf(stderr, "loop: %ld, %d..%d\n", v, a-b, z-b);
                   2152: #endif
                   2153:         st->tab[st->u.a.itab++] = v;
                   2154:         if (v != 0) {
                   2155:           if (st->u.a.isdescr > 0) {
                   2156:             st->u.a.isdescr += 1;
                   2157:           }
                   2158:           for (i = LOOP_DEPTH-1; i >= 0; i--) {
                   2159:             st->u.a.loopbegin[i+1] = st->u.a.loopbegin[i];
                   2160:             st->u.a.loopcount[i+1] = st->u.a.loopcount[i];
                   2161:           }
                   2162:           st->u.a.loopbegin[0] = ++st->u.a.isyn;
                   2163:           st->u.a.loopcount[0] = v;
                   2164:         } else {
                   2165:           do {
                   2166:             st->u.a.isyn += 1;
                   2167:             s = syntax[(st->u.a.isdescr > 0) ? 1 : 0]
                   2168:                       [(st->u.a.isdescr > 0) ? st->u.a.descrtag : st->esi]
                   2169:                       [st->u.a.isyn];
                   2170:             if (s == SYNTAX_LOOP) {
                   2171:               v += 1;
                   2172:             }
                   2173:           } while ((s != SYNTAX_END) && ((s != SYNTAX_LOOPEND) || (--v >= 0)));
                   2174:           if (s == SYNTAX_LOOPEND) {
                   2175:             st->u.a.isyn += 1;
                   2176:           }
                   2177:         }
                   2178:         *e = '\n';
                   2179:         return z-b;
                   2180:       case SYNTAX_DESCR:
                   2181:         v = strtol(a, &z, 0);
                   2182:         if (a == z) {
                   2183:           return -EINVAL;
                   2184:         }
                   2185: #ifdef DEBUG
                   2186:         fprintf(stderr, "descr: %ld, %d..%d\n", v, a-b, z-b);
                   2187: #endif
                   2188:         st->tab[st->u.a.itab++] = v;
                   2189:         st->u.a.isyn += 1;
                   2190:         if (v != 0) {
                   2191:           st->u.a.isdescr = 1;
                   2192:           st->u.a.descrtag = 0;
                   2193:           for (i = LOOP_DEPTH-1; i >= 0; i--) {
                   2194:             st->u.a.loopbegin[i+1] = st->u.a.loopbegin[i];
                   2195:             st->u.a.loopcount[i+1] = st->u.a.loopcount[i];
                   2196:           }
                   2197:           st->u.a.loopbegin[0] = 0;
                   2198:           st->u.a.loopcount[0] = v;
                   2199:           st->u.a.isyntab = st->u.a.isyn;
                   2200:           st->u.a.isyn = 0;
                   2201:         }
                   2202:         *e = '\n';
                   2203:         return z-b;
                   2204:       case SYNTAX_DESCRTAG:
                   2205:         v = strtol(a, &z, 0);
                   2206:         if (a == z) {
                   2207:           return -EINVAL;
                   2208:         }
                   2209: #ifdef DEBUG
                   2210:         fprintf(stderr, "descrtag: %ld, %d..%d\n", v, a-b, z-b);
                   2211: #endif
                   2212:         st->tab[st->u.a.itab++] = v;
                   2213:         v -= DESCR_FIRST;
                   2214:         if ((v < 0) || (v > (DESCR_LAST - DESCR_FIRST))) {
                   2215:           return -EINVAL;
                   2216:         }
                   2217:         st->descrnum[v] += 1;
                   2218:         if (!((1 << st->esi) & possible_descr[v])) {
                   2219:           return -EINVAL;
                   2220:         }
                   2221:         st->u.a.descrtag = v;
                   2222:         st->u.a.isyn += 1;
                   2223:         *e = '\n';
                   2224:         return z-b;
                   2225:       case SYNTAX_DATETIME:
                   2226:         /* yyyy/mm/dd hh:mm:ss */
                   2227:         z = a;
                   2228:         i = e-z;
                   2229:         if (i < 19) {
                   2230:           return -EINVAL;
                   2231:         }
                   2232:         if (taballoc(st, 2)) {
                   2233:           return -ENOMEM;
                   2234:         }
                   2235:         if ((v = longval(&z, 4)) < 0) {
                   2236:           return v;
                   2237:         }
                   2238:         if ((v < 1582) || (*z++ != '/')) {
                   2239:           return -EINVAL;
                   2240:         }
                   2241:         if ((s = longval(&z, 2)) < 0) {
                   2242:           return s;
                   2243:         }
                   2244:         s -= 1;
                   2245:         if ((s < 0) || (s > 11) || (*z++ != '/')) {
                   2246:           return -EINVAL;
                   2247:         }
                   2248:         s -= 2;
                   2249:         if (s < 0) {
                   2250:           s += 12;
                   2251:           v -= 1;
                   2252:         }
                   2253:         v = (1461*v)/4 - ((v/100+1)*3)/4 + (153*s)/5;
                   2254:         if ((s = longval(&z, 2)) < 0) {
                   2255:           return s;
                   2256:         }
                   2257:         if ((s <= 0) || (s > 31)) {
                   2258:           return -EINVAL;
                   2259:         }
                   2260:         v += s - 678912;
                   2261:         st->tab[st->u.a.itab++] = v;
                   2262:         v = 0;
                   2263:         s = ' ';
                   2264:         for (i = 2; i >= 0; i--) {
                   2265:           if (*z++ != s) {
                   2266:             return -EINVAL;
                   2267:           }
                   2268:           s = *z++;
                   2269:           if (!isdigit(s)) {
                   2270:             return -EINVAL;
                   2271:           }
                   2272:           v = (v<<4) + (s-'0');
                   2273:           s = *z++;
                   2274:           if (!isdigit(s)) {
                   2275:             return -EINVAL;
                   2276:           }
                   2277:           v = (v<<4) + (s-'0');
                   2278:           s = ':';
                   2279:         }
                   2280:         st->tab[st->u.a.itab++] = v;
                   2281: #ifdef DEBUG
                   2282:         fprintf(stderr, "datetime: %04lx %06lx, %d..%d\n",
                   2283:                 st->tab[st->u.a.itab-2], v, a-b, z-b);
                   2284: #endif
                   2285:         st->u.a.isyn += 1;
                   2286:         *e = '\n';
                   2287:         return z-b;
                   2288:       case SYNTAX_STRING:
                   2289:         if (*a++ != '"') {
                   2290:           return -EINVAL;
                   2291:         }
                   2292:         v = 0;
                   2293:         z = strchr(a, '"');
                   2294:         if (z == NULL) {
                   2295:           return -EINVAL;
                   2296:         }
                   2297:         i = v;
                   2298:         v += z-a;
                   2299:         taballoc(st, 1 + (v + sizeof(long) - 1) / sizeof(long));
                   2300:         memcpy(((char *)&st->tab[st->u.a.itab+1]) + i, a, z-a);
                   2301:         z += 1;
                   2302:         while (*z == '"') {
                   2303:           a = z;
                   2304:           z = strchr(a+1, '"');
                   2305:           if (z == NULL) {
                   2306:             return -EINVAL;
                   2307:           }
                   2308:           i = v;
                   2309:           v += z-a;
                   2310:           taballoc(st, 1 + (v + sizeof(long) - 1) / sizeof(long));
                   2311:           memcpy(((char *)&st->tab[st->u.a.itab+1]) + i, a, z-a);
                   2312:           z += 1;
                   2313:         }
                   2314:         st->tab[st->u.a.itab] = v;
                   2315: #ifdef DEBUG
                   2316:         fprintf(stderr, "string: %ld, %d..%d\n", v, a-b, z-b);
                   2317: #endif
                   2318:         st->u.a.itab += 1 + (v + sizeof(long) - 1) / sizeof(long);
                   2319:         st->u.a.isyn += 1;
                   2320:         *e = '\n';
                   2321:         return z-b;
                   2322:     }
                   2323:   } else {
                   2324:     return e-b+1;
                   2325:   }
                   2326: }
                   2327: 
                   2328: static unsigned int tab2ts(unsigned char *t, unsigned char *conticnt)
                   2329: {
                   2330:   unsigned int l, d;
                   2331:   unsigned char *i = &t[2];
                   2332:   unsigned char *o;
                   2333:   unsigned char c = *conticnt;
1.4     ! oskar    2334:   l = ((t[3] & 0x0F) << 8) + t[4] + TS_HEADSLEN + TS_PFIELDLEN;
1.1       oskar    2335:   d = (l-1) % (TS_PACKET_SIZE - TS_PACKET_HEADSIZE) + 1;
                   2336:   if (outin >= OUTBUF_SIZE) {
                   2337:     outin = 0;
                   2338:   }
                   2339:   o = &outbuf[outin];
                   2340:   if (d <= (TS_PACKET_SIZE - TS_PACKET_HEADSIZE - 1)) {
                   2341:     if (d < (TS_PACKET_SIZE - TS_PACKET_HEADSIZE - 1)) {
                   2342:       o[5] = 0; /* no indicators, no flags, padding: */
                   2343:       memset(&o[6], -1, TS_PACKET_SIZE - TS_PACKET_HEADSIZE - 2 - d);
                   2344:     }
                   2345:     o[4] = TS_PACKET_SIZE - TS_PACKET_HEADSIZE - 1 - d;
                   2346:     o[3] = (0x00 << 6) | (0x03 << 4) | c;
                   2347:   } else {
                   2348:     o[3] = (0x00 << 6) | (0x01 << 4) | c;
                   2349:   }
1.4     ! oskar    2350:   o[TS_PACKET_SIZE - d] = 0; /* pointer_field */
        !          2351:   d -= TS_PFIELDLEN;
1.1       oskar    2352:   memcpy(&o[TS_PACKET_SIZE - d], i, d);
                   2353:   i += d;
1.4     ! oskar    2354:   d = l - d - TS_PFIELDLEN;
1.1       oskar    2355:   o[1] = (0 << 7) | (1 << 6) | (0 << 5) | t[0];
                   2356:   o[2] = t[1];
                   2357:   o[0] = TS_SYNC_BYTE;
                   2358:   c = (c + 1) & 0x0F;
                   2359:   outin += TS_PACKET_SIZE;
                   2360:   while (d > 0) {
                   2361:     if (outin >= OUTBUF_SIZE) {
                   2362:       outin = 0;
                   2363:     }
                   2364:     o = &outbuf[outin];
                   2365:     o[3] = (0x00 << 6) | (0x01 << 4) | c;
                   2366:     memcpy(&o[4], i, TS_PACKET_SIZE-TS_PACKET_HEADSIZE);
                   2367:     i += (TS_PACKET_SIZE - TS_PACKET_HEADSIZE);
                   2368:     d -= (TS_PACKET_SIZE - TS_PACKET_HEADSIZE);
                   2369:     o[1] = (0 << 7) | (0 << 6) | (0 << 5) | t[0];
                   2370:     o[2] = t[1];
                   2371:     o[0] = TS_SYNC_BYTE;
                   2372:     c = (c + 1) & 0x0F;
                   2373:     outin += TS_PACKET_SIZE;
                   2374:   }
                   2375:   *conticnt = c;
                   2376:   return l+2;
                   2377: }
                   2378: 
                   2379: static void argloop(int f0)
                   2380: {
                   2381:   int i0 = 0;
                   2382:   char buf0[PATH_MAX];
                   2383:   do {
                   2384:     int i, n, r, n0, n1, nst, tmo;
                   2385:     struct timeval tv;
                   2386:     struct sitab *st;
                   2387:     struct sitab **pst;
                   2388:     pollfd_init();
                   2389:     if (f0 >= 0) {
                   2390:       n0 = pollfd_add(f0, POLLIN);
                   2391:     } else {
                   2392:       n0 = -1;
                   2393:     }
                   2394:     if (newtab != NULL) {
                   2395:       st = newtab;
                   2396:       nst = pollfd_add(st->u.a.fd, POLLIN);
                   2397:       while ((st = st->next) != NULL) {
                   2398:         pollfd_add(st->u.a.fd, POLLIN);
                   2399:       }
                   2400:     } else {
                   2401:       nst = -1;
                   2402:     }
                   2403:     tmo = -1;
                   2404:     if (outin == 0) {
                   2405:       r = OUTBUF_SIZE;
                   2406:       n1 = -1;
                   2407:     } else {
                   2408:       r = outout - outin;
                   2409:       if (r < 0) {
                   2410:         r += OUTBUF_SIZE;
                   2411:       }
                   2412:       n1 = pollfd_add(STDOUT_FILENO, POLLOUT);
                   2413:     }
                   2414:     for (i = 0; i <= TABLE_PID_LAST-TABLE_PID_FIRST; i++) {
                   2415:       if ((tabin[i] > tabout[i])
                   2416:        && (r >= (((((tabbuf[i][tabout[i]+3] & 0x0F) << 8)
1.4     ! oskar    2417:                  + tabbuf[i][tabout[i]+4] + TS_HEADSLEN + TS_PFIELDLEN
1.1       oskar    2418:                  + TS_PACKET_SIZE - TS_PACKET_HEADSIZE)
                   2419:                 * 131) / 128))) {
                   2420:         tmo = 0;
                   2421:         break;
                   2422:       }
                   2423:     }
                   2424:     gettimeofday(&tv, NULL);
                   2425:     st = runtab;
                   2426:     while (st != NULL) {
                   2427:       i = st->pid - TABLE_PID_FIRST;
                   2428:       if ((i < 0) || (i >= (TABLE_PID_LAST-TABLE_PID_FIRST))) {
                   2429:         fprintf(stderr, "internal error (pid)\n");
                   2430:         exit(1);
                   2431:       }
                   2432:       tabinold[i] = tabin[i];
                   2433:       if (tmo != 0) {
                   2434:         if (tabin[i] == 0) {
                   2435:           i = (st->u.s.next.tv_sec - tv.tv_sec) * 1000
                   2436:             + (st->u.s.next.tv_usec - tv.tv_usec) / 1000;
                   2437:           if (i <= 0) {
                   2438:             tmo = 0;
                   2439:           } else if ((tmo < 0) || (i < tmo)) {
                   2440:             tmo = i;
                   2441:           }
                   2442:         }
                   2443:       }
                   2444:       st = st->next;
                   2445:     }
                   2446:     n = pollfd_poll(tmo);
                   2447:     gettimeofday(&tv, NULL);
                   2448:     for (i = 0; i <= TABLE_PID_LAST-TABLE_PID_FIRST; i++) {
                   2449:       while ((tabin[i] > tabout[i])
                   2450:           && (r >= (((((tabbuf[i][tabout[i]+3] & 0x0F) << 8)
1.4     ! oskar    2451:                     + tabbuf[i][tabout[i]+4] + TS_HEADSLEN + TS_PFIELDLEN
1.1       oskar    2452:                     + TS_PACKET_SIZE - TS_PACKET_HEADSIZE)
                   2453:                  * 131) / 128))) {
                   2454:         tabout[i] += tab2ts(&tabbuf[i][tabout[i]], &conticnt[i]);
                   2455:         r = outout - outin;
                   2456:         if (r < 0) {
                   2457:           r += OUTBUF_SIZE;
                   2458:         }
                   2459:       }
                   2460:       if (tabin[i] <= tabout[i]) {
                   2461:         tabin[i] = tabout[i] = 0;
                   2462:       }
                   2463:     }
                   2464:     if ((n > 0) && (n1 >= 0) && (r = pollfd_rev(n1))) {
                   2465:       if (r & (POLLNVAL | POLLERR)) {
                   2466:         fprintf(stderr, "poll error: %x\n", r);
                   2467:         return;
                   2468:       }
                   2469:       if (outout >= OUTBUF_SIZE) {
                   2470:         outout = 0;
                   2471:       }
                   2472:       r = ((outin > outout) ? outin : OUTBUF_SIZE) - outout;
                   2473:       r = write(STDOUT_FILENO, &outbuf[outout], r);
                   2474:       if (r < 0) {
                   2475:         fprintf(stderr, "write error(%d)\n", errno);
                   2476:         return;
                   2477:       }
                   2478:       if (r == 0) {
                   2479:         exit(0);
                   2480:       }
                   2481:       outout += r;
                   2482:       if (outout == outin) {
                   2483:         outin = outout = 0;
                   2484:       }
                   2485:     }
                   2486:     pst = &runtab;
                   2487:     while ((st = *pst) != NULL) {
                   2488:       i = st->pid - TABLE_PID_FIRST;
                   2489:       if ((tabinold[i] == 0)
                   2490:        && (tabin[i] < (TABBUF_SIZE-MAX_PSI_SIZE+1-2))
                   2491:        && ((st->u.s.next.tv_sec < tv.tv_sec)
                   2492:         || ((st->u.s.next.tv_sec == tv.tv_sec)
                   2493:          && (st->u.s.next.tv_usec <= tv.tv_usec)))) {
                   2494:         if (st->freqmsec > 0) {
                   2495:           i = (st->u.s.next.tv_sec - tv.tv_sec) * 1000
                   2496:             + (st->u.s.next.tv_usec - tv.tv_usec) / 1000;
                   2497:           if (i < -st->freqmsec) {
                   2498:             st->u.s.next = tv;
                   2499:           } else {
                   2500:             st->u.s.next.tv_sec += st->freqmsec / 1000;
                   2501:             st->u.s.next.tv_usec += (st->freqmsec % 1000) * 1000;
                   2502:             if (st->u.s.next.tv_usec > 1000000) {
                   2503:               st->u.s.next.tv_usec -= 1000000;
                   2504:               st->u.s.next.tv_sec += 1;
                   2505:             }
                   2506:           }
                   2507:         }
                   2508: #ifdef DEBUG
                   2509:         fprintf(stderr, "do tab: %ld.%06ld: %ld, %u\n", tv.tv_sec, tv.tv_usec,
                   2510:                 st->pid, st->tableid);
                   2511: #endif
                   2512:         gentab(st, &tv);
                   2513:         if (st->freqmsec <= 0) {
                   2514:           *pst = st->next;
                   2515:           nextversion[st->tableid - TABLEID_FIRST] = (st->version + 1) & 0x1F;
                   2516:           free(st->tab);
                   2517:           free(st);
                   2518:         } else {
                   2519:           pst = &st->next;
                   2520:         }
                   2521:       } else {
                   2522:         pst = &st->next;
                   2523:       }
                   2524:     }
                   2525:     if ((n > 0) && (nst >= 0)) {
                   2526:       pst = &newtab;
                   2527:       do {
                   2528:         st = *pst;
                   2529:         if ((r = pollfd_rev(nst))) {
                   2530:           if (r & (POLLNVAL | POLLERR)) {
                   2531:             fprintf(stderr, "poll error: %x\n", r);
                   2532:             *pst = st->next;
                   2533:             close(st->u.a.fd);
                   2534:             free(st->tab);
                   2535:             free(st);
                   2536:           } else {
                   2537:             i = st->u.a.ibuf;
                   2538:             r = read(st->u.a.fd, &st->u.a.buf[i], sizeof(st->u.a.buf) - i - 1);
                   2539:             if (r <= 0) {
                   2540:               fprintf(stderr, "read error(%d): %d\n", errno, st->u.a.fd);
                   2541:               *pst = st->next;
                   2542:               close(st->u.a.fd);
                   2543:               free(st->tab);
                   2544:               free(st);
                   2545:             } else {
                   2546:               int j = 0;
                   2547:               i += r;
                   2548:               while ((r = siline(st, &st->u.a.buf[j], i)) >= 0) {
                   2549:                 j += r;
                   2550:                 i -= r;
                   2551:               }
                   2552:               switch (r) {
                   2553:               case -ENOBUFS:
                   2554:                 *pst = st->next;
                   2555:                 close(st->u.a.fd);
                   2556: #ifdef DEBUG
                   2557:                 fprintf(stderr, "done, itab=%d\n", st->u.a.itab);
                   2558:                 for (i = 0; i < st->u.a.itab; i++) {
                   2559:                   fprintf(stderr, "%lu,", st->tab[i]);
                   2560:                 }
                   2561:                 fprintf(stderr, "\n");
                   2562: #endif
                   2563:                 i = st->pid - TABLE_PID_FIRST;
                   2564:                 if ((tabbuf[i] == NULL)
                   2565:                  && ((tabbuf[i] = malloc(TABBUF_SIZE)) == NULL)) {
                   2566:                   fprintf(stderr, "malloc failed for table buffer pid=%02lx\n",
                   2567:                         st->pid);
                   2568:                   free(st->tab);
                   2569:                   free(st);
                   2570:                 }
                   2571:                 st->next = runtab;
                   2572:                 runtab = st;
                   2573:                 st->u.s.next = tv;
                   2574:                 break;
                   2575:               case -EAGAIN:
                   2576:                 if (i > 0) {
                   2577:                   memmove(&st->u.a.buf[0], &st->u.a.buf[j], i);
                   2578:                 }
                   2579:                 st->u.a.ibuf = i;
                   2580:                 pst = &st->next;
                   2581:                 break;
                   2582:               default:
                   2583:                 fprintf(stderr, "eval error: %d\n", r);
                   2584:                 *pst = st->next;
                   2585:                 close(st->u.a.fd);
                   2586:                 free(st->tab);
                   2587:                 free(st);
                   2588:                 break;
                   2589:               }
                   2590:             }
                   2591:           }
                   2592:           n -= 1;
                   2593:         } else {
                   2594:           pst = &st->next;
                   2595:         }
                   2596:         nst += 1;
                   2597:       } while ((*pst != NULL) && (n > 0));
                   2598:     }
                   2599:     if ((n > 0) && (n0 >= 0) && (r = pollfd_rev(n0))) {
                   2600:       if (r & (POLLNVAL | POLLERR)) {
                   2601:         fprintf(stderr, "poll error: %x\n", r);
                   2602:         return;
                   2603:       }
                   2604:       r = read(f0, &buf0[i0], sizeof(buf0) - i0 - 1);
                   2605:       if (r < 0) {
                   2606:         fprintf(stderr, "read error(%d): %d\n", errno, f0);
                   2607:         return;
                   2608:       }
                   2609:       if (r == 0) {
                   2610:         return;
                   2611:       }
                   2612:       i0 += r;
                   2613:       if (i0 == sizeof(buf0)-1) {
                   2614:         buf0[sizeof(buf0)-1] = '\n';
                   2615:         i0 += 1;
                   2616:       }
                   2617:       i = 0;
                   2618:       while ((r = tabline(&buf0[i], i0))) {
                   2619:         i += r;
                   2620:         i0 -= r;
                   2621:       }
                   2622:       if (i0 > 0) {
                   2623:         memmove(&buf0[0], &buf0[i], i0);
                   2624:       }
                   2625:       n -= 1;
                   2626:     }
                   2627:   } while (1);
                   2628: }
                   2629: 
                   2630: int main(int argc, char *argv[])
                   2631: {
                   2632:   int f = -1;
                   2633:   int a;
                   2634:   if (sizeof(unsigned) != sizeof(struct loop_descr *)) {
                   2635:     fprintf(stderr, "data type prerequisites not met\n");
                   2636:     return 1;
                   2637:   }
                   2638:   gen_crc32_table();
                   2639:   system_init();
                   2640:   unblockf(STDIN_FILENO);
                   2641:   unblockf(STDOUT_FILENO);
                   2642:   memset(&tabin[0], 0, sizeof(tabin));
                   2643:   memset(&tabout[0], 0, sizeof(tabout));
                   2644:   memset(&conticnt[0], 0, sizeof(conticnt));
                   2645:   memset(&nextversion[0], 0, sizeof(nextversion));
                   2646:   for (a = TABLE_PID_LAST-TABLE_PID_FIRST; a >= 0; a--) {
                   2647:     tabbuf[a] = NULL;
                   2648:   }
                   2649:   a = 1;
                   2650:   do {
                   2651:     if ((a < argc) && (strcmp(argv[a], "-"))) {
                   2652:       f = open(argv[a], O_RDONLY | O_NONBLOCK);
                   2653:       if (f < 0) {
                   2654:         fprintf(stderr, "open failed(%d): %s\n", errno, argv[a]);
                   2655:       }
                   2656:     } else {
                   2657:       f = STDIN_FILENO;
                   2658:     }
                   2659:     argloop(f);
                   2660:   } while (++a < argc);
                   2661:   argloop(-1);
                   2662:   return 0;
                   2663: }

LinuxTV legacy CVS <linuxtv.org/cvs>