This file is indexed.

/usr/include/pcp/pmapi.h is in libpcp3-dev 4.0.1-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
/*
 * Copyright (c) 2012-2018 Red Hat.
 * Copyright (c) 1997,2004 Silicon Graphics, Inc.  All Rights Reserved.
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 * License for more details.
 */
#ifndef PCP_PMAPI_H
#define PCP_PMAPI_H

/*
 * Platform and environment customization
 */
#include "platform_defs.h"

#include <time.h>
#include <fcntl.h>
#include <dirent.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h> 
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif

#define PMAPI_VERSION_2	2
#define PMAPI_VERSION	PMAPI_VERSION_2

/*
 * -------- Naming Services --------
 */
typedef unsigned int	pmID;		/* Metric Identifier */
#define PM_ID_NULL	0xffffffff

typedef unsigned int	pmInDom;	/* Instance-Domain */
#define PM_INDOM_NULL	0xffffffff
#define PM_IN_NULL	0xffffffff

#define PM_NS_DEFAULT	NULL	/* default name */

/*
 * Encoding for the units (dimensions Time and Space) and scale
 * for Performance Metric Values
 *
 * For example, a pmUnits struct of
 *	{ 1, -1, 0, PM_SPACE_MBYTE, PM_TIME_SEC, 0 }
 * represents Mbytes/sec, while 
 *	{ 0, 1, -1, 0, PM_TIME_HOUR, 6 }
 * represents hours/million-events
 */
typedef struct pmUnits {
#ifdef HAVE_BITFIELDS_LTOR
    signed int		dimSpace : 4;	/* space dimension */
    signed int		dimTime : 4;	/* time dimension */
    signed int		dimCount : 4;	/* event dimension */
    unsigned int	scaleSpace : 4;	/* one of PM_SPACE_* below */
    unsigned int	scaleTime : 4;	/* one of PM_TIME_* below */
    signed int		scaleCount : 4;	/* one of PM_COUNT_* below */
    unsigned int	pad : 8;
#else
    unsigned int	pad : 8;
    signed int		scaleCount : 4;	/* one of PM_COUNT_* below */
    unsigned int	scaleTime : 4;	/* one of PM_TIME_* below */
    unsigned int	scaleSpace : 4;	/* one of PM_SPACE_* below */
    signed int		dimCount : 4;	/* event dimension */
    signed int		dimTime : 4;	/* time dimension */
    signed int		dimSpace : 4;	/* space dimension */
#endif
} pmUnits;			/* dimensional units and scale of value */

/* pmUnits.scaleSpace */
#define PM_SPACE_BYTE	0	/* bytes */
#define PM_SPACE_KBYTE	1	/* kibibytes (1024) */
#define PM_SPACE_MBYTE	2	/* mebibytes (1024^2) */
#define PM_SPACE_GBYTE	3	/* gibibytes (1024^3) */
#define PM_SPACE_TBYTE	4	/* tebibytes (1024^4) */
#define PM_SPACE_PBYTE	5	/* pebibytes (1024^5) */
#define PM_SPACE_EBYTE	6	/* exbibytes (1024^6) */
#define PM_SPACE_ZBYTE	7	/* zebibytes (1024^7) */
#define PM_SPACE_YBYTE	8	/* yobibytes (1024^8) */
/* pmUnits.scaleTime */
#define PM_TIME_NSEC	0	/* nanoseconds */
#define PM_TIME_USEC	1	/* microseconds */
#define PM_TIME_MSEC	2	/* milliseconds */
#define PM_TIME_SEC	3	/* seconds */
#define PM_TIME_MIN	4	/* minutes */
#define PM_TIME_HOUR	5	/* hours */
/*
 * pmUnits.scaleCount (e.g. count events, syscalls, interrupts, etc.)
 * -- these are simply powers of 10, and not enumerated here,
 *    e.g. 6 for 10^6, or -3 for 10^-3
 */
#define PM_COUNT_ONE	0	/* 1 */

/* Performance Metric Descriptor */
typedef struct pmDesc {
    pmID	pmid;		/* unique identifier */
    int		type;		/* base data type (see below) */
    pmInDom	indom;		/* instance domain */
    int		sem;		/* semantics of value (see below) */
    pmUnits	units;		/* dimension and units */
} pmDesc;

/* pmDesc.type -- data type of metric values */
#define PM_TYPE_NOSUPPORT	-1	/* not implemented in this version */
#define PM_TYPE_32		0	/* 32-bit signed integer */
#define PM_TYPE_U32		1	/* 32-bit unsigned integer */
#define PM_TYPE_64		2	/* 64-bit signed integer */
#define PM_TYPE_U64		3	/* 64-bit unsigned integer */
#define PM_TYPE_FLOAT		4	/* 32-bit floating point */
#define PM_TYPE_DOUBLE		5	/* 64-bit floating point */
#define PM_TYPE_STRING		6	/* array of char */
#define PM_TYPE_AGGREGATE	7	/* arbitrary binary data (aggregate) */
#define PM_TYPE_AGGREGATE_STATIC 8	/* static pointer to aggregate */
#define PM_TYPE_EVENT		9	/* packed pmEventArray */
#define PM_TYPE_HIGHRES_EVENT	10	/* packed pmHighResEventArray */
#define PM_TYPE_UNKNOWN		255	/* used in pmValueBlock, not pmDesc */

/* pmDesc.sem -- semantics/interpretation of metric values */
#define PM_SEM_COUNTER	1	/* cumulative counter (monotonic increasing) */
				/* was PM_SEM_RATE, no longer used now */
#define PM_SEM_INSTANT	3	/* instantaneous value, continuous domain */
#define PM_SEM_DISCRETE	4	/* instantaneous value, discrete domain */

#define PM_ERR_BASE2 12345
#define PM_ERR_BASE  PM_ERR_BASE2

/* PMAPI Error Conditions */

