Annotation of multiplexer/en300468ts.c, revision 1.1

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

LinuxTV legacy CVS <linuxtv.org/cvs>