1 /*
2 * FECFG145.H
3 *
4 * 'C' Structures of FastEcho 1.45 (also work for 1.46)
5 * Copyright (c) 1995 by Tobias Burchhardt. Last update: 30 Jun 1995.
6 * Modified by Aleksandar Ivanisevic 30 Oct 1996.
7 * Minor alterations by Andrew Clarke 22 Dec 1996.
8 * Modfications by Tobias Ernst 04 Oct 1998
9 */
10
11 #ifndef __FECFG145_H__
12 #define __FECFG145_H__
13
14 /*
15 We don't set pragma pack anymore. The result is that the structures below
16 are probably larger than their pendants in the binary file. You need to write
17 portable reader functions for reading them from file. For those structures
18 that are used by MsgEd, such reader functions can be found in fecfg145.c.
19
20 #if defined(PACIFIC) || defined(MSC) || defined(__EMX__) || defined(__IBMC__) || defined(__HIGHC__) || defined(UNIX) || defined(__DJGPP__)
21 #pragma pack(1)
22 #endif
23
24 */
25
26 /********************************************************
27 * FASTECHO.CFG = <CONFIG> *
28 * + <optional extensions> *
29 * + <CONFIG.NodeCnt * Node> *
30 * + <CONFIG.AreaCnt * Area> *
31 ********************************************************/
32
33 #define REVISION 6 /* current revision */
34
35 /*
36 * Note: there is a major change in this revision - the Node records
37 * have no longer a fixed length!
38 */
39
40 #define MAX_AREAS 3072 /* max # of areas */
41 #define MAX_NODES 1024 /* max # of nodes */
42 #define MAX_GROUPS 26 /* max # of groups */
43 #define MAX_AKAS 32 /* max # of akas */
44 #define MAX_ROUTE 15 /* max # of 'vias' */
45 #define MAX_ORIGINS 20 /* max # of origins */
46
47 /*
48 * Note: The MAX_AREAS and MAX_NODES are only the absolute maximums as the
49 * handling is flexible. To get the maximums which are used for the config
50 * file you read, you have to examine the CONFIG.MaxAreas and
51 * CONFIG.MaxNodes variables!
52 *
53 * Note: The MAX_AREAS and MAX_NODES maximums are subject to change with
54 * any new version, therefore - if possible - make handling as flexible as
55 * possible and use CONFIG.MaxAreas and .MaxNodes whereever possible. But
56 * be aware that you might (under normal DOS and depending on the way you
57 * handle it) hit the 64kB segment limit pretty quickly!
58 *
59 * Same goes for the # of AKAs and Groups - use the values found in
60 * CONFIG.AkaCnt and CONFIG.GroupCnt!
61 */
62
63 /********************************************************
64 * CONFIG.flags *
65 ********************************************************/
66
67 #define RETEAR 0x00000001l
68 #define AUTOCREATE 0x00000002l
69 #define KILLEMPTY 0x00000004l
70 #define KILLDUPES 0x00000008l
71 #define CLEANTEARLINE 0x00001000l
72 #define IMPORT_INCLUDEUSERSBBS 0x00002000l
73 #define KILLSTRAYATTACHES 0x00004000l
74 #define PURGE_PROCESSDATE 0x00008000l
75 #define MAILER_RESCAN 0x00010000l
76 #define EXCLUDE_USERS 0x00020000l
77 #define EXCLUDE_SYSOPS 0x00040000l
78 #define CHECK_DESTINATION 0x00080000l
79 #define UPDATE_BBS_CONFIG 0x00100000l
80 #define KILL_GRUNGED_DATE 0x00200000l
81 #define NOT_BUFFER_EMS 0x00400000l
82 #define KEEP_NETMAILS 0x00800000l
83 #define NOT_UPDATE_MAILER 0x01000000l
84 #define NOT_CHECK_SEMAPHORES 0x02000000l
85 #define CREATE_SEMAPHORES 0x04000000l
86 #define CHECK_COMPLETE 0x08000000l
87 #define RESPOND_TO_RRQ 0x10000000l
88 #define TEMP_OUTB_HARDDISK 0x20000000l
89 #define FORWARD_PACKETS 0x40000000l
90 #define UNPACK_UNPROTECTED 0x80000000l
91
92 /********************************************************
93 * CONFIG.mailer *
94 ********************************************************/
95
96 #define FrontDoor 0x0001
97 #define InterMail 0x0002
98 #define DBridge 0x0004
99 #define Binkley 0x0010
100 #define PortalOfPower 0x0020
101 #define McMail 0x0040
102
103 /********************************************************
104 * CONFIG.BBSSoftware *
105 ********************************************************/
106
107 enum BBSSoft
108 {
109 NoBBSSoft = 0,
110 RemoteAccess111,
111 QuickBBS,
112 SuperBBS,
113 ProBoard122 /* Unused */,
114 TagBBS,
115 RemoteAccess200,
116 ProBoard130 /* Unused */,
117 ProBoard200,
118 ProBoard202,
119 Maximus202,
120 Maximus300
121 };
122
123 /********************************************************
124 * CONFIG.CC.what *
125 ********************************************************/
126
127 #define CC_FROM 1
128 #define CC_TO 2
129 #define CC_SUBJECT 3
130 #define CC_KLUDGE 4
131
132 /********************************************************
133 * CONFIG.QuietLevel *
134 ********************************************************/
135
136 #define QUIET_PACK 0x0001
137 #define QUIET_UNPACK 0x0002
138 #define QUIET_EXTERN 0x0004
139
140 /********************************************************
141 * CONFIG.Swapping *
142 ********************************************************/
143
144 #define SWAP_TO_XMS 0x0001
145 #define SWAP_TO_EMS 0x0002
146 #define SWAP_TO_DISK 0x0004
147
148 /********************************************************
149 * CONFIG.Buffers *
150 ********************************************************/
151
152 #define BUF_LARGE 0x0000
153 #define BUF_MEDIUM 0x0001
154 #define BUF_SMALL 0x0002
155
156 /********************************************************
157 * CONFIG.arcext.inb/outb *
158 ********************************************************/
159
160 enum ARCmailExt
161 {
162 ARCDigits = 0, ARCHex, ARCAlpha
163 };
164
165 /********************************************************
166 * CONFIG.AreaFixFlags *
167 ********************************************************/
168
169 #define ALLOWRESCAN 0x0001
170 #define KEEPREQUEST 0x0002
171 #define KEEPRECEIPT 0x0004
172 #define ALLOWREMOTE 0x0008
173 #define DETAILEDLIST 0x0010
174 #define ALLOWPASSWORD 0x0020
175 #define ALLOWPKTPWD 0x0040
176 #define ALLOWCOMPRESS 0x0080
177 #define SCANBEFORE 0x0100
178 #define ADDRECEIPTLIST 0x0200
179 #define NOTIFYPASSWORDS 0x0400
180
181 /********************************************************
182 * Area.board (1-200 = Hudson) *
183 ********************************************************/
184
185 #define NO_BOARD 0x4000u /* JAM/Sq/Passthru etc. */
186 #define AREA_DELETED 0x8000u /* usually never written */
187
188 /********************************************************
189 * Area.flags.storage *
190 ********************************************************/
191
192 #define FE_QBBS 0
193 #define FE_FIDO 1 /* to avoid confusion with Msged's defs */
194 #define FE_SQUISH 2
195 #define FE_JAM 3
196 #define FE_PASSTHRU 7
197
198 /********************************************************
199 * Area.flags.atype *
200 ********************************************************/
201
202 #define AREA_ECHOMAIL 0
203 #define AREA_NETMAIL 1
204 #define AREA_LOCAL 2
205 #define AREA_BADMAILBOARD 3
206 #define AREA_DUPEBOARD 4
207
208 /********************************************************
209 * Types and other definitions *
210 ********************************************************/
211
212 enum ARCers
213 {
214 ARC_Unknown = -1, ARC_SeaArc, ARC_PkArc, ARC_Pak,
215 ARC_ArcPlus, ARC_Zoo, ARC_PkZip, ARC_Lha, ARC_Arj,
216 ARC_Sqz, ARC_RAR, ARC_UC2
217 }; /* for Unpackers */
218
219 enum NetmailStatus
220 {
221 NetNormal = 0, NetHold, NetCrash /* , NetImm */
222 };
223
224 enum AreaFixType
225 {
226 NoAreaFix = 0, NormalAreaFix, FSC57AreaFix
227 };
228 enum AreaFixSendTo
229 {
230 AreaFix = 0, AreaMgr, AreaLink, EchoMgr
231 };
232
233 /********************************************************
234 * Structures *
235 ********************************************************/
236
237 typedef struct
238 {
239 unsigned short zone, net, node, point;
240 }
241 FEAddress;
242 #define FE_ADDRESS_SIZE 8
243
244 #define _MAXPATH 56
245
246 typedef struct CONFIGURATION
247 {
248 unsigned short revision;
249 unsigned long flags;
250 unsigned short NodeCnt, AreaCnt, unused1;
251 char NetMPath[_MAXPATH];
252 char MsgBase[_MAXPATH];
253 char InBound[_MAXPATH];
254 char OutBound[_MAXPATH];
255 char Unpacker[_MAXPATH]; /* DOS default decompression program */
256 char LogFile[_MAXPATH];
257 char unused2[336];
258 char Unpacker2[_MAXPATH]; /* OS/2 default decompression program */
259 char UnprotInBound[_MAXPATH];
260 char StatFile[_MAXPATH];
261 char SwapPath[_MAXPATH];
262 char SemaphorePath[_MAXPATH];
263 char BBSConfigPath[_MAXPATH];
264 char DBQueuePath[_MAXPATH];
265 char unused3[32];
266 char RetearTo[40];
267 char LocalInBound[_MAXPATH];
268 char ExtAfter[_MAXPATH - 4];
269 char ExtBefore[_MAXPATH - 4];
270 unsigned char unused4[480];
271 struct
272 {
273 unsigned char what;
274 char object[31];
275 unsigned short conference;
276 }
277 CC[10];
278 unsigned char security, loglevel;
279 unsigned short def_days, def_messages;
280 unsigned char unused5[462];
281 unsigned short autorenum;
282 unsigned short def_recvdays;
283 unsigned char openQQQs, Swapping;
284 unsigned short compressafter;
285 unsigned short afixmaxmsglen;
286 unsigned short compressfree;
287 char TempPath[_MAXPATH];
288 unsigned char graphics, BBSSoftware;
289 char AreaFixHelp[_MAXPATH];
290 unsigned char unused6[504];
291 unsigned short AreaFixFlags;
292 unsigned char QuietLevel, Buffers;
293 unsigned char FWACnt; /* # of ForwardAreaFix records */
294 unsigned char GDCnt; /* # of Group Default records */
295 struct
296 {
297 unsigned short flags;
298 unsigned short days[2];
299 unsigned short msgs[2];
300 }
301 rescan_def;
302 unsigned long duperecords;
303 struct
304 {
305 unsigned char inb;
306 unsigned char outb;
307 }
308 arcext;
309 unsigned short AFixRcptLen;
310 unsigned char AkaCnt, resv; /* # of Aka records stored */
311 unsigned short maxPKT;
312 unsigned char sharing, sorting;
313 struct
314 {
315 char name[36];
316 unsigned long resv;
317 }
318 sysops[11];
319 char AreaFixLog[_MAXPATH];
320 char TempInBound[_MAXPATH];
321 unsigned short maxPKTmsgs;
322 unsigned short RouteCnt; /* # of PackRoute records */
323 unsigned char maxPACKratio;
324 unsigned char SemaphoreTimer;
325 unsigned char PackerCnt, UnpackerCnt; /* # of Packer + Unpacker records */
326 unsigned char GroupCnt, OriginCnt; /* # of GroupName + Origin records */
327 unsigned short mailer;
328 unsigned short maxarcsize, maxarcdays;
329 char reserved[806];
330
331 unsigned short AreaRecSize, GrpDefRecSize;
332 /*
333 * Size of Area and GroupDefaults
334 * records stored in this file
335 */
336
337 unsigned short MaxAreas, MaxNodes; /* Current max values for this config */
338 unsigned short NodeRecSize; /* Size of each stored Node record */
339
340 unsigned long offset; /*
341 * This is the offset from the current
342 * file-pointer to the 1st Node
343 */
344 }
345 CONFIG;
346 #define FE_CONFIG_SIZE 4644
347
348 /*
349 * To directly access the 'Nodes' and/or 'Areas' while bypassing the
350 * Extensions, perform an absolute (from beginning of file) seek to
351 * sizeof(CONFIG) + CONFIG.offset.
352 *
353 * If you want to access the 'Areas', you have to add the following value
354 * to the above formula: CONFIG.NodeCnt * CONFIG.NodeRecSize.
355 */
356
357 typedef struct
358 {
359 FEAddress addr; /* Main address */
360 FEAddress arcdest; /* ARCmail fileattach address */
361 unsigned char aka, autopassive, newgroup, resv1;
362 struct
363 {
364 unsigned short flags1;
365 /*
366 unsigned passive : 1;
367 unsigned dddd : 1; Type 2+/4D
368 unsigned arcmail060 : 1;
369 unsigned tosscan : 1;
370 unsigned umlautnet : 1;
371 unsigned exportbyname : 1;
372 unsigned allowareacreate : 1;
373 unsigned disablerescan : 1;
374 unsigned arc_status : 2; NetmailStatus for ARCmail attaches
375 unsigned arc_direct : 1; Direct flag for ARCmail attaches
376 unsigned noattach : 1; don't create a ARCmail file attach
377 unsigned mgr_status : 2; NetMailStatus for AreaFix receipts
378 unsigned mgr_direct : 1; Direct flag for ...
379 unsigned not_help : 1;
380 unsigned not_notify : 1;
381 unsigned packer : 4;
382 unsigned packpriority : 1;
383 unsigned resv : 2;
384 */
385 unsigned char flags2;
386 }
387 flags; /* 24 bits total! */
388 struct
389 {
390 /*
391 unsigned type : 2; Type of AreaFix: None (human),
392 Normal or Advanced (FSC-57)
393 unsigned noforward : 1; Don't forward AFix requests
394 unsigned allowremote : 1;
395 unsigned allowdelete : 1; flags for different FSC-57 requests
396 unsigned allowrename : 1; all 3 reserved for future use
397 unsigned binarylist : 1;
398 unsigned addplus : 1; add '+' when requesting new area
399 unsigned addtear : 1; add tearline to the end of requests
400 unsigned sendto : 3; name of this systems's AreaFix robot
401 unsigned resv : 4;
402 */
403 unsigned short afixflags;
404 }
405 afixflags;
406 unsigned short resv2;
407 char password[9]; /* .PKT password */
408 char areafixpw[9]; /* AreaFix password */
409 unsigned short sec_level;
410 unsigned long groups; /* Bit-field, UCHAR 0/Bit 7 = 'A' etc. */
411 /* FALSE means group is active */
412 unsigned long resv3;
413 unsigned short resv4;
414 unsigned short maxarcsize;
415 char name[36]; /* Name of sysop */
416 unsigned char areas[1]; /*
417 * Bit-field with CONFIG.MaxAreas / 8
418 * bits, Unsigned Char 0/Bit 7 is conference #0
419 */
420 }
421 Node; /*
422 * Total size of each record is stored in
423 * CONFIG.NodeRecSize.
424 */
425 #define FE_NODE_SIZE (80 + (2 * FE_ADDRESS_SIZE))
426
427
428 typedef struct
429 {
430 char name[52];
431 unsigned short board; /* 1-200 Hudson, others reserved/special */
432 unsigned short conference; /* 0 ... CONFIG.MaxAreas-1 */
433 unsigned short read_sec, write_sec;
434 struct
435 {
436 unsigned aka : 8; /* 0 ... CONFIG.AkaCnt */
437 unsigned group : 8; /* 0 ... CONFIG.GroupCnt */
438 }
439 info;
440 struct
441 {
442 unsigned storage: 4;
443 unsigned atype : 4;
444 unsigned origin : 5; /* # of origin line */
445 unsigned resv : 3;
446 }
447 flags;
448 struct
449 {
450 unsigned autoadded : 1;
451 unsigned tinyseen : 1;
452 unsigned cpd : 1;
453 unsigned passive : 1;
454 unsigned keepseen : 1;
455 unsigned mandatory : 1;
456 unsigned keepsysop : 1;
457 unsigned killread : 1;
458 unsigned disablepsv : 1;
459 unsigned keepmails : 1;
460 unsigned hide : 1;
461 unsigned nomanual : 1;
462 unsigned umlaut : 1;
463 unsigned resv : 3;
464 }
465 advflags;
466 unsigned short resv1;
467 unsigned long seenbys; /* LSB = Aka0, MSB = Aka31 */
468 unsigned long resv2;
469 short days;
470 short messages;
471 short recvdays;
472 char path[_MAXPATH];
473 char desc[52];
474 }
475 Area;
476
477 #define FE_AREA_SIZE 190
478
479 /********************************************************
480 * Optional Extensions *
481 ********************************************************
482 *
483 * These are the variable length extensions between CONFIG and the first
484 * Node record. Each extension has a header which contains the info about
485 * the type and the length of the extension. You can read the fields using
486 * the following algorithm:
487 *
488 * offset = 0;
489 * while (offset < CONFIG.offset)
490 * {
491 * read_header();
492 * if (header.type == EH_abc)
493 * {
494 * read_and_process_data();
495 * }
496 * else if (header.type == EH_xyz)
497 * {
498 * read_and_process_data();
499 * }
500 * else if (header.type == ...)
501 * {
502 * ...
503 * }
504 * else
505 * {
506 * // unknown or unwanted extension found
507 * }
508 * seek_forward(header.offset); // Seek to next header
509 * offset += header.offset + sizeof(header);
510 * }
511 *
512 */
513
514 typedef struct
515 {
516 unsigned short type; /* EH_... */
517 unsigned long offset; /* length of field excluding header */
518 }
519 ExtensionHeader;
520 #define FE_EXTHEADER_SIZE 6
521
522 #define EH_AREAFIX 0x0001 /* CONFIG.FWACnt * <ForwardAreaFix> */
523
524 enum AreaFixAreaListFormat
525 {
526 Areas_BBS = 0, Area_List
527 };
528
529 typedef struct
530 {
531 unsigned short nodenr;
532 struct
533 {
534 /*
535 unsigned newgroup : 8;
536 unsigned active : 1;
537 unsigned valid : 1;
538 unsigned uncond : 1;
539 unsigned format : 3;
540 unsigned resv : 2;
541 */
542 unsigned short flags;
543 }
544 flags;
545 char file[_MAXPATH];
546 unsigned short sec_level;
547 unsigned short resv1;
548 unsigned long groups;
549 char resv2[4];
550 }
551 ForwardAreaFix;
552
553 #define EH_GROUPS 0x000C /* CONFIG.GroupCnt * <GroupNames> */
554
555 typedef struct
556 {
557 char name[36];
558 }
559 GroupNames;
560 #define FE_GROUPNAMES_LEN 36
561
562 #define EH_GRPDEFAULTS 0x0006 /* CONFIG.GDCnt * <GroupDefaults> */
563
564 /* Size of each full GroupDefault record is CONFIG.GrpDefResSize */
565
566 typedef struct
567 {
568 unsigned char group;
569 unsigned char resv[15];
570 Area area;
571 unsigned char nodes[1]; /* variable, c.MaxNodes / 8 bytes */
572 }
573 GroupDefaults;
574
575 #define EH_AKAS 0x0007 /* CONFIG.AkaCnt * <SysAddress> */
576
577 typedef struct
578 {
579 FEAddress main;
580 char domain[28];
581 unsigned short pointnet;
582 unsigned long flags; /* unused */
583 }
584 SysAddress;
585 #define FE_SYS_ADDRESS_SIZE FE_ADDRESS_SIZE + 34
586
587 #define EH_ORIGINS 0x0008 /* CONFIG.OriginCnt * <OriginLines> */
588
589 typedef struct
590 {
591 char line[62];
592 }
593 OriginLines;
594
595 #define EH_PACKROUTE 0x0009 /* CONFIG.RouteCnt * <PackRoute> */
596
597 typedef struct
598 {
599 FEAddress dest;
600 FEAddress routes[MAX_ROUTE];
601 }
602 PackRoute;
603
604 #define EH_PACKERS 0x000A /* CONFIG.Packers * <Packers> (DOS) */
605 #define EH_PACKERS2 0x100A /* CONFIG.Packers * <Packers> (OS/2) */
606
607 typedef struct
608 {
609 char tag[6];
610 char command[_MAXPATH];
611 char list[4];
612 unsigned char ratio;
613 unsigned char resv[7];
614 }
615 Packers;
616
617 #define EH_UNPACKERS 0x000B /* CONFIG.Unpackers * <Unpackers> (DOS) */
618 #define EH_UNPACKERS2 0x100B /* CONFIG.Unpackers * <Unpackers> (OS/2) */
619
620 /* Calling convention: *
621 * 0 = change path to inbound directory, 1 = <path> *.PKT, *
622 * 2 = *.PKT <path>, 3 = *.PKT #<path>, 4 = *.PKT -d <path> */
623
624 typedef struct
625 {
626 char command[_MAXPATH];
627 unsigned char callingconvention;
628 unsigned char resv[7];
629 }
630 Unpackers;
631
632 #define EH_RA111_MSG 0x0100 /* Original records of BBS systems */
633 #define EH_QBBS_MSG 0x0101
634 #define EH_SBBS_MSG 0x0102
635 #define EH_TAG_MSG 0x0104
636 #define EH_RA200_MSG 0x0105
637 #define EH_PB200_MSG 0x0106 /* See BBS package's documentation */
638 #define EH_PB202_MSG 0x0107 /* for details */
639 #define EH_MAX202_MSG 0x0108
640
641
642 /********************************************************
643 * Routines to access Node.areas, Node.groups *
644 ********************************************************/
645
646 #ifdef INC_FE_BAMPROCS
647
AddBam(unsigned char * bam,unsigned short nr)648 unsigned short AddBam(unsigned char * bam, unsigned short nr)
649 {
650 unsigned char c, d;
651 c = 1 << (7 - (nr & 7));
652 d = bam[nr / 8] & c;
653 bam[nr / 8] |= c;
654 return d;
655 }
656
FreeBam(unsigned char * bam,unsigned short nr)657 void FreeBam(unsigned char * bam, unsigned short nr)
658 {
659 bam[nr / 8] &= ~(1 << (7 - (nr & 7)));
660 }
661
GetBam(unsigned char * bam,unsigned short nr)662 unsigned short GetBam(unsigned char * bam, unsigned short nr)
663 {
664 if (bam[nr / 8] & (1 << (7 - (nr & 7))))
665 {
666 return TRUE;
667 }
668 return FALSE;
669 }
670
671 #define IsActive(nr,area) GetBam(Node[nr].areas,area)
672 #define SetActive(nr,area) AddBam(Node[nr].areas,area)
673 #define SetDeActive(nr,area) FreeBam(Node[nr].areas,area)
674
675 #endif
676
677 /********************************************************
678 * FASTECHO.DAT = <STATHEADER> *
679 * + <STATHEADER.NodeCnt * StatNode> *
680 * + <STATHEADER.AreaCnt * StatArea> *
681 ********************************************************/
682
683 #define STAT_REVISION 3 /* current revision */
684
685 struct fe_date /* Used in FASTECHO.DAT */
686 {
687 unsigned short year;
688 unsigned char day;
689 unsigned char month;
690 };
691
692 typedef struct
693 {
694 char signature[10]; /* contains 'FASTECHO\0^Z' */
695 unsigned short revision;
696 struct fe_date lastupdate; /* last time file was updated */
697 unsigned short NodeCnt, AreaCnt;
698 unsigned long startnode, startarea;/* unix timestamp of last reset */
699 unsigned short NodeSize, AreaSize; /* size of StatNode and StatArea records */
700 char resv[32];
701 }
702 STATHEADER;
703
704 typedef struct
705 {
706 FEAddress adr;
707 unsigned long import, export;
708 struct fe_date lastimport, lastexport;
709 unsigned long dupes;
710 unsigned long importbytes, exprotbytes;
711 }
712 StatNode;
713
714 typedef struct
715 {
716 unsigned short conference; /* conference # of area */
717 unsigned long tagcrc; /* CRC32 of area tag */
718 unsigned long import, export;
719 struct fe_date lastimport, lastexport;
720 unsigned long dupes;
721 }
722 StatArea;
723
724 /* ======================================================================= */
725 /* Functions for reading some of these structs in a portable manner */
726 /* ======================================================================= */
727
728 #ifdef __cplusplus
729 extern "C" {
730 #endif
731
732 int read_fe_config(CONFIG *c, FILE *fp);
733 int read_fe_extension_header(ExtensionHeader *h, FILE *fp);
734 int read_fe_sysaddress(SysAddress *a, FILE *fp);
735 int read_fe_area(Area *a, FILE *fp);
736 int read_fe_node(Node *a, FILE *fp);
737
738 #ifdef __cplusplus
739 }
740 #endif
741
742 #endif
743