#define PM_ERR_GENERIC		(-PM_ERR_BASE-0)    /* Generic error, already reported above */
#define PM_ERR_PMNS		(-PM_ERR_BASE-1)    /* Problems parsing PMNS definitions */
#define PM_ERR_NOPMNS		(-PM_ERR_BASE-2)    /* PMNS not accessible */
#define PM_ERR_DUPPMNS		(-PM_ERR_BASE-3)    /* Attempt to reload the PMNS */
#define PM_ERR_TEXT		(-PM_ERR_BASE-4)    /* Oneline or help text is not available */
#define PM_ERR_APPVERSION	(-PM_ERR_BASE-5)    /* Metric not supported by this version of monitored application */
#define PM_ERR_VALUE		(-PM_ERR_BASE-6)    /* Missing metric value(s) */
/* retired PM_ERR_LICENSE (-PM_ERR_BASE-7) Current PCP license does not permit this operation */
#define PM_ERR_TIMEOUT		(-PM_ERR_BASE-8)    /* Timeout waiting for a response from PMCD */
#define PM_ERR_NODATA		(-PM_ERR_BASE-9)    /* Empty archive log file */
#define PM_ERR_RESET		(-PM_ERR_BASE-10)   /* pmcd reset or configuration changed */
/* retired PM_ERR_FILE (-PM_ERR_BASE-11) Cannot locate a file */
#define PM_ERR_NAME		(-PM_ERR_BASE-12)   /* Unknown metric name */
#define PM_ERR_PMID		(-PM_ERR_BASE-13)   /* Unknown or illegal metric identifier */
#define PM_ERR_INDOM		(-PM_ERR_BASE-14)   /* Unknown or illegal instance domain identifier */
#define PM_ERR_INST		(-PM_ERR_BASE-15)   /* Unknown or illegal instance identifier */
#define PM_ERR_UNIT		(-PM_ERR_BASE-16)   /* Illegal pmUnits specification */
#define PM_ERR_CONV		(-PM_ERR_BASE-17)   /* Impossible value or scale conversion */
#define PM_ERR_TRUNC		(-PM_ERR_BASE-18)   /* Truncation in value conversion */
#define PM_ERR_SIGN		(-PM_ERR_BASE-19)   /* Negative value in conversion to unsigned */
#define PM_ERR_PROFILE		(-PM_ERR_BASE-20)   /* Explicit instance identifier(s) required */
#define PM_ERR_IPC		(-PM_ERR_BASE-21)   /* IPC protocol failure */
/* retired PM_ERR_NOASCII (-PM_ERR_BASE-22) ASCII format not supported for this PDU */
#define PM_ERR_EOF		(-PM_ERR_BASE-23)   /* IPC channel closed */
#define PM_ERR_NOTHOST		(-PM_ERR_BASE-24)   /* Operation requires context with host source of metrics */
#define PM_ERR_EOL		(-PM_ERR_BASE-25)   /* End of PCP archive log */
#define PM_ERR_MODE		(-PM_ERR_BASE-26)   /* Illegal mode specification */
#define PM_ERR_LABEL		(-PM_ERR_BASE-27)   /* Illegal label record at start of a PCP archive log file */
#define PM_ERR_LOGREC		(-PM_ERR_BASE-28)   /* Corrupted record in a PCP archive log */
#define PM_ERR_NOTARCHIVE	(-PM_ERR_BASE-29)   /* Operation requires context with archive source of metrics */
#define PM_ERR_LOGFILE          (-PM_ERR_BASE-30)   /* Missing archive file */
#define PM_ERR_NOCONTEXT	(-PM_ERR_BASE-31)   /* Attempt to use an illegal context */
#define PM_ERR_PROFILESPEC	(-PM_ERR_BASE-32)   /* NULL pmInDom with non-NULL instlist */
#define PM_ERR_PMID_LOG		(-PM_ERR_BASE-33)   /* Metric not defined in the PCP archive log */
#define PM_ERR_INDOM_LOG	(-PM_ERR_BASE-34)   /* Instance domain identifier not defined in the PCP archive log */
#define PM_ERR_INST_LOG		(-PM_ERR_BASE-35)   /* Instance identifier not defined in the PCP archive log */
#define PM_ERR_NOPROFILE	(-PM_ERR_BASE-36)   /* Missing profile - protocol botch */
#define	PM_ERR_NOAGENT		(-PM_ERR_BASE-41)   /* No pmcd agent for domain of request */
#define PM_ERR_PERMISSION	(-PM_ERR_BASE-42)   /* No permission to perform requested operation */
#define PM_ERR_CONNLIMIT	(-PM_ERR_BASE-43)   /* PMCD connection limit for this host exceeded */
#define PM_ERR_AGAIN		(-PM_ERR_BASE-44)   /* try again. Info not currently available */
#define PM_ERR_ISCONN		(-PM_ERR_BASE-45)   /* already connected */
#define PM_ERR_NOTCONN		(-PM_ERR_BASE-46)   /* not connected */
#define PM_ERR_NEEDPORT		(-PM_ERR_BASE-47)   /* port name required */
/* retired PM_ERR_WANTACK (-PM_ERR_BASE-48) can not send due to pending acks */
#define PM_ERR_NONLEAF		(-PM_ERR_BASE-49)   /* PMNS node is not a leaf node */
/* retired PM_ERR_OBJSTYLE (-PM_ERR_BASE-50) user/kernel object style mismatch */
/* retired PM_ERR_PMCDLICENSE (-PM_ERR_BASE-51) PMCD is not licensed to accept connections */
#define PM_ERR_TYPE		(-PM_ERR_BASE-52)   /* Unknown or illegal metric type */
#define PM_ERR_THREAD		(-PM_ERR_BASE-53)   /* Operation not supported for multi-threaded applications */
#define PM_ERR_NOCONTAINER	(-PM_ERR_BASE-54)   /* Container not found */
#define PM_ERR_BADSTORE		(-PM_ERR_BASE-55)   /* Bad input to pmstore */
#define PM_ERR_LOGOVERLAP	(-PM_ERR_BASE-56)   /* Archives overlap in time */
#define PM_ERR_LOGHOST		(-PM_ERR_BASE-57)   /* Archives differ by host */
  /* retired PM_ERR_LOGTIMEZONE	(-PM_ERR_BASE-58) Archives differ in time zone */
#define PM_ERR_LOGCHANGETYPE	(-PM_ERR_BASE-59)   /* The type of a metric has changed in an archive */
#define PM_ERR_LOGCHANGESEM	(-PM_ERR_BASE-60)   /* The semantics of a metric has changed in an archive */
#define PM_ERR_LOGCHANGEINDOM	(-PM_ERR_BASE-61)   /* The instance domain of a metric has changed in an archive */
#define PM_ERR_LOGCHANGEUNITS	(-PM_ERR_BASE-62)   /* The units of a metric have changed in an archive */
#define PM_ERR_NEEDCLIENTCERT	(-PM_ERR_BASE-63)   /* PMCD requires a client certificate */
#define PM_ERR_BADDERIVE	(-PM_ERR_BASE-64)   /* Derived metric definition failed */
#define PM_ERR_NOLABELS		(-PM_ERR_BASE-65)   /* No support for label metadata */

/* retired PM_ERR_CTXBUSY (-PM_ERR_BASE-97) Context is busy */
#define PM_ERR_TOOSMALL		(-PM_ERR_BASE-98)   /* Insufficient elements in list */
#define PM_ERR_TOOBIG		(-PM_ERR_BASE-99)   /* Result size exceeded */
#define PM_ERR_FAULT		(-PM_ERR_BASE-100)  /* QA fault injected */

#define PM_ERR_PMDAREADY	(-PM_ERR_BASE-1048) /* now ready to respond */
#define PM_ERR_PMDANOTREADY	(-PM_ERR_BASE-1049) /* not yet ready to respond */
#define PM_ERR_NYI		(-PM_ERR_BASE-8999) /* Functionality not yet implemented [end-of-range mark] */

/*
 * Report PMAPI errors messages
 */
PCP_CALL extern char *pmErrStr(int);			/* NOT thread-safe */
PCP_CALL extern char *pmErrStr_r(int, char *, int);
/* safe size for a pmErrStr_r buffer to accommodate all error messages */
#define PM_MAXERRMSGLEN		128

/*
 * Load a Performance Metrics Name Space
 */
PCP_CALL extern int pmLoadNameSpace(const char *);
PCP_CALL extern int pmLoadASCIINameSpace(const char *, int);
PCP_CALL extern void pmUnloadNameSpace(void);

/*
 * Where is PMNS located - added for distributed PMNS.
 */
PCP_CALL extern int pmGetPMNSLocation(void);
#define PMNS_LOCAL   1
#define PMNS_REMOTE  2
#define PMNS_ARCHIVE 3

/*
 * Trim a name space with respect to the current context
 * (usually from an archive, or after processing an archive)
 */
PCP_CALL extern int pmTrimNameSpace(void);

/*
 * Expand a list of names to a list of metrics ids
 */
PCP_CALL extern int pmLookupName(int, char **, pmID *);

/*
 * Find the names of descendent nodes in the PMNS
 * and in the latter case get the status of each child.
 */
PCP_CALL extern int pmGetChildren(const char *, char ***);
PCP_CALL extern int pmGetChildrenStatus(const char *, char ***, int **);
#define PMNS_LEAF_STATUS     0	/* leaf node in PMNS tree */
#define PMNS_NONLEAF_STATUS  1	/* non-terminal node in PMNS tree */

/*
 * Reverse Lookup: find name(s) given a metric id
 */
PCP_CALL extern int pmNameID(pmID, char **);		/* one */
PCP_CALL extern int pmNameAll(pmID, char ***);		/* all */

/*
 * Handy recursive descent of the PMNS
 */
PCP_CALL extern int pmTraversePMNS(const char *, void(*)(const char *));
PCP_CALL extern int pmTraversePMNS_r(const char *, void(*)(const char *, void *), void *);

/*
 * Given a metric, find it's descriptor (caller supplies buffer for desc),
 * from the current context.
 */
PCP_CALL extern int pmLookupDesc(pmID, pmDesc *);

/*
 * Return the internal instance identifier, from the current context,
 * given an instance domain and the external instance name.
 * Archive variant scans the union of the indom entries in the archive
 * log.
 */
PCP_CALL extern int pmLookupInDom(pmInDom, const char *);
PCP_CALL extern int pmLookupInDomArchive(pmInDom, const char *);

/*
 * Return the external instance name, from the current context,
 * given an instance domain and the internal instance identifier.
 * Archive variant scans the union of the indom entries in the archive
 * log.
 */
PCP_CALL extern int pmNameInDom(pmInDom, int, char **);
PCP_CALL extern int pmNameInDomArchive(pmInDom, int, char **);

/*
 * Return all of the internal instance identifiers (instlist) and external
 * instance names (namelist) for the given instance domain in the current
 * context.
 * Archive variant returns the union of the indom entries in the archive
 * log.
 */
PCP_CALL extern int pmGetInDom(pmInDom, int **, char ***);
PCP_CALL extern int pmGetInDomArchive(pmInDom, int **, char ***);

/*
 * Given context ID, return the host name associated with that context,
 * or the empty string if no name can be found
 */
PCP_CALL extern const char *pmGetContextHostName(int);
PCP_CALL extern char *pmGetContextHostName_r(int, char *, int);

/*
 * Return the handle of the current context
 */
PCP_CALL extern int pmWhichContext(void);

/*
 * Destroy a context and close its connection
 */
PCP_CALL extern int pmDestroyContext(int);

/*
 * Establish a new context (source of performance data + instance profile)
 * for the named host
 */
PCP_CALL extern int pmNewContext(int, const char *);
#define PM_CONTEXT_UNDEF	-1	/* current context is undefined */
#define PM_CONTEXT_HOST		1	/* host via pmcd */
#define PM_CONTEXT_ARCHIVE	2	/* PCP archive */
#define PM_CONTEXT_LOCAL	3	/* local host, no pmcd connection */
#define PM_CONTEXT_TYPEMASK	0xff	/* mask to separate types / flags */
#define PM_CTXFLAG_SHALLOW	(1U<<8)	/* DEPRECATED (don't actually connect to host) */
#define PM_CTXFLAG_EXCLUSIVE	(1U<<9)	/* DEPRECATED (don't share socket among ctxts) */
#define PM_CTXFLAG_SECURE	(1U<<10)/* encrypted socket comms channel */
#define PM_CTXFLAG_COMPRESS	(1U<<11)/* compressed socket host channel */
#define PM_CTXFLAG_RELAXED	(1U<<12)/* encrypted if possible else not */
#define PM_CTXFLAG_AUTH		(1U<<13)/* make authenticated connection */
#define PM_CTXFLAG_CONTAINER	(1U<<14)/* container connection attribute */

/*
 * Duplicate current context -- returns handle to new one for pmUseContext()
 */
PCP_CALL extern int pmDupContext(void);

/*
 * Restore (previously established or duplicated) context
 */
PCP_CALL extern int pmUseContext(int);

/*
 * Reconnect an existing context (when pmcd dies, etc). All existing context
 * settings are preserved and the previous context settings are restored.
 */
PCP_CALL extern int pmReconnectContext(int);

/*
 * Add to instance profile.
 * If pmInDom == PM_INDOM_NULL, then all instance domains are selected.
 * If no inst parameters are given, then all instances are selected.
 * e.g. to select all available instances in all domains,
 * then use pmAddProfile(PM_INDOM_NULL, 0, NULL).
 */
PCP_CALL extern int pmAddProfile(pmInDom, int, int *);

/*
 * Delete from instance profile.
 * Similar (but negated) functional semantics to pmProfileAdd.
 * E.g. to disable all instances in all domains then use
 * pmDelProfile(PM_INDOM_NULL, 0, NULL).
 */
PCP_CALL extern int pmDelProfile(pmInDom, int, int *);

/*
 * Profile entry (per instance domain)
 * Only the PMDAs and pmcd need to know about this.
 */
typedef struct pmInDomProfile {
    pmInDom	indom;			/* instance domain */
    int		state;			/* include all or exclude all */
    int		instances_len;		/* length of instances array */
    int		*instances;		/* array of instances */
} pmInDomProfile;

/* Internal instance profile states: state in pmInDomProfile */
#define PM_PROFILE_INCLUDE 0	/* include all, exclude some */
#define PM_PROFILE_EXCLUDE 1	/* exclude all, include some */

/*
 * Instance profile for all domains
 * Only the PMDAs and pmcd need to know about this.
 */
typedef struct pmProfile {
    int			state;			/* default global state */
    int			profile_len;		/* length of profile array */
    pmInDomProfile	*profile;		/* array of instance profiles */
} pmProfile;

/*
 * Result structure for instance domain queries
 * Only the PMDAs and pmcd need to know about this.
 */
typedef struct pmInResult {
    pmInDom	indom;		/* instance domain */
    int		numinst;	/* may be 0 */
    int		*instlist;	/* instance ids, may be NULL */
    char	**namelist;	/* instance names, may be NULL */
} pmInResult;

/* 
 * ---------- Collection services ---------- 
 *
 * Result from pmFetch is encoded as a timestamp and vector of pointers
 * to pmValueSet instances (one per PMID in the result).
 * Each pmValueSet has a PMID, a value count, a value format, and a vector of
 * instance-value pairs.  Aggregate, string and non-int values are returned
 * via one further level of indirection using pmValueBlocks.
 *
 * timeStamp
 * ->pmID
 *   value format
 *     instance, value
 *     instance, value
 *     ... etc
 *
 * ->pmID
 *   value format
 *     instance, value
 *     ... etc
 *
 *
 * Notes on pmValueBlock
 *   0. may be used for arbitrary binary data
 *   1. only ever allocated dynamically, and vbuf expands to accommodate
 *	an arbitrary value (don't believe the [1] size!)
 *   2. len is the length of the len field + the real size of vbuf
 *	(which includes the null-byte terminator if there is one)
 */
typedef struct pmValueBlock {
#ifdef HAVE_BITFIELDS_LTOR
    unsigned int	vtype : 8;	/* value type */
    unsigned int	vlen : 24;	/* bytes for vtype/vlen + vbuf */
#else
    unsigned int	vlen : 24;	/* bytes for vtype/vlen + vbuf */
    unsigned int	vtype : 8;	/* value type */
#endif
    char		vbuf[1];	/* the value */
} pmValueBlock;

#define PM_VAL_HDR_SIZE	4		/* bytes for the vtype/vlen header */
#define PM_VAL_VLEN_MAX	0x00ffffff	/* maximum vbuf[] size */

typedef struct pmValue {
    int		inst;		/* instance identifier */
    union {
	pmValueBlock	*pval;	/* pointer to value-block */
	int		lval;	/* integer value insitu (lval 'cuz it WAS a long) */
    } value;
} pmValue;

typedef struct pmValueSet {
    pmID	pmid;		/* metric identifier */
    int		numval;		/* number of values */
    int		valfmt;		/* value style */
    pmValue	vlist[1];	/* set of instances/values */
} pmValueSet;

/* values for valfmt */
#define PM_VAL_INSITU	0	/* value.lval is it */
#define PM_VAL_DPTR	1	/* value.pval->vbuf is it, and dynamic alloc */
#define PM_VAL_SPTR	2	/* value.pval->vbuf is it, and static alloc */


/* Result returned by pmFetch() */
typedef struct pmResult {
    struct timeval	timestamp;	/* time stamped by collector */
    int			numpmid;	/* number of PMIDs */
    pmValueSet		*vset[1];	/* set of value sets, one per PMID */
} pmResult;

/* High resolution event timer result from pmUnpackHighResEventRecords() */
typedef struct pmHighResResult {
    struct timespec	timestamp;	/* time stamped by collector */
    int			numpmid;	/* number of PMIDs */
    pmValueSet		*vset[1];	/* set of value sets, one per PMID */
} pmHighResResult;

/* Generic Union for Value-Type conversions */
typedef union {
    __int32_t		l;	/* 32-bit signed */
    __uint32_t		ul;	/* 32-bit unsigned */
    __int64_t		ll;	/* 64-bit signed */
    __uint64_t		ull;	/* 64-bit unsigned */
    float		f;	/* 32-bit floating point */
    double		d;	/* 64-bit floating point */
    char		*cp;	/* char ptr */
    pmValueBlock	*vbp;	/* pmValueBlock ptr */
} pmAtomValue;

/*
 * Fetch metrics. Value/instances returned depends on current instance profile.
 * By default, all available instances for each requested metric id are
 * returned. The metrics argument is terminated with PM_NULL_ID
 *
 * The value sets returned are in the same order as the metrics argument,
 * and the number of value sets returned is guaranteed to be the same as
 * the number of metrics in the agument.  
 */
PCP_CALL extern int pmFetch(int, pmID *, pmResult **);

/*
 * PMCD state changes returned as pmFetch function result for PM_CONTEXT_HOST
 * contexts, i.e. when communicating with PMCD
 */
#define PMCD_ADD_AGENT		(1<<0)
#define PMCD_RESTART_AGENT	(1<<1)
#define PMCD_DROP_AGENT		(1<<2)

#define PMCD_NO_CHANGE		0
#define PMCD_AGENT_CHANGE	\
	(PMCD_ADD_AGENT | PMCD_RESTART_AGENT | PMCD_DROP_AGENT)
#define PMCD_LABEL_CHANGE	(1<<3)
#define PMCD_NAMES_CHANGE	(1<<4)

/*
 * Variant that is used to return a pmResult from an archive
 */
PCP_CALL extern int pmFetchArchive(pmResult **);

/*
 * Support for metric values annotated with name:value pairs (labels).
 *
 * The full set of labels for a given metric instance is the union of
 * those found at the levels: source (host/archive), domain (agent),
 * indom, metric, and finally instances (individual metric values).
 *
 * Individual labels can be intrinsic to a metric value (i.e. they
 * form an inherent part of its identity like the pmDesc metadata)
 * or extrinsic (i.e. they are simply optional annotations).
 */
typedef struct pmLabel {
    unsigned int	name : 16;	/* label name offset in JSONB string */
    unsigned int	namelen : 8;	/* length of name excluding the null */
    unsigned int	flags : 8;	/* information about this label */
    unsigned int	value : 16;	/* offset of the label value */
    unsigned int	valuelen : 16;	/* length of value in bytes */
} pmLabel;

/* Bits for the flags field (above) */
#define PM_LABEL_OPTIONAL	(1<<7)

typedef struct pmLabelSet {
    unsigned int 	inst;		/* PM_IN_NULL or the instance ID */
    int			nlabels;	/* count of labels or error code */
    char		*json;		/* JSON formatted labels string */
    unsigned int	jsonlen : 16;	/* JSON string length byte count */
    unsigned int	padding : 16;	/* zero, reserved for future use */
    pmLabel		*labels;	/* indexing into the JSON string */
} pmLabelSet;

#define PM_MAXLABELS		((1<<8)-1)
#define PM_MAXLABELJSONLEN	((1<<16)-1)

/* These identify label set classes. */
#define PM_LABEL_CONTEXT	(1<<0)
#define PM_LABEL_DOMAIN		(1<<1)
#define PM_LABEL_INDOM		(1<<2)
#define PM_LABEL_CLUSTER	(1<<3)
#define PM_LABEL_ITEM		(1<<4)
#define PM_LABEL_INSTANCES	(1<<5)

PCP_CALL extern int pmGetContextLabels(pmLabelSet **);
PCP_CALL extern int pmGetDomainLabels(int, pmLabelSet **);
PCP_CALL extern int pmGetInDomLabels(pmInDom, pmLabelSet **);
PCP_CALL extern int pmGetClusterLabels(pmID, pmLabelSet **);
PCP_CALL extern int pmGetItemLabels(pmID, pmLabelSet **);
PCP_CALL extern int pmGetInstancesLabels(pmInDom, pmLabelSet **);

PCP_CALL extern int pmLookupLabels(pmID, pmLabelSet **);

/*
 * The full set is formed by merging labels from all levels of the
 * hierarchy using the precedence rules described in pmLookupLabels(3).
 */
PCP_CALL extern int pmMergeLabels(char **, int, char *, int);
PCP_CALL extern int pmMergeLabelSets(pmLabelSet **, int, char *, int,
		int (*filter)(const pmLabel *, const char *, void *), void *);

/* Free a labelset array */
PCP_CALL extern void pmFreeLabelSets(pmLabelSet *, int);

/*
 * struct timeval is sometimes 2 x 64-bit ... we use a 2 x 32-bit format for
 * PDUs, internally within libpcp and for (external) archive logs
 */
typedef struct pmTimeval {
    __int32_t	tv_sec;		/* seconds since Jan. 1, 1970 */
    __int32_t	tv_usec;	/* and microseconds */
} pmTimeval;

typedef struct pmTimespec {
    __int64_t	tv_sec;		/* seconds since Jan. 1, 1970 */
    __int64_t	tv_nsec;	/* and nanoseconds */
} pmTimespec;

/*
 * Label Record at the start of every log file - as exported above
 * the PMAPI ...
 * NOTE MAXHOSTNAMELEN is a bad choice here for ll_hostname[], as
 *	it may vary on different hosts ... we use PM_LOG_MAXHOSTLEN instead, and
 *	size this to be the same as MAXHOSTNAMELEN in IRIX 5.3
 * NOTE	that the struct timeval means we have another struct (__pmLogLabel)
 *	for internal use that has a pmTimeval in place of the struct timeval.
 */
#define PM_TZ_MAXLEN	40
#define PM_LOG_MAXHOSTLEN		64
#define PM_LOG_MAGIC	0x50052600
#define PM_LOG_VERS02	0x2
#define PM_LOG_VOL_TI	-2	/* temporal index */
#define PM_LOG_VOL_META	-1	/* meta data */
typedef struct pmLogLabel {
    int		ll_magic;	/* PM_LOG_MAGIC | log format version no. */
    pid_t	ll_pid;				/* PID of logger */
    struct timeval	ll_start;		/* start of this log */
    char	ll_hostname[PM_LOG_MAXHOSTLEN];	/* name of collection host */
    char	ll_tz[PM_TZ_MAXLEN];		/* $TZ at collection host */
} pmLogLabel;

/*
 * Get the label record from the current archive context, and discover
 * when the archive ends
 */
PCP_CALL extern int pmGetArchiveLabel(pmLogLabel *);
PCP_CALL extern int pmGetArchiveEnd(struct timeval *);

/* Free result buffer */
PCP_CALL extern void pmFreeResult(pmResult *);

/* Value extract from pmValue and type conversion */
PCP_CALL extern int pmExtractValue(int, const pmValue *, int, pmAtomValue *, int);

/* Print single pmValue */
PCP_CALL extern void pmPrintValue(FILE *, int, int, const pmValue *, int);

/* Scale conversion, based on value format, value type and scale */
PCP_CALL extern int pmConvScale(int, const pmAtomValue *, const pmUnits *, pmAtomValue *, 
		       const pmUnits *);

/* Sort instances for each metric within a pmResult */
PCP_CALL extern void pmSortInstances(pmResult *);

/* Adjust collection time and/or mode for pmFetch */
PCP_CALL extern int pmSetMode(int, const struct timeval *, int);
#define PM_MODE_LIVE	0
#define PM_MODE_INTERP	1
#define PM_MODE_FORW	2
#define PM_MODE_BACK	3

/* Modify the value of one or more metrics */
PCP_CALL extern int pmStore(const pmResult *);

/* Get help and descriptive text */
PCP_CALL extern int pmLookupText(pmID, int, char **);
PCP_CALL extern int pmLookupInDomText(pmInDom, int, char **);
#define PM_TEXT_ONELINE	1
#define PM_TEXT_HELP	2

/*
 * For the help text PDUs, the type (PM_TEXT_ONELINE or PM_TEXT_HELP)
 * is 'or'd with the following to encode the request for a PMID or
 * a pmInDom.  Default is to fallback to ONELINE if HELP unavailable;
 * the (internal) PM_TEXT_DIRECT flag disables this behaviour.
 * Note the values must therefore be (a) bit fields and (b) different
 *	to the public macros PM_TEXT_* in pmapi.h 
 */
#define PM_TEXT_PMID	4
#define PM_TEXT_INDOM	8
#define PM_TEXT_DIRECT	16

/*
 * Some handy formatting routines for messages, and other output
 */
PCP_CALL extern const char *pmIDStr(pmID);			/* NOT thread-safe */
PCP_CALL extern char *pmIDStr_r(pmID, char *, int);
PCP_CALL extern const char *pmInDomStr(pmInDom);		/* NOT thread-safe */
PCP_CALL extern char *pmInDomStr_r(pmInDom, char *, int);
PCP_CALL extern const char *pmTypeStr(int);			/* NOT thread-safe */
PCP_CALL extern char *pmTypeStr_r(int, char *, int);
PCP_CALL extern const char *pmSemStr(int);			/* NOT thread-safe */
PCP_CALL extern char *pmSemStr_r(int, char *, int);
PCP_CALL extern const char *pmUnitsStr(const pmUnits *);	/* NOT thread-safe */
PCP_CALL extern char *pmUnitsStr_r(const pmUnits *, char *, int);
PCP_CALL extern const char *pmAtomStr(const pmAtomValue *, int);/* NOT thread-safe */
PCP_CALL extern char *pmAtomStr_r(const pmAtomValue *, int, char *, int);
PCP_CALL extern const char *pmNumberStr(double);		/* NOT thread-safe */
PCP_CALL extern char *pmNumberStr_r(double, char *, int);
PCP_CALL extern const char *pmEventFlagsStr(int);		/* NOT thread-safe */
PCP_CALL extern char *pmEventFlagsStr_r(int, char *, int);

/* Extended time base definitions and macros */
#define PM_XTB_FLAG	0x1000000

#define PM_XTB_SET(type) (PM_XTB_FLAG | ((type) << 16))
#define PM_XTB_GET(x) (((x) & PM_XTB_FLAG) ? (((x) & 0xff0000) >> 16) : -1)

/* Parse -t, -S, -T, -A and -O options */
PCP_CALL extern int pmParseInterval(const char *, struct timeval *, char **);
PCP_CALL extern int pmParseTimeWindow(
      const char *, const char *, const char *, const char *,
      const struct timeval *, const struct timeval *,
      struct timeval *, struct timeval *, struct timeval *, char **);

/* Reporting timezone */
PCP_CALL extern int pmUseZone(const int);
PCP_CALL extern int pmNewZone(const char *);
PCP_CALL extern int pmNewContextZone(void);
PCP_CALL extern int pmWhichZone(char **);
PCP_CALL extern char *pmCtime(const time_t *, char *);
PCP_CALL extern struct tm *pmLocaltime(const time_t *, struct tm *);

/* Parse host:metric[instances] or archive/metric[instances] */
typedef struct pmMetricSpec {
    int		isarch;         /* source type: 0 -> live host, 1 -> archive, 2 -> local context */
    char	*source;        /* name of source host or archive */
    char	*metric;        /* name of metric */
    int		ninst;          /* number of instances, 0 -> all */
    char	*inst[1];       /* array of instance names */
} pmMetricSpec;

/* Parsing of host:metric[instances] or archive/metric[instances] */
PCP_CALL extern int pmParseMetricSpec(const char *, int, char *, pmMetricSpec **,
			     char **);
PCP_CALL extern void pmFreeMetricSpec(pmMetricSpec *p);

/*
 * Configurable error reporting
 */
#ifdef __GNUC__
# define __PM_PRINTFLIKE(idx,cnt) __attribute__ ((format (printf, idx,cnt)))
#else
# define __PM_PRINTFLIKE(idx,cnt)
#endif

PCP_CALL extern int pmprintf(const char *, ...) __PM_PRINTFLIKE(1,2);
PCP_CALL extern int pmflush(void);

/*
 * Wrapper for string formatting that ensures null termination,
 * even if truncation occurs or the underlying call errors out.
 */
PCP_CALL extern int pmsprintf(char *, size_t, const char *, ...) __PM_PRINTFLIKE(3,4);

/*
 * Wrapper for config/environment variables. Warning: this will exit() with
 * a FATAL error if /etc/pcp.conf does not exist and $PCP_CONF is not set.
 * Use the pmGetOptionalConfig variant if this behaviour is not sought.
 * Return values point to strings in the environment, or NULL in the optional
 * case when the requested configuration variable was not found.
 */
PCP_CALL extern char *pmGetConfig(const char *);
PCP_CALL extern char *pmGetOptionalConfig(const char *);

/* Ditto for library features */
PCP_CALL extern const char *pmGetAPIConfig(const char *);

PCP_CALL extern int pmGetVersion(void);

/*
 * Common command line argument parsing interfaces
 */

#define PMAPI_OPTIONS	"A:a:D:gh:n:O:p:S:s:T:t:VZ:z?"
#define PMAPI_OPTIONS_HEADER(s)	{ "", 0, '-', 0, (s) }
#define PMAPI_OPTIONS_TEXT(s)	{ "", 0, '|', 0, (s) }
#define PMAPI_OPTIONS_END	{ NULL, 0, 0, 0, NULL }

#define PMLONGOPT_ALIGN		"align"
#define PMOPT_ALIGN	{ PMLONGOPT_ALIGN,	1, 'A',	"TIME", \
			"align sample times on natural boundaries" }
#define PMLONGOPT_ARCHIVE	"archive"
#define PMOPT_ARCHIVE	{ PMLONGOPT_ARCHIVE,	1, 'a',	"FILE", \
			"metrics source is a PCP log archive" }
#define PMLONGOPT_DEBUG		"debug"
#define PMOPT_DEBUG	{ PMLONGOPT_DEBUG,	1, 'D',	"DBG", \
			NULL }
#define PMLONGOPT_GUIMODE	"guimode"
#define PMOPT_GUIMODE	{ PMLONGOPT_GUIMODE,	0, 'g',	0, \
			"start in GUI mode with new time control" }
#define PMLONGOPT_HOST		"host"
#define PMOPT_HOST	{ PMLONGOPT_HOST,	1, 'h', "HOST", \
			"metrics source is PMCD on host" }
#define PMLONGOPT_HOSTSFILE	"hostsfile"
#define PMOPT_HOSTSFILE	{ PMLONGOPT_HOSTSFILE,	1, 'H', "FILE", \
			"read metric source hosts from a file" }
#define PMLONGOPT_SPECLOCAL	"spec-local"
#define PMOPT_SPECLOCAL	{ PMLONGOPT_SPECLOCAL,	1, 'K',	"SPEC", \
			"optional additional PMDA spec for local connection" }
#define PMLONGOPT_LOCALPMDA	"local-PMDA"
#define PMOPT_LOCALPMDA	{ PMLONGOPT_LOCALPMDA,	0, 'L', 0, \
			"metrics source is local connection to a PMDA" }
#define PMLONGOPT_NAMESPACE	"namespace"
#define PMOPT_NAMESPACE	{ PMLONGOPT_NAMESPACE,	1, 'n', "FILE", \
			"use an alternative PMNS" }
#define PMLONGOPT_UNIQNAMES	"uniqnames"
#define PMOPT_UNIQNAMES	{ PMLONGOPT_UNIQNAMES,	1, 'N', "FILE", \
			"like -n but only one name allowed for each PMID" }
#define PMLONGOPT_ORIGIN	"origin"
#define PMOPT_ORIGIN	{ PMLONGOPT_ORIGIN,	1, 'O', "TIME", \
			"initial sample time within the time window" }
#define PMLONGOPT_GUIPORT	"guiport"
#define PMOPT_GUIPORT	{ PMLONGOPT_GUIPORT,	1, 'p', "N", \
			"port for connection to existing time control" }
#define PMLONGOPT_START		"start"
#define PMOPT_START	{ PMLONGOPT_START,	1, 'S', "TIME", \
			"start of the time window" }
#define PMLONGOPT_SAMPLES	"samples"
#define PMOPT_SAMPLES	{ PMLONGOPT_SAMPLES,	1, 's', "N", \
			"terminate after this many samples" }
#define PMLONGOPT_FINISH	"finish"
#define PMOPT_FINISH	{ PMLONGOPT_FINISH,	1, 'T', "TIME", \
			"end of the time window" }
#define PMLONGOPT_INTERVAL	"interval"
#define PMOPT_INTERVAL	{ PMLONGOPT_INTERVAL,	1, 't', "DELTA", \
			"sampling interval" }
#define PMLONGOPT_VERSION	"version"
#define PMOPT_VERSION	{ PMLONGOPT_VERSION,	0, 'V', 0, \
			"display version number and exit" }
#define PMLONGOPT_TIMEZONE	"timezone"
#define PMOPT_TIMEZONE	{ PMLONGOPT_TIMEZONE,	1, 'Z', "TZ", \
			"set reporting timezone" }
#define PMLONGOPT_HOSTZONE	"hostzone"
#define PMOPT_HOSTZONE	{ PMLONGOPT_HOSTZONE,	0, 'z', 0, \
			"set reporting timezone to local time of metrics source" }
#define PMLONGOPT_HELP		"help"
#define PMOPT_HELP	{ PMLONGOPT_HELP,	0, '?', 0, \
			"show this usage message and exit" }

#define PMAPI_GENERAL_OPTIONS	\
	PMAPI_OPTIONS_HEADER("General options"), \
	PMOPT_ALIGN, \
	PMOPT_ARCHIVE, \
	PMOPT_DEBUG, \
	PMOPT_GUIMODE, \
	PMOPT_HOST, \
	PMOPT_NAMESPACE, \
	PMOPT_ORIGIN, \
	PMOPT_GUIPORT, \
	PMOPT_START, \
	PMOPT_SAMPLES, \
	PMOPT_FINISH, \
	PMOPT_INTERVAL, \
	PMOPT_TIMEZONE, \
	PMOPT_HOSTZONE, \
	PMOPT_VERSION, \
	PMOPT_HELP

/* long-only standard options */
#define PMLONGOPT_ARCHIVE_LIST "archive-list"
#define PMOPT_ARCHIVE_LIST { PMLONGOPT_ARCHIVE_LIST, 1, 0, "FILES", \
		"comma-separated list of metric source archives" }
#define PMLONGOPT_ARCHIVE_FOLIO "archive-folio"
#define PMOPT_ARCHIVE_FOLIO { PMLONGOPT_ARCHIVE_FOLIO, 1, 0, "FILE", \
		"read metric source archives from a folio" }
#define PMLONGOPT_HOST_LIST "host-list"
#define PMOPT_HOST_LIST { PMLONGOPT_HOST_LIST, 1, 0, "HOSTS", \
		"comma-separated list of metric source hosts" }
#define PMLONGOPT_CONTAINER "container"
#define PMOPT_CONTAINER { PMLONGOPT_CONTAINER, 1, 0, "NAME", \
		"specify an individual container to be queried" }
#define PMLONGOPT_DERIVED "derived"
#define PMOPT_DERIVED { PMLONGOPT_DERIVED, 1, 0, "FILE", \
		"load derived metric definitions from FILE(s)" }

/* pmOptions flags */
#define PM_OPTFLAG_INIT		(1<<0)	/* initialisation done */
#define PM_OPTFLAG_DONE		(1<<1)	/* parsing is complete */
#define PM_OPTFLAG_MULTI	(1<<2)	/* allow multi-context */
#define PM_OPTFLAG_USAGE_ERR	(1<<3)	/* argument parse fail */
#define PM_OPTFLAG_RUNTIME_ERR	(1<<4)	/* any runtime failure */
#define PM_OPTFLAG_EXIT		(1<<5)	/* tool should exit(0) */
#define PM_OPTFLAG_POSIX	(1<<6)	/* POSIXLY_CORRECT set */
#define PM_OPTFLAG_MIXED	(1<<7)	/* allow hosts+archives */
#define PM_OPTFLAG_ENV_ONLY	(1<<8)	/* use env options only */
#define PM_OPTFLAG_LONG_ONLY	(1<<9)	/* use long options only */
#define PM_OPTFLAG_BOUNDARIES	(1<<10)	/* calculate time window */
#define PM_OPTFLAG_STDOUT_TZ	(1<<11)	/* write timezone change */
#define PM_OPTFLAG_NOFLUSH	(1<<12)	/* caller issues pmflush */
#define PM_OPTFLAG_QUIET	(1<<13)	/* silence getopt errors */

struct pmOptions;
typedef int (*pmOptionOverride)(int, struct pmOptions *);

typedef struct pmLongOptions {
    const char *	long_opt;
    int			has_arg;
    int			short_opt;
    const char *	argname;
    const char *	message;
} pmLongOptions;

typedef struct pmOptions {
    int			version;
    int			flags;

    /* in: define set of all options */
    const char *	short_options;
    pmLongOptions *	long_options;
    const char *	short_usage;

    /* in: method for general override */
    pmOptionOverride	override;

    /* out: usual getopt information */
    int			index;
    int			optind;
    int			opterr;
    int			optopt;
    char		*optarg;

    /* internals; do not ever access */
    int			__initialized;
    char *		__nextchar;
    int			__ordering;
    int			__posixly_correct;
    int			__first_nonopt;
    int			__last_nonopt;

    /* out: error count */
    int 		errors;

    /* out: PMAPI options and values */
    int			context;	/* PM_CONTEXT_{HOST,ARCHIVE,LOCAL} */
    int			nhosts;
    int			narchives;
    char **		hosts;
    char **		archives;
    struct timeval	start;
    struct timeval	finish;
    struct timeval	origin;
    struct timeval	interval;
    char *		align_optarg;
    char *		start_optarg;
    char *		finish_optarg;
    char *		origin_optarg;
    char *		guiport_optarg;
    char *		timezone;
    int			samples;
    int			guiport;
    int			padding;
    unsigned int	guiflag : 1;
    unsigned int	tzflag  : 1;
    unsigned int	nsflag  : 1;
    unsigned int	Lflag   : 1;
    unsigned int	zeroes  : 28;
} pmOptions;

PCP_CALL extern int pmgetopt_r(int, char *const *, pmOptions *);
PCP_CALL extern int pmGetOptions(int, char *const *, pmOptions *);
PCP_CALL extern int pmGetContextOptions(int, pmOptions *);
PCP_CALL extern void pmUsageMessage(pmOptions *);
PCP_CALL extern void pmFreeOptions(pmOptions *);

/*
 * Derived Metrics support
 */
PCP_CALL extern int pmLoadDerivedConfig(const char *);
PCP_CALL extern int pmRegisterDerivedMetric(const char *, const char *, char **);
PCP_CALL extern char *pmRegisterDerived(const char *, const char *);
PCP_CALL extern char *pmDerivedErrStr(void);

/*
 * Event Record support
 */
typedef struct pmEventParameter {
    pmID		ep_pmid;
    /* vtype and vlen fields the format same as for pmValueBlock */
#ifdef HAVE_BITFIELDS_LTOR
    unsigned int	ep_type : 8;	/* value type */
    unsigned int	ep_len : 24;	/* bytes for type/len + vbuf */
#else
    unsigned int	ep_len : 24;	/* bytes for type/len + vbuf */
    unsigned int	ep_type : 8;	/* value type */
#endif
    /* actual value (vbuf) goes here ... */
} pmEventParameter;

typedef struct pmEventRecord {
    pmTimeval		er_timestamp;	/* must be 2 x 32-bit format */
    unsigned int	er_flags;	/* event record characteristics */
    int			er_nparams;	/* number of er_param[] entries */
    pmEventParameter	er_param[1];
} pmEventRecord;

typedef struct pmHighResEventRecord {
    pmTimespec	er_timestamp;	/* must be 2 x 64-bit format */
    unsigned int	er_flags;	/* event record characteristics */
    int			er_nparams;	/* number of er_param[] entries */
    pmEventParameter	er_param[1];
} pmHighResEventRecord;

/* Potential flags bits set in er_flags (above) */
#define PM_EVENT_FLAG_POINT	(1U<<0)	/* an observation, default type */
#define PM_EVENT_FLAG_START	(1U<<1)	/* marking start of a new event */
#define PM_EVENT_FLAG_END	(1U<<2)	/* completion of a traced event */
#define PM_EVENT_FLAG_ID	(1U<<3)	/* 1st parameter is a trace ID */
#define PM_EVENT_FLAG_PARENT	(1U<<4)	/* 2nd parameter is parents ID */
#define PM_EVENT_FLAG_MISSED	(1U<<31)/* nparams shows #missed events */

typedef struct pmEventArray {
		/* align initial declarations with start of pmValueBlock */
#ifdef HAVE_BITFIELDS_LTOR
    unsigned int	ea_type : 8;	/* value type */
    unsigned int	ea_len : 24;	/* bytes for type/len + vbuf */
#else
    unsigned int	ea_len : 24;	/* bytes for type/len + vbuf */
    unsigned int	ea_type : 8;	/* value type */
#endif
		/* real event records start here */
    int			ea_nrecords;    /* number of ea_record[] entries */
    pmEventRecord	ea_record[1];
} pmEventArray;

typedef struct pmHighResEventArray {
		/* align initial declarations with start of pmValueBlock */
#ifdef HAVE_BITFIELDS_LTOR
    unsigned int	ea_type : 8;	/* value type */
    unsigned int	ea_len : 24;	/* bytes for type/len + vbuf */
#else
    unsigned int	ea_len : 24;	/* bytes for type/len + vbuf */
    unsigned int	ea_type : 8;	/* value type */
#endif
		/* real event records start here */
    int			ea_nrecords;    /* number of ea_record[] entries */
    pmHighResEventRecord ea_record[1];
} pmHighResEventArray;

/* Unpack a PM_TYPE_EVENT value into a set on pmResults */
PCP_CALL extern int pmUnpackEventRecords(pmValueSet *, int, pmResult ***);

/* Free set of pmResults from pmUnpackEventRecords */
PCP_CALL extern void pmFreeEventResult(pmResult **);

/* Unpack a PM_TYPE_HIGHRES_EVENT value into a set on pmHighResResults */
PCP_CALL extern int pmUnpackHighResEventRecords(pmValueSet *, int, pmHighResResult ***);

/* Free set of pmHighResResults from pmUnpackEventRecords */
PCP_CALL extern void pmFreeHighResEventResult(pmHighResResult **);

/* Service discovery, for clients. */
#define PM_SERVER_SERVICE_SPEC	"pmcd"
#define PM_SERVER_PROXY_SPEC	"pmproxy"
#define PM_SERVER_WEBD_SPEC	"pmwebd"

PCP_CALL extern int pmDiscoverServices(const char *, const char *, char ***);

PCP_CALL extern int pmParseUnitsStr(const char *, pmUnits *, double *, char **);

typedef struct __pmFetchGroup *pmFG;	/* opaque handle */
PCP_CALL extern int pmCreateFetchGroup(pmFG *, int, const char *);
PCP_CALL extern int pmGetFetchGroupContext(pmFG);
PCP_CALL extern int pmExtendFetchGroup_item(pmFG, const char *, const char *,
			const char *, pmAtomValue *, int, int *);
PCP_CALL extern int pmExtendFetchGroup_indom(pmFG, const char *, const char *,
			int[], char *[], pmAtomValue[], int, int[],
			unsigned int, unsigned int *, int *);
PCP_CALL extern int pmExtendFetchGroup_event(pmFG, const char *, const char *,
			const char *, const char *,
			struct timespec[], pmAtomValue[], int, int[],
			unsigned int, unsigned int *, int *);
PCP_CALL extern int pmExtendFetchGroup_timestamp(pmFG, struct timeval *);
PCP_CALL extern int pmFetchGroup(pmFG);
PCP_CALL extern int pmDestroyFetchGroup(pmFG);

/* libpcp debug/tracing */
PCP_CALL extern int pmSetDebug(const char *);
PCP_CALL extern int pmClearDebug(const char *);

/*
 * New style ...
 * Note that comments are important ... these are extracted and
 * built into pmdbg.h.
 */
typedef struct {
    int	pdu;		/* PDU traffic at the Xmit and Recv level */
    int	fetch;		/* Results from pmFetch */
    int	profile;	/* Changes and xmits for instance profile */
    int	value;		/* Metric value extraction and conversion */
    int	context;	/* Changes to PMAPI contexts */
    int	indom;		/* Low-level instance profile xfers */
    int	pdubuf;		/* PDU buffer operations */
    int	log;		/* Archive log manipulations */
    int	logmeta;	/* Archive metadata operations */
    int	optfetch;	/* optFetch magic */
    int	af;		/* Asynchronous event scheduling */
    int	appl0;		/* Application-specific flag 0 */
    int	appl1;		/* Application-specific flag 1 */
    int	appl2;		/* Application-specific flag 2 */
    int	pmns;		/* PMNS operations */
    int	libpmda;	/* PMDA operations in libpcp_pmda */
    int	timecontrol;	/* Time control API */
    int	pmc;		/* Metrics class operations */
    int	derive;		/* Derived metrics functionality */
    int	lock;		/* Synchronization and lock tracing */
    int	interp;		/* Interpolate mode for archives */
    int	config;		/* Configuration parameters */
    int	pmapi;		/* PMAPI call tracing */
    int	fault;		/* Fault injection tracing */
    int	auth;		/* Authentication tracing */
    int	discovery;	/* Service discovery tracing */
    int	attr;		/* Connection attribute handling */
    int	http;		/* Trace HTTP operations in libpcp_web */
    int	desperate;	/* Verbose/Desperate level (developers only) */
/* new ones start here, no DBG_TRACE_xxx macro and no backwards compatibility */
    int	deprecated;	/* Report use of deprecated services */
    int	exec;	 	/* __pmProcessExec and related calls */
    int labels;		/* Metric label metadata operations */
    int series;		/* Time series tracing */
    int	libweb;		/* Trace services from libpcp_web */
} pmdebugoptions_t;

PCP_DATA extern pmdebugoptions_t	pmDebugOptions;

/*
 * Startup handling:
 * set/get program name, as used in pmNotifyErr() ... default is "pcp"
 */
PCP_CALL extern void pmSetProgname(const char *);
PCP_CALL extern char *pmGetProgname(void);

/*
 * Special case PMIDs
 *   Domain DYNAMIC_PMID (number 511) is reserved for PMIDs representing
 *   the root of a dynamic subtree in the PMNS (and in this case the real
 *   domain number is encoded in the cluster field and the item field is
 *   zero).
 *   Domain DYNAMIC_PMID is also reserved for the PMIDs of derived metrics
 *   and in this case the item field is non-zero.  If a derived metric is
 *   written to a PCP archive, then the top bit is set in the cluster field
 *   (to disambiguate this from derived metics that must be evaluted on
 *   the pmFetch() path).
 */
#define DYNAMIC_PMID	511
#define IS_DYNAMIC_ROOT(x) (pmID_domain(x) == DYNAMIC_PMID && pmID_item(x) == 0)
#define IS_DERIVED(x) (pmID_domain(x) == DYNAMIC_PMID && (pmID_cluster(x) & 2048) == 0 && pmID_item(x) != 0)

/*
 * pmID helper functions
 */
PCP_CALL extern pmID pmID_build(unsigned int, unsigned int, unsigned int);
PCP_CALL extern unsigned int pmID_domain(pmID);
PCP_CALL extern unsigned int pmID_cluster(pmID);
PCP_CALL extern unsigned int pmID_item(pmID);

/*
 * pmInDom helper functions
 */
PCP_CALL extern pmInDom pmInDom_build(unsigned int, unsigned int);
PCP_CALL extern unsigned int pmInDom_domain(pmInDom);
PCP_CALL extern unsigned int pmInDom_serial(pmInDom);

/*
 * Create a diagnostic log file (not an archive)
 */
PCP_CALL extern FILE *pmOpenLog(const char *, const char *, FILE *, int *);

/*
 * no mem today, my love has gone away ....
 */
PCP_CALL extern void pmNoMem(const char *, size_t, int);
#define PM_FATAL_ERR 1
#define PM_RECOV_ERR 0

/* standard error, warning and info wrapper for syslog(3) */
PCP_CALL extern void pmNotifyErr(int, const char *, ...) __PM_PRINTFLIKE(2,3);
/* make pmNotifyErr also add entries to syslog */
PCP_CALL extern void pmSyslog(int);

PCP_CALL extern void pmPrintDesc(FILE *, const pmDesc *);
PCP_CALL extern void pmPrintLabelSets(FILE *, int, int, pmLabelSet *, int);

/* struct timeval manipulations */
PCP_CALL extern void pmtimevalNow(struct timeval *);
PCP_CALL extern void pmtimevalInc(struct timeval *, const struct timeval *);
PCP_CALL extern void pmtimevalDec(struct timeval *, const struct timeval *);
PCP_CALL extern double pmtimevalAdd(const struct timeval *, const struct timeval *);
PCP_CALL extern double pmtimevalSub(const struct timeval *, const struct timeval *);
PCP_CALL extern double pmtimevalToReal(const struct timeval *);
PCP_CALL extern void pmtimevalFromReal(double, struct timeval *);
PCP_CALL extern void pmPrintStamp(FILE *, const struct timeval *);
PCP_CALL extern void pmPrintHighResStamp(FILE *, const struct timespec *);

/* filesystem path name separator */
PCP_CALL extern int pmPathSeparator(void);

/* platform independent set process identity */
PCP_CALL extern int pmSetProcessIdentity(const char *);

/*
 * get special PCP user name (for pmSetProcessIdentity() use) ...
 * default is "pcp"
 */
PCP_CALL extern int pmGetUsername(char **);

/* DSO PMDA helpers */
PCP_CALL extern char *pmSpecLocalPMDA(const char *);

#ifdef __cplusplus
}
#endif

#endif /* PCP_PMAPI_H